@grexx/grexxlinter 0.2.2397 → 0.2.2581

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -3998,10 +3998,10 @@ var require_resolve_block_map = __commonJS({
3998
3998
  let offset = bm.offset;
3999
3999
  let commentEnd = null;
4000
4000
  for (const collItem of bm.items) {
4001
- const { start, key: key2, sep, value } = collItem;
4001
+ const { start, key: key2, sep: sep2, value } = collItem;
4002
4002
  const keyProps = resolveProps.resolveProps(start, {
4003
4003
  indicator: "explicit-key-ind",
4004
- next: key2 ?? sep?.[0],
4004
+ next: key2 ?? sep2?.[0],
4005
4005
  offset,
4006
4006
  onError,
4007
4007
  parentIndent: bm.indent,
@@ -4015,7 +4015,7 @@ var require_resolve_block_map = __commonJS({
4015
4015
  else if ("indent" in key2 && key2.indent !== bm.indent)
4016
4016
  onError(offset, "BAD_INDENT", startColMsg);
4017
4017
  }
4018
- if (!keyProps.anchor && !keyProps.tag && !sep) {
4018
+ if (!keyProps.anchor && !keyProps.tag && !sep2) {
4019
4019
  commentEnd = keyProps.end;
4020
4020
  if (keyProps.comment) {
4021
4021
  if (map.comment)
@@ -4039,7 +4039,7 @@ var require_resolve_block_map = __commonJS({
4039
4039
  ctx.atKey = false;
4040
4040
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
4041
4041
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
4042
- const valueProps = resolveProps.resolveProps(sep ?? [], {
4042
+ const valueProps = resolveProps.resolveProps(sep2 ?? [], {
4043
4043
  indicator: "map-value-ind",
4044
4044
  next: value,
4045
4045
  offset: keyNode.range[2],
@@ -4055,7 +4055,7 @@ var require_resolve_block_map = __commonJS({
4055
4055
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
4056
4056
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
4057
4057
  }
4058
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep, null, valueProps, onError);
4058
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep2, null, valueProps, onError);
4059
4059
  if (ctx.schema.compat)
4060
4060
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
4061
4061
  offset = valueNode.range[2];
@@ -4146,7 +4146,7 @@ var require_resolve_end = __commonJS({
4146
4146
  let comment = "";
4147
4147
  if (end) {
4148
4148
  let hasSpace = false;
4149
- let sep = "";
4149
+ let sep2 = "";
4150
4150
  for (const token of end) {
4151
4151
  const { source, type } = token;
4152
4152
  switch (type) {
@@ -4160,13 +4160,13 @@ var require_resolve_end = __commonJS({
4160
4160
  if (!comment)
4161
4161
  comment = cb;
4162
4162
  else
4163
- comment += sep + cb;
4164
- sep = "";
4163
+ comment += sep2 + cb;
4164
+ sep2 = "";
4165
4165
  break;
4166
4166
  }
4167
4167
  case "newline":
4168
4168
  if (comment)
4169
- sep += source;
4169
+ sep2 += source;
4170
4170
  hasSpace = true;
4171
4171
  break;
4172
4172
  default:
@@ -4209,18 +4209,18 @@ var require_resolve_flow_collection = __commonJS({
4209
4209
  let offset = fc.offset + fc.start.source.length;
4210
4210
  for (let i = 0; i < fc.items.length; ++i) {
4211
4211
  const collItem = fc.items[i];
4212
- const { start, key: key2, sep, value } = collItem;
4212
+ const { start, key: key2, sep: sep2, value } = collItem;
4213
4213
  const props = resolveProps.resolveProps(start, {
4214
4214
  flow: fcName,
4215
4215
  indicator: "explicit-key-ind",
4216
- next: key2 ?? sep?.[0],
4216
+ next: key2 ?? sep2?.[0],
4217
4217
  offset,
4218
4218
  onError,
4219
4219
  parentIndent: fc.indent,
4220
4220
  startOnNewline: false
4221
4221
  });
4222
4222
  if (!props.found) {
4223
- if (!props.anchor && !props.tag && !sep && !value) {
4223
+ if (!props.anchor && !props.tag && !sep2 && !value) {
4224
4224
  if (i === 0 && props.comma)
4225
4225
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
4226
4226
  else if (i < fc.items.length - 1)
@@ -4274,8 +4274,8 @@ var require_resolve_flow_collection = __commonJS({
4274
4274
  }
4275
4275
  }
4276
4276
  }
4277
- if (!isMap && !sep && !props.found) {
4278
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep, null, props, onError);
4277
+ if (!isMap && !sep2 && !props.found) {
4278
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep2, null, props, onError);
4279
4279
  coll.items.push(valueNode);
4280
4280
  offset = valueNode.range[2];
4281
4281
  if (isBlock(value))
@@ -4287,7 +4287,7 @@ var require_resolve_flow_collection = __commonJS({
4287
4287
  if (isBlock(key2))
4288
4288
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
4289
4289
  ctx.atKey = false;
4290
- const valueProps = resolveProps.resolveProps(sep ?? [], {
4290
+ const valueProps = resolveProps.resolveProps(sep2 ?? [], {
4291
4291
  flow: fcName,
4292
4292
  indicator: "map-value-ind",
4293
4293
  next: value,
@@ -4298,8 +4298,8 @@ var require_resolve_flow_collection = __commonJS({
4298
4298
  });
4299
4299
  if (valueProps.found) {
4300
4300
  if (!isMap && !props.found && ctx.options.strict) {
4301
- if (sep)
4302
- for (const st of sep) {
4301
+ if (sep2)
4302
+ for (const st of sep2) {
4303
4303
  if (st === valueProps.found)
4304
4304
  break;
4305
4305
  if (st.type === "newline") {
@@ -4316,7 +4316,7 @@ var require_resolve_flow_collection = __commonJS({
4316
4316
  else
4317
4317
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
4318
4318
  }
4319
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep, null, valueProps, onError) : null;
4319
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep2, null, valueProps, onError) : null;
4320
4320
  if (valueNode) {
4321
4321
  if (isBlock(value))
4322
4322
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -4496,7 +4496,7 @@ var require_resolve_block_scalar = __commonJS({
4496
4496
  chompStart = i + 1;
4497
4497
  }
4498
4498
  let value = "";
4499
- let sep = "";
4499
+ let sep2 = "";
4500
4500
  let prevMoreIndented = false;
4501
4501
  for (let i = 0; i < contentStart; ++i)
4502
4502
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -4513,24 +4513,24 @@ var require_resolve_block_scalar = __commonJS({
4513
4513
  indent = "";
4514
4514
  }
4515
4515
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
4516
- value += sep + indent.slice(trimIndent) + content;
4517
- sep = "\n";
4516
+ value += sep2 + indent.slice(trimIndent) + content;
4517
+ sep2 = "\n";
4518
4518
  } else if (indent.length > trimIndent || content[0] === " ") {
4519
- if (sep === " ")
4520
- sep = "\n";
4521
- else if (!prevMoreIndented && sep === "\n")
4522
- sep = "\n\n";
4523
- value += sep + indent.slice(trimIndent) + content;
4524
- sep = "\n";
4519
+ if (sep2 === " ")
4520
+ sep2 = "\n";
4521
+ else if (!prevMoreIndented && sep2 === "\n")
4522
+ sep2 = "\n\n";
4523
+ value += sep2 + indent.slice(trimIndent) + content;
4524
+ sep2 = "\n";
4525
4525
  prevMoreIndented = true;
4526
4526
  } else if (content === "") {
4527
- if (sep === "\n")
4527
+ if (sep2 === "\n")
4528
4528
  value += "\n";
4529
4529
  else
4530
- sep = "\n";
4530
+ sep2 = "\n";
4531
4531
  } else {
4532
- value += sep + content;
4533
- sep = " ";
4532
+ value += sep2 + content;
4533
+ sep2 = " ";
4534
4534
  prevMoreIndented = false;
4535
4535
  }
4536
4536
  }
@@ -4712,25 +4712,25 @@ var require_resolve_flow_scalar = __commonJS({
4712
4712
  if (!match)
4713
4713
  return source;
4714
4714
  let res = match[1];
4715
- let sep = " ";
4715
+ let sep2 = " ";
4716
4716
  let pos = first.lastIndex;
4717
4717
  line.lastIndex = pos;
4718
4718
  while (match = line.exec(source)) {
4719
4719
  if (match[1] === "") {
4720
- if (sep === "\n")
4721
- res += sep;
4720
+ if (sep2 === "\n")
4721
+ res += sep2;
4722
4722
  else
4723
- sep = "\n";
4723
+ sep2 = "\n";
4724
4724
  } else {
4725
- res += sep + match[1];
4726
- sep = " ";
4725
+ res += sep2 + match[1];
4726
+ sep2 = " ";
4727
4727
  }
4728
4728
  pos = line.lastIndex;
4729
4729
  }
4730
4730
  const last = /[ \t]*(.*)/sy;
4731
4731
  last.lastIndex = pos;
4732
4732
  match = last.exec(source);
4733
- return res + sep + (match?.[1] ?? "");
4733
+ return res + sep2 + (match?.[1] ?? "");
4734
4734
  }
4735
4735
  function doubleQuotedValue(source, onError) {
4736
4736
  let res = "";
@@ -5540,14 +5540,14 @@ var require_cst_stringify = __commonJS({
5540
5540
  }
5541
5541
  }
5542
5542
  }
5543
- function stringifyItem({ start, key: key2, sep, value }) {
5543
+ function stringifyItem({ start, key: key2, sep: sep2, value }) {
5544
5544
  let res = "";
5545
5545
  for (const st of start)
5546
5546
  res += st.source;
5547
5547
  if (key2)
5548
5548
  res += stringifyToken(key2);
5549
- if (sep)
5550
- for (const st of sep)
5549
+ if (sep2)
5550
+ for (const st of sep2)
5551
5551
  res += st.source;
5552
5552
  if (value)
5553
5553
  res += stringifyToken(value);
@@ -6714,18 +6714,18 @@ var require_parser = __commonJS({
6714
6714
  if (this.type === "map-value-ind") {
6715
6715
  const prev = getPrevProps(this.peek(2));
6716
6716
  const start = getFirstKeyStartProps(prev);
6717
- let sep;
6717
+ let sep2;
6718
6718
  if (scalar.end) {
6719
- sep = scalar.end;
6720
- sep.push(this.sourceToken);
6719
+ sep2 = scalar.end;
6720
+ sep2.push(this.sourceToken);
6721
6721
  delete scalar.end;
6722
6722
  } else
6723
- sep = [this.sourceToken];
6723
+ sep2 = [this.sourceToken];
6724
6724
  const map = {
6725
6725
  type: "block-map",
6726
6726
  offset: scalar.offset,
6727
6727
  indent: scalar.indent,
6728
- items: [{ start, key: scalar, sep }]
6728
+ items: [{ start, key: scalar, sep: sep2 }]
6729
6729
  };
6730
6730
  this.onKeyLine = true;
6731
6731
  this.stack[this.stack.length - 1] = map;
@@ -6878,15 +6878,15 @@ var require_parser = __commonJS({
6878
6878
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
6879
6879
  const start2 = getFirstKeyStartProps(it.start);
6880
6880
  const key2 = it.key;
6881
- const sep = it.sep;
6882
- sep.push(this.sourceToken);
6881
+ const sep2 = it.sep;
6882
+ sep2.push(this.sourceToken);
6883
6883
  delete it.key;
6884
6884
  delete it.sep;
6885
6885
  this.stack.push({
6886
6886
  type: "block-map",
6887
6887
  offset: this.offset,
6888
6888
  indent: this.indent,
6889
- items: [{ start: start2, key: key2, sep }]
6889
+ items: [{ start: start2, key: key2, sep: sep2 }]
6890
6890
  });
6891
6891
  } else if (start.length > 0) {
6892
6892
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -7080,13 +7080,13 @@ var require_parser = __commonJS({
7080
7080
  const prev = getPrevProps(parent);
7081
7081
  const start = getFirstKeyStartProps(prev);
7082
7082
  fixFlowSeqItems(fc);
7083
- const sep = fc.end.splice(1, fc.end.length);
7084
- sep.push(this.sourceToken);
7083
+ const sep2 = fc.end.splice(1, fc.end.length);
7084
+ sep2.push(this.sourceToken);
7085
7085
  const map = {
7086
7086
  type: "block-map",
7087
7087
  offset: fc.offset,
7088
7088
  indent: fc.indent,
7089
- items: [{ start, key: fc, sep }]
7089
+ items: [{ start, key: fc, sep: sep2 }]
7090
7090
  };
7091
7091
  this.onKeyLine = true;
7092
7092
  this.stack[this.stack.length - 1] = map;
@@ -10434,16 +10434,18 @@ var require_data = __commonJS({
10434
10434
  }
10435
10435
  });
10436
10436
 
10437
- // ../../node_modules/.pnpm/fast-uri@4.1.2/node_modules/fast-uri/lib/utils.js
10437
+ // ../../node_modules/.pnpm/fast-uri@4.1.4/node_modules/fast-uri/lib/utils.js
10438
10438
  var require_utils = __commonJS({
10439
- "../../node_modules/.pnpm/fast-uri@4.1.2/node_modules/fast-uri/lib/utils.js"(exports, module) {
10439
+ "../../node_modules/.pnpm/fast-uri@4.1.4/node_modules/fast-uri/lib/utils.js"(exports, module) {
10440
10440
  "use strict";
10441
10441
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
10442
10442
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
10443
+ var isPort = RegExp.prototype.test.bind(/^\d*$/u);
10443
10444
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
10444
10445
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
10445
- var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
10446
- var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/?]$/iu);
10446
+ var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
10447
+ var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
10448
+ var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
10447
10449
  function stringArrayToHexStripped(input) {
10448
10450
  let acc = "";
10449
10451
  let code = 0;
@@ -10468,91 +10470,110 @@ var require_utils = __commonJS({
10468
10470
  }
10469
10471
  return acc;
10470
10472
  }
10473
+ var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
10474
+ var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
10475
+ var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
10471
10476
  var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
10472
- function consumeIsZone(buffer) {
10473
- buffer.length = 0;
10474
- return true;
10475
- }
10476
- function consumeHextets(buffer, address, output) {
10477
- if (buffer.length) {
10478
- const hex = stringArrayToHexStripped(buffer);
10479
- if (hex !== "") {
10480
- address.push(hex);
10481
- } else {
10482
- output.error = true;
10483
- return false;
10477
+ var nonSimpleDomainChars = RegExp.prototype.test.bind(/[^\d!"$&'()*+,\-.;=_`a-z{}~]/u);
10478
+ var numericLastLabel = RegExp.prototype.test.bind(/(?:^|\.)\d+$/u);
10479
+ function nonSimpleMailtoDomain(domain) {
10480
+ return nonSimpleDomainChars(domain) || numericLastLabel(domain);
10481
+ }
10482
+ function isZoneIdentifier(zone) {
10483
+ if (zone.length === 0) return false;
10484
+ for (let i = 0; i < zone.length; i++) {
10485
+ if (isZoneCharacter(zone[i])) continue;
10486
+ if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
10487
+ i += 2;
10488
+ continue;
10484
10489
  }
10485
- buffer.length = 0;
10490
+ return false;
10486
10491
  }
10487
10492
  return true;
10488
10493
  }
10489
- function getIPV6(input) {
10490
- let tokenCount = 0;
10491
- const output = { error: false, address: "", zone: "" };
10492
- const address = [];
10493
- const buffer = [];
10494
- let endipv6Encountered = false;
10495
- let endIpv6 = false;
10496
- let consume = consumeHextets;
10497
- for (let i = 0; i < input.length; i++) {
10498
- const cursor = input[i];
10499
- if (cursor === "[" || cursor === "]") {
10500
- continue;
10501
- }
10502
- if (cursor === ":") {
10503
- if (endipv6Encountered === true) {
10504
- endIpv6 = true;
10505
- }
10506
- if (!consume(buffer, address, output)) {
10507
- break;
10508
- }
10509
- if (++tokenCount > 7) {
10510
- output.error = true;
10511
- break;
10512
- }
10513
- if (i > 0 && input[i - 1] === ":") {
10514
- endipv6Encountered = true;
10515
- }
10516
- address.push(":");
10517
- continue;
10518
- } else if (cursor === "%") {
10519
- if (!consume(buffer, address, output)) {
10520
- break;
10494
+ function compressIPv6ZeroRun(hextets) {
10495
+ let bestStart = -1;
10496
+ let bestLength = 0;
10497
+ let runStart = -1;
10498
+ let runLength = 0;
10499
+ for (let i = 0; i < hextets.length; i++) {
10500
+ if (hextets[i] === "0") {
10501
+ if (runStart === -1) runStart = i;
10502
+ runLength++;
10503
+ if (runLength > bestLength) {
10504
+ bestLength = runLength;
10505
+ bestStart = runStart;
10521
10506
  }
10522
- consume = consumeIsZone;
10523
10507
  } else {
10524
- buffer.push(cursor);
10508
+ runStart = -1;
10509
+ runLength = 0;
10510
+ }
10511
+ }
10512
+ if (bestLength < 2) return hextets.join(":");
10513
+ const head = hextets.slice(0, bestStart).join(":");
10514
+ const tail = hextets.slice(bestStart + bestLength).join(":");
10515
+ return head + "::" + tail;
10516
+ }
10517
+ function normalizeIPv6Address(input) {
10518
+ const compression = input.indexOf("::");
10519
+ if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
10520
+ const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
10521
+ const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
10522
+ if (compression !== -1) {
10523
+ if (left.length === 1 && left[0] === "") left.length = 0;
10524
+ if (right.length === 1 && right[0] === "") right.length = 0;
10525
+ }
10526
+ const parts = left.concat(right);
10527
+ let hextetCount = 0;
10528
+ for (let i = 0; i < parts.length; i++) {
10529
+ const part = parts[i];
10530
+ if (part === "") return void 0;
10531
+ if (part.indexOf(".") !== -1) {
10532
+ if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
10533
+ hextetCount += 2;
10525
10534
  continue;
10526
10535
  }
10536
+ if (!isHextet(part)) return void 0;
10537
+ parts[i] = parseInt(part, 16).toString(16);
10538
+ hextetCount++;
10527
10539
  }
10528
- if (buffer.length) {
10529
- if (consume === consumeIsZone) {
10530
- output.zone = buffer.join("");
10531
- } else if (endIpv6) {
10532
- address.push(buffer.join(""));
10533
- } else {
10534
- address.push(stringArrayToHexStripped(buffer));
10535
- }
10540
+ if (compression === -1) {
10541
+ if (hextetCount !== 8) return void 0;
10542
+ return compressIPv6ZeroRun(parts);
10536
10543
  }
10537
- output.address = address.join("");
10538
- return output;
10544
+ if (hextetCount >= 8) return void 0;
10545
+ const expanded = parts.slice(0, left.length);
10546
+ for (let i = hextetCount; i < 8; i++) expanded.push("0");
10547
+ for (let i = left.length; i < parts.length; i++) expanded.push(parts[i]);
10548
+ return compressIPv6ZeroRun(expanded);
10539
10549
  }
10540
10550
  function normalizeIPv6(host) {
10541
- if (findToken(host, ":") < 2) {
10542
- return { host, isIPV6: false };
10543
- }
10544
- const ipv6 = getIPV6(host);
10545
- if (!ipv6.error) {
10546
- let newHost = ipv6.address;
10547
- let escapedHost = ipv6.address;
10548
- if (ipv6.zone) {
10549
- newHost += "%" + ipv6.zone;
10550
- escapedHost += "%25" + ipv6.zone;
10551
- }
10552
- return { host: newHost, isIPV6: true, escapedHost };
10553
- } else {
10554
- return { host, isIPV6: false };
10555
- }
10551
+ const bracketed = host[0] === "[" && host[host.length - 1] === "]";
10552
+ const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
10553
+ if (hasBracket && !bracketed) return { host, isIPV6: false, error: true };
10554
+ let input = bracketed ? host.slice(1, -1) : host;
10555
+ if (bracketed && isIPvFuture(input)) {
10556
+ input = input.toLowerCase();
10557
+ return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
10558
+ }
10559
+ if (findToken(input, ":") < 2) {
10560
+ return { host, isIPV6: false, error: bracketed };
10561
+ }
10562
+ let zoneIdentifier = "";
10563
+ const zoneSeparator = input.indexOf("%");
10564
+ if (zoneSeparator !== -1) {
10565
+ const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
10566
+ zoneIdentifier = input.slice(zoneSeparator + separatorLength);
10567
+ if (!isZoneIdentifier(zoneIdentifier)) return { host, isIPV6: false, error: true };
10568
+ input = input.slice(0, zoneSeparator);
10569
+ }
10570
+ const address = normalizeIPv6Address(input);
10571
+ if (address === void 0) return { host, isIPV6: false, error: true };
10572
+ return {
10573
+ host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
10574
+ escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
10575
+ isIPV6: true
10576
+ };
10556
10577
  }
10557
10578
  function findToken(str, token) {
10558
10579
  let ind = 0;
@@ -10728,6 +10749,45 @@ var require_utils = __commonJS({
10728
10749
  }
10729
10750
  return output;
10730
10751
  }
10752
+ function serializePathEncoding(input, pathNoScheme = false) {
10753
+ let output = "";
10754
+ let firstSegment = pathNoScheme && input[0] !== "/";
10755
+ for (let i = 0; i < input.length; i++) {
10756
+ const ch = input[i];
10757
+ if (ch === "%" && i + 2 < input.length) {
10758
+ const hex = input.slice(i + 1, i + 3);
10759
+ if (isHexPair(hex)) {
10760
+ output += "%" + hex.toUpperCase();
10761
+ i += 2;
10762
+ continue;
10763
+ }
10764
+ }
10765
+ if (ch === "/") {
10766
+ firstSegment = false;
10767
+ }
10768
+ if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
10769
+ output += ch;
10770
+ } else {
10771
+ const code = input.charCodeAt(i);
10772
+ if (code < 128) {
10773
+ output += BYTE_HEX[code];
10774
+ } else if (code < 55296 || code > 57343) {
10775
+ output += percentEncodeNonAscii(code);
10776
+ } else if (code <= 56319 && i + 1 < input.length) {
10777
+ const low = input.charCodeAt(i + 1);
10778
+ if (low >= 56320 && low <= 57343) {
10779
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
10780
+ i++;
10781
+ } else {
10782
+ output += percentEncodeNonAscii(65533);
10783
+ }
10784
+ } else {
10785
+ output += percentEncodeNonAscii(65533);
10786
+ }
10787
+ }
10788
+ }
10789
+ return output;
10790
+ }
10731
10791
  function normalizeQueryFragmentEncoding(input) {
10732
10792
  let output = "";
10733
10793
  for (let i = 0; i < input.length; i++) {
@@ -10769,6 +10829,50 @@ var require_utils = __commonJS({
10769
10829
  }
10770
10830
  return output;
10771
10831
  }
10832
+ function encodeComponent(input, isAllowed) {
10833
+ let output = "";
10834
+ for (let i = 0; i < input.length; i++) {
10835
+ const ch = input[i];
10836
+ if (ch === "%" && i + 2 < input.length) {
10837
+ const hex = input.slice(i + 1, i + 3);
10838
+ if (isHexPair(hex)) {
10839
+ output += "%" + hex.toUpperCase();
10840
+ i += 2;
10841
+ continue;
10842
+ }
10843
+ }
10844
+ if (isAllowed(ch)) {
10845
+ output += ch;
10846
+ } else {
10847
+ const code = input.charCodeAt(i);
10848
+ if (code < 128) {
10849
+ output += BYTE_HEX[code];
10850
+ } else if (code < 55296 || code > 57343) {
10851
+ output += percentEncodeNonAscii(code);
10852
+ } else if (code <= 56319 && i + 1 < input.length) {
10853
+ const low = input.charCodeAt(i + 1);
10854
+ if (low >= 56320 && low <= 57343) {
10855
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
10856
+ i++;
10857
+ } else {
10858
+ output += percentEncodeNonAscii(65533);
10859
+ }
10860
+ } else {
10861
+ output += percentEncodeNonAscii(65533);
10862
+ }
10863
+ }
10864
+ }
10865
+ return output;
10866
+ }
10867
+ function encodeUserinfo(input) {
10868
+ return encodeComponent(input, isUserinfoCharacter);
10869
+ }
10870
+ function encodeQuery(input) {
10871
+ return encodeComponent(input, isQueryFragmentCharacter);
10872
+ }
10873
+ function encodeFragment(input) {
10874
+ return encodeComponent(input, isQueryFragmentCharacter);
10875
+ }
10772
10876
  function escapePreservingEscapes(input) {
10773
10877
  let output = "";
10774
10878
  for (let i = 0; i < input.length; i++) {
@@ -10803,14 +10907,18 @@ var require_utils = __commonJS({
10803
10907
  function recomposeAuthority(component) {
10804
10908
  const uriTokens = [];
10805
10909
  if (component.userinfo !== void 0) {
10806
- uriTokens.push(component.userinfo);
10910
+ uriTokens.push(encodeUserinfo(component.userinfo));
10807
10911
  uriTokens.push("@");
10808
10912
  }
10809
10913
  if (component.host !== void 0) {
10810
- let host = unescape(component.host);
10914
+ let host = component.host;
10811
10915
  if (!isIPv4(host)) {
10812
- const ipV6res = normalizeIPv6(host);
10813
- if (ipV6res.isIPV6 === true) {
10916
+ let ipV6res = normalizeIPv6(host);
10917
+ if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
10918
+ host = normalizePercentEncoding(host, true);
10919
+ ipV6res = normalizeIPv6(host);
10920
+ }
10921
+ if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
10814
10922
  host = `[${ipV6res.escapedHost}]`;
10815
10923
  } else {
10816
10924
  host = reescapeHostDelimiters(host, false);
@@ -10819,18 +10927,29 @@ var require_utils = __commonJS({
10819
10927
  uriTokens.push(host);
10820
10928
  }
10821
10929
  if (typeof component.port === "number" || typeof component.port === "string") {
10930
+ const port = String(component.port);
10931
+ if (!isPort(port)) {
10932
+ throw new TypeError("URI port is malformed.");
10933
+ }
10822
10934
  uriTokens.push(":");
10823
- uriTokens.push(String(component.port));
10935
+ uriTokens.push(port);
10824
10936
  }
10825
10937
  return uriTokens.length ? uriTokens.join("") : void 0;
10826
10938
  }
10827
10939
  module.exports = {
10940
+ BYTE_HEX,
10941
+ percentEncodeNonAscii,
10828
10942
  nonSimpleDomain,
10943
+ nonSimpleMailtoDomain,
10829
10944
  recomposeAuthority,
10830
10945
  reescapeHostDelimiters,
10831
10946
  normalizePercentEncoding,
10832
10947
  normalizePathEncoding,
10948
+ serializePathEncoding,
10833
10949
  normalizeQueryFragmentEncoding,
10950
+ encodeUserinfo,
10951
+ encodeQuery,
10952
+ encodeFragment,
10834
10953
  escapePreservingEscapes,
10835
10954
  removeDotSegments,
10836
10955
  isIPv4,
@@ -10841,12 +10960,12 @@ var require_utils = __commonJS({
10841
10960
  }
10842
10961
  });
10843
10962
 
10844
- // ../../node_modules/.pnpm/fast-uri@4.1.2/node_modules/fast-uri/lib/schemes.js
10963
+ // ../../node_modules/.pnpm/fast-uri@4.1.4/node_modules/fast-uri/lib/schemes.js
10845
10964
  var require_schemes = __commonJS({
10846
- "../../node_modules/.pnpm/fast-uri@4.1.2/node_modules/fast-uri/lib/schemes.js"(exports, module) {
10965
+ "../../node_modules/.pnpm/fast-uri@4.1.4/node_modules/fast-uri/lib/schemes.js"(exports, module) {
10847
10966
  "use strict";
10848
- var { isUUID } = require_utils();
10849
- var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
10967
+ var { isUUID, BYTE_HEX, percentEncodeNonAscii, nonSimpleMailtoDomain } = require_utils();
10968
+ var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
10850
10969
  var supportedSchemeNames = (
10851
10970
  /** @type {const} */
10852
10971
  [
@@ -10855,7 +10974,8 @@ var require_schemes = __commonJS({
10855
10974
  "ws",
10856
10975
  "wss",
10857
10976
  "urn",
10858
- "urn:uuid"
10977
+ "urn:uuid",
10978
+ "mailto"
10859
10979
  ]
10860
10980
  );
10861
10981
  function isValidSchemeName(name) {
@@ -10907,9 +11027,10 @@ var require_schemes = __commonJS({
10907
11027
  wsComponent.secure = void 0;
10908
11028
  }
10909
11029
  if (wsComponent.resourceName) {
10910
- const [path, query] = wsComponent.resourceName.split("?");
11030
+ const queryIndex = wsComponent.resourceName.indexOf("?");
11031
+ const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
10911
11032
  wsComponent.path = path && path !== "/" ? path : void 0;
10912
- wsComponent.query = query;
11033
+ wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
10913
11034
  wsComponent.resourceName = void 0;
10914
11035
  }
10915
11036
  wsComponent.fragment = void 0;
@@ -10921,7 +11042,7 @@ var require_schemes = __commonJS({
10921
11042
  return urnComponent;
10922
11043
  }
10923
11044
  const matches = urnComponent.path.match(URN_REG);
10924
- if (matches) {
11045
+ if (matches && matches[0] === urnComponent.path) {
10925
11046
  const scheme = options.scheme || urnComponent.scheme || "urn";
10926
11047
  urnComponent.nid = matches[1].toLowerCase();
10927
11048
  urnComponent.nss = matches[2];
@@ -11021,6 +11142,226 @@ var require_schemes = __commonJS({
11021
11142
  skipNormalize: true
11022
11143
  }
11023
11144
  );
11145
+ var LOCAL_PART_ALLOWED = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$'()*+=";
11146
+ var HFNAME_ALLOWED = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$'()*+,;:@";
11147
+ var DTEXT_ALLOWED = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$'()*+;:";
11148
+ function allowSet(chars, allowNonAscii = false) {
11149
+ const table = new Uint8Array(128);
11150
+ for (let i = 0; i < chars.length; i++) {
11151
+ table[chars.charCodeAt(i)] = 1;
11152
+ }
11153
+ const escaped = chars.replace(/[\\\]^-]/gu, "\\$&");
11154
+ const cls = allowNonAscii ? `[${escaped}]|[^\\0-\\x7F\\uD800-\\uDFFF]` : `[${escaped}]`;
11155
+ return { all: new RegExp(`^(?:${cls})*$`, "u"), table, allowNonAscii };
11156
+ }
11157
+ var LOCAL_PART = allowSet(LOCAL_PART_ALLOWED);
11158
+ var HFNAME = allowSet(HFNAME_ALLOWED);
11159
+ var DTEXT = allowSet(DTEXT_ALLOWED);
11160
+ var DTEXT_IRI = allowSet(DTEXT_ALLOWED, true);
11161
+ var HEX_PAIR = /^[\da-f]{2}$/iu;
11162
+ var MAILTO_DOMAIN_LITERAL = /^\[[\x21-\x5A\x5E-\x7E]*\]$/u;
11163
+ var MAILTO_DOMAIN_ERROR = "URI mailto has an invalid recipient domain.";
11164
+ var HAS_SURROGATE = /[\uD800-\uDFFF]/u;
11165
+ function decodeHex(str) {
11166
+ if (typeof str !== "string" || str.indexOf("%") === -1) {
11167
+ return str;
11168
+ }
11169
+ try {
11170
+ return decodeURIComponent(str);
11171
+ } catch {
11172
+ return str;
11173
+ }
11174
+ }
11175
+ function replaceLoneSurrogates(input) {
11176
+ let result = "";
11177
+ for (let i = 0; i < input.length; i++) {
11178
+ const code = input.charCodeAt(i);
11179
+ if (code >= 55296 && code <= 56319 && i + 1 < input.length) {
11180
+ const low = input.charCodeAt(i + 1);
11181
+ if (low >= 56320 && low <= 57343) {
11182
+ result += input[i] + input[i + 1];
11183
+ i++;
11184
+ continue;
11185
+ }
11186
+ }
11187
+ result += code >= 55296 && code <= 57343 ? "\uFFFD" : input[i];
11188
+ }
11189
+ return result;
11190
+ }
11191
+ function encodeWithAllow(input, set) {
11192
+ if (set.all.test(input)) {
11193
+ return input;
11194
+ }
11195
+ const table = set.table;
11196
+ let result = "";
11197
+ for (let i = 0; i < input.length; i++) {
11198
+ const code = input.charCodeAt(i);
11199
+ if (code < 128) {
11200
+ if (table[code] === 1) {
11201
+ result += input[i];
11202
+ } else if (code === 37 && i + 2 < input.length && HEX_PAIR.test(input.slice(i + 1, i + 3))) {
11203
+ result += "%" + input.slice(i + 1, i + 3).toUpperCase();
11204
+ i += 2;
11205
+ } else {
11206
+ result += BYTE_HEX[code];
11207
+ }
11208
+ continue;
11209
+ }
11210
+ if (code < 55296 || code > 57343) {
11211
+ result += set.allowNonAscii ? input[i] : percentEncodeNonAscii(code);
11212
+ continue;
11213
+ }
11214
+ if (code <= 56319 && i + 1 < input.length) {
11215
+ const low = input.charCodeAt(i + 1);
11216
+ if (low >= 56320 && low <= 57343) {
11217
+ result += set.allowNonAscii ? input[i] + input[i + 1] : percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
11218
+ i++;
11219
+ continue;
11220
+ }
11221
+ }
11222
+ result += set.allowNonAscii ? "\uFFFD" : percentEncodeNonAscii(65533);
11223
+ }
11224
+ return result;
11225
+ }
11226
+ function mailtoNormalizeDomain(domain, options, component) {
11227
+ const normalizedDomain = String(domain).toLowerCase();
11228
+ if (MAILTO_DOMAIN_LITERAL.test(normalizedDomain)) {
11229
+ return normalizedDomain;
11230
+ }
11231
+ if (normalizedDomain !== "" && !nonSimpleMailtoDomain(normalizedDomain)) {
11232
+ return normalizedDomain;
11233
+ }
11234
+ try {
11235
+ const parsedDomain = new URL("http://" + normalizedDomain);
11236
+ if (parsedDomain.username || parsedDomain.password || parsedDomain.port || parsedDomain.pathname !== "/" || parsedDomain.search || parsedDomain.hash || !parsedDomain.hostname) {
11237
+ throw new Error(MAILTO_DOMAIN_ERROR);
11238
+ }
11239
+ return options && options.unicodeSupport ? normalizedDomain : parsedDomain.hostname;
11240
+ } catch {
11241
+ if (component) {
11242
+ component.error = component.error || MAILTO_DOMAIN_ERROR;
11243
+ }
11244
+ return normalizedDomain;
11245
+ }
11246
+ }
11247
+ function mailtoEncodeDomain(domain, options) {
11248
+ const set = options && options.unicodeSupport ? DTEXT_IRI : DTEXT;
11249
+ if (domain.length > 1 && domain[0] === "[" && domain[domain.length - 1] === "]") {
11250
+ return "[" + encodeWithAllow(domain.slice(1, -1), set) + "]";
11251
+ }
11252
+ return encodeWithAllow(domain, set);
11253
+ }
11254
+ function mailtoParse(component, options) {
11255
+ const mailtoComponent = component;
11256
+ let rawPath = mailtoComponent.path;
11257
+ let rawQuery = mailtoComponent.query;
11258
+ if (rawPath && HAS_SURROGATE.test(rawPath)) rawPath = replaceLoneSurrogates(rawPath);
11259
+ if (rawQuery && HAS_SURROGATE.test(rawQuery)) rawQuery = replaceLoneSurrogates(rawQuery);
11260
+ const to = rawPath ? rawPath.indexOf(",") === -1 ? [rawPath] : rawPath.split(",") : [];
11261
+ mailtoComponent.path = void 0;
11262
+ if (rawQuery) {
11263
+ let headers = null;
11264
+ let start = 0;
11265
+ while (start <= rawQuery.length) {
11266
+ let end = rawQuery.indexOf("&", start);
11267
+ if (end === -1) end = rawQuery.length;
11268
+ const token = rawQuery.slice(start, end);
11269
+ start = end + 1;
11270
+ const eqIdx = token.indexOf("=");
11271
+ if (eqIdx !== token.lastIndexOf("=")) {
11272
+ mailtoComponent.error = mailtoComponent.error || "URI mailto has malformed header fields.";
11273
+ continue;
11274
+ }
11275
+ const name = eqIdx === -1 ? token : token.slice(0, eqIdx);
11276
+ const value = eqIdx === -1 ? "" : token.slice(eqIdx + 1);
11277
+ if (name === "to") {
11278
+ const addrs = value.split(",");
11279
+ for (let j = 0; j < addrs.length; j++) to.push(addrs[j]);
11280
+ continue;
11281
+ }
11282
+ if (name === "subject") {
11283
+ mailtoComponent.subject = decodeHex(value);
11284
+ continue;
11285
+ }
11286
+ if (name === "body") {
11287
+ mailtoComponent.body = decodeHex(value);
11288
+ continue;
11289
+ }
11290
+ if (headers === null) headers = /** @type {Record<string,string>} */
11291
+ /* @__PURE__ */ Object.create(null);
11292
+ headers[decodeHex(name)] = decodeHex(value);
11293
+ }
11294
+ if (headers !== null) mailtoComponent.headers = headers;
11295
+ }
11296
+ mailtoComponent.query = void 0;
11297
+ for (let i = 0; i < to.length; i++) {
11298
+ const rawAddr = to[i];
11299
+ const atIdx = rawAddr.lastIndexOf("@");
11300
+ if (atIdx < 0) {
11301
+ mailtoComponent.error = mailtoComponent.error || MAILTO_DOMAIN_ERROR;
11302
+ to[i] = decodeHex(rawAddr);
11303
+ continue;
11304
+ }
11305
+ const local = decodeHex(rawAddr.slice(0, atIdx));
11306
+ const domain = mailtoNormalizeDomain(decodeHex(rawAddr.slice(atIdx + 1)), options, mailtoComponent);
11307
+ to[i] = local + "@" + domain;
11308
+ }
11309
+ if (to.length) mailtoComponent.to = to;
11310
+ return mailtoComponent;
11311
+ }
11312
+ function mailtoSerialize(component, options) {
11313
+ const mailtoComponent = component;
11314
+ const to = Array.isArray(mailtoComponent.to) ? mailtoComponent.to.slice() : [];
11315
+ if (to.length) {
11316
+ for (let i = 0; i < to.length; i++) {
11317
+ const addr = String(to[i]);
11318
+ const atIdx = addr.lastIndexOf("@");
11319
+ const rawLocal = atIdx >= 0 ? addr.slice(0, atIdx) : addr;
11320
+ const rawDomain = atIdx >= 0 ? addr.slice(atIdx + 1) : "";
11321
+ const local = encodeWithAllow(rawLocal, LOCAL_PART);
11322
+ const decodedDomain = decodeHex(rawDomain);
11323
+ const normalizedDomain = mailtoNormalizeDomain(decodedDomain, options);
11324
+ to[i] = local + "@" + mailtoEncodeDomain(normalizedDomain, options);
11325
+ }
11326
+ mailtoComponent.path = to.join(",");
11327
+ options.skipEscape = true;
11328
+ } else {
11329
+ mailtoComponent.path = void 0;
11330
+ }
11331
+ const headers = mailtoComponent.headers && typeof mailtoComponent.headers === "object" ? Object.assign(/* @__PURE__ */ Object.create(null), mailtoComponent.headers) : /* @__PURE__ */ Object.create(null);
11332
+ if (mailtoComponent.subject) headers.subject = mailtoComponent.subject;
11333
+ if (mailtoComponent.body) headers.body = mailtoComponent.body;
11334
+ mailtoComponent.headers = headers;
11335
+ let query = "";
11336
+ let count = 0;
11337
+ for (const name in headers) {
11338
+ if (count++ !== 0) query += "&";
11339
+ query += encodeWithAllow(name, HFNAME) + "=" + encodeWithAllow(String(headers[name]), HFNAME);
11340
+ }
11341
+ if (count !== 0) {
11342
+ mailtoComponent.query = query;
11343
+ } else {
11344
+ mailtoComponent.headers = void 0;
11345
+ }
11346
+ return mailtoComponent;
11347
+ }
11348
+ var mailto = (
11349
+ /** @type {SchemeHandler} */
11350
+ {
11351
+ scheme: "mailto",
11352
+ parse: mailtoParse,
11353
+ serialize: mailtoSerialize,
11354
+ domainHost: false,
11355
+ unicodeSupport: true,
11356
+ // `mailtoParse` re-derives every component from the raw path/query via
11357
+ // `decodeHex`, which subsumes the generic normalizers, so running them first
11358
+ // is wasted work (~28% of parsing a URI with header fields).
11359
+ skipNormalize: true,
11360
+ // A recipient list has no dot segments to remove, and `removeDotSegments`
11361
+ // would rewrite a "./"-prefixed local part.
11362
+ absolutePath: true
11363
+ }
11364
+ );
11024
11365
  var SCHEMES = (
11025
11366
  /** @type {Record<SchemeName, SchemeHandler>} */
11026
11367
  {
@@ -11029,7 +11370,8 @@ var require_schemes = __commonJS({
11029
11370
  ws,
11030
11371
  wss,
11031
11372
  urn,
11032
- "urn:uuid": urnuuid
11373
+ "urn:uuid": urnuuid,
11374
+ mailto
11033
11375
  }
11034
11376
  );
11035
11377
  Object.setPrototypeOf(SCHEMES, null);
@@ -11051,12 +11393,21 @@ var require_schemes = __commonJS({
11051
11393
  }
11052
11394
  });
11053
11395
 
11054
- // ../../node_modules/.pnpm/fast-uri@4.1.2/node_modules/fast-uri/index.js
11396
+ // ../../node_modules/.pnpm/fast-uri@4.1.4/node_modules/fast-uri/index.js
11055
11397
  var require_fast_uri = __commonJS({
11056
- "../../node_modules/.pnpm/fast-uri@4.1.2/node_modules/fast-uri/index.js"(exports, module) {
11398
+ "../../node_modules/.pnpm/fast-uri@4.1.4/node_modules/fast-uri/index.js"(exports, module) {
11057
11399
  "use strict";
11058
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, normalizeQueryFragmentEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
11400
+ var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
11059
11401
  var { SCHEMES, getSchemeHandler } = require_schemes();
11402
+ var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
11403
+ var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
11404
+ function decodeValidScheme(scheme) {
11405
+ const decodedScheme = unescape(String(scheme));
11406
+ if (!VALID_SCHEME.test(decodedScheme)) {
11407
+ throw new TypeError(MALFORMED_SCHEME_ERROR);
11408
+ }
11409
+ return decodedScheme;
11410
+ }
11060
11411
  function normalize(uri, options) {
11061
11412
  if (typeof uri === "string") {
11062
11413
  uri = /** @type {T} */
@@ -11069,58 +11420,80 @@ var require_fast_uri = __commonJS({
11069
11420
  }
11070
11421
  function resolve2(baseURI, relativeURI, options) {
11071
11422
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
11072
- const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
11073
- const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
11074
- if (baseMalformed || relativeMalformed) {
11423
+ const {
11424
+ parsed: baseParsed,
11425
+ malformedAuthorityOrPort: baseMalformed,
11426
+ malformedPercentEncoding: baseMalformedPercentEncoding,
11427
+ malformedSchemeSpecific: baseMalformedSchemeSpecific,
11428
+ malformedHost: baseMalformedHost,
11429
+ malformedScheme: baseMalformedScheme
11430
+ } = parseWithStatus(baseURI, schemelessOptions);
11431
+ const {
11432
+ parsed: relativeParsed,
11433
+ malformedAuthorityOrPort: relativeMalformed,
11434
+ malformedPercentEncoding: relativeMalformedPercentEncoding,
11435
+ malformedSchemeSpecific: relativeMalformedSchemeSpecific,
11436
+ malformedHost: relativeMalformedHost,
11437
+ malformedScheme: relativeMalformedScheme
11438
+ } = parseWithStatus(relativeURI, schemelessOptions);
11439
+ if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
11075
11440
  throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
11076
11441
  }
11077
11442
  const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
11443
+ const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
11444
+ const resolvedHost = resolved.host;
11445
+ const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
11446
+ canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
11447
+ const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
11448
+ if (resolved.error && !encodedASCIIHost) {
11449
+ throw new Error(resolved.error);
11450
+ }
11078
11451
  schemelessOptions.skipEscape = true;
11079
11452
  return serialize(resolved, schemelessOptions);
11080
11453
  }
11081
- function resolveComponent(base, relative2, options, skipNormalization) {
11454
+ function resolveComponent(base, relative3, options, skipNormalization) {
11082
11455
  const target = {};
11083
11456
  if (!skipNormalization) {
11084
11457
  base = parse(serialize(base, options), options);
11085
- relative2 = parse(serialize(relative2, options), options);
11458
+ relative3 = parse(serialize(relative3, options), options);
11086
11459
  }
11087
11460
  options = options || {};
11088
- if (!options.tolerant && relative2.scheme) {
11089
- target.scheme = relative2.scheme;
11090
- target.userinfo = relative2.userinfo;
11091
- target.host = relative2.host;
11092
- target.port = relative2.port;
11093
- target.path = removeDotSegments(relative2.path || "");
11094
- target.query = relative2.query;
11461
+ if (!options.tolerant && relative3.scheme) {
11462
+ target.scheme = relative3.scheme;
11463
+ target.userinfo = relative3.userinfo;
11464
+ target.host = relative3.host;
11465
+ target.port = relative3.port;
11466
+ target.path = removeDotSegments(relative3.path || "");
11467
+ target.query = relative3.query;
11095
11468
  } else {
11096
- if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
11097
- target.userinfo = relative2.userinfo;
11098
- target.host = relative2.host;
11099
- target.port = relative2.port;
11100
- target.path = removeDotSegments(relative2.path || "");
11101
- target.query = relative2.query;
11469
+ if (relative3.userinfo !== void 0 || relative3.host !== void 0 || relative3.port !== void 0) {
11470
+ target.userinfo = relative3.userinfo;
11471
+ target.host = relative3.host;
11472
+ target.port = relative3.port;
11473
+ target.path = removeDotSegments(relative3.path || "");
11474
+ target.query = relative3.query;
11102
11475
  } else {
11103
- if (!relative2.path) {
11476
+ if (!relative3.path) {
11104
11477
  target.path = base.path;
11105
- if (relative2.query !== void 0) {
11106
- target.query = relative2.query;
11478
+ if (relative3.query !== void 0) {
11479
+ target.query = relative3.query;
11107
11480
  } else {
11108
11481
  target.query = base.query;
11109
11482
  }
11110
11483
  } else {
11111
- if (relative2.path[0] === "/") {
11112
- target.path = removeDotSegments(relative2.path);
11484
+ if (relative3.path[0] === "/") {
11485
+ target.path = removeDotSegments(relative3.path);
11113
11486
  } else {
11114
11487
  if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
11115
- target.path = "/" + relative2.path;
11488
+ target.path = "/" + relative3.path;
11116
11489
  } else if (!base.path) {
11117
- target.path = relative2.path;
11490
+ target.path = relative3.path;
11118
11491
  } else {
11119
- target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
11492
+ target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
11120
11493
  }
11121
11494
  target.path = removeDotSegments(target.path);
11122
11495
  }
11123
- target.query = relative2.query;
11496
+ target.query = relative3.query;
11124
11497
  }
11125
11498
  target.userinfo = base.userinfo;
11126
11499
  target.host = base.host;
@@ -11128,13 +11501,13 @@ var require_fast_uri = __commonJS({
11128
11501
  }
11129
11502
  target.scheme = base.scheme;
11130
11503
  }
11131
- target.fragment = relative2.fragment;
11504
+ target.fragment = relative3.fragment;
11132
11505
  return target;
11133
11506
  }
11134
11507
  function equal(uriA, uriB, options) {
11135
11508
  const normalizedA = normalizeComparableURI(uriA, options);
11136
11509
  const normalizedB = normalizeComparableURI(uriB, options);
11137
- return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
11510
+ return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
11138
11511
  }
11139
11512
  function serialize(cmpts, opts) {
11140
11513
  const component = {
@@ -11151,23 +11524,30 @@ var require_fast_uri = __commonJS({
11151
11524
  reference: cmpts.reference,
11152
11525
  resourceName: cmpts.resourceName,
11153
11526
  secure: cmpts.secure,
11527
+ to: cmpts.to,
11528
+ subject: cmpts.subject,
11529
+ body: cmpts.body,
11530
+ headers: cmpts.headers,
11154
11531
  error: ""
11155
11532
  };
11156
11533
  const options = Object.assign({}, opts);
11157
11534
  const uriTokens = [];
11535
+ if (component.scheme) {
11536
+ component.scheme = decodeValidScheme(component.scheme);
11537
+ }
11158
11538
  const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
11159
11539
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
11540
+ const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
11541
+ const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
11160
11542
  if (component.path !== void 0) {
11161
11543
  if (!options.skipEscape) {
11162
- component.path = escapePreservingEscapes(component.path);
11163
- if (component.scheme !== void 0) {
11164
- component.path = component.path.split("%3A").join(":");
11165
- }
11544
+ component.path = serializePathEncoding(component.path, pathNoScheme);
11166
11545
  } else {
11167
11546
  component.path = normalizePercentEncoding(component.path);
11168
11547
  }
11169
11548
  }
11170
11549
  if (options.reference !== "suffix" && component.scheme) {
11550
+ component.scheme = decodeValidScheme(component.scheme);
11171
11551
  uriTokens.push(component.scheme, ":");
11172
11552
  }
11173
11553
  const authority = recomposeAuthority(component);
@@ -11185,16 +11565,19 @@ var require_fast_uri = __commonJS({
11185
11565
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
11186
11566
  s = removeDotSegments(s);
11187
11567
  }
11568
+ if (pathNoScheme) {
11569
+ s = serializePathEncoding(s, true);
11570
+ }
11188
11571
  if (authority === void 0 && s[0] === "/" && s[1] === "/") {
11189
11572
  s = "/%2F" + s.slice(2);
11190
11573
  }
11191
11574
  uriTokens.push(s);
11192
11575
  }
11193
11576
  if (component.query !== void 0) {
11194
- uriTokens.push("?", component.query);
11577
+ uriTokens.push("?", encodeQuery(component.query));
11195
11578
  }
11196
11579
  if (component.fragment !== void 0) {
11197
- uriTokens.push("#", component.fragment);
11580
+ uriTokens.push("#", encodeFragment(component.fragment));
11198
11581
  }
11199
11582
  return uriTokens.join("");
11200
11583
  }
@@ -11210,6 +11593,36 @@ var require_fast_uri = __commonJS({
11210
11593
  }
11211
11594
  return void 0;
11212
11595
  }
11596
+ function hasMalformedPercentEncoding(component) {
11597
+ if (component === void 0) return false;
11598
+ let percent = component.indexOf("%");
11599
+ while (percent !== -1) {
11600
+ if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
11601
+ return true;
11602
+ }
11603
+ percent = component.indexOf("%", percent + 3);
11604
+ }
11605
+ return false;
11606
+ }
11607
+ function isIPLiteral(host) {
11608
+ return host[0] === "[" && host[host.length - 1] === "]";
11609
+ }
11610
+ function hasMalformedComponentPercentEncoding(matches) {
11611
+ const host = matches[4];
11612
+ return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
11613
+ }
11614
+ function canonicalizeHost(parsed, options, schemeHandler, isIP) {
11615
+ const bracketedIPLiteral = parsed.host && parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
11616
+ if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && !bracketedIPLiteral && nonSimpleDomain(parsed.host)) {
11617
+ try {
11618
+ parsed.host = new URL("http://" + parsed.host).hostname;
11619
+ } catch (e) {
11620
+ parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
11621
+ return true;
11622
+ }
11623
+ }
11624
+ return false;
11625
+ }
11213
11626
  function parseWithStatus(uri, opts) {
11214
11627
  const options = Object.assign({}, opts);
11215
11628
  const parsed = {
@@ -11222,6 +11635,11 @@ var require_fast_uri = __commonJS({
11222
11635
  fragment: void 0
11223
11636
  };
11224
11637
  let malformedAuthorityOrPort = false;
11638
+ let malformedPercentEncoding = false;
11639
+ let malformedSchemeSpecific = false;
11640
+ let malformedHost = false;
11641
+ let malformedIPLiteral = false;
11642
+ let malformedScheme = false;
11225
11643
  let isIP = false;
11226
11644
  if (options.reference === "suffix") {
11227
11645
  if (options.scheme) {
@@ -11251,13 +11669,26 @@ var require_fast_uri = __commonJS({
11251
11669
  }
11252
11670
  const matches = uri.match(URI_PARSE);
11253
11671
  if (matches) {
11254
- parsed.scheme = matches[1] === void 0 ? void 0 : matches[1].toLowerCase();
11672
+ parsed.scheme = matches[1];
11255
11673
  parsed.userinfo = matches[3];
11256
11674
  parsed.host = matches[4];
11257
11675
  parsed.port = parseInt(matches[5], 10);
11258
11676
  parsed.path = matches[6] || "";
11259
11677
  parsed.query = matches[7];
11260
11678
  parsed.fragment = matches[8];
11679
+ if (parsed.scheme !== void 0) {
11680
+ const decodedScheme = unescape(parsed.scheme);
11681
+ if (VALID_SCHEME.test(decodedScheme)) {
11682
+ parsed.scheme = decodedScheme.toLowerCase();
11683
+ } else {
11684
+ parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
11685
+ malformedScheme = true;
11686
+ }
11687
+ }
11688
+ malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
11689
+ if (malformedPercentEncoding) {
11690
+ parsed.error = parsed.error || "URI contains malformed percent-encoding.";
11691
+ }
11261
11692
  if (isNaN(parsed.port)) {
11262
11693
  parsed.port = matches[5];
11263
11694
  }
@@ -11269,9 +11700,16 @@ var require_fast_uri = __commonJS({
11269
11700
  if (parsed.host) {
11270
11701
  const ipv4result = isIPv4(parsed.host);
11271
11702
  if (ipv4result === false) {
11703
+ const bracketedIPLiteral = isIPLiteral(parsed.host);
11704
+ const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
11272
11705
  const ipv6result = normalizeIPv6(parsed.host);
11273
- parsed.host = ipv6result.host.toLowerCase();
11274
- isIP = ipv6result.isIPV6;
11706
+ isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
11707
+ malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
11708
+ parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
11709
+ if (malformedIPLiteral) {
11710
+ parsed.error = parsed.error || "URI host is malformed.";
11711
+ malformedAuthorityOrPort = true;
11712
+ }
11275
11713
  } else {
11276
11714
  isIP = true;
11277
11715
  }
@@ -11289,22 +11727,14 @@ var require_fast_uri = __commonJS({
11289
11727
  parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
11290
11728
  }
11291
11729
  const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
11292
- if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
11293
- if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
11294
- try {
11295
- parsed.host = new URL("http://" + parsed.host).hostname;
11296
- } catch (e) {
11297
- parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
11298
- }
11299
- }
11730
+ if (!malformedIPLiteral) {
11731
+ malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
11300
11732
  }
11301
11733
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
11302
11734
  if (uri.indexOf("%") !== -1) {
11303
- if (parsed.scheme !== void 0) {
11304
- parsed.scheme = unescape(parsed.scheme);
11305
- }
11306
- if (parsed.host !== void 0) {
11307
- parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
11735
+ if (parsed.host !== void 0 && !malformedIPLiteral) {
11736
+ const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
11737
+ parsed.host = reescapeHostDelimiters(host, isIP);
11308
11738
  }
11309
11739
  }
11310
11740
  if (parsed.path) {
@@ -11319,11 +11749,14 @@ var require_fast_uri = __commonJS({
11319
11749
  }
11320
11750
  if (schemeHandler && schemeHandler.parse) {
11321
11751
  schemeHandler.parse(parsed, options);
11752
+ if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
11753
+ malformedSchemeSpecific = true;
11754
+ }
11322
11755
  }
11323
11756
  } else {
11324
11757
  parsed.error = parsed.error || "URI can not be parsed.";
11325
11758
  }
11326
- return { parsed, malformedAuthorityOrPort };
11759
+ return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
11327
11760
  }
11328
11761
  function parse(uri, opts) {
11329
11762
  return parseWithStatus(uri, opts).parsed;
@@ -11332,20 +11765,28 @@ var require_fast_uri = __commonJS({
11332
11765
  return normalizeStringWithStatus(uri, opts).normalized;
11333
11766
  }
11334
11767
  function normalizeStringWithStatus(uri, opts) {
11335
- const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
11768
+ const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
11336
11769
  return {
11337
- normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
11338
- malformedAuthorityOrPort
11770
+ normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
11771
+ malformedAuthorityOrPort,
11772
+ malformedPercentEncoding,
11773
+ malformedSchemeSpecific,
11774
+ malformedHost,
11775
+ malformedScheme
11339
11776
  };
11340
11777
  }
11341
11778
  function normalizeComparableURI(uri, opts) {
11342
- if (typeof uri === "string") {
11343
- const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
11344
- return malformedAuthorityOrPort ? void 0 : normalized;
11779
+ if (typeof uri !== "string" && typeof uri !== "object") {
11780
+ return void 0;
11345
11781
  }
11346
- if (typeof uri === "object") {
11347
- return serialize(uri, opts);
11782
+ let value;
11783
+ try {
11784
+ value = typeof uri === "string" ? uri : serialize(uri, opts);
11785
+ } catch {
11786
+ return void 0;
11348
11787
  }
11788
+ const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
11789
+ return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
11349
11790
  }
11350
11791
  var fastUri = {
11351
11792
  SCHEMES,
@@ -14598,10 +15039,9 @@ var require__ = __commonJS({
14598
15039
  });
14599
15040
 
14600
15041
  // src/cli.ts
14601
- var import_yaml3 = __toESM(require_dist(), 1);
14602
- import { readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
15042
+ import { readFileSync as readFileSync3, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
14603
15043
  import { availableParallelism } from "node:os";
14604
- import { extname, join as join2, relative } from "node:path";
15044
+ import { extname, join as join2, relative as relative2 } from "node:path";
14605
15045
  import { fileURLToPath as fileURLToPath2 } from "node:url";
14606
15046
  import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";
14607
15047
 
@@ -14609,7 +15049,7 @@ import { Worker, isMainThread, parentPort, workerData } from "node:worker_thread
14609
15049
  var import_yaml = __toESM(require_dist(), 1);
14610
15050
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
14611
15051
  import { createRequire } from "node:module";
14612
- import { dirname, join, resolve } from "node:path";
15052
+ import { dirname, join, relative, resolve, sep } from "node:path";
14613
15053
  import { fileURLToPath } from "node:url";
14614
15054
 
14615
15055
  // src/coverage.ts
@@ -14726,6 +15166,7 @@ var DEFAULT_RULE_SEVERITY = {
14726
15166
  "invalid-format": "error",
14727
15167
  "invalid-reference": "error",
14728
15168
  "unknown-casetype": "warning",
15169
+ "invalid-location": "error",
14729
15170
  "parse-error": "error",
14730
15171
  // A warning, not an error: a red test is a statement about the SCRIPT, and the
14731
15172
  // write gate must not make a casetype unsaveable because its code is mid-fix.
@@ -14751,6 +15192,7 @@ var LINT_RULE_DESCRIPTORS = [
14751
15192
  { id: "invalid-format", label: "Invalid format", description: "Value fails a pattern / format constraint.", defaultSeverity: "error" },
14752
15193
  { id: "invalid-reference", label: "Invalid reference", description: "A case-reference field points at a file whose `_type` is not in the field's allowedCasetypes.", defaultSeverity: "error" },
14753
15194
  { id: "unknown-casetype", label: "Unknown casetype", description: "No schema found for the document `_type`.", defaultSeverity: "warning" },
15195
+ { id: "invalid-location", label: "Invalid location", description: "The file sits where its `_type` may not \u2014 a casetype needs a folder of its own inside a component.", defaultSeverity: "error" },
14754
15196
  { id: "parse-error", label: "Parse error", description: "The YAML document could not be parsed.", defaultSeverity: "error" },
14755
15197
  { id: "schema", label: "Other schema error", description: "Any other constraint reported by the validator.", defaultSeverity: "error" }
14756
15198
  ];
@@ -14896,6 +15338,13 @@ function referenceFindings(value, file, caseRefs, settings) {
14896
15338
  walk(value, "");
14897
15339
  return out;
14898
15340
  }
15341
+ function layoutRootOf(paths) {
15342
+ if (paths.length !== 1) return void 0;
15343
+ return statSync(paths[0]).isDirectory() ? paths[0] : void 0;
15344
+ }
15345
+ function repoPathOf(root, file) {
15346
+ return root === void 0 ? void 0 : relative(root, file).split(sep).join("/");
15347
+ }
14899
15348
  function createNodeContext(opts = {}) {
14900
15349
  const schemasDir = resolveSchemasDir(opts.schemasDir);
14901
15350
  const registry = createSchemaRegistry(loadSchemasFromDir(schemasDir));
@@ -14903,8 +15352,36 @@ function createNodeContext(opts = {}) {
14903
15352
  return { registry, coverage, schemasDir };
14904
15353
  }
14905
15354
 
14906
- // src/yaml.ts
14907
- var import_yaml2 = __toESM(require_dist(), 1);
15355
+ // src/lint-files.ts
15356
+ var import_yaml3 = __toESM(require_dist(), 1);
15357
+ import { readFileSync as readFileSync2 } from "node:fs";
15358
+
15359
+ // src/layout.ts
15360
+ function rootType(value) {
15361
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
15362
+ const t = value._type;
15363
+ return typeof t === "string" ? t : null;
15364
+ }
15365
+ function layoutFindings(value, repoPath, settings) {
15366
+ const sev = severityFor("invalid-location", normalizeSettings(settings));
15367
+ if (sev === "off") return [];
15368
+ const type = rootType(value);
15369
+ if (type !== "casetype") return [];
15370
+ const segments = repoPath.split("/").filter(Boolean);
15371
+ if (segments.length >= 3) return [];
15372
+ const where = segments.length === 2 ? `component "${segments[0]}"` : "the repository root";
15373
+ return [
15374
+ {
15375
+ severity: sev,
15376
+ rule: "invalid-location",
15377
+ casetype: type,
15378
+ path: "",
15379
+ field: null,
15380
+ message: `a casetype is its own folder, so it cannot sit directly in ${where} \u2014 give it a folder of its own inside a component`,
15381
+ file: repoPath
15382
+ }
15383
+ ];
15384
+ }
14908
15385
 
14909
15386
  // src/lint.ts
14910
15387
  function ruleForKeyword(keyword) {
@@ -15234,6 +15711,7 @@ function summarize(results) {
15234
15711
  }
15235
15712
 
15236
15713
  // src/yaml.ts
15714
+ var import_yaml2 = __toESM(require_dist(), 1);
15237
15715
  function isLintableYaml(text) {
15238
15716
  return text.includes("_type");
15239
15717
  }
@@ -15245,10 +15723,53 @@ function toJSOrError(doc) {
15245
15723
  }
15246
15724
  }
15247
15725
 
15726
+ // src/lint-files.ts
15727
+ function parseErrorResult(file, message, settings) {
15728
+ return {
15729
+ file,
15730
+ casetype: null,
15731
+ skipped: false,
15732
+ ok: settings.failOn === "never",
15733
+ messages: [{ severity: "error", rule: "parse-error", casetype: null, path: "", field: null, message, file }]
15734
+ };
15735
+ }
15736
+ function lintOneDoc(doc, file, ctx, settings, caseRefs) {
15737
+ if (doc.errors.length > 0) return parseErrorResult(file, doc.errors[0].message, settings);
15738
+ const resolved = toJSOrError(doc);
15739
+ if (resolved.error !== void 0) return parseErrorResult(file, resolved.error, settings);
15740
+ const input = { value: resolved.value, file };
15741
+ const result = lintDocument({ registry: ctx.registry, coverage: ctx.coverage, settings }, input);
15742
+ const repoPath = repoPathOf(ctx.root, file);
15743
+ const extra = [
15744
+ ...referenceFindings(input.value, file, caseRefs, settings),
15745
+ ...repoPath === void 0 ? [] : layoutFindings(input.value, repoPath, settings).map((m) => ({ ...m, file }))
15746
+ ];
15747
+ if (extra.length) {
15748
+ result.messages.push(...extra);
15749
+ if (result.ok && extra.some((m) => meetsThreshold(m.severity, settings.failOn))) result.ok = false;
15750
+ }
15751
+ return result;
15752
+ }
15753
+ function lintOneFile(file, ctx, settings, caseRefs) {
15754
+ const text = readFileSync2(file, "utf8");
15755
+ if (!isLintableYaml(text)) return [];
15756
+ let docs;
15757
+ try {
15758
+ docs = (0, import_yaml3.parseAllDocuments)(text);
15759
+ } catch (e) {
15760
+ return [parseErrorResult(file, e.message, settings)];
15761
+ }
15762
+ return docs.map((doc) => lintOneDoc(doc, file, ctx, settings, caseRefs));
15763
+ }
15764
+ function lintFiles(files, ctx, settings) {
15765
+ const caseRefs = loadCaseRefs(ctx.schemasDir);
15766
+ return files.flatMap((file) => lintOneFile(file, ctx, settings, caseRefs));
15767
+ }
15768
+
15248
15769
  // src/cli.ts
15249
15770
  var PARALLEL_THRESHOLD = 200;
15250
15771
  var MAX_WORKERS = 8;
15251
- var VERSION = "0.2.2397";
15772
+ var VERSION = "0.2.2581";
15252
15773
  function isNewer(latest, current) {
15253
15774
  const a = latest.split(".").map(Number);
15254
15775
  const b = current.split(".").map(Number);
@@ -15362,7 +15883,7 @@ function printResult(r, quiet, errorsOnly) {
15362
15883
  if (r.skipped) return;
15363
15884
  const msgs = errorsOnly ? r.messages.filter((m) => m.severity === "error") : r.messages;
15364
15885
  if (quiet && msgs.length === 0) return;
15365
- const rel = r.file ? relative(process.cwd(), r.file) : "<input>";
15886
+ const rel = r.file ? relative2(process.cwd(), r.file) : "<input>";
15366
15887
  const casetypeTag = r.casetype ? ` (${r.casetype})` : "";
15367
15888
  const head = `${rel}${casetypeTag}`;
15368
15889
  if (msgs.length === 0) {
@@ -15424,44 +15945,7 @@ function printReport(results, kind, errorsOnly) {
15424
15945
  }
15425
15946
  }
15426
15947
  var WORKER_FILE = fileURLToPath2(import.meta.url);
15427
- function parseErrorResult(file, message, settings) {
15428
- return {
15429
- file,
15430
- casetype: null,
15431
- skipped: false,
15432
- ok: settings.failOn === "never",
15433
- messages: [{ severity: "error", rule: "parse-error", casetype: null, path: "", field: null, message, file }]
15434
- };
15435
- }
15436
- function lintOneDoc(doc, file, ctx, settings, caseRefs) {
15437
- if (doc.errors.length > 0) return parseErrorResult(file, doc.errors[0].message, settings);
15438
- const resolved = toJSOrError(doc);
15439
- if (resolved.error !== void 0) return parseErrorResult(file, resolved.error, settings);
15440
- const input = { value: resolved.value, file };
15441
- const result = lintDocument({ registry: ctx.registry, coverage: ctx.coverage, settings }, input);
15442
- const refs = referenceFindings(input.value, file, caseRefs, settings);
15443
- if (refs.length) {
15444
- result.messages.push(...refs);
15445
- if (result.ok && refs.some((m) => meetsThreshold(m.severity, settings.failOn))) result.ok = false;
15446
- }
15447
- return result;
15448
- }
15449
- function lintOneFile(file, ctx, settings, caseRefs) {
15450
- const text = readFileSync2(file, "utf8");
15451
- if (!isLintableYaml(text)) return [];
15452
- let docs;
15453
- try {
15454
- docs = (0, import_yaml3.parseAllDocuments)(text);
15455
- } catch (e) {
15456
- return [parseErrorResult(file, e.message, settings)];
15457
- }
15458
- return docs.map((doc) => lintOneDoc(doc, file, ctx, settings, caseRefs));
15459
- }
15460
- function lintFiles(files, ctx, settings) {
15461
- const caseRefs = loadCaseRefs(ctx.schemasDir);
15462
- return files.flatMap((file) => lintOneFile(file, ctx, settings, caseRefs));
15463
- }
15464
- async function runParallel(files, settings, schemasDir) {
15948
+ async function runParallel(files, settings, schemasDir, root) {
15465
15949
  const n = Math.min(MAX_WORKERS, availableParallelism(), files.length);
15466
15950
  const shards = Array.from({ length: n }, () => []);
15467
15951
  files.forEach((f, i) => shards[i % n].push(f));
@@ -15470,7 +15954,7 @@ async function runParallel(files, settings, schemasDir) {
15470
15954
  const parts = await Promise.all(
15471
15955
  shards.map(
15472
15956
  (shard) => new Promise((resolve2, reject) => {
15473
- const w = new Worker(WORKER_FILE, { workerData: { shard, settings, schemasDir } });
15957
+ const w = new Worker(WORKER_FILE, { workerData: { shard, settings, schemasDir, root } });
15474
15958
  w.once("message", (m) => {
15475
15959
  void w.terminate();
15476
15960
  resolve2(m);
@@ -15483,32 +15967,33 @@ async function runParallel(files, settings, schemasDir) {
15483
15967
  } catch (e) {
15484
15968
  if (process.env.GREXXLINT_DEBUG) console.error("[grexxlint] worker pool failed, inline fallback:", e);
15485
15969
  const ctx = createNodeContext({ schemasDir });
15486
- return lintFiles(files, ctx, settings);
15970
+ return lintFiles(files, { ...ctx, root }, settings);
15487
15971
  }
15488
15972
  }
15489
15973
  function runWorker() {
15490
- const { shard, settings, schemasDir } = workerData;
15974
+ const { shard, settings, schemasDir, root } = workerData;
15491
15975
  const ctx = createNodeContext({ schemasDir });
15492
- parentPort.postMessage(lintFiles(shard, ctx, settings));
15976
+ parentPort.postMessage(lintFiles(shard, { ...ctx, root }, settings));
15493
15977
  }
15494
15978
  async function main() {
15495
15979
  const args = parseArgs(process.argv.slice(2));
15496
15980
  const updatePromise = checkForUpdate(args.noUpdateCheck);
15497
15981
  let partial = {};
15498
- if (args.settingsFile) partial = JSON.parse(readFileSync2(args.settingsFile, "utf8"));
15982
+ if (args.settingsFile) partial = JSON.parse(readFileSync3(args.settingsFile, "utf8"));
15499
15983
  if (args.failOn) partial = { ...partial, failOn: args.failOn };
15500
15984
  if (args.off.length > 0) {
15501
15985
  partial = { ...partial, rules: { ...partial.rules, ...Object.fromEntries(args.off.map((r) => [r, "off"])) } };
15502
15986
  }
15503
15987
  const settings = normalizeSettings(partial);
15504
15988
  const files = discover(args.paths, settings.exclude);
15989
+ const root = layoutRootOf(args.paths);
15505
15990
  const canParallel = WORKER_FILE.endsWith(".js") && files.length > PARALLEL_THRESHOLD;
15506
15991
  let results;
15507
15992
  if (canParallel) {
15508
- results = await runParallel(files, settings, args.schemasDir);
15993
+ results = await runParallel(files, settings, args.schemasDir, root);
15509
15994
  } else {
15510
15995
  const ctx = createNodeContext({ schemasDir: args.schemasDir });
15511
- results = lintFiles(files, ctx, settings);
15996
+ results = lintFiles(files, { ...ctx, root }, settings);
15512
15997
  }
15513
15998
  if (args.report) {
15514
15999
  printReport(results, args.report, args.errorsOnly);