react-doctor 0.9.2-dev.86add14 → 0.9.2-dev.992205a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cc06d86a-0b85-5115-a9f2-cc30c268ad79")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="61d9689f-8ba5-5ca3-a0c2-09557d3f7028")}catch(e){}}();
3
3
  import { i as __toESM$1, r as __require, t as __commonJSMin$1 } from "./chunk-ChKA3wi6.js";
4
4
  import { createRequire } from "node:module";
5
- import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
5
+ import { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, REACT_DOCTOR_RULE_REGISTRY, REACT_DOCTOR_SCAN_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor/core";
6
6
  import * as Crypto from "node:crypto";
7
7
  import crypto, { createHash } from "node:crypto";
8
8
  import * as NFS from "node:fs";
@@ -20,6 +20,7 @@ import os from "node:os";
20
20
  import { parseJSON5 } from "confbox";
21
21
  import { createJiti } from "jiti";
22
22
  import { ANALYZED_MANIFEST_FILENAMES, DEFAULT_EXTENSIONS } from "deslop-js/analyzed-inputs";
23
+ import { convertToTSX } from "@astrojs/compiler/sync";
23
24
  import { gzipSync } from "node:zlib";
24
25
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.70/node_modules/effect/dist/Pipeable.js
25
26
  /**
@@ -10262,7 +10263,7 @@ const Number$4 = globalThis.Number;
10262
10263
  * @category constructors
10263
10264
  * @since 2.0.0
10264
10265
  */
10265
- const parse = (s) => {
10266
+ const parse$1 = (s) => {
10266
10267
  if (s === "NaN") return some(NaN);
10267
10268
  if (s === "Infinity") return some(Infinity);
10268
10269
  if (s === "-Infinity") return some(-Infinity);
@@ -14304,12 +14305,12 @@ TaggedError("EncodingError");
14304
14305
  //#endregion
14305
14306
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.70/node_modules/effect/dist/internal/schema/annotations.js
14306
14307
  /** @internal */
14307
- function resolve(ast) {
14308
+ function resolve$1(ast) {
14308
14309
  return ast.checks ? ast.checks[ast.checks.length - 1].annotations : ast.annotations;
14309
14310
  }
14310
14311
  /** @internal */
14311
14312
  function resolveAt(key) {
14312
- return (ast) => resolve(ast)?.[key];
14313
+ return (ast) => resolve$1(ast)?.[key];
14313
14314
  }
14314
14315
  /** @internal */
14315
14316
  const resolveIdentifier = /* @__PURE__ */ resolveAt("identifier");
@@ -18061,7 +18062,7 @@ function asSync(parser) {
18061
18062
  }
18062
18063
  const recur$1 = /* @__PURE__ */ memoize((ast) => {
18063
18064
  let parser;
18064
- const astOptions = resolve(ast)?.["parseOptions"];
18065
+ const astOptions = resolve$1(ast)?.["parseOptions"];
18065
18066
  if (!ast.context && !ast.encoding && !ast.checks) return (ou, options) => {
18066
18067
  parser ??= ast.getParser(recur$1);
18067
18068
  if (astOptions) options = {
@@ -57666,7 +57667,7 @@ var UrlParamsError = class extends TaggedError("UrlParamsError") {};
57666
57667
  * @category converting
57667
57668
  * @since 4.0.0
57668
57669
  */
57669
- const makeUrl = (url, params, hash) => {
57670
+ const makeUrl$1 = (url, params, hash) => {
57670
57671
  try {
57671
57672
  const urlInstance = new URL(url, baseUrl());
57672
57673
  for (let i = 0; i < params.params.length; i++) {
@@ -58300,7 +58301,7 @@ const Proto$2 = {
58300
58301
  const make$10 = (f) => makeWith$1((effect) => flatMap$2(effect, (request) => withFiber((fiber) => {
58301
58302
  const scopedController = scopedRequests.get(request);
58302
58303
  const controller = scopedController ?? new AbortController();
58303
- const urlResult = makeUrl(request.url, request.urlParams, getOrUndefined(request.hash));
58304
+ const urlResult = makeUrl$1(request.url, request.urlParams, getOrUndefined(request.hash));
58304
58305
  if (isFailure(urlResult)) return fail$4(new HttpClientError({ reason: new InvalidUrlError({
58305
58306
  request,
58306
58307
  cause: urlResult.failure
@@ -58739,7 +58740,7 @@ const layer$7 = (loggers, options) => effect(CurrentLoggers, withFiber$1(fnUntra
58739
58740
  * @since 4.0.0
58740
58741
  */
58741
58742
  const policy = /* @__PURE__ */ forever$1.pipe(passthrough$2, /* @__PURE__ */ addDelay((error) => {
58742
- if (isHttpClientError(error) && error.reason._tag === "StatusCodeError" && error.reason.response.status === 429) return succeed$2(seconds(fromUndefinedOr(error.reason.response.headers["retry-after"]).pipe(flatMap$5(parse), getOrElse$1(() => 5))));
58743
+ if (isHttpClientError(error) && error.reason._tag === "StatusCodeError" && error.reason.response.status === 429) return succeed$2(seconds(fromUndefinedOr(error.reason.response.headers["retry-after"]).pipe(flatMap$5(parse$1), getOrElse$1(() => 5))));
58743
58744
  return succeed$2(seconds(1));
58744
58745
  }));
58745
58746
  /**
@@ -61381,6 +61382,428 @@ const layer = /* @__PURE__ */ succeed$3(Path$1)({
61381
61382
  toFileUrl
61382
61383
  });
61383
61384
  //#endregion
61385
+ //#region ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
61386
+ var comma = ",".charCodeAt(0);
61387
+ ";".charCodeAt(0);
61388
+ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
61389
+ var intToChar = new Uint8Array(64);
61390
+ var charToInt = new Uint8Array(128);
61391
+ for (let i = 0; i < chars.length; i++) {
61392
+ const c = chars.charCodeAt(i);
61393
+ intToChar[i] = c;
61394
+ charToInt[c] = i;
61395
+ }
61396
+ function decodeInteger(reader, relative) {
61397
+ let value = 0;
61398
+ let shift = 0;
61399
+ let integer = 0;
61400
+ do {
61401
+ integer = charToInt[reader.next()];
61402
+ value |= (integer & 31) << shift;
61403
+ shift += 5;
61404
+ } while (integer & 32);
61405
+ const shouldNegate = value & 1;
61406
+ value >>>= 1;
61407
+ if (shouldNegate) value = -2147483648 | -value;
61408
+ return relative + value;
61409
+ }
61410
+ function hasMoreVlq(reader, max) {
61411
+ if (reader.pos >= max) return false;
61412
+ return reader.peek() !== comma;
61413
+ }
61414
+ var StringReader = class {
61415
+ constructor(buffer) {
61416
+ this.pos = 0;
61417
+ this.buffer = buffer;
61418
+ }
61419
+ next() {
61420
+ return this.buffer.charCodeAt(this.pos++);
61421
+ }
61422
+ peek() {
61423
+ return this.buffer.charCodeAt(this.pos);
61424
+ }
61425
+ indexOf(char) {
61426
+ const { buffer, pos } = this;
61427
+ const idx = buffer.indexOf(char, pos);
61428
+ return idx === -1 ? buffer.length : idx;
61429
+ }
61430
+ };
61431
+ function decode(mappings) {
61432
+ const { length } = mappings;
61433
+ const reader = new StringReader(mappings);
61434
+ const decoded = [];
61435
+ let genColumn = 0;
61436
+ let sourcesIndex = 0;
61437
+ let sourceLine = 0;
61438
+ let sourceColumn = 0;
61439
+ let namesIndex = 0;
61440
+ do {
61441
+ const semi = reader.indexOf(";");
61442
+ const line = [];
61443
+ let sorted = true;
61444
+ let lastCol = 0;
61445
+ genColumn = 0;
61446
+ while (reader.pos < semi) {
61447
+ let seg;
61448
+ genColumn = decodeInteger(reader, genColumn);
61449
+ if (genColumn < lastCol) sorted = false;
61450
+ lastCol = genColumn;
61451
+ if (hasMoreVlq(reader, semi)) {
61452
+ sourcesIndex = decodeInteger(reader, sourcesIndex);
61453
+ sourceLine = decodeInteger(reader, sourceLine);
61454
+ sourceColumn = decodeInteger(reader, sourceColumn);
61455
+ if (hasMoreVlq(reader, semi)) {
61456
+ namesIndex = decodeInteger(reader, namesIndex);
61457
+ seg = [
61458
+ genColumn,
61459
+ sourcesIndex,
61460
+ sourceLine,
61461
+ sourceColumn,
61462
+ namesIndex
61463
+ ];
61464
+ } else seg = [
61465
+ genColumn,
61466
+ sourcesIndex,
61467
+ sourceLine,
61468
+ sourceColumn
61469
+ ];
61470
+ } else seg = [genColumn];
61471
+ line.push(seg);
61472
+ reader.pos++;
61473
+ }
61474
+ if (!sorted) sort(line);
61475
+ decoded.push(line);
61476
+ reader.pos = semi + 1;
61477
+ } while (reader.pos <= length);
61478
+ return decoded;
61479
+ }
61480
+ function sort(line) {
61481
+ line.sort(sortComparator$1);
61482
+ }
61483
+ function sortComparator$1(a, b) {
61484
+ return a[0] - b[0];
61485
+ }
61486
+ //#endregion
61487
+ //#region ../../node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
61488
+ const schemeRegex = /^[\w+.-]+:\/\//;
61489
+ /**
61490
+ * Matches the parts of a URL:
61491
+ * 1. Scheme, including ":", guaranteed.
61492
+ * 2. User/password, including "@", optional.
61493
+ * 3. Host, guaranteed.
61494
+ * 4. Port, including ":", optional.
61495
+ * 5. Path, including "/", optional.
61496
+ * 6. Query, including "?", optional.
61497
+ * 7. Hash, including "#", optional.
61498
+ */
61499
+ const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
61500
+ /**
61501
+ * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
61502
+ * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
61503
+ *
61504
+ * 1. Host, optional.
61505
+ * 2. Path, which may include "/", guaranteed.
61506
+ * 3. Query, including "?", optional.
61507
+ * 4. Hash, including "#", optional.
61508
+ */
61509
+ const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
61510
+ function isAbsoluteUrl(input) {
61511
+ return schemeRegex.test(input);
61512
+ }
61513
+ function isSchemeRelativeUrl(input) {
61514
+ return input.startsWith("//");
61515
+ }
61516
+ function isAbsolutePath(input) {
61517
+ return input.startsWith("/");
61518
+ }
61519
+ function isFileUrl(input) {
61520
+ return input.startsWith("file:");
61521
+ }
61522
+ function isRelative(input) {
61523
+ return /^[.?#]/.test(input);
61524
+ }
61525
+ function parseAbsoluteUrl(input) {
61526
+ const match = urlRegex.exec(input);
61527
+ return makeUrl(match[1], match[2] || "", match[3], match[4] || "", match[5] || "/", match[6] || "", match[7] || "");
61528
+ }
61529
+ function parseFileUrl(input) {
61530
+ const match = fileRegex.exec(input);
61531
+ const path = match[2];
61532
+ return makeUrl("file:", "", match[1] || "", "", isAbsolutePath(path) ? path : "/" + path, match[3] || "", match[4] || "");
61533
+ }
61534
+ function makeUrl(scheme, user, host, port, path, query, hash) {
61535
+ return {
61536
+ scheme,
61537
+ user,
61538
+ host,
61539
+ port,
61540
+ path,
61541
+ query,
61542
+ hash,
61543
+ type: 7
61544
+ };
61545
+ }
61546
+ function parseUrl(input) {
61547
+ if (isSchemeRelativeUrl(input)) {
61548
+ const url = parseAbsoluteUrl("http:" + input);
61549
+ url.scheme = "";
61550
+ url.type = 6;
61551
+ return url;
61552
+ }
61553
+ if (isAbsolutePath(input)) {
61554
+ const url = parseAbsoluteUrl("http://foo.com" + input);
61555
+ url.scheme = "";
61556
+ url.host = "";
61557
+ url.type = 5;
61558
+ return url;
61559
+ }
61560
+ if (isFileUrl(input)) return parseFileUrl(input);
61561
+ if (isAbsoluteUrl(input)) return parseAbsoluteUrl(input);
61562
+ const url = parseAbsoluteUrl("http://foo.com/" + input);
61563
+ url.scheme = "";
61564
+ url.host = "";
61565
+ url.type = input ? input.startsWith("?") ? 3 : input.startsWith("#") ? 2 : 4 : 1;
61566
+ return url;
61567
+ }
61568
+ function stripPathFilename(path) {
61569
+ if (path.endsWith("/..")) return path;
61570
+ const index = path.lastIndexOf("/");
61571
+ return path.slice(0, index + 1);
61572
+ }
61573
+ function mergePaths(url, base) {
61574
+ normalizePath(base, base.type);
61575
+ if (url.path === "/") url.path = base.path;
61576
+ else url.path = stripPathFilename(base.path) + url.path;
61577
+ }
61578
+ /**
61579
+ * The path can have empty directories "//", unneeded parents "foo/..", or current directory
61580
+ * "foo/.". We need to normalize to a standard representation.
61581
+ */
61582
+ function normalizePath(url, type) {
61583
+ const rel = type <= 4;
61584
+ const pieces = url.path.split("/");
61585
+ let pointer = 1;
61586
+ let positive = 0;
61587
+ let addTrailingSlash = false;
61588
+ for (let i = 1; i < pieces.length; i++) {
61589
+ const piece = pieces[i];
61590
+ if (!piece) {
61591
+ addTrailingSlash = true;
61592
+ continue;
61593
+ }
61594
+ addTrailingSlash = false;
61595
+ if (piece === ".") continue;
61596
+ if (piece === "..") {
61597
+ if (positive) {
61598
+ addTrailingSlash = true;
61599
+ positive--;
61600
+ pointer--;
61601
+ } else if (rel) pieces[pointer++] = piece;
61602
+ continue;
61603
+ }
61604
+ pieces[pointer++] = piece;
61605
+ positive++;
61606
+ }
61607
+ let path = "";
61608
+ for (let i = 1; i < pointer; i++) path += "/" + pieces[i];
61609
+ if (!path || addTrailingSlash && !path.endsWith("/..")) path += "/";
61610
+ url.path = path;
61611
+ }
61612
+ /**
61613
+ * Attempts to resolve `input` URL/path relative to `base`.
61614
+ */
61615
+ function resolve(input, base) {
61616
+ if (!input && !base) return "";
61617
+ const url = parseUrl(input);
61618
+ let inputType = url.type;
61619
+ if (base && inputType !== 7) {
61620
+ const baseUrl = parseUrl(base);
61621
+ const baseType = baseUrl.type;
61622
+ switch (inputType) {
61623
+ case 1: url.hash = baseUrl.hash;
61624
+ case 2: url.query = baseUrl.query;
61625
+ case 3:
61626
+ case 4: mergePaths(url, baseUrl);
61627
+ case 5:
61628
+ url.user = baseUrl.user;
61629
+ url.host = baseUrl.host;
61630
+ url.port = baseUrl.port;
61631
+ case 6: url.scheme = baseUrl.scheme;
61632
+ }
61633
+ if (baseType > inputType) inputType = baseType;
61634
+ }
61635
+ normalizePath(url, inputType);
61636
+ const queryHash = url.query + url.hash;
61637
+ switch (inputType) {
61638
+ case 2:
61639
+ case 3: return queryHash;
61640
+ case 4: {
61641
+ const path = url.path.slice(1);
61642
+ if (!path) return queryHash || ".";
61643
+ if (isRelative(base || input) && !isRelative(path)) return "./" + path + queryHash;
61644
+ return path + queryHash;
61645
+ }
61646
+ case 5: return url.path + queryHash;
61647
+ default: return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
61648
+ }
61649
+ }
61650
+ //#endregion
61651
+ //#region ../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
61652
+ function stripFilename(path) {
61653
+ if (!path) return "";
61654
+ const index = path.lastIndexOf("/");
61655
+ return path.slice(0, index + 1);
61656
+ }
61657
+ function resolver(mapUrl, sourceRoot) {
61658
+ const from = stripFilename(mapUrl);
61659
+ const prefix = sourceRoot ? sourceRoot + "/" : "";
61660
+ return (source) => resolve(prefix + (source || ""), from);
61661
+ }
61662
+ var COLUMN = 0;
61663
+ var SOURCES_INDEX = 1;
61664
+ var SOURCE_LINE = 2;
61665
+ var SOURCE_COLUMN = 3;
61666
+ var NAMES_INDEX = 4;
61667
+ function maybeSort(mappings, owned) {
61668
+ const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
61669
+ if (unsortedIndex === mappings.length) return mappings;
61670
+ if (!owned) mappings = mappings.slice();
61671
+ for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) mappings[i] = sortSegments(mappings[i], owned);
61672
+ return mappings;
61673
+ }
61674
+ function nextUnsortedSegmentLine(mappings, start) {
61675
+ for (let i = start; i < mappings.length; i++) if (!isSorted(mappings[i])) return i;
61676
+ return mappings.length;
61677
+ }
61678
+ function isSorted(line) {
61679
+ for (let j = 1; j < line.length; j++) if (line[j][COLUMN] < line[j - 1][COLUMN]) return false;
61680
+ return true;
61681
+ }
61682
+ function sortSegments(line, owned) {
61683
+ if (!owned) line = line.slice();
61684
+ return line.sort(sortComparator);
61685
+ }
61686
+ function sortComparator(a, b) {
61687
+ return a[COLUMN] - b[COLUMN];
61688
+ }
61689
+ var found = false;
61690
+ function binarySearch(haystack, needle, low, high) {
61691
+ while (low <= high) {
61692
+ const mid = low + (high - low >> 1);
61693
+ const cmp = haystack[mid][COLUMN] - needle;
61694
+ if (cmp === 0) {
61695
+ found = true;
61696
+ return mid;
61697
+ }
61698
+ if (cmp < 0) low = mid + 1;
61699
+ else high = mid - 1;
61700
+ }
61701
+ found = false;
61702
+ return low - 1;
61703
+ }
61704
+ function upperBound(haystack, needle, index) {
61705
+ for (let i = index + 1; i < haystack.length; index = i++) if (haystack[i][COLUMN] !== needle) break;
61706
+ return index;
61707
+ }
61708
+ function lowerBound(haystack, needle, index) {
61709
+ for (let i = index - 1; i >= 0; index = i--) if (haystack[i][COLUMN] !== needle) break;
61710
+ return index;
61711
+ }
61712
+ function memoizedState() {
61713
+ return {
61714
+ lastKey: -1,
61715
+ lastNeedle: -1,
61716
+ lastIndex: -1
61717
+ };
61718
+ }
61719
+ function memoizedBinarySearch(haystack, needle, state, key) {
61720
+ const { lastKey, lastNeedle, lastIndex } = state;
61721
+ let low = 0;
61722
+ let high = haystack.length - 1;
61723
+ if (key === lastKey) {
61724
+ if (needle === lastNeedle) {
61725
+ found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
61726
+ return lastIndex;
61727
+ }
61728
+ if (needle >= lastNeedle) low = lastIndex === -1 ? 0 : lastIndex;
61729
+ else high = lastIndex;
61730
+ }
61731
+ state.lastKey = key;
61732
+ state.lastNeedle = needle;
61733
+ return state.lastIndex = binarySearch(haystack, needle, low, high);
61734
+ }
61735
+ function parse(map) {
61736
+ return typeof map === "string" ? JSON.parse(map) : map;
61737
+ }
61738
+ var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)";
61739
+ var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)";
61740
+ var TraceMap = class {
61741
+ constructor(map, mapUrl) {
61742
+ const isString = typeof map === "string";
61743
+ if (!isString && map._decodedMemo) return map;
61744
+ const parsed = parse(map);
61745
+ const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
61746
+ this.version = version;
61747
+ this.file = file;
61748
+ this.names = names || [];
61749
+ this.sourceRoot = sourceRoot;
61750
+ this.sources = sources;
61751
+ this.sourcesContent = sourcesContent;
61752
+ this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0;
61753
+ const resolve = resolver(mapUrl, sourceRoot);
61754
+ this.resolvedSources = sources.map(resolve);
61755
+ const { mappings } = parsed;
61756
+ if (typeof mappings === "string") {
61757
+ this._encoded = mappings;
61758
+ this._decoded = void 0;
61759
+ } else if (Array.isArray(mappings)) {
61760
+ this._encoded = void 0;
61761
+ this._decoded = maybeSort(mappings, isString);
61762
+ } else if (parsed.sections) throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`);
61763
+ else throw new Error(`invalid source map: ${JSON.stringify(parsed)}`);
61764
+ this._decodedMemo = memoizedState();
61765
+ this._bySources = void 0;
61766
+ this._bySourceMemos = void 0;
61767
+ }
61768
+ };
61769
+ function cast(map) {
61770
+ return map;
61771
+ }
61772
+ function decodedMappings(map) {
61773
+ var _a;
61774
+ return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded));
61775
+ }
61776
+ function originalPositionFor(map, needle) {
61777
+ let { line, column, bias } = needle;
61778
+ line--;
61779
+ if (line < 0) throw new Error(LINE_GTR_ZERO);
61780
+ if (column < 0) throw new Error(COL_GTR_EQ_ZERO);
61781
+ const decoded = decodedMappings(map);
61782
+ if (line >= decoded.length) return OMapping(null, null, null, null);
61783
+ const segments = decoded[line];
61784
+ const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || 1);
61785
+ if (index === -1) return OMapping(null, null, null, null);
61786
+ const segment = segments[index];
61787
+ if (segment.length === 1) return OMapping(null, null, null, null);
61788
+ const { names, resolvedSources } = map;
61789
+ return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
61790
+ }
61791
+ function OMapping(source, line, column, name) {
61792
+ return {
61793
+ source,
61794
+ line,
61795
+ column,
61796
+ name
61797
+ };
61798
+ }
61799
+ function traceSegmentInternal(segments, memo, line, column, bias) {
61800
+ let index = memoizedBinarySearch(segments, column, memo, line);
61801
+ if (found) index = (bias === -1 ? upperBound : lowerBound)(segments, column, index);
61802
+ else if (bias === -1) index++;
61803
+ if (index === -1 || index === segments.length) return -1;
61804
+ return index;
61805
+ }
61806
+ //#endregion
61384
61807
  //#region ../core/dist/index.js
61385
61808
  var __create = Object.create;
61386
61809
  var __defProp = Object.defineProperty;
@@ -61450,7 +61873,7 @@ var AmbiguousProjectError = class extends Error {
61450
61873
  };
61451
61874
  const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
61452
61875
  const HTML_FILE_PATTERN = /\.html$/i;
61453
- const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
61876
+ const SOURCE_FILE_PATTERN = /\.(?:astro|tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
61454
61877
  const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
61455
61878
  const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
61456
61879
  const MINIFIED_SNIFF_BYTES = 65536;
@@ -62178,6 +62601,7 @@ const FRAMEWORK_PACKAGES = {
62178
62601
  "@tanstack/react-start": "tanstack-start",
62179
62602
  "@remix-run/react": "remix",
62180
62603
  gatsby: "gatsby",
62604
+ astro: "astro",
62181
62605
  vite: "vite",
62182
62606
  "react-scripts": "cra",
62183
62607
  expo: "expo",
@@ -65249,7 +65673,7 @@ const evaluateSuppression = (lines, diagnosticLineIndex, ruleId) => {
65249
65673
  const getDiagnosticRuleIdentity = (diagnostic) => ({
65250
65674
  ruleKey: `${diagnostic.plugin}/${diagnostic.rule}`,
65251
65675
  category: diagnostic.category,
65252
- tags: diagnostic.plugin === "react-doctor" ? reactDoctorPlugin.rules[diagnostic.rule]?.tags ?? [] : []
65676
+ tags: diagnostic.plugin === "react-doctor" ? REACT_DOCTOR_RULE_REGISTRY[diagnostic.rule]?.tags ?? [] : []
65253
65677
  });
65254
65678
  const compileIgnoredFilePatterns = (userConfig) => {
65255
65679
  const files = userConfig?.ignore?.files;
@@ -65601,7 +66025,7 @@ const buildDiagnosticPipeline = (input) => {
65601
66025
  };
65602
66026
  const shouldAutoSuppress = (diagnostic) => {
65603
66027
  if (diagnostic.plugin !== "react-doctor") return false;
65604
- const rule = reactDoctorPlugin.rules[diagnostic.rule];
66028
+ const rule = REACT_DOCTOR_RULE_REGISTRY[diagnostic.rule];
65605
66029
  if (!rule?.tags?.includes("test-noise")) return false;
65606
66030
  if (rule.tags.includes("migration-hint")) return false;
65607
66031
  return getFileContext(diagnostic.filePath) !== "production";
@@ -66033,6 +66457,7 @@ var OxlintConcurrency = class extends Reference("react-doctor/OxlintConcurrency"
66033
66457
  if (Number.isInteger(parsed) && parsed > 0) return resolveScanConcurrency(parsed);
66034
66458
  return resolveAutoScanConcurrency();
66035
66459
  } }) {};
66460
+ var OxlintSpawnSlots = class extends Reference("react-doctor/OxlintSpawnSlots", { defaultValue: () => null }) {};
66036
66461
  /**
66037
66462
  * Three-state control for overlapping the dead-code pass with the lint pass —
66038
66463
  * forking dead-code as a child fiber that runs DURING lint instead of strictly
@@ -68355,8 +68780,8 @@ const getCapabilities = (project) => {
68355
68780
  const cached = capabilitiesByProject.get(project);
68356
68781
  if (cached !== void 0) return cached;
68357
68782
  const capabilities = new Set(buildCapabilities(project));
68358
- const packageJson = readPackageJson(Path.join(project.rootDirectory, "package.json"));
68359
- const targetBlankOpenerProtection = detectTargetBlankOpenerProtection(project.rootDirectory, packageJson);
68783
+ const capabilityRootDirectory = isFile(Path.join(project.rootDirectory, "package.json")) ? project.rootDirectory : findNearestAncestorPackageJson(project.rootDirectory) ?? project.rootDirectory;
68784
+ const targetBlankOpenerProtection = detectTargetBlankOpenerProtection(capabilityRootDirectory, readPackageJson(Path.join(capabilityRootDirectory, "package.json")));
68360
68785
  if (targetBlankOpenerProtection !== void 0) capabilities.add("target-blank-needs-explicit-protection");
68361
68786
  if (targetBlankOpenerProtection === "noreferrer") capabilities.add("target-blank-needs-noreferrer");
68362
68787
  capabilitiesByProject.set(project, capabilities);
@@ -68386,7 +68811,7 @@ const createSecurityScanSession = (rootDirectory, options) => {
68386
68811
  const capabilities = options.project ? getCapabilities(options.project) : /* @__PURE__ */ new Set();
68387
68812
  const ignoredTags = options.ignoredTags ?? /* @__PURE__ */ new Set();
68388
68813
  const includedTags = options.includedTags ?? /* @__PURE__ */ new Set();
68389
- const enabledScanRules = REACT_DOCTOR_RULES.flatMap((entry) => {
68814
+ const enabledScanRules = REACT_DOCTOR_SCAN_RULES.flatMap((entry) => {
68390
68815
  const rule = entry.rule;
68391
68816
  const scan = rule.scan;
68392
68817
  if (typeof scan !== "function") return [];
@@ -68831,47 +69256,55 @@ const resolveDeadCodeConcurrency = (facts = readSystemFacts()) => {
68831
69256
  const memoryBoundedWorkers = Math.floor(availableMemoryBytes / DEAD_CODE_WORKER_MEM_BUDGET_BYTES);
68832
69257
  return Math.max(1, Math.min(facts.availableCores, memoryBoundedWorkers));
68833
69258
  };
68834
- let availableSlots = -1;
68835
- const waiters = [];
68836
- const releaseSlot = () => {
68837
- const nextWaiter = waiters.shift();
68838
- if (nextWaiter !== void 0) nextWaiter();
68839
- else availableSlots += 1;
69259
+ const createWorkerSlots = (input) => {
69260
+ let availableSlotCount = input.slotCount;
69261
+ const waiters = [];
69262
+ const releaseSlot = () => {
69263
+ const nextWaiter = waiters.shift();
69264
+ if (nextWaiter === void 0) {
69265
+ availableSlotCount += 1;
69266
+ return;
69267
+ }
69268
+ nextWaiter.abortSignal?.removeEventListener("abort", nextWaiter.onAbort);
69269
+ nextWaiter.resolve();
69270
+ };
69271
+ const acquireSlot = async (abortSignal) => {
69272
+ if (abortSignal?.aborted) throw input.createAbortError();
69273
+ if (availableSlotCount > 0) {
69274
+ availableSlotCount -= 1;
69275
+ return;
69276
+ }
69277
+ await new Promise((resolve, reject) => {
69278
+ const onAbort = () => {
69279
+ const waiterIndex = waiters.indexOf(waiter);
69280
+ if (waiterIndex !== -1) waiters.splice(waiterIndex, 1);
69281
+ reject(input.createAbortError());
69282
+ };
69283
+ const waiter = {
69284
+ resolve,
69285
+ abortSignal,
69286
+ onAbort
69287
+ };
69288
+ waiters.push(waiter);
69289
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
69290
+ });
69291
+ };
69292
+ return { run: async (task, abortSignal) => {
69293
+ await acquireSlot(abortSignal);
69294
+ try {
69295
+ return await task();
69296
+ } finally {
69297
+ releaseSlot();
69298
+ }
69299
+ } };
68840
69300
  };
68841
- /**
68842
- * Runs `task` once a dead-code worker slot is free, releasing the slot when the
68843
- * task settles (success or failure). With a high cap (roomy machine) every
68844
- * caller proceeds immediately; with a low cap (constrained runner) callers
68845
- * queue and run as slots free.
68846
- *
68847
- * `abortSignal` short-circuits the WAIT: if it's already aborted, or fires while
68848
- * this caller is queued, the call rejects without acquiring a slot or running
68849
- * `task` — so a cancelled scan (e.g. lint failed) doesn't sit in the queue and
68850
- * then spawn a child only to tear it down. A queued caller that aborts removes
68851
- * its own waiter so a later release never hands a slot to a dead request.
68852
- */
69301
+ let deadCodeWorkerSlots = null;
68853
69302
  const withDeadCodeWorkerSlot = async (task, abortSignal) => {
68854
- if (abortSignal?.aborted) throw new Error("Dead-code worker aborted.");
68855
- if (availableSlots < 0) availableSlots = resolveDeadCodeConcurrency();
68856
- if (availableSlots > 0) availableSlots -= 1;
68857
- else await new Promise((resolve, reject) => {
68858
- const waiter = () => {
68859
- abortSignal?.removeEventListener("abort", onAbort);
68860
- resolve();
68861
- };
68862
- const onAbort = () => {
68863
- const queuedIndex = waiters.indexOf(waiter);
68864
- if (queuedIndex !== -1) waiters.splice(queuedIndex, 1);
68865
- reject(/* @__PURE__ */ new Error("Dead-code worker aborted."));
68866
- };
68867
- waiters.push(waiter);
68868
- abortSignal?.addEventListener("abort", onAbort, { once: true });
69303
+ deadCodeWorkerSlots ??= createWorkerSlots({
69304
+ slotCount: resolveDeadCodeConcurrency(),
69305
+ createAbortError: () => /* @__PURE__ */ new Error("Dead-code worker aborted.")
68869
69306
  });
68870
- try {
68871
- return await task();
68872
- } finally {
68873
- releaseSlot();
68874
- }
69307
+ return deadCodeWorkerSlots.run(task, abortSignal);
68875
69308
  };
68876
69309
  const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
68877
69310
  const resolveReactDoctorCacheDir = (projectDirectory) => {
@@ -70398,12 +70831,12 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
70398
70831
  const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
70399
70832
  const enabledReactDoctorRules = {};
70400
70833
  for (const registryEntry of REACT_DOCTOR_RULES) {
70401
- const rule = reactDoctorPlugin.rules[registryEntry.id];
70834
+ const rule = REACT_DOCTOR_RULE_REGISTRY[registryEntry.id];
70402
70835
  if (!rule) continue;
70403
70836
  if (ruleSelection === "cacheable" && CROSS_FILE_RULE_IDS.has(registryEntry.id)) continue;
70404
70837
  if (ruleSelection === "sidecar" && !CROSS_FILE_RULE_IDS.has(registryEntry.id)) continue;
70405
70838
  if (ruleSelection === "sidecar" && sidecarRuleIdFilter !== void 0 && !sidecarRuleIdFilter.has(registryEntry.id)) continue;
70406
- if (rule.scan !== void 0) continue;
70839
+ if (rule.isScanRule) continue;
70407
70840
  if (customRulesOnly && registryEntry.originallyExternal) continue;
70408
70841
  if (rule.framework !== "global" && !rule.requires) continue;
70409
70842
  if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
@@ -71028,6 +71461,50 @@ const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
71028
71461
  while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
71029
71462
  return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
71030
71463
  };
71464
+ const utf8OffsetFromSourcePosition = (sourceBuffer, lineNumber, zeroBasedColumn) => {
71465
+ if (lineNumber < 1 || zeroBasedColumn < 0) return null;
71466
+ const sourceLines = sourceBuffer.toString("utf8").split("\n");
71467
+ const sourceLine = sourceLines[lineNumber - 1];
71468
+ if (sourceLine === void 0 || zeroBasedColumn > sourceLine.length) return null;
71469
+ const precedingLines = sourceLines.slice(0, lineNumber - 1).join("\n");
71470
+ return (lineNumber === 1 ? 0 : Buffer.byteLength(precedingLines) + Buffer.byteLength("\n")) + Buffer.byteLength(sourceLine.slice(0, zeroBasedColumn));
71471
+ };
71472
+ const mapPreparedSourceSpan = (span, preparedSourceMap) => {
71473
+ const generatedLine = lineOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset);
71474
+ const generatedColumn = columnOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset) - 1;
71475
+ const originalStart = originalPositionFor(preparedSourceMap.traceMap, {
71476
+ line: generatedLine,
71477
+ column: generatedColumn
71478
+ });
71479
+ if (originalStart.source === null || originalStart.line === null || originalStart.column === null) return null;
71480
+ const originalOffset = utf8OffsetFromSourcePosition(preparedSourceMap.sourceBuffer, originalStart.line, originalStart.column);
71481
+ if (originalOffset === null) return null;
71482
+ const generatedSpan = preparedSourceMap.generatedBuffer.subarray(span.offset, span.offset + span.length);
71483
+ return {
71484
+ offset: originalOffset,
71485
+ length: preparedSourceMap.sourceBuffer.subarray(originalOffset, originalOffset + generatedSpan.length).equals(generatedSpan) ? generatedSpan.length : 0,
71486
+ line: originalStart.line,
71487
+ column: originalStart.column + 1
71488
+ };
71489
+ };
71490
+ const mapPreparedSourceLabels = (labels, preparedSourceMap) => {
71491
+ const primaryLabel = labels[0];
71492
+ if (primaryLabel === void 0) return null;
71493
+ const primarySpan = mapPreparedSourceSpan(primaryLabel.span, preparedSourceMap);
71494
+ if (primarySpan === null) return null;
71495
+ const mappedLabels = [{
71496
+ ...primaryLabel,
71497
+ span: primarySpan
71498
+ }];
71499
+ for (const relatedLabel of labels.slice(1)) {
71500
+ const relatedSpan = mapPreparedSourceSpan(relatedLabel.span, preparedSourceMap);
71501
+ if (relatedSpan !== null) mappedLabels.push({
71502
+ ...relatedLabel,
71503
+ span: relatedSpan
71504
+ });
71505
+ }
71506
+ return mappedLabels;
71507
+ };
71031
71508
  const REDACTED_PLACEHOLDER = "<redacted>";
71032
71509
  const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
71033
71510
  const KNOWN_SECRET_RULES = [
@@ -71670,7 +72147,7 @@ const PLUGIN_CATEGORY_MAP = {
71670
72147
  };
71671
72148
  const lookupOwnString = (record, key) => Object.hasOwn(record, key) ? record[key] : void 0;
71672
72149
  const getRuleRecommendation = (ruleName, project) => {
71673
- const rule = reactDoctorPlugin.rules[ruleName];
72150
+ const rule = REACT_DOCTOR_RULE_REGISTRY[ruleName];
71674
72151
  if (!rule) return void 0;
71675
72152
  if (rule.recommendationFor) {
71676
72153
  const capabilities = getCapabilities(project);
@@ -71679,8 +72156,8 @@ const getRuleRecommendation = (ruleName, project) => {
71679
72156
  }
71680
72157
  return rule.recommendation;
71681
72158
  };
71682
- const getRuleCategory = (ruleName) => reactDoctorPlugin.rules[ruleName]?.category;
71683
- const getRuleTitle = (ruleName) => reactDoctorPlugin.rules[ruleName]?.title;
72159
+ const getRuleCategory = (ruleName) => REACT_DOCTOR_RULE_REGISTRY[ruleName]?.category;
72160
+ const getRuleTitle = (ruleName) => REACT_DOCTOR_RULE_REGISTRY[ruleName]?.title;
71684
72161
  const resolveDiagnosticTitle = (plugin, rule) => {
71685
72162
  if (plugin !== "react-hooks-js") return getRuleTitle(rule);
71686
72163
  if (rule === "error-boundaries") return REACT_ERROR_BOUNDARY_TITLE;
@@ -71735,7 +72212,7 @@ const resolveDiagnosticCategory = (plugin, rule) => {
71735
72212
  if (plugin === "react-hooks-js" && rule === "error-boundaries") return "Bugs";
71736
72213
  return getRuleCategory(rule) ?? lookupOwnString(PLUGIN_CATEGORY_MAP, plugin) ?? "Bugs";
71737
72214
  };
71738
- const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORIES.has(category) || Boolean(reactDoctorPlugin.rules[rule]?.matchByOccurrence);
72215
+ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORIES.has(category) || Boolean(REACT_DOCTOR_RULE_REGISTRY[rule]?.matchByOccurrence);
71739
72216
  /**
71740
72217
  * Maps oxlint's non-primary labels (`labels[1..]`) into related source
71741
72218
  * locations. Editors surface these as a diagnostic's
@@ -71772,7 +72249,7 @@ const isOxlintOutput = (value) => isRecord(value) && Array.isArray(value.diagnos
71772
72249
  * to the first `{`. Raises `OxlintOutputUnparseable` when the
71773
72250
  * stdout isn't valid JSON or doesn't carry a `diagnostics` array.
71774
72251
  */
71775
- const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
72252
+ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath) => {
71776
72253
  if (!stdout) return [];
71777
72254
  const jsonStart = stdout.indexOf("{");
71778
72255
  const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
@@ -71790,6 +72267,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath)
71790
72267
  const sourceLinesCache = /* @__PURE__ */ new Map();
71791
72268
  const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
71792
72269
  const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
72270
+ const resolvePreparedSourceMap = (filename) => sourceMapByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
71793
72271
  const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
71794
72272
  const readSourceBuffer = (filename) => {
71795
72273
  const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
@@ -71821,7 +72299,19 @@ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath)
71821
72299
  minifiedFileCache.set(absolutePath, minified);
71822
72300
  return minified;
71823
72301
  };
71824
- return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(resolveSourceFilename(diagnostic.filename)) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
72302
+ return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.flatMap((diagnostic) => {
72303
+ const preparedSourceMap = resolvePreparedSourceMap(diagnostic.filename);
72304
+ if (preparedSourceMap === void 0) return [diagnostic];
72305
+ const { plugin, rule } = parseRuleCode(diagnostic.code);
72306
+ if (plugin !== "react-doctor" || !REACT_DOCTOR_RULE_REGISTRY[rule]?.tags?.includes("design")) return [];
72307
+ const labels = mapPreparedSourceLabels(diagnostic.labels, preparedSourceMap);
72308
+ const sourceFilename = resolveMappedSourceFilename(diagnostic.filename);
72309
+ return labels === null || sourceFilename === void 0 ? [] : [{
72310
+ ...diagnostic,
72311
+ filename: sourceFilename,
72312
+ labels
72313
+ }];
72314
+ }).filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(resolveSourceFilename(diagnostic.filename)) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
71825
72315
  const { plugin, rule } = parseRuleCode(diagnostic.code);
71826
72316
  const primaryLabel = diagnostic.labels[0];
71827
72317
  const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
@@ -71899,11 +72389,12 @@ const SANITIZED_ENV = buildOxlintChildEnv(process.env);
71899
72389
  * The first three are splittable (the caller's binary-split retry
71900
72390
  * shrinks the batch and re-spawns); the fourth isn't.
71901
72391
  */
71902
- const spawnOxlint = (args, rootDirectory, nodeBinaryPath, spawnTimeoutMs = OXLINT_SPAWN_TIMEOUT_MS, outputMaxBytes = OXLINT_OUTPUT_MAX_BYTES, abortSignal) => new Promise((resolve, reject) => {
72392
+ const spawnOxlint = (args, rootDirectory, nodeBinaryPath, spawnTimeoutMs = OXLINT_SPAWN_TIMEOUT_MS, outputMaxBytes = OXLINT_OUTPUT_MAX_BYTES, abortSignal, onSpawn) => new Promise((resolve, reject) => {
71903
72393
  if (abortSignal?.aborted) {
71904
72394
  reject(new ReactDoctorError({ reason: new OxlintSpawnFailed({ cause: "lint phase aborted" }) }));
71905
72395
  return;
71906
72396
  }
72397
+ onSpawn?.();
71907
72398
  const child = spawn(nodeBinaryPath, buildProfiledNodeArguments({
71908
72399
  argumentsList: args,
71909
72400
  cpuProfileDirectory: SANITIZED_ENV.REACT_DOCTOR_CPU_PROFILE_DIR,
@@ -72039,7 +72530,7 @@ const isParallelismRelatedSpawnError = (error) => {
72039
72530
  * loop with a slimmer config in that case.
72040
72531
  */
72041
72532
  const spawnLintBatches = async (input) => {
72042
- const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
72533
+ const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, sourceMapByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
72043
72534
  const resolveSourcePath = (filePath) => {
72044
72535
  const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
72045
72536
  return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
@@ -72063,7 +72554,21 @@ const spawnLintBatches = async (input) => {
72063
72554
  }
72064
72555
  const batchArgs = [...baseArgs, ...batch];
72065
72556
  try {
72066
- return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
72557
+ const spawnBatch = () => {
72558
+ if (isPastDeadline()) {
72559
+ deadlineSkippedFiles.push(...batch);
72560
+ batchState.deadlineSkippedFileCount += batch.length;
72561
+ return Promise.resolve(null);
72562
+ }
72563
+ return spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal, () => {
72564
+ if (batchState.didStart) return;
72565
+ batchState.didStart = true;
72566
+ startedFileCount += batchState.initialFileCount;
72567
+ });
72568
+ };
72569
+ const stdout = input.spawnSlots === void 0 ? await spawnBatch() : await input.spawnSlots.run(spawnBatch, signal);
72570
+ if (stdout === null) return [];
72571
+ return parseOxlintOutput(stdout, project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath);
72067
72572
  } catch (error) {
72068
72573
  if (!isSplittableReactDoctorError(error)) throw error;
72069
72574
  if (isPastDeadline()) {
@@ -72107,14 +72612,15 @@ const spawnLintBatches = async (input) => {
72107
72612
  deadlineSkippedFiles.push(...batch);
72108
72613
  return [];
72109
72614
  }
72110
- startedFileCount += batch.length;
72111
72615
  const batchState = {
72112
72616
  deadlineMs: null,
72113
- deadlineSkippedFileCount: 0
72617
+ deadlineSkippedFileCount: 0,
72618
+ didStart: false,
72619
+ initialFileCount: batch.length
72114
72620
  };
72115
72621
  const batchDiagnostics = await spawnLintBatch(batch, 0, batchState);
72116
72622
  scannedFileCount += batch.length - batchState.deadlineSkippedFileCount;
72117
- if (passOnFileProgress) {
72623
+ if (passOnFileProgress && batchState.didStart) {
72118
72624
  displayedFileCount = Math.min(Math.max(displayedFileCount, scannedFileCount), totalFileCount);
72119
72625
  passOnFileProgress(displayedFileCount, totalFileCount);
72120
72626
  }
@@ -72198,8 +72704,8 @@ const validateRuleRegistration = () => {
72198
72704
  for (const fullKey of ALL_REACT_DOCTOR_RULE_KEYS) {
72199
72705
  const ruleName = fullKey.replace(/^react-doctor\//, "");
72200
72706
  if (!getRuleCategory(ruleName)) missingCategory.push(fullKey);
72201
- if (!reactDoctorPlugin.rules[ruleName]?.recommendation) missingHelp.push(fullKey);
72202
- if (FRAMEWORK_SPECIFIC_RULE_KEYS.has(fullKey) && !reactDoctorPlugin.rules[ruleName]?.requires) missingMetadata.push(fullKey);
72707
+ if (!REACT_DOCTOR_RULE_REGISTRY[ruleName]?.recommendation) missingHelp.push(fullKey);
72708
+ if (FRAMEWORK_SPECIFIC_RULE_KEYS.has(fullKey) && !REACT_DOCTOR_RULE_REGISTRY[ruleName]?.requires) missingMetadata.push(fullKey);
72203
72709
  }
72204
72710
  if (missingCategory.length === 0 && missingHelp.length === 0 && missingMetadata.length === 0) return;
72205
72711
  const detail = [
@@ -72502,20 +73008,47 @@ const prepareHtmlScriptSource = (sourceBuffer) => {
72502
73008
  lintBuffer: maskedBuffer ?? sourceBuffer
72503
73009
  };
72504
73010
  };
72505
- const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
73011
+ const ASTRO_FILE_PATTERN = /\.astro$/;
73012
+ const prepareLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
72506
73013
  const lintFiles = [];
72507
73014
  const sourcePathByLintPath = /* @__PURE__ */ new Map();
73015
+ const sourceMapByLintPath = /* @__PURE__ */ new Map();
72508
73016
  const sizeByLintPath = /* @__PURE__ */ new Map();
72509
73017
  const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
73018
+ const astroSourcesDirectory = Path.join(temporaryDirectory, "astro-sources");
72510
73019
  let htmlFileIndex = 0;
73020
+ let astroFileIndex = 0;
72511
73021
  let hasThreeModuleImport = false;
72512
73022
  for (const candidateFile of candidateFiles) {
72513
- if (!HTML_FILE_PATTERN.test(candidateFile)) {
73023
+ if (!HTML_FILE_PATTERN.test(candidateFile) && !ASTRO_FILE_PATTERN.test(candidateFile)) {
72514
73024
  lintFiles.push(candidateFile);
72515
73025
  continue;
72516
73026
  }
72517
73027
  const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
72518
73028
  const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
73029
+ if (ASTRO_FILE_PATTERN.test(candidateFile)) {
73030
+ const compilerSourcePath = absoluteSourcePath.replaceAll("\\", "/");
73031
+ const convertedSource = convertToTSX(sourceBuffer.toString("utf8"), {
73032
+ filename: compilerSourcePath,
73033
+ sourcemap: "external",
73034
+ includeScripts: true
73035
+ });
73036
+ if (astroFileIndex === 0) NFS.mkdirSync(astroSourcesDirectory, { recursive: true });
73037
+ const lintPath = Path.join(astroSourcesDirectory, `${astroFileIndex}.tsx`);
73038
+ const generatedBuffer = Buffer.from(convertedSource.code);
73039
+ NFS.writeFileSync(lintPath, generatedBuffer);
73040
+ lintFiles.push(candidateFile);
73041
+ lintFiles.push(lintPath);
73042
+ sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
73043
+ sourceMapByLintPath.set(Path.resolve(lintPath), {
73044
+ traceMap: new TraceMap(JSON.stringify(convertedSource.map)),
73045
+ generatedBuffer,
73046
+ sourceBuffer
73047
+ });
73048
+ sizeByLintPath.set(lintPath, sourceBuffer.length);
73049
+ astroFileIndex++;
73050
+ continue;
73051
+ }
72519
73052
  const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
72520
73053
  if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
72521
73054
  const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
@@ -72529,6 +73062,7 @@ const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFile
72529
73062
  return {
72530
73063
  lintFiles,
72531
73064
  sourcePathByLintPath,
73065
+ sourceMapByLintPath,
72532
73066
  sizeByLintPath,
72533
73067
  hasThreeModuleImport
72534
73068
  };
@@ -72747,10 +73281,10 @@ const runOxlint = async (options) => {
72747
73281
  rootDirectory,
72748
73282
  candidateFiles
72749
73283
  });
72750
- const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
72751
- const lintFiles = preparedHtmlSources.lintFiles;
72752
- const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
72753
- const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
73284
+ const preparedLintSources = prepareLintSources(rootDirectory, configDirectory, candidateFiles);
73285
+ const lintFiles = preparedLintSources.lintFiles;
73286
+ const hasPreparedFiles = preparedLintSources.sourcePathByLintPath.size > 0;
73287
+ const lintProject = !project.hasThree && preparedLintSources.hasThreeModuleImport ? {
72754
73288
  ...project,
72755
73289
  hasThree: true
72756
73290
  } : project;
@@ -72772,7 +73306,7 @@ const runOxlint = async (options) => {
72772
73306
  sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
72773
73307
  });
72774
73308
  const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
72775
- if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
73309
+ if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedLintSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
72776
73310
  const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
72777
73311
  baseArgs: passBaseArgs,
72778
73312
  files: passFiles,
@@ -72802,7 +73336,8 @@ const runOxlint = async (options) => {
72802
73336
  rootDirectory,
72803
73337
  nodeBinaryPath,
72804
73338
  project: lintProject,
72805
- sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
73339
+ sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
73340
+ sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
72806
73341
  onPartialFailure: reportPartialFailure,
72807
73342
  onAnalyzedFiles: (filePaths) => {
72808
73343
  analyzedFiles = filePaths;
@@ -72811,6 +73346,7 @@ const runOxlint = async (options) => {
72811
73346
  spawnTimeoutMs,
72812
73347
  outputMaxBytes,
72813
73348
  concurrency: options.concurrency,
73349
+ spawnSlots: options.spawnSlots,
72814
73350
  signal: options.signal,
72815
73351
  deadlineEpochMs: options.deadlineEpochMs
72816
73352
  });
@@ -72837,7 +73373,7 @@ const runOxlint = async (options) => {
72837
73373
  };
72838
73374
  }
72839
73375
  };
72840
- if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
73376
+ if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasPreparedFiles) {
72841
73377
  const rulesetHash = computeRulesetHash({
72842
73378
  config: buildConfig({
72843
73379
  extendsPaths: [],
@@ -73003,7 +73539,8 @@ const runOxlint = async (options) => {
73003
73539
  rootDirectory,
73004
73540
  nodeBinaryPath,
73005
73541
  project: lintProject,
73006
- sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
73542
+ sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
73543
+ sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
73007
73544
  onPartialFailure,
73008
73545
  onAnalyzedFiles: (filePaths) => {
73009
73546
  analyzedFiles = filePaths;
@@ -73012,6 +73549,7 @@ const runOxlint = async (options) => {
73012
73549
  spawnTimeoutMs,
73013
73550
  outputMaxBytes,
73014
73551
  concurrency: options.concurrency,
73552
+ spawnSlots: options.spawnSlots,
73015
73553
  signal: options.signal,
73016
73554
  deadlineEpochMs: options.deadlineEpochMs
73017
73555
  });
@@ -73106,6 +73644,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
73106
73644
  const spawnTimeoutMs = yield* OxlintSpawnTimeoutMs;
73107
73645
  const outputMaxBytes = yield* OxlintOutputMaxBytes;
73108
73646
  const concurrency = yield* OxlintConcurrency;
73647
+ const spawnSlots = yield* OxlintSpawnSlots;
73109
73648
  const lintBatchOrdering = yield* LintBatchOrdering;
73110
73649
  const perFileLintCacheEnabled = yield* PerFileLintCacheEnabled;
73111
73650
  const sidecarLintCacheEnabled = yield* SidecarLintCacheEnabled;
@@ -73135,6 +73674,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
73135
73674
  onSidecarStats: input.onSidecarStats,
73136
73675
  spawnTimeoutMs,
73137
73676
  outputMaxBytes,
73677
+ spawnSlots: spawnSlots ?? void 0,
73138
73678
  concurrency,
73139
73679
  signal,
73140
73680
  lintBatchOrdering,
@@ -74662,6 +75202,11 @@ const filterSourceFiles = (filePaths) => filePaths.filter(isLintableSourceFile);
74662
75202
  * other `clear*` helpers.
74663
75203
  */
74664
75204
  const clearAutoSuppressionCaches = () => {};
75205
+ const createLintPhaseAbortError = () => new ReactDoctorError({ reason: new OxlintSpawnFailed({ cause: "lint phase aborted" }) });
75206
+ const createOxlintSpawnSlots = (concurrency) => createWorkerSlots({
75207
+ slotCount: resolveScanConcurrency(concurrency),
75208
+ createAbortError: createLintPhaseAbortError
75209
+ });
74665
75210
  /**
74666
75211
  * Identity helper for authoring a typed `doctor.config.{ts,js,mjs,cjs}`.
74667
75212
  * Gives editor autocomplete and type-checking for the config object without
@@ -74782,7 +75327,7 @@ const buildDiagnoseLayer = (input) => {
74782
75327
  resolvedDirectory: input.configOverrideTarget.resolvedDirectory,
74783
75328
  configSourceDirectory: input.configOverrideTarget.configSourceDirectory
74784
75329
  });
74785
- return mergeAll$1(Project.layerNode, configLayer, input.shouldRunDeadCode ? DeadCode.layerNode : DeadCode.layerOf([]), Files.layerNode, Git.layerNode, input.shouldRunLint ? Linter.layerOxlint : Linter.layerOf([]), LintPartialFailures.layerLive, Progress.layerNoop, Reporter.layerNoop, Score.layerHttp, input.config?.supplyChain?.enabled !== false ? SupplyChain.layerNode : SupplyChain.layerOf([]));
75330
+ return mergeAll$1(Project.layerNode, configLayer, input.shouldRunDeadCode ? DeadCode.layerNode : DeadCode.layerOf([]), Files.layerNode, Git.layerNode, input.shouldRunLint ? Linter.layerOxlint : Linter.layerOf([]), LintPartialFailures.layerLive, succeed$3(OxlintConcurrency, input.oxlintConcurrency), succeed$3(OxlintSpawnSlots, input.oxlintSpawnSlots), Progress.layerNoop, Reporter.layerNoop, Score.layerHttp, input.config?.supplyChain?.enabled !== false ? SupplyChain.layerNode : SupplyChain.layerOf([]));
74786
75331
  };
74787
75332
  const buildInspectProgram = (scanTarget, options, configOverride) => {
74788
75333
  const effectiveConfig = configOverride ?? scanTarget.userConfig;
@@ -74823,10 +75368,14 @@ const diagnoseDirectory = async (directory, options) => {
74823
75368
  const program = buildInspectProgram(scanTarget, options);
74824
75369
  const shouldRunLint = resolveShouldRunLint(options, scanTarget.userConfig);
74825
75370
  const shouldRunDeadCode = resolveShouldRunDeadCode(options, scanTarget.userConfig);
75371
+ const oxlintConcurrency = runSync(OxlintConcurrency);
75372
+ const oxlintSpawnSlots = createOxlintSpawnSlots(oxlintConcurrency);
74826
75373
  return outputToDiagnoseResult(await runPromise(restoreLegacyThrow(program.pipe(provide(buildDiagnoseLayer({
74827
75374
  config: scanTarget.userConfig,
74828
75375
  shouldRunLint,
74829
- shouldRunDeadCode
75376
+ shouldRunDeadCode,
75377
+ oxlintConcurrency,
75378
+ oxlintSpawnSlots
74830
75379
  })), provide(layerOtlp)))), globalThis.performance.now() - startTime);
74831
75380
  };
74832
75381
  const findWorstScore = (projectResults) => {
@@ -74841,7 +75390,7 @@ const findWorstScore = (projectResults) => {
74841
75390
  }
74842
75391
  return worstResult;
74843
75392
  };
74844
- const diagnoseProject = async (projectDefinition, baseOptions, batchConfig) => {
75393
+ const diagnoseProject = async (projectDefinition, baseOptions, batchConfig, oxlintConcurrency, oxlintSpawnSlots) => {
74845
75394
  const startTime = globalThis.performance.now();
74846
75395
  try {
74847
75396
  const scanTarget = await resolveScanTarget(projectDefinition.directory);
@@ -74860,6 +75409,8 @@ const diagnoseProject = async (projectDefinition, baseOptions, batchConfig) => {
74860
75409
  config: effectiveConfig,
74861
75410
  shouldRunLint,
74862
75411
  shouldRunDeadCode,
75412
+ oxlintConcurrency,
75413
+ oxlintSpawnSlots,
74863
75414
  configOverrideTarget: {
74864
75415
  resolvedDirectory: scanTarget.resolvedDirectory,
74865
75416
  configSourceDirectory: didOverridePlugins ? null : scanTarget.configSourceDirectory
@@ -74867,7 +75418,9 @@ const diagnoseProject = async (projectDefinition, baseOptions, batchConfig) => {
74867
75418
  } : {
74868
75419
  config: effectiveConfig,
74869
75420
  shouldRunLint,
74870
- shouldRunDeadCode
75421
+ shouldRunDeadCode,
75422
+ oxlintConcurrency,
75423
+ oxlintSpawnSlots
74871
75424
  });
74872
75425
  return {
74873
75426
  ok: true,
@@ -74886,7 +75439,9 @@ const diagnoseProjectBatch = async (input) => {
74886
75439
  warnIfAiTrainingEnvironment();
74887
75440
  const startTime = globalThis.performance.now();
74888
75441
  const { projects, concurrency, config: batchConfig, ...baseOptions } = input;
74889
- const projectResults = await mapWithConcurrency(projects, concurrency ?? 4, (projectDefinition) => diagnoseProject(projectDefinition, baseOptions, batchConfig));
75442
+ const oxlintConcurrency = runSync(OxlintConcurrency);
75443
+ const oxlintSpawnSlots = createOxlintSpawnSlots(oxlintConcurrency);
75444
+ const projectResults = await mapWithConcurrency(projects, concurrency ?? 4, (projectDefinition) => diagnoseProject(projectDefinition, baseOptions, batchConfig, oxlintConcurrency, oxlintSpawnSlots));
74890
75445
  const succeededProjects = projectResults.filter((projectResult) => projectResult.ok);
74891
75446
  return {
74892
75447
  projects: projectResults,
@@ -74932,4 +75487,4 @@ const toJsonReport = (result, options) => buildJsonReport({
74932
75487
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
74933
75488
 
74934
75489
  //# sourceMappingURL=index.js.map
74935
- //# debugId=cc06d86a-0b85-5115-a9f2-cc30c268ad79
75490
+ //# debugId=61d9689f-8ba5-5ca3-a0c2-09557d3f7028