react-doctor 0.9.1 → 0.9.2-dev.1098b9c

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/lsp.js CHANGED
@@ -10,12 +10,14 @@ import * as Crypto from "node:crypto";
10
10
  import crypto, { createHash } from "node:crypto";
11
11
  import * as NodeChildProcess from "node:child_process";
12
12
  import { execFileSync, spawn, spawnSync } from "node:child_process";
13
+ import { ResolverFactory } from "oxc-resolver";
13
14
  import ts from "typescript";
14
- import { parseJSON5 } from "confbox";
15
15
  import * as NodeUrl from "node:url";
16
16
  import { fileURLToPath } from "node:url";
17
+ import { parseJSON5 } from "confbox";
17
18
  import { createJiti } from "jiti";
18
19
  import { ANALYZED_MANIFEST_FILENAMES, DEFAULT_EXTENSIONS } from "deslop-js/analyzed-inputs";
20
+ import { convertToTSX } from "@astrojs/compiler/sync";
19
21
  import { gzipSync } from "node:zlib";
20
22
  import { CodeActionKind, CodeActionTriggerKind, DidChangeWatchedFilesNotification, DocumentDiagnosticReportKind, FileChangeType, TextDocumentSyncKind, TextDocuments, createConnection } from "vscode-languageserver/node.js";
21
23
  import { TextDocument } from "vscode-languageserver-textdocument";
@@ -10279,7 +10281,7 @@ const Number$4 = globalThis.Number;
10279
10281
  * @category constructors
10280
10282
  * @since 2.0.0
10281
10283
  */
10282
- const parse = (s) => {
10284
+ const parse$1 = (s) => {
10283
10285
  if (s === "NaN") return some(NaN);
10284
10286
  if (s === "Infinity") return some(Infinity);
10285
10287
  if (s === "-Infinity") return some(-Infinity);
@@ -14333,12 +14335,12 @@ TaggedError("EncodingError");
14333
14335
  //#endregion
14334
14336
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.70/node_modules/effect/dist/internal/schema/annotations.js
14335
14337
  /** @internal */
14336
- function resolve(ast) {
14338
+ function resolve$1(ast) {
14337
14339
  return ast.checks ? ast.checks[ast.checks.length - 1].annotations : ast.annotations;
14338
14340
  }
14339
14341
  /** @internal */
14340
14342
  function resolveAt(key) {
14341
- return (ast) => resolve(ast)?.[key];
14343
+ return (ast) => resolve$1(ast)?.[key];
14342
14344
  }
14343
14345
  /** @internal */
14344
14346
  const resolveIdentifier = /* @__PURE__ */ resolveAt("identifier");
@@ -18090,7 +18092,7 @@ function asSync(parser) {
18090
18092
  }
18091
18093
  const recur$1 = /* @__PURE__ */ memoize((ast) => {
18092
18094
  let parser;
18093
- const astOptions = resolve(ast)?.["parseOptions"];
18095
+ const astOptions = resolve$1(ast)?.["parseOptions"];
18094
18096
  if (!ast.context && !ast.encoding && !ast.checks) return (ou, options) => {
18095
18097
  parser ??= ast.getParser(recur$1);
18096
18098
  if (astOptions) options = {
@@ -57695,7 +57697,7 @@ var UrlParamsError = class extends TaggedError("UrlParamsError") {};
57695
57697
  * @category converting
57696
57698
  * @since 4.0.0
57697
57699
  */
57698
- const makeUrl = (url, params, hash) => {
57700
+ const makeUrl$1 = (url, params, hash) => {
57699
57701
  try {
57700
57702
  const urlInstance = new URL(url, baseUrl());
57701
57703
  for (let i = 0; i < params.params.length; i++) {
@@ -58329,7 +58331,7 @@ const Proto$2 = {
58329
58331
  const make$10 = (f) => makeWith$1((effect) => flatMap$2(effect, (request) => withFiber((fiber) => {
58330
58332
  const scopedController = scopedRequests.get(request);
58331
58333
  const controller = scopedController ?? new AbortController();
58332
- const urlResult = makeUrl(request.url, request.urlParams, getOrUndefined(request.hash));
58334
+ const urlResult = makeUrl$1(request.url, request.urlParams, getOrUndefined(request.hash));
58333
58335
  if (isFailure(urlResult)) return fail$4(new HttpClientError({ reason: new InvalidUrlError({
58334
58336
  request,
58335
58337
  cause: urlResult.failure
@@ -58768,7 +58770,7 @@ const layer$7 = (loggers, options) => effect(CurrentLoggers, withFiber$1(fnUntra
58768
58770
  * @since 4.0.0
58769
58771
  */
58770
58772
  const policy = /* @__PURE__ */ forever$1.pipe(passthrough$2, /* @__PURE__ */ addDelay((error) => {
58771
- 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))));
58773
+ 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))));
58772
58774
  return succeed$2(seconds(1));
58773
58775
  }));
58774
58776
  /**
@@ -61410,6 +61412,428 @@ const layer = /* @__PURE__ */ succeed$3(Path$1)({
61410
61412
  toFileUrl
61411
61413
  });
61412
61414
  //#endregion
61415
+ //#region ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
61416
+ var comma = ",".charCodeAt(0);
61417
+ ";".charCodeAt(0);
61418
+ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
61419
+ var intToChar = new Uint8Array(64);
61420
+ var charToInt = new Uint8Array(128);
61421
+ for (let i = 0; i < chars.length; i++) {
61422
+ const c = chars.charCodeAt(i);
61423
+ intToChar[i] = c;
61424
+ charToInt[c] = i;
61425
+ }
61426
+ function decodeInteger(reader, relative) {
61427
+ let value = 0;
61428
+ let shift = 0;
61429
+ let integer = 0;
61430
+ do {
61431
+ integer = charToInt[reader.next()];
61432
+ value |= (integer & 31) << shift;
61433
+ shift += 5;
61434
+ } while (integer & 32);
61435
+ const shouldNegate = value & 1;
61436
+ value >>>= 1;
61437
+ if (shouldNegate) value = -2147483648 | -value;
61438
+ return relative + value;
61439
+ }
61440
+ function hasMoreVlq(reader, max) {
61441
+ if (reader.pos >= max) return false;
61442
+ return reader.peek() !== comma;
61443
+ }
61444
+ var StringReader = class {
61445
+ constructor(buffer) {
61446
+ this.pos = 0;
61447
+ this.buffer = buffer;
61448
+ }
61449
+ next() {
61450
+ return this.buffer.charCodeAt(this.pos++);
61451
+ }
61452
+ peek() {
61453
+ return this.buffer.charCodeAt(this.pos);
61454
+ }
61455
+ indexOf(char) {
61456
+ const { buffer, pos } = this;
61457
+ const idx = buffer.indexOf(char, pos);
61458
+ return idx === -1 ? buffer.length : idx;
61459
+ }
61460
+ };
61461
+ function decode(mappings) {
61462
+ const { length } = mappings;
61463
+ const reader = new StringReader(mappings);
61464
+ const decoded = [];
61465
+ let genColumn = 0;
61466
+ let sourcesIndex = 0;
61467
+ let sourceLine = 0;
61468
+ let sourceColumn = 0;
61469
+ let namesIndex = 0;
61470
+ do {
61471
+ const semi = reader.indexOf(";");
61472
+ const line = [];
61473
+ let sorted = true;
61474
+ let lastCol = 0;
61475
+ genColumn = 0;
61476
+ while (reader.pos < semi) {
61477
+ let seg;
61478
+ genColumn = decodeInteger(reader, genColumn);
61479
+ if (genColumn < lastCol) sorted = false;
61480
+ lastCol = genColumn;
61481
+ if (hasMoreVlq(reader, semi)) {
61482
+ sourcesIndex = decodeInteger(reader, sourcesIndex);
61483
+ sourceLine = decodeInteger(reader, sourceLine);
61484
+ sourceColumn = decodeInteger(reader, sourceColumn);
61485
+ if (hasMoreVlq(reader, semi)) {
61486
+ namesIndex = decodeInteger(reader, namesIndex);
61487
+ seg = [
61488
+ genColumn,
61489
+ sourcesIndex,
61490
+ sourceLine,
61491
+ sourceColumn,
61492
+ namesIndex
61493
+ ];
61494
+ } else seg = [
61495
+ genColumn,
61496
+ sourcesIndex,
61497
+ sourceLine,
61498
+ sourceColumn
61499
+ ];
61500
+ } else seg = [genColumn];
61501
+ line.push(seg);
61502
+ reader.pos++;
61503
+ }
61504
+ if (!sorted) sort(line);
61505
+ decoded.push(line);
61506
+ reader.pos = semi + 1;
61507
+ } while (reader.pos <= length);
61508
+ return decoded;
61509
+ }
61510
+ function sort(line) {
61511
+ line.sort(sortComparator$1);
61512
+ }
61513
+ function sortComparator$1(a, b) {
61514
+ return a[0] - b[0];
61515
+ }
61516
+ //#endregion
61517
+ //#region ../../node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
61518
+ const schemeRegex = /^[\w+.-]+:\/\//;
61519
+ /**
61520
+ * Matches the parts of a URL:
61521
+ * 1. Scheme, including ":", guaranteed.
61522
+ * 2. User/password, including "@", optional.
61523
+ * 3. Host, guaranteed.
61524
+ * 4. Port, including ":", optional.
61525
+ * 5. Path, including "/", optional.
61526
+ * 6. Query, including "?", optional.
61527
+ * 7. Hash, including "#", optional.
61528
+ */
61529
+ const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
61530
+ /**
61531
+ * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
61532
+ * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
61533
+ *
61534
+ * 1. Host, optional.
61535
+ * 2. Path, which may include "/", guaranteed.
61536
+ * 3. Query, including "?", optional.
61537
+ * 4. Hash, including "#", optional.
61538
+ */
61539
+ const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
61540
+ function isAbsoluteUrl(input) {
61541
+ return schemeRegex.test(input);
61542
+ }
61543
+ function isSchemeRelativeUrl(input) {
61544
+ return input.startsWith("//");
61545
+ }
61546
+ function isAbsolutePath(input) {
61547
+ return input.startsWith("/");
61548
+ }
61549
+ function isFileUrl(input) {
61550
+ return input.startsWith("file:");
61551
+ }
61552
+ function isRelative(input) {
61553
+ return /^[.?#]/.test(input);
61554
+ }
61555
+ function parseAbsoluteUrl(input) {
61556
+ const match = urlRegex.exec(input);
61557
+ return makeUrl(match[1], match[2] || "", match[3], match[4] || "", match[5] || "/", match[6] || "", match[7] || "");
61558
+ }
61559
+ function parseFileUrl(input) {
61560
+ const match = fileRegex.exec(input);
61561
+ const path = match[2];
61562
+ return makeUrl("file:", "", match[1] || "", "", isAbsolutePath(path) ? path : "/" + path, match[3] || "", match[4] || "");
61563
+ }
61564
+ function makeUrl(scheme, user, host, port, path, query, hash) {
61565
+ return {
61566
+ scheme,
61567
+ user,
61568
+ host,
61569
+ port,
61570
+ path,
61571
+ query,
61572
+ hash,
61573
+ type: 7
61574
+ };
61575
+ }
61576
+ function parseUrl(input) {
61577
+ if (isSchemeRelativeUrl(input)) {
61578
+ const url = parseAbsoluteUrl("http:" + input);
61579
+ url.scheme = "";
61580
+ url.type = 6;
61581
+ return url;
61582
+ }
61583
+ if (isAbsolutePath(input)) {
61584
+ const url = parseAbsoluteUrl("http://foo.com" + input);
61585
+ url.scheme = "";
61586
+ url.host = "";
61587
+ url.type = 5;
61588
+ return url;
61589
+ }
61590
+ if (isFileUrl(input)) return parseFileUrl(input);
61591
+ if (isAbsoluteUrl(input)) return parseAbsoluteUrl(input);
61592
+ const url = parseAbsoluteUrl("http://foo.com/" + input);
61593
+ url.scheme = "";
61594
+ url.host = "";
61595
+ url.type = input ? input.startsWith("?") ? 3 : input.startsWith("#") ? 2 : 4 : 1;
61596
+ return url;
61597
+ }
61598
+ function stripPathFilename(path) {
61599
+ if (path.endsWith("/..")) return path;
61600
+ const index = path.lastIndexOf("/");
61601
+ return path.slice(0, index + 1);
61602
+ }
61603
+ function mergePaths(url, base) {
61604
+ normalizePath(base, base.type);
61605
+ if (url.path === "/") url.path = base.path;
61606
+ else url.path = stripPathFilename(base.path) + url.path;
61607
+ }
61608
+ /**
61609
+ * The path can have empty directories "//", unneeded parents "foo/..", or current directory
61610
+ * "foo/.". We need to normalize to a standard representation.
61611
+ */
61612
+ function normalizePath(url, type) {
61613
+ const rel = type <= 4;
61614
+ const pieces = url.path.split("/");
61615
+ let pointer = 1;
61616
+ let positive = 0;
61617
+ let addTrailingSlash = false;
61618
+ for (let i = 1; i < pieces.length; i++) {
61619
+ const piece = pieces[i];
61620
+ if (!piece) {
61621
+ addTrailingSlash = true;
61622
+ continue;
61623
+ }
61624
+ addTrailingSlash = false;
61625
+ if (piece === ".") continue;
61626
+ if (piece === "..") {
61627
+ if (positive) {
61628
+ addTrailingSlash = true;
61629
+ positive--;
61630
+ pointer--;
61631
+ } else if (rel) pieces[pointer++] = piece;
61632
+ continue;
61633
+ }
61634
+ pieces[pointer++] = piece;
61635
+ positive++;
61636
+ }
61637
+ let path = "";
61638
+ for (let i = 1; i < pointer; i++) path += "/" + pieces[i];
61639
+ if (!path || addTrailingSlash && !path.endsWith("/..")) path += "/";
61640
+ url.path = path;
61641
+ }
61642
+ /**
61643
+ * Attempts to resolve `input` URL/path relative to `base`.
61644
+ */
61645
+ function resolve(input, base) {
61646
+ if (!input && !base) return "";
61647
+ const url = parseUrl(input);
61648
+ let inputType = url.type;
61649
+ if (base && inputType !== 7) {
61650
+ const baseUrl = parseUrl(base);
61651
+ const baseType = baseUrl.type;
61652
+ switch (inputType) {
61653
+ case 1: url.hash = baseUrl.hash;
61654
+ case 2: url.query = baseUrl.query;
61655
+ case 3:
61656
+ case 4: mergePaths(url, baseUrl);
61657
+ case 5:
61658
+ url.user = baseUrl.user;
61659
+ url.host = baseUrl.host;
61660
+ url.port = baseUrl.port;
61661
+ case 6: url.scheme = baseUrl.scheme;
61662
+ }
61663
+ if (baseType > inputType) inputType = baseType;
61664
+ }
61665
+ normalizePath(url, inputType);
61666
+ const queryHash = url.query + url.hash;
61667
+ switch (inputType) {
61668
+ case 2:
61669
+ case 3: return queryHash;
61670
+ case 4: {
61671
+ const path = url.path.slice(1);
61672
+ if (!path) return queryHash || ".";
61673
+ if (isRelative(base || input) && !isRelative(path)) return "./" + path + queryHash;
61674
+ return path + queryHash;
61675
+ }
61676
+ case 5: return url.path + queryHash;
61677
+ default: return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
61678
+ }
61679
+ }
61680
+ //#endregion
61681
+ //#region ../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
61682
+ function stripFilename(path) {
61683
+ if (!path) return "";
61684
+ const index = path.lastIndexOf("/");
61685
+ return path.slice(0, index + 1);
61686
+ }
61687
+ function resolver(mapUrl, sourceRoot) {
61688
+ const from = stripFilename(mapUrl);
61689
+ const prefix = sourceRoot ? sourceRoot + "/" : "";
61690
+ return (source) => resolve(prefix + (source || ""), from);
61691
+ }
61692
+ var COLUMN = 0;
61693
+ var SOURCES_INDEX = 1;
61694
+ var SOURCE_LINE = 2;
61695
+ var SOURCE_COLUMN = 3;
61696
+ var NAMES_INDEX = 4;
61697
+ function maybeSort(mappings, owned) {
61698
+ const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
61699
+ if (unsortedIndex === mappings.length) return mappings;
61700
+ if (!owned) mappings = mappings.slice();
61701
+ for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) mappings[i] = sortSegments(mappings[i], owned);
61702
+ return mappings;
61703
+ }
61704
+ function nextUnsortedSegmentLine(mappings, start) {
61705
+ for (let i = start; i < mappings.length; i++) if (!isSorted(mappings[i])) return i;
61706
+ return mappings.length;
61707
+ }
61708
+ function isSorted(line) {
61709
+ for (let j = 1; j < line.length; j++) if (line[j][COLUMN] < line[j - 1][COLUMN]) return false;
61710
+ return true;
61711
+ }
61712
+ function sortSegments(line, owned) {
61713
+ if (!owned) line = line.slice();
61714
+ return line.sort(sortComparator);
61715
+ }
61716
+ function sortComparator(a, b) {
61717
+ return a[COLUMN] - b[COLUMN];
61718
+ }
61719
+ var found = false;
61720
+ function binarySearch(haystack, needle, low, high) {
61721
+ while (low <= high) {
61722
+ const mid = low + (high - low >> 1);
61723
+ const cmp = haystack[mid][COLUMN] - needle;
61724
+ if (cmp === 0) {
61725
+ found = true;
61726
+ return mid;
61727
+ }
61728
+ if (cmp < 0) low = mid + 1;
61729
+ else high = mid - 1;
61730
+ }
61731
+ found = false;
61732
+ return low - 1;
61733
+ }
61734
+ function upperBound(haystack, needle, index) {
61735
+ for (let i = index + 1; i < haystack.length; index = i++) if (haystack[i][COLUMN] !== needle) break;
61736
+ return index;
61737
+ }
61738
+ function lowerBound(haystack, needle, index) {
61739
+ for (let i = index - 1; i >= 0; index = i--) if (haystack[i][COLUMN] !== needle) break;
61740
+ return index;
61741
+ }
61742
+ function memoizedState() {
61743
+ return {
61744
+ lastKey: -1,
61745
+ lastNeedle: -1,
61746
+ lastIndex: -1
61747
+ };
61748
+ }
61749
+ function memoizedBinarySearch(haystack, needle, state, key) {
61750
+ const { lastKey, lastNeedle, lastIndex } = state;
61751
+ let low = 0;
61752
+ let high = haystack.length - 1;
61753
+ if (key === lastKey) {
61754
+ if (needle === lastNeedle) {
61755
+ found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
61756
+ return lastIndex;
61757
+ }
61758
+ if (needle >= lastNeedle) low = lastIndex === -1 ? 0 : lastIndex;
61759
+ else high = lastIndex;
61760
+ }
61761
+ state.lastKey = key;
61762
+ state.lastNeedle = needle;
61763
+ return state.lastIndex = binarySearch(haystack, needle, low, high);
61764
+ }
61765
+ function parse(map) {
61766
+ return typeof map === "string" ? JSON.parse(map) : map;
61767
+ }
61768
+ var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)";
61769
+ var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)";
61770
+ var TraceMap = class {
61771
+ constructor(map, mapUrl) {
61772
+ const isString = typeof map === "string";
61773
+ if (!isString && map._decodedMemo) return map;
61774
+ const parsed = parse(map);
61775
+ const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
61776
+ this.version = version;
61777
+ this.file = file;
61778
+ this.names = names || [];
61779
+ this.sourceRoot = sourceRoot;
61780
+ this.sources = sources;
61781
+ this.sourcesContent = sourcesContent;
61782
+ this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0;
61783
+ const resolve = resolver(mapUrl, sourceRoot);
61784
+ this.resolvedSources = sources.map(resolve);
61785
+ const { mappings } = parsed;
61786
+ if (typeof mappings === "string") {
61787
+ this._encoded = mappings;
61788
+ this._decoded = void 0;
61789
+ } else if (Array.isArray(mappings)) {
61790
+ this._encoded = void 0;
61791
+ this._decoded = maybeSort(mappings, isString);
61792
+ } else if (parsed.sections) throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`);
61793
+ else throw new Error(`invalid source map: ${JSON.stringify(parsed)}`);
61794
+ this._decodedMemo = memoizedState();
61795
+ this._bySources = void 0;
61796
+ this._bySourceMemos = void 0;
61797
+ }
61798
+ };
61799
+ function cast(map) {
61800
+ return map;
61801
+ }
61802
+ function decodedMappings(map) {
61803
+ var _a;
61804
+ return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded));
61805
+ }
61806
+ function originalPositionFor(map, needle) {
61807
+ let { line, column, bias } = needle;
61808
+ line--;
61809
+ if (line < 0) throw new Error(LINE_GTR_ZERO);
61810
+ if (column < 0) throw new Error(COL_GTR_EQ_ZERO);
61811
+ const decoded = decodedMappings(map);
61812
+ if (line >= decoded.length) return OMapping(null, null, null, null);
61813
+ const segments = decoded[line];
61814
+ const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || 1);
61815
+ if (index === -1) return OMapping(null, null, null, null);
61816
+ const segment = segments[index];
61817
+ if (segment.length === 1) return OMapping(null, null, null, null);
61818
+ const { names, resolvedSources } = map;
61819
+ return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
61820
+ }
61821
+ function OMapping(source, line, column, name) {
61822
+ return {
61823
+ source,
61824
+ line,
61825
+ column,
61826
+ name
61827
+ };
61828
+ }
61829
+ function traceSegmentInternal(segments, memo, line, column, bias) {
61830
+ let index = memoizedBinarySearch(segments, column, memo, line);
61831
+ if (found) index = (bias === -1 ? upperBound : lowerBound)(segments, column, index);
61832
+ else if (bias === -1) index++;
61833
+ if (index === -1 || index === segments.length) return -1;
61834
+ return index;
61835
+ }
61836
+ //#endregion
61413
61837
  //#region ../core/dist/index.js
61414
61838
  var __create = Object.create;
61415
61839
  var __defProp = Object.defineProperty;
@@ -61478,7 +61902,8 @@ var AmbiguousProjectError = class extends Error {
61478
61902
  }
61479
61903
  };
61480
61904
  const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
61481
- const SOURCE_FILE_PATTERN = /\.(tsx?|jsx?|mts|mjs)$/;
61905
+ const HTML_FILE_PATTERN = /\.html$/i;
61906
+ const SOURCE_FILE_PATTERN = /\.(?:astro|tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
61482
61907
  const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
61483
61908
  const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
61484
61909
  const MINIFIED_SNIFF_BYTES = 65536;
@@ -61844,7 +62269,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
61844
62269
  const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
61845
62270
  const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
61846
62271
  const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
61847
- const CORE_PACKAGE_VERSION = "0.9.1";
62272
+ const CORE_PACKAGE_VERSION = "0.9.2";
61848
62273
  const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
61849
62274
  const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
61850
62275
  const SUPPLY_CHAIN_PLUGIN = "socket";
@@ -62094,8 +62519,13 @@ const findMonorepoRoot = (startDirectory) => {
62094
62519
  * byte-equivalent copy.
62095
62520
  */
62096
62521
  const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
62522
+ const unwrapTypescriptExpression = (expression) => {
62523
+ let currentExpression = expression;
62524
+ while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
62525
+ return currentExpression;
62526
+ };
62097
62527
  const TSCONFIG_FILENAME = "tsconfig.json";
62098
- const isRelativeExtendsValue = (extendsValue) => extendsValue.startsWith("./") || extendsValue.startsWith("../") || Path.isAbsolute(extendsValue);
62528
+ const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
62099
62529
  const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
62100
62530
  const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
62101
62531
  const requireFromConfig = createRequire(Path.join(fromConfigDirectory, "tsconfig.json"));
@@ -62112,7 +62542,12 @@ const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
62112
62542
  return null;
62113
62543
  };
62114
62544
  const resolveExtendsPath = (extendsValue, fromConfigDirectory) => {
62115
- if (isRelativeExtendsValue(extendsValue)) return ensureJsonExtension(Path.resolve(fromConfigDirectory, extendsValue));
62545
+ if (isLocalModuleSpecifier(extendsValue)) {
62546
+ const resolvedPath = Path.resolve(fromConfigDirectory, extendsValue);
62547
+ if (isFile(resolvedPath)) return resolvedPath;
62548
+ const directoryConfigPath = Path.join(resolvedPath, TSCONFIG_FILENAME);
62549
+ return isFile(directoryConfigPath) ? directoryConfigPath : ensureJsonExtension(resolvedPath);
62550
+ }
62116
62551
  return resolvePackageExtendsPath(extendsValue, fromConfigDirectory);
62117
62552
  };
62118
62553
  const normalizeCompilerOptions = (compilerOptions) => {
@@ -62219,6 +62654,7 @@ const FRAMEWORK_PACKAGES = {
62219
62654
  "@tanstack/react-start": "tanstack-start",
62220
62655
  "@remix-run/react": "remix",
62221
62656
  gatsby: "gatsby",
62657
+ astro: "astro",
62222
62658
  vite: "vite",
62223
62659
  "react-scripts": "cra",
62224
62660
  expo: "expo",
@@ -62306,6 +62742,15 @@ const REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS = [
62306
62742
  ".cts",
62307
62743
  ".json"
62308
62744
  ];
62745
+ const REACT_COMPILER_CONFIG_RESOLVER = new ResolverFactory({
62746
+ conditionNames: [
62747
+ "import",
62748
+ "require",
62749
+ "node",
62750
+ "default"
62751
+ ],
62752
+ extensions: REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS
62753
+ });
62309
62754
  const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
62310
62755
  const hasCompilerPackage = (packageJson, compilerPackages) => {
62311
62756
  const allDependencies = {
@@ -62329,6 +62774,18 @@ const hasCompilerPackageInAncestors = (directory, compilerPackages) => {
62329
62774
  return false;
62330
62775
  };
62331
62776
  const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
62777
+ if (!isLocalModuleSpecifier(moduleSpecifier)) {
62778
+ try {
62779
+ const resolvedPath = REACT_COMPILER_CONFIG_RESOLVER.resolveFileSync(fromFilePath, moduleSpecifier).path;
62780
+ if (resolvedPath && isFile(resolvedPath)) return resolvedPath;
62781
+ } catch {}
62782
+ try {
62783
+ const resolvedPath = createRequire(fromFilePath).resolve(moduleSpecifier);
62784
+ return isFile(resolvedPath) ? resolvedPath : null;
62785
+ } catch {
62786
+ return null;
62787
+ }
62788
+ }
62332
62789
  const unresolvedPath = Path.resolve(Path.dirname(fromFilePath), moduleSpecifier);
62333
62790
  const extension = Path.extname(unresolvedPath);
62334
62791
  return (extension ? [unresolvedPath, ...REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS.map((sourceExtension) => `${unresolvedPath.slice(0, -extension.length)}${sourceExtension}`)] : [
@@ -62338,10 +62795,10 @@ const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
62338
62795
  ]).find(isFile) ?? null;
62339
62796
  };
62340
62797
  const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json") || Path.basename(filePath) === ".babelrc" ? ts.parseJsonText(filePath, content) : ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
62341
- const getStaticPropertyName$1 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
62798
+ const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
62342
62799
  const isCommonJsConfigExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
62343
62800
  const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
62344
- const getRequireModuleSpecifier = (expression) => {
62801
+ const getRequireModuleSpecifier$1 = (expression) => {
62345
62802
  if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
62346
62803
  const moduleSpecifier = expression.arguments[0];
62347
62804
  return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
@@ -62354,7 +62811,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
62354
62811
  const namedBindings = importClause?.namedBindings;
62355
62812
  return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
62356
62813
  }
62357
- if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => ts.isIdentifier(declaration.name) && declaration.name.text === bindingName);
62814
+ if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
62358
62815
  return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
62359
62816
  });
62360
62817
  const getImportBinding = (sourceFile, bindingName) => {
@@ -62385,24 +62842,24 @@ const getImportBinding = (sourceFile, bindingName) => {
62385
62842
  for (const declaration of statement.declarationList.declarations) {
62386
62843
  if (!declaration.initializer) continue;
62387
62844
  if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
62388
- const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
62845
+ const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
62389
62846
  if (directModuleSpecifier) return {
62390
62847
  moduleSpecifier: directModuleSpecifier,
62391
62848
  exportName: "default",
62392
62849
  isNamespace: true
62393
62850
  };
62394
- if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
62395
- moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
62851
+ if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
62852
+ moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
62396
62853
  exportName: declaration.initializer.name.text,
62397
62854
  isNamespace: false
62398
62855
  };
62399
62856
  }
62400
62857
  if (!ts.isObjectBindingPattern(declaration.name)) continue;
62401
62858
  const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
62402
- const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
62859
+ const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
62403
62860
  if (bindingElement && moduleSpecifier) return {
62404
62861
  moduleSpecifier,
62405
- exportName: bindingElement.propertyName ? getStaticPropertyName$1(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
62862
+ exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
62406
62863
  isNamespace: false
62407
62864
  };
62408
62865
  }
@@ -62419,10 +62876,16 @@ const getTopLevelBinding = (sourceFile, bindingName) => {
62419
62876
  }
62420
62877
  return null;
62421
62878
  };
62422
- const getFunctionLocalBindings = (functionNode, argumentsList) => {
62879
+ const getFunctionLocalBindings = (functionNode, argumentsList, argumentAnalysis, functionAnalysis) => {
62423
62880
  const localBindings = /* @__PURE__ */ new Map();
62424
62881
  functionNode.parameters.forEach((parameter, parameterIndex) => {
62425
- if (ts.isIdentifier(parameter.name)) localBindings.set(parameter.name.text, argumentsList[parameterIndex] ?? parameter.initializer ?? null);
62882
+ if (ts.isIdentifier(parameter.name)) {
62883
+ const argument = argumentsList[parameterIndex];
62884
+ localBindings.set(parameter.name.text, {
62885
+ expression: argument ?? parameter.initializer ?? null,
62886
+ analysis: argument ? argumentAnalysis : functionAnalysis
62887
+ });
62888
+ }
62426
62889
  });
62427
62890
  return localBindings;
62428
62891
  };
@@ -62455,6 +62918,48 @@ const getScopedConfigBinding = (identifier) => {
62455
62918
  };
62456
62919
  };
62457
62920
  const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
62921
+ const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
62922
+ const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
62923
+ const isNodeCreateRequireCall = (node, analysis) => {
62924
+ if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
62925
+ if (!ts.isCallExpression(node)) return false;
62926
+ const target = node.expression;
62927
+ if (ts.isIdentifier(target)) {
62928
+ if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
62929
+ const importBinding = getImportBinding(analysis.sourceFile, target.text);
62930
+ return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
62931
+ }
62932
+ if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
62933
+ if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
62934
+ const createRequireReceiver = target.expression;
62935
+ if (ts.isCallExpression(createRequireReceiver)) {
62936
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
62937
+ if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
62938
+ const requireIdentifier = createRequireReceiver.expression;
62939
+ return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
62940
+ }
62941
+ if (!ts.isIdentifier(createRequireReceiver)) return false;
62942
+ if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
62943
+ const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
62944
+ return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
62945
+ };
62946
+ const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
62947
+ const [moduleSpecifierNode] = callExpression.arguments;
62948
+ if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
62949
+ const target = callExpression.expression;
62950
+ if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
62951
+ if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
62952
+ if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
62953
+ if (!ts.isIdentifier(target.expression)) return null;
62954
+ const resolverIdentifier = target.expression;
62955
+ if (analysis.localBindings.has(resolverIdentifier.text)) return null;
62956
+ const scopedBinding = getScopedConfigBinding(resolverIdentifier);
62957
+ const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
62958
+ const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
62959
+ if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
62960
+ if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
62961
+ return moduleSpecifierNode.text;
62962
+ };
62458
62963
  const getAssignedPropertyInitializer = (identifier, propertyName) => {
62459
62964
  let bindingScope = null;
62460
62965
  let currentNode = identifier;
@@ -62497,9 +63002,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
62497
63002
  initializer: assignedInitializer
62498
63003
  };
62499
63004
  };
62500
- const getStaticConfigValueState = (expression, analysis) => {
62501
- let unwrappedExpression = expression;
62502
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
63005
+ const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
63006
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
63007
+ if (visitedExpressions.has(unwrappedExpression)) return null;
63008
+ const nextVisitedExpressions = new Set(visitedExpressions);
63009
+ nextVisitedExpressions.add(unwrappedExpression);
62503
63010
  if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
62504
63011
  isNullish: true,
62505
63012
  isTruthy: false
@@ -62514,32 +63021,32 @@ const getStaticConfigValueState = (expression, analysis) => {
62514
63021
  };
62515
63022
  if (ts.isIdentifier(unwrappedExpression)) {
62516
63023
  if (analysis.localBindings.has(unwrappedExpression.text)) {
62517
- const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
62518
- return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
63024
+ const localReference = analysis.localBindings.get(unwrappedExpression.text);
63025
+ return localReference?.expression ? getStaticConfigValueState(localReference.expression, localReference.analysis, nextVisitedExpressions) : null;
62519
63026
  }
62520
63027
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
62521
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
63028
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
62522
63029
  }
62523
63030
  if (ts.isConditionalExpression(unwrappedExpression)) {
62524
- const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
62525
- if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
62526
- const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
62527
- const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
63031
+ const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
63032
+ if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
63033
+ const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
63034
+ const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
62528
63035
  return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
62529
63036
  }
62530
63037
  if (ts.isBinaryExpression(unwrappedExpression)) {
62531
- const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
63038
+ const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
62532
63039
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
62533
63040
  if (leftState === null) return null;
62534
- return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
63041
+ return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
62535
63042
  }
62536
63043
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
62537
63044
  if (leftState === null) return null;
62538
- return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
63045
+ return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
62539
63046
  }
62540
63047
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
62541
63048
  if (leftState === null) return null;
62542
- return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
63049
+ return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
62543
63050
  }
62544
63051
  }
62545
63052
  return null;
@@ -62548,25 +63055,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
62548
63055
  const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
62549
63056
  const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
62550
63057
  const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
62551
- const getReactCompilerFlagState = (expression, analysis) => {
62552
- let unwrappedExpression = expression;
62553
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
63058
+ const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
63059
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
63060
+ if (visitedExpressions.has(unwrappedExpression)) return null;
63061
+ const nextVisitedExpressions = new Set(visitedExpressions);
63062
+ nextVisitedExpressions.add(unwrappedExpression);
62554
63063
  if (ts.isIdentifier(unwrappedExpression)) {
62555
63064
  const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
62556
63065
  if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
62557
63066
  if (analysis.localBindings.has(unwrappedExpression.text)) {
62558
- const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
62559
- return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
63067
+ const localReference = analysis.localBindings.get(unwrappedExpression.text);
63068
+ return localReference?.expression ? getReactCompilerFlagState(localReference.expression, localReference.analysis, nextVisitedExpressions) : null;
62560
63069
  }
62561
63070
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
62562
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
63071
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
62563
63072
  }
62564
63073
  if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
62565
63074
  for (const property of [...unwrappedExpression.properties].reverse()) {
62566
- if (ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
63075
+ if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
62567
63076
  if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
62568
63077
  if (ts.isSpreadAssignment(property)) {
62569
- const spreadState = getReactCompilerFlagState(property.expression, analysis);
63078
+ const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
62570
63079
  if (spreadState) return spreadState;
62571
63080
  }
62572
63081
  }
@@ -62579,8 +63088,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
62579
63088
  visitedExpressions.add(resolvedExpression);
62580
63089
  if (ts.isIdentifier(resolvedExpression)) {
62581
63090
  if (analysis.localBindings.has(resolvedExpression.text)) {
62582
- const localInitializer = analysis.localBindings.get(resolvedExpression.text);
62583
- return localInitializer ? getSelectedObjectProperty(localInitializer, propertyName, analysis, visitedExpressions) : null;
63091
+ const localReference = analysis.localBindings.get(resolvedExpression.text);
63092
+ return localReference?.expression ? getSelectedObjectProperty(localReference.expression, propertyName, localReference.analysis, visitedExpressions) : null;
62584
63093
  }
62585
63094
  const scopedBinding = getScopedConfigBinding(resolvedExpression);
62586
63095
  if (scopedBinding.wasFound) return scopedBinding.initializer ? getSelectedObjectProperty(scopedBinding.initializer, propertyName, analysis, visitedExpressions) : null;
@@ -62589,9 +63098,18 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
62589
63098
  }
62590
63099
  if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
62591
63100
  for (const property of [...resolvedExpression.properties].reverse()) {
62592
- if (ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === propertyName) return property.initializer;
62593
- if (ts.isMethodDeclaration(property) && getStaticPropertyName$1(property.name) === propertyName) return property;
62594
- if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return property.name;
63101
+ if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return {
63102
+ node: property.initializer,
63103
+ analysis
63104
+ };
63105
+ if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return {
63106
+ node: property,
63107
+ analysis
63108
+ };
63109
+ if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return {
63110
+ node: property.name,
63111
+ analysis
63112
+ };
62595
63113
  if (ts.isSpreadAssignment(property)) {
62596
63114
  const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
62597
63115
  if (spreadProperty) return spreadProperty;
@@ -62604,8 +63122,8 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
62604
63122
  while (ts.isParenthesizedExpression(resolvedExpression) || ts.isAsExpression(resolvedExpression) || ts.isTypeAssertionExpression(resolvedExpression) || ts.isSatisfiesExpression(resolvedExpression) || ts.isNonNullExpression(resolvedExpression)) resolvedExpression = resolvedExpression.expression;
62605
63123
  if (ts.isIdentifier(resolvedExpression)) {
62606
63124
  if (analysis.localBindings.has(resolvedExpression.text)) {
62607
- const localInitializer = analysis.localBindings.get(resolvedExpression.text);
62608
- return localInitializer ? configExpressionMayDefineProperty(localInitializer, propertyName, analysis) : true;
63125
+ const localReference = analysis.localBindings.get(resolvedExpression.text);
63126
+ return localReference?.expression ? configExpressionMayDefineProperty(localReference.expression, propertyName, localReference.analysis) : true;
62609
63127
  }
62610
63128
  const scopedBinding = getScopedConfigBinding(resolvedExpression);
62611
63129
  if (scopedBinding.wasFound) return scopedBinding.initializer ? configExpressionMayDefineProperty(scopedBinding.initializer, propertyName, analysis) : true;
@@ -62621,7 +63139,7 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
62621
63139
  return resolvedExpression.properties.some((property) => {
62622
63140
  if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis);
62623
63141
  if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
62624
- const staticPropertyName = getStaticPropertyName$1(property.name);
63142
+ const staticPropertyName = getStaticPropertyName$2(property.name);
62625
63143
  return staticPropertyName === null || staticPropertyName === propertyName;
62626
63144
  }
62627
63145
  return false;
@@ -62640,7 +63158,7 @@ const getExportedConfigNodes = (sourceFile, exportName) => {
62640
63158
  continue;
62641
63159
  }
62642
63160
  if (ts.isExpressionStatement(statement) && isCommonJsConfigExportAssignment(statement.expression, sourceFile) && exportName !== "default" && ts.isObjectLiteralExpression(statement.expression.right)) for (const property of [...statement.expression.right.properties].reverse()) {
62643
- if (ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === exportName) {
63161
+ if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === exportName) {
62644
63162
  exportedNodes.push(property.initializer);
62645
63163
  break;
62646
63164
  }
@@ -62689,15 +63207,15 @@ const getReExportedConfigModules = (sourceFile, exportName) => {
62689
63207
  }
62690
63208
  return bindings;
62691
63209
  };
62692
- const analyzeConfigModuleExport = (filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = []) => {
63210
+ const analyzeConfigModuleExport = (filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = [], argumentAnalysis) => {
62693
63211
  if (!isFile(filePath) || importDepth > 4) return false;
62694
63212
  const moduleVisitKey = `${filePath}:${exportName}:${allowCompilerTransform}`;
62695
63213
  if (visitedModules.has(moduleVisitKey)) return false;
62696
63214
  const nextVisitedModules = new Set(visitedModules);
62697
63215
  nextVisitedModules.add(moduleVisitKey);
62698
- return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, NFS.readFileSync(filePath, "utf-8")), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList);
63216
+ return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, NFS.readFileSync(filePath, "utf-8")), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList, argumentAnalysis);
62699
63217
  };
62700
- const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = []) => {
63218
+ const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = [], argumentAnalysis) => {
62701
63219
  const analysis = {
62702
63220
  filePath,
62703
63221
  sourceFile,
@@ -62707,14 +63225,27 @@ const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCo
62707
63225
  localBindings: /* @__PURE__ */ new Map(),
62708
63226
  activeFunctions: /* @__PURE__ */ new Set()
62709
63227
  };
63228
+ const resolvedArgumentAnalysis = argumentAnalysis ?? analysis;
62710
63229
  const exportedConfigNodes = getExportedConfigNodes(sourceFile, exportName);
62711
- return exportedConfigNodes.some((node) => ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node) ? analyzeConfigFunction(node, analysis, allowCompilerTransform, argumentsList) : analyzeConfigNode(node, analysis, allowCompilerTransform)) || getReExportedConfigModules(sourceFile, exportName).some((binding) => {
63230
+ return exportedConfigNodes.some((node) => {
63231
+ if (ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) return analyzeConfigFunction(node, analysis, allowCompilerTransform, argumentsList, resolvedArgumentAnalysis);
63232
+ if (argumentsList.length > 0 && ts.isIdentifier(node)) {
63233
+ const topLevelBinding = getTopLevelBinding(sourceFile, node.text);
63234
+ if (topLevelBinding && ts.isFunctionLike(topLevelBinding)) return analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, argumentsList, resolvedArgumentAnalysis);
63235
+ const importBinding = getImportBinding(sourceFile, node.text);
63236
+ if (importBinding) {
63237
+ const importedFilePath = resolveImportedConfigFile(filePath, importBinding.moduleSpecifier);
63238
+ return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, importBinding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList, resolvedArgumentAnalysis));
63239
+ }
63240
+ }
63241
+ return analyzeConfigNode(node, analysis, allowCompilerTransform);
63242
+ }) || getReExportedConfigModules(sourceFile, exportName).some((binding) => {
62712
63243
  if (exportedConfigNodes.length > 0 && binding.isNamespace) return false;
62713
63244
  const importedFilePath = resolveImportedConfigFile(filePath, binding.moduleSpecifier);
62714
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, binding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList));
63245
+ return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, binding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList, resolvedArgumentAnalysis));
62715
63246
  });
62716
63247
  };
62717
- const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, argumentsList = []) => {
63248
+ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, argumentsList = [], argumentAnalysis = analysis) => {
62718
63249
  if (!functionNode.body) return false;
62719
63250
  if (analysis.activeFunctions.has(functionNode.pos)) return false;
62720
63251
  const activeFunctions = new Set(analysis.activeFunctions);
@@ -62722,7 +63253,7 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
62722
63253
  const functionAnalysis = {
62723
63254
  ...analysis,
62724
63255
  visitedNodes: /* @__PURE__ */ new Set(),
62725
- localBindings: getFunctionLocalBindings(functionNode, argumentsList),
63256
+ localBindings: getFunctionLocalBindings(functionNode, argumentsList, argumentAnalysis, analysis),
62726
63257
  activeFunctions
62727
63258
  };
62728
63259
  if (!ts.isBlock(functionNode.body)) return analyzeConfigNode(functionNode.body, functionAnalysis, allowCompilerTransform);
@@ -62738,6 +63269,11 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
62738
63269
  visitReturns(functionNode.body);
62739
63270
  return hasCompiler;
62740
63271
  };
63272
+ const analyzeImportedConfig = ({ analysis, moduleSpecifier, exportName, allowCompilerTransform, argumentsList }) => {
63273
+ const importedFilePath = resolveImportedConfigFile(analysis.filePath, moduleSpecifier);
63274
+ if (!importedFilePath) return null;
63275
+ return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList, analysis);
63276
+ };
62741
63277
  const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, isCompilerTransformCollection, excludedPropertyNames) => {
62742
63278
  const assignedReactCompiler = getAssignedPropertyInitializer(identifier, "reactCompiler");
62743
63279
  if (assignedReactCompiler.initializer && !isStaticallyDisabledConfigExpression(assignedReactCompiler.initializer, analysis)) return true;
@@ -62750,42 +63286,74 @@ const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, i
62750
63286
  if (assignedPlugins.wasFound) overriddenPropertyNames.add("plugins");
62751
63287
  if (assignedPresets.wasFound) overriddenPropertyNames.add("presets");
62752
63288
  if (analysis.localBindings.has(identifier.text)) {
62753
- const localInitializer = analysis.localBindings.get(identifier.text);
62754
- return Boolean(localInitializer && analyzeConfigNode(localInitializer, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
63289
+ const localReference = analysis.localBindings.get(identifier.text);
63290
+ return Boolean(localReference?.expression && analyzeConfigNode(localReference.expression, localReference.analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
62755
63291
  }
62756
63292
  const scopedBinding = getScopedConfigBinding(identifier);
62757
63293
  if (scopedBinding.wasFound) return Boolean(scopedBinding.initializer && analyzeConfigNode(scopedBinding.initializer, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
62758
63294
  const importBinding = getImportBinding(analysis.sourceFile, identifier.text);
62759
63295
  if (importBinding) {
62760
63296
  if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
62761
- if (!importBinding.moduleSpecifier.startsWith(".")) return false;
62762
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, importBinding.moduleSpecifier);
62763
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, importBinding.exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules));
63297
+ return Boolean(analyzeImportedConfig({
63298
+ analysis,
63299
+ moduleSpecifier: importBinding.moduleSpecifier,
63300
+ exportName: importBinding.exportName,
63301
+ allowCompilerTransform
63302
+ }));
62764
63303
  }
62765
63304
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, identifier.text);
62766
63305
  return Boolean(topLevelBinding && analyzeConfigNode(topLevelBinding, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
62767
63306
  };
62768
63307
  const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransform) => {
62769
63308
  const target = callExpression.expression;
63309
+ const callableRequiredModuleSpecifier = getRequireModuleSpecifier$1(target);
63310
+ if (callableRequiredModuleSpecifier !== null) {
63311
+ if (ts.isCallExpression(target) && ts.isIdentifier(target.expression) && (analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
63312
+ if (allowCompilerTransform && isCompilerTransformModule(callableRequiredModuleSpecifier, "default")) return true;
63313
+ const hasCompilerTransform = analyzeImportedConfig({
63314
+ analysis,
63315
+ moduleSpecifier: callableRequiredModuleSpecifier,
63316
+ exportName: "default",
63317
+ allowCompilerTransform,
63318
+ argumentsList: callExpression.arguments
63319
+ });
63320
+ if (isLocalModuleSpecifier(callableRequiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
63321
+ return null;
63322
+ }
62770
63323
  if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
62771
63324
  const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
62772
63325
  if (propertyName === null) return null;
62773
- const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
63326
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
62774
63327
  if (requiredModuleSpecifier !== null) {
62775
- if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
62776
- if (!requiredModuleSpecifier.startsWith(".")) return null;
62777
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, requiredModuleSpecifier);
62778
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, propertyName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, callExpression.arguments));
63328
+ if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (analysis.localBindings.has(target.expression.expression.text) || getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
63329
+ if (allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, propertyName)) return true;
63330
+ const hasCompilerTransform = analyzeImportedConfig({
63331
+ analysis,
63332
+ moduleSpecifier: requiredModuleSpecifier,
63333
+ exportName: propertyName,
63334
+ allowCompilerTransform,
63335
+ argumentsList: callExpression.arguments
63336
+ });
63337
+ if (isLocalModuleSpecifier(requiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
63338
+ return null;
62779
63339
  }
62780
63340
  if (!ts.isIdentifier(target.expression)) return null;
62781
- const importBinding = getImportBinding(analysis.sourceFile, target.expression.text);
62782
- if (importBinding?.isNamespace && importBinding.moduleSpecifier.startsWith(".")) {
62783
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, importBinding.moduleSpecifier);
62784
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, propertyName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, callExpression.arguments));
63341
+ const importBinding = analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound ? null : getImportBinding(analysis.sourceFile, target.expression.text);
63342
+ if (importBinding?.isNamespace) {
63343
+ if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, propertyName)) return true;
63344
+ const hasCompilerTransform = analyzeImportedConfig({
63345
+ analysis,
63346
+ moduleSpecifier: importBinding.moduleSpecifier,
63347
+ exportName: propertyName,
63348
+ allowCompilerTransform,
63349
+ argumentsList: callExpression.arguments
63350
+ });
63351
+ if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
63352
+ return null;
62785
63353
  }
62786
63354
  const selectedProperty = getSelectedObjectProperty(target.expression, propertyName, analysis);
62787
63355
  if (selectedProperty === null) return null;
62788
- return ts.isFunctionLike(selectedProperty) ? analyzeConfigFunction(selectedProperty, analysis, allowCompilerTransform, callExpression.arguments) : analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
63356
+ return ts.isFunctionLike(selectedProperty.node) ? analyzeConfigFunction(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform, callExpression.arguments, analysis) : analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
62789
63357
  };
62790
63358
  const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTransformCollection = false, excludedPropertyNames) => {
62791
63359
  const excludedPropertiesVisitKey = excludedPropertyNames ? [...excludedPropertyNames].sort().join(",") : "";
@@ -62799,25 +63367,29 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
62799
63367
  const reactCompilerFlagState = excludedPropertyNames?.has("reactCompiler") ? null : getReactCompilerFlagState(node, analysis);
62800
63368
  if (reactCompilerFlagState?.isEnabled) return true;
62801
63369
  for (const [propertyIndex, property] of node.properties.entries()) if (ts.isPropertyAssignment(property)) {
62802
- const propertyName = getStaticPropertyName$1(property.name);
63370
+ const propertyName = getStaticPropertyName$2(property.name);
62803
63371
  if (propertyName && excludedPropertyNames?.has(propertyName)) continue;
62804
63372
  if (propertyName === "reactCompiler") continue;
62805
- if ((propertyName === "plugins" || propertyName === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, propertyName, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$1(laterProperty.name) === propertyName)) continue;
63373
+ if ((propertyName === "plugins" || propertyName === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, propertyName, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$2(laterProperty.name) === propertyName)) continue;
62806
63374
  const propertyAllowsCompilerTransform = propertyName === "plugins" || propertyName === "presets";
62807
- if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer) && property.initializer.text.startsWith(".")) {
62808
- const extendedFilePath = resolveImportedConfigFile(analysis.filePath, property.initializer.text);
62809
- if (extendedFilePath && analyzeConfigModuleExport(extendedFilePath, "default", false, analysis.importDepth + 1, analysis.visitedModules)) return true;
63375
+ if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)) {
63376
+ if (analyzeImportedConfig({
63377
+ analysis,
63378
+ moduleSpecifier: property.initializer.text,
63379
+ exportName: "default",
63380
+ allowCompilerTransform: false
63381
+ })) return true;
62810
63382
  }
62811
63383
  if (analyzeConfigNode(property.initializer, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
62812
63384
  } else if (ts.isShorthandPropertyAssignment(property)) {
62813
63385
  if (excludedPropertyNames?.has(property.name.text)) continue;
62814
63386
  if (property.name.text === "reactCompiler") continue;
62815
- if ((property.name.text === "plugins" || property.name.text === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, property.name.text, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$1(laterProperty.name) === property.name.text)) continue;
63387
+ if ((property.name.text === "plugins" || property.name.text === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, property.name.text, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$2(laterProperty.name) === property.name.text)) continue;
62816
63388
  const propertyAllowsCompilerTransform = property.name.text === "plugins" || property.name.text === "presets";
62817
63389
  if (analyzeConfigNode(property.name, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
62818
63390
  } else if (ts.isSpreadAssignment(property)) {
62819
63391
  if (reactCompilerFlagState && getReactCompilerFlagState(property.expression, analysis) !== null) continue;
62820
- if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$1(laterProperty.name) === "plugins" || getStaticPropertyName$1(laterProperty.name) === "presets"))) continue;
63392
+ if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$2(laterProperty.name) === "plugins" || getStaticPropertyName$2(laterProperty.name) === "presets"))) continue;
62821
63393
  if (analyzeConfigNode(property.expression, analysis, allowCompilerTransform, false, excludedPropertyNames)) return true;
62822
63394
  }
62823
63395
  return false;
@@ -62830,23 +63402,36 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
62830
63402
  });
62831
63403
  }
62832
63404
  if (ts.isCallExpression(node)) {
63405
+ const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
63406
+ if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
62833
63407
  const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
62834
63408
  if (callTargetResult !== null) return callTargetResult;
62835
- const directModuleSpecifier = getRequireModuleSpecifier(node);
63409
+ const directModuleSpecifier = getRequireModuleSpecifier$1(node);
62836
63410
  const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
62837
63411
  if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
62838
63412
  if (directModuleSpecifier && !isRequireShadowed) {
62839
63413
  if (allowCompilerTransform && isCompilerTransformModule(directModuleSpecifier, "default")) return true;
62840
- if (directModuleSpecifier.startsWith(".")) {
62841
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, directModuleSpecifier);
62842
- if (importedFilePath && analyzeConfigModuleExport(importedFilePath, "default", allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules)) return true;
62843
- }
63414
+ if (analyzeImportedConfig({
63415
+ analysis,
63416
+ moduleSpecifier: directModuleSpecifier,
63417
+ exportName: "default",
63418
+ allowCompilerTransform
63419
+ })) return true;
62844
63420
  }
62845
63421
  if (ts.isIdentifier(node.expression)) {
62846
- const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
62847
- if (importBinding?.moduleSpecifier.startsWith(".")) {
62848
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, importBinding.moduleSpecifier);
62849
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, importBinding.exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, node.arguments));
63422
+ if (!analysis.localBindings.has(node.expression.text) && !getScopedConfigBinding(node.expression).wasFound) {
63423
+ const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
63424
+ if (importBinding) {
63425
+ if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
63426
+ const hasCompilerTransform = analyzeImportedConfig({
63427
+ analysis,
63428
+ moduleSpecifier: importBinding.moduleSpecifier,
63429
+ exportName: importBinding.exportName,
63430
+ allowCompilerTransform,
63431
+ argumentsList: node.arguments
63432
+ });
63433
+ if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
63434
+ }
62850
63435
  }
62851
63436
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, node.expression.text);
62852
63437
  if (topLevelBinding && ts.isFunctionLike(topLevelBinding) && analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, node.arguments)) return true;
@@ -62854,47 +63439,57 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
62854
63439
  return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
62855
63440
  }
62856
63441
  if (ts.isPropertyAccessExpression(node)) {
62857
- const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
63442
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
62858
63443
  if (requiredModuleSpecifier) {
62859
- if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
62860
- if (requiredModuleSpecifier.startsWith(".")) {
62861
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, requiredModuleSpecifier);
62862
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, node.name.text, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules));
62863
- }
63444
+ if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (analysis.localBindings.has(node.expression.expression.text) || getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
63445
+ if (analyzeImportedConfig({
63446
+ analysis,
63447
+ moduleSpecifier: requiredModuleSpecifier,
63448
+ exportName: node.name.text,
63449
+ allowCompilerTransform
63450
+ })) return true;
62864
63451
  return allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, node.name.text);
62865
63452
  }
62866
63453
  if (ts.isIdentifier(node.expression)) {
62867
- if (analysis.localBindings.has(node.expression.text)) {
62868
- const localInitializer = analysis.localBindings.get(node.expression.text);
62869
- return Boolean(localInitializer && analyzeConfigNode(localInitializer, analysis, allowCompilerTransform));
63454
+ if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
63455
+ const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
63456
+ return Boolean(selectedProperty && analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform));
62870
63457
  }
62871
63458
  const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
62872
63459
  if (importBinding?.isNamespace) {
62873
63460
  if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.name.text)) return true;
62874
- if (importBinding.moduleSpecifier.startsWith(".")) {
62875
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, importBinding.moduleSpecifier);
62876
- if (importedFilePath && analyzeConfigModuleExport(importedFilePath, node.name.text, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules)) return true;
62877
- }
63461
+ if (analyzeImportedConfig({
63462
+ analysis,
63463
+ moduleSpecifier: importBinding.moduleSpecifier,
63464
+ exportName: node.name.text,
63465
+ allowCompilerTransform
63466
+ })) return true;
62878
63467
  return false;
62879
63468
  }
62880
63469
  const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
62881
- if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
63470
+ if (selectedProperty) return analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
62882
63471
  return false;
62883
63472
  }
62884
63473
  return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
62885
63474
  }
62886
63475
  if (ts.isElementAccessExpression(node) && node.argumentExpression && ts.isStringLiteralLike(node.argumentExpression)) {
62887
63476
  if (ts.isIdentifier(node.expression)) {
63477
+ if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
63478
+ const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
63479
+ return Boolean(selectedProperty && analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform));
63480
+ }
62888
63481
  const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
62889
63482
  if (importBinding?.isNamespace) {
62890
63483
  if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.argumentExpression.text)) return true;
62891
- if (importBinding.moduleSpecifier.startsWith(".")) {
62892
- const importedFilePath = resolveImportedConfigFile(analysis.filePath, importBinding.moduleSpecifier);
62893
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, node.argumentExpression.text, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules));
62894
- }
63484
+ return Boolean(analyzeImportedConfig({
63485
+ analysis,
63486
+ moduleSpecifier: importBinding.moduleSpecifier,
63487
+ exportName: node.argumentExpression.text,
63488
+ allowCompilerTransform
63489
+ }));
62895
63490
  }
62896
63491
  const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
62897
- if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
63492
+ if (selectedProperty) return analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
62898
63493
  return false;
62899
63494
  }
62900
63495
  return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
@@ -62929,14 +63524,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
62929
63524
  };
62930
63525
  const hasCompilerInConfigFile = (filePath) => analyzeConfigModuleExport(filePath, "default", false, 0, /* @__PURE__ */ new Set());
62931
63526
  const hasCompilerInConfigFiles = (directory, filenames) => filenames.some((filename) => hasCompilerInConfigFile(Path.join(directory, filename)));
62932
- const hasCompilerInPackageJsonConfig = (packageJson) => isPlainObject(packageJson.babel) && analyzeConfigSourceFileExport(ts.parseJsonText("package.json", JSON.stringify(packageJson.babel)), "package.json#babel", "default", false, 0, /* @__PURE__ */ new Set());
62933
- const hasCompilerConfiguration = (directory, packageJson) => hasCompilerInPackageJsonConfig(packageJson) || hasCompilerInConfigFiles(directory, REACT_COMPILER_CONFIG_FILENAMES);
63527
+ const hasCompilerInPackageJsonConfig = (directory, packageJson) => {
63528
+ if (!isPlainObject(packageJson.babel)) return false;
63529
+ const packageJsonPath = Path.join(directory, "package.json");
63530
+ return analyzeConfigSourceFileExport(ts.parseJsonText(packageJsonPath, JSON.stringify(packageJson.babel)), packageJsonPath, "default", false, 0, /* @__PURE__ */ new Set());
63531
+ };
63532
+ const hasCompilerConfiguration = (directory, packageJson) => hasCompilerInPackageJsonConfig(directory, packageJson) || hasCompilerInConfigFiles(directory, REACT_COMPILER_CONFIG_FILENAMES);
62934
63533
  const hasCompilerConfigurationInAncestors = (directory) => {
62935
63534
  if (isProjectBoundary(directory)) return false;
62936
63535
  let ancestorDirectory = Path.dirname(directory);
62937
63536
  while (ancestorDirectory !== Path.dirname(ancestorDirectory)) {
62938
63537
  const ancestorPackagePath = Path.join(ancestorDirectory, "package.json");
62939
- if (hasCompilerInPackageJsonConfig(isFile(ancestorPackagePath) ? readPackageJson(ancestorPackagePath) : {}) || hasCompilerInConfigFiles(ancestorDirectory, BABEL_CONFIG_FILENAMES)) return true;
63538
+ const ancestorPackageJson = isFile(ancestorPackagePath) ? readPackageJson(ancestorPackagePath) : {};
63539
+ if (hasCompilerInPackageJsonConfig(ancestorDirectory, ancestorPackageJson) || hasCompilerInConfigFiles(ancestorDirectory, BABEL_CONFIG_FILENAMES)) return true;
62940
63540
  if (isProjectBoundary(ancestorDirectory)) return false;
62941
63541
  ancestorDirectory = Path.dirname(ancestorDirectory);
62942
63542
  }
@@ -65262,6 +65862,7 @@ const classifyPackageRole = (filename) => {
65262
65862
  * Resolves the absolute path to read for a diagnostic's `filePath`,
65263
65863
  * accounting for the various shapes oxlint emits:
65264
65864
  *
65865
+ * - `file://` URL — decode to an absolute filesystem path.
65265
65866
  * - Absolute POSIX (`/abs/path/file.tsx`) — pass through.
65266
65867
  * - Absolute Windows (`C:/...` or `C:\...`) — pass through.
65267
65868
  * - `./relative` or bare relative — join against `rootDirectory`.
@@ -65271,6 +65872,7 @@ const classifyPackageRole = (filename) => {
65271
65872
  * use one canonical resolution path.
65272
65873
  */
65273
65874
  const resolveCandidateReadPath = (rootDirectory, filePath) => {
65875
+ if (filePath.startsWith("file://")) return fileURLToPath(filePath);
65274
65876
  const normalizedFile = filePath.replace(/\\/g, "/");
65275
65877
  if (normalizedFile.startsWith("/") || /^[a-zA-Z]:\//.test(normalizedFile) || /^[a-zA-Z]:\\/.test(filePath)) return filePath;
65276
65878
  return `${rootDirectory.replace(/\\/g, "/").replace(/\/$/, "")}/${normalizedFile.replace(/^\.\//, "")}`;
@@ -66165,7 +66767,7 @@ const warn = (message) => {
66165
66767
  runSync(warn$1(message));
66166
66768
  };
66167
66769
  const CONFIG_BASENAME = "doctor.config";
66168
- const CONFIG_EXTENSIONS = [
66770
+ const CONFIG_EXTENSIONS$1 = [
66169
66771
  "ts",
66170
66772
  "mts",
66171
66773
  "cts",
@@ -66269,7 +66871,7 @@ const loadLegacyConfig = (directory) => {
66269
66871
  };
66270
66872
  const loadConfigFromDirectory = async (directory) => {
66271
66873
  let sawBrokenConfigFile = false;
66272
- for (const extension of CONFIG_EXTENSIONS) {
66874
+ for (const extension of CONFIG_EXTENSIONS$1) {
66273
66875
  const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
66274
66876
  if (!isFile(filePath)) continue;
66275
66877
  const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
@@ -66956,6 +67558,316 @@ const buildReactNativeDiagnostic = (input) => ({
66956
67558
  column: input.column ?? 0,
66957
67559
  category: input.category ?? "Correctness"
66958
67560
  });
67561
+ const ANDROID_APP_BUILD_FILE_NAMES = ["build.gradle", "build.gradle.kts"];
67562
+ const BUILD_TYPES_BLOCK_PATTERN = /\bbuildTypes\s*\{/g;
67563
+ const RELEASE_STRING_MARKER = "__RD_RELEASE__";
67564
+ const RELEASE_BLOCK_PATTERNS = [/\brelease\s*\{/g, /\b(?:getByName|named)\s*\(\s*(?:["']release["']|__RD_RELEASE__)\s*\)\s*\{/g];
67565
+ const MINIFY_ASSIGNMENT_PATTERN = /\b(?:isMinifyEnabled|minifyEnabled)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
67566
+ const SHRINK_RESOURCES_ASSIGNMENT_PATTERN = /\b(?:isShrinkResources|shrinkResources)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
67567
+ const stripGradleComments = (contents) => {
67568
+ let result = "";
67569
+ let index = 0;
67570
+ let quote = null;
67571
+ while (index < contents.length) {
67572
+ const character = contents[index];
67573
+ const nextCharacter = contents[index + 1];
67574
+ if (quote !== null) {
67575
+ result += character;
67576
+ if (character === "\\") {
67577
+ result += nextCharacter ?? "";
67578
+ index += 2;
67579
+ continue;
67580
+ }
67581
+ if (character === quote) quote = null;
67582
+ index += 1;
67583
+ continue;
67584
+ }
67585
+ if (character === "\"" || character === "'") {
67586
+ quote = character;
67587
+ result += character;
67588
+ index += 1;
67589
+ continue;
67590
+ }
67591
+ if (character === "/" && nextCharacter === "/") {
67592
+ while (index < contents.length && contents[index] !== "\n") {
67593
+ result += " ";
67594
+ index += 1;
67595
+ }
67596
+ continue;
67597
+ }
67598
+ if (character === "/" && nextCharacter === "*") {
67599
+ result += " ";
67600
+ index += 2;
67601
+ while (index < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
67602
+ result += contents[index] === "\n" ? "\n" : " ";
67603
+ index += 1;
67604
+ }
67605
+ if (index < contents.length) {
67606
+ result += " ";
67607
+ index += 2;
67608
+ }
67609
+ continue;
67610
+ }
67611
+ result += character;
67612
+ index += 1;
67613
+ }
67614
+ return result;
67615
+ };
67616
+ const maskGradleStrings = (contents) => {
67617
+ let result = "";
67618
+ let index = 0;
67619
+ let quote = null;
67620
+ while (index < contents.length) {
67621
+ const character = contents[index];
67622
+ if (quote === null) {
67623
+ if (character === "\"" || character === "'") {
67624
+ quote = character;
67625
+ result += " ";
67626
+ } else result += character;
67627
+ index += 1;
67628
+ continue;
67629
+ }
67630
+ if (character === "\\") {
67631
+ result += " ";
67632
+ index += 2;
67633
+ continue;
67634
+ }
67635
+ if (character === quote) quote = null;
67636
+ result += character === "\n" ? "\n" : " ";
67637
+ index += 1;
67638
+ }
67639
+ return result;
67640
+ };
67641
+ const findBlockContents = (contents, pattern) => {
67642
+ const blocks = [];
67643
+ pattern.lastIndex = 0;
67644
+ let match = pattern.exec(contents);
67645
+ while (match !== null) {
67646
+ const openingBraceIndex = pattern.lastIndex - 1;
67647
+ let depth = 1;
67648
+ let index = openingBraceIndex + 1;
67649
+ let quote = null;
67650
+ while (index < contents.length && depth > 0) {
67651
+ const character = contents[index];
67652
+ if (quote !== null) {
67653
+ if (character === "\\") {
67654
+ index += 2;
67655
+ continue;
67656
+ }
67657
+ if (character === quote) quote = null;
67658
+ } else if (character === "\"" || character === "'") quote = character;
67659
+ else if (character === "{") depth += 1;
67660
+ else if (character === "}") depth -= 1;
67661
+ index += 1;
67662
+ }
67663
+ if (depth === 0) blocks.push(contents.slice(openingBraceIndex + 1, index - 1));
67664
+ match = pattern.exec(contents);
67665
+ }
67666
+ return blocks;
67667
+ };
67668
+ const getFinalStaticBoolean = (contents, pattern) => {
67669
+ pattern.lastIndex = 0;
67670
+ let finalValue = null;
67671
+ let match = pattern.exec(contents);
67672
+ while (match !== null) {
67673
+ const staticValue = match[1]?.trim().replace(/\)$/, "").trim();
67674
+ if (staticValue === "true") finalValue = true;
67675
+ else if (staticValue === "false") finalValue = false;
67676
+ else finalValue = null;
67677
+ match = pattern.exec(contents);
67678
+ }
67679
+ return finalValue;
67680
+ };
67681
+ const getReleaseBlocks = (contents) => findBlockContents(contents, BUILD_TYPES_BLOCK_PATTERN).flatMap((buildTypesBlock) => RELEASE_BLOCK_PATTERNS.flatMap((pattern) => findBlockContents(buildTypesBlock, pattern)));
67682
+ const readAndroidReleaseShrinking = (rootDirectory) => {
67683
+ for (const buildFileName of ANDROID_APP_BUILD_FILE_NAMES) {
67684
+ const filePath = Path.posix.join("android", "app", buildFileName);
67685
+ const absoluteFilePath = Path.join(rootDirectory, filePath);
67686
+ if (!isFile(absoluteFilePath)) continue;
67687
+ let contents;
67688
+ try {
67689
+ contents = stripGradleComments(NFS.readFileSync(absoluteFilePath, "utf-8"));
67690
+ } catch {
67691
+ return null;
67692
+ }
67693
+ const releaseBlocks = getReleaseBlocks(maskGradleStrings(contents.replace(/(["'])release\1/g, RELEASE_STRING_MARKER)));
67694
+ const [releaseBlock] = releaseBlocks;
67695
+ if (releaseBlock === void 0 || releaseBlocks.length !== 1) return null;
67696
+ const hasDisabledMinification = getFinalStaticBoolean(releaseBlock, MINIFY_ASSIGNMENT_PATTERN) === false;
67697
+ const hasDisabledResourceShrinking = getFinalStaticBoolean(releaseBlock, SHRINK_RESOURCES_ASSIGNMENT_PATTERN) === false;
67698
+ if (!hasDisabledMinification && !hasDisabledResourceShrinking) return null;
67699
+ return {
67700
+ filePath,
67701
+ hasDisabledMinification,
67702
+ hasDisabledResourceShrinking
67703
+ };
67704
+ }
67705
+ return null;
67706
+ };
67707
+ const checkReactNativeAndroidReleaseShrinking = (rootDirectory) => {
67708
+ const releaseShrinking = readAndroidReleaseShrinking(rootDirectory);
67709
+ if (releaseShrinking === null) return [];
67710
+ const disabledFeatures = [releaseShrinking.hasDisabledMinification ? "code minification" : null, releaseShrinking.hasDisabledResourceShrinking ? "resource shrinking" : null].filter((feature) => feature !== null);
67711
+ return [buildReactNativeDiagnostic({
67712
+ filePath: releaseShrinking.filePath,
67713
+ rule: "rn-android-release-shrinking-disabled",
67714
+ category: "Performance",
67715
+ message: `The Android release build explicitly disables ${disabledFeatures.join(" and ")}, leaving unreachable code or resources in the shipped app.`,
67716
+ help: "Enable release code minification and resource shrinking, then test the optimized build and add keep rules for libraries that require them."
67717
+ })];
67718
+ };
67719
+ const getTypescriptScriptKind = (fileName) => {
67720
+ if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
67721
+ if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
67722
+ if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
67723
+ return ts.ScriptKind.JS;
67724
+ };
67725
+ const BABEL_CONFIG_FILE_NAMES$1 = [
67726
+ "babel.config.js",
67727
+ "babel.config.cjs",
67728
+ "babel.config.mjs",
67729
+ "babel.config.ts",
67730
+ "babel.config.cts",
67731
+ "babel.config.json",
67732
+ ".babelrc",
67733
+ ".babelrc.js",
67734
+ ".babelrc.cjs",
67735
+ ".babelrc.mjs",
67736
+ ".babelrc.cts",
67737
+ ".babelrc.json"
67738
+ ];
67739
+ const readUnknownPluginNames = (value) => {
67740
+ if (!Array.isArray(value)) return null;
67741
+ const pluginNames = [];
67742
+ for (const entry of value) {
67743
+ if (typeof entry === "string") {
67744
+ pluginNames.push(entry);
67745
+ continue;
67746
+ }
67747
+ if (Array.isArray(entry) && typeof entry[0] === "string") {
67748
+ pluginNames.push(entry[0]);
67749
+ continue;
67750
+ }
67751
+ return null;
67752
+ }
67753
+ return pluginNames;
67754
+ };
67755
+ const getStaticPropertyName$1 = (propertyName) => {
67756
+ if (ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName)) return propertyName.text;
67757
+ return null;
67758
+ };
67759
+ const getStaticPluginName = (expression) => {
67760
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
67761
+ if (ts.isStringLiteralLike(unwrappedExpression)) return unwrappedExpression.text;
67762
+ if (!ts.isArrayLiteralExpression(unwrappedExpression)) return null;
67763
+ const pluginExpression = unwrappedExpression.elements[0];
67764
+ return pluginExpression && ts.isStringLiteralLike(pluginExpression) ? pluginExpression.text : null;
67765
+ };
67766
+ const getPluginNamesFromObject = (objectExpression) => {
67767
+ if (objectExpression.properties.some((property) => ts.isSpreadAssignment(property))) return null;
67768
+ const pluginProperties = objectExpression.properties.filter((property) => ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "plugins");
67769
+ if (pluginProperties.length !== 1) return pluginProperties.length === 0 ? [] : null;
67770
+ const pluginListExpression = unwrapTypescriptExpression(pluginProperties[0].initializer);
67771
+ if (!ts.isArrayLiteralExpression(pluginListExpression)) return null;
67772
+ const pluginNames = [];
67773
+ for (const element of pluginListExpression.elements) {
67774
+ if (ts.isSpreadElement(element)) return null;
67775
+ const pluginName = getStaticPluginName(element);
67776
+ if (pluginName === null) return null;
67777
+ pluginNames.push(pluginName);
67778
+ }
67779
+ return pluginNames;
67780
+ };
67781
+ const isModuleExports = (expression) => ts.isPropertyAccessExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "module" && expression.name.text === "exports" || ts.isElementAccessExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "module" && expression.argumentExpression !== void 0 && ts.isStringLiteralLike(expression.argumentExpression) && expression.argumentExpression.text === "exports";
67782
+ const getDirectExportedObject = (sourceFile) => {
67783
+ const exportedExpressions = [];
67784
+ for (const statement of sourceFile.statements) {
67785
+ if (ts.isExportAssignment(statement)) {
67786
+ exportedExpressions.push(statement.expression);
67787
+ continue;
67788
+ }
67789
+ if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExports(statement.expression.left)) exportedExpressions.push(statement.expression.right);
67790
+ }
67791
+ if (exportedExpressions.length !== 1) return null;
67792
+ const exportedExpression = unwrapTypescriptExpression(exportedExpressions[0]);
67793
+ return ts.isObjectLiteralExpression(exportedExpression) ? exportedExpression : null;
67794
+ };
67795
+ const parseConfigPluginNames = (filePath, contents) => {
67796
+ try {
67797
+ const parsedJson = JSON.parse(contents);
67798
+ return isPlainObject(parsedJson) ? readUnknownPluginNames(parsedJson.plugins) : null;
67799
+ } catch {
67800
+ if (ts.transpileModule(contents, {
67801
+ fileName: filePath,
67802
+ reportDiagnostics: true,
67803
+ compilerOptions: { allowJs: true }
67804
+ }).diagnostics?.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) return null;
67805
+ const exportedObject = getDirectExportedObject(ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filePath)));
67806
+ return exportedObject === null ? null : getPluginNamesFromObject(exportedObject);
67807
+ }
67808
+ };
67809
+ const readStaticBabelPluginNames = (rootDirectory) => {
67810
+ for (const fileName of BABEL_CONFIG_FILE_NAMES$1) {
67811
+ const absoluteFilePath = Path.join(rootDirectory, fileName);
67812
+ if (!isFile(absoluteFilePath)) continue;
67813
+ try {
67814
+ return {
67815
+ filePath: fileName,
67816
+ pluginNames: parseConfigPluginNames(fileName, NFS.readFileSync(absoluteFilePath, "utf-8"))
67817
+ };
67818
+ } catch {
67819
+ return {
67820
+ filePath: fileName,
67821
+ pluginNames: null
67822
+ };
67823
+ }
67824
+ }
67825
+ const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
67826
+ if (!isPlainObject(packageJson.babel)) return null;
67827
+ return {
67828
+ filePath: "package.json",
67829
+ pluginNames: readUnknownPluginNames(packageJson.babel.plugins)
67830
+ };
67831
+ };
67832
+ const REACT_COMPILER_PLUGIN_NAMES = new Set(["babel-plugin-react-compiler", "react-compiler"]);
67833
+ const REANIMATED_PLUGIN_NAME = "react-native-reanimated/plugin";
67834
+ const WORKLETS_PLUGIN_NAME = "react-native-worklets/plugin";
67835
+ const checkReactCompilerPluginOrder = (filePath, pluginNames) => {
67836
+ if (pluginNames.findIndex((pluginName) => REACT_COMPILER_PLUGIN_NAMES.has(pluginName)) <= 0) return [];
67837
+ return [buildReactNativeDiagnostic({
67838
+ filePath,
67839
+ rule: "rn-react-compiler-plugin-first",
67840
+ category: "Performance",
67841
+ message: "The React Compiler Babel plugin is not first, so an earlier transform can change component or hook code before the compiler analyzes it.",
67842
+ help: "Move `babel-plugin-react-compiler` to the first entry in the Babel `plugins` array."
67843
+ })];
67844
+ };
67845
+ const checkReanimatedPluginOrder = (project, filePath, pluginNames) => {
67846
+ const reanimatedMajorVersion = project.reanimatedVersion === null || project.reanimatedVersion === void 0 ? null : getLowestDependencyMajor(project.reanimatedVersion);
67847
+ if (reanimatedMajorVersion === null || reanimatedMajorVersion < 4) return [];
67848
+ const diagnostics = [];
67849
+ if (pluginNames.includes(REANIMATED_PLUGIN_NAME)) diagnostics.push(buildReactNativeDiagnostic({
67850
+ filePath,
67851
+ rule: "rn-reanimated-worklets-plugin-last",
67852
+ category: "Performance",
67853
+ message: "This Reanimated 4 project still uses `react-native-reanimated/plugin`, which was renamed to the Worklets Babel plugin.",
67854
+ help: "Replace it with `react-native-worklets/plugin` and keep that plugin last in the Babel `plugins` array."
67855
+ }));
67856
+ const workletsPluginIndex = pluginNames.lastIndexOf(WORKLETS_PLUGIN_NAME);
67857
+ if (workletsPluginIndex !== -1 && workletsPluginIndex !== pluginNames.length - 1) diagnostics.push(buildReactNativeDiagnostic({
67858
+ filePath,
67859
+ rule: "rn-reanimated-worklets-plugin-last",
67860
+ category: "Performance",
67861
+ message: "`react-native-worklets/plugin` is not last in the Babel `plugins` array, so later transforms can prevent worklets from being compiled correctly.",
67862
+ help: "Move `react-native-worklets/plugin` to the final entry in the Babel `plugins` array."
67863
+ }));
67864
+ return diagnostics;
67865
+ };
67866
+ const checkReactNativeBabelPluginOrder = (rootDirectory, project) => {
67867
+ const babelPlugins = readStaticBabelPluginNames(rootDirectory);
67868
+ if (babelPlugins === null || babelPlugins.pluginNames === null) return [];
67869
+ return [...checkReactCompilerPluginOrder(babelPlugins.filePath, babelPlugins.pluginNames), ...checkReanimatedPluginOrder(project, babelPlugins.filePath, babelPlugins.pluginNames)];
67870
+ };
66959
67871
  const BUILDER_BOB_PACKAGE = "react-native-builder-bob";
66960
67872
  const isBuilderBobLibrary = (packageJson) => {
66961
67873
  const bobConfig = packageJson[BUILDER_BOB_PACKAGE];
@@ -67032,7 +67944,12 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
67032
67944
  const isReactNativeProject = (project) => project.framework === "react-native" || project.framework === "expo" || project.hasReactNativeWorkspace || project.expoVersion !== null;
67033
67945
  const checkReactNativeProject = (rootDirectory, project) => {
67034
67946
  if (!isReactNativeProject(project)) return [];
67035
- return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
67947
+ return [
67948
+ ...checkReactNativeMetroBabelPreset(rootDirectory),
67949
+ ...checkReactNativeBabelPluginOrder(rootDirectory, project),
67950
+ ...checkReactNativeAndroidReleaseShrinking(rootDirectory),
67951
+ ...checkReactNativeLibraryDependencies(rootDirectory)
67952
+ ];
67036
67953
  };
67037
67954
  const RULE_KEY = "no-vulnerable-react-server-components";
67038
67955
  const REACT_RSC_ADVISORIES_BY_MINOR = {
@@ -67183,17 +68100,6 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
67183
68100
  }
67184
68101
  return diagnostics;
67185
68102
  };
67186
- const getTypescriptScriptKind = (fileName) => {
67187
- if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
67188
- if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
67189
- if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
67190
- return ts.ScriptKind.JS;
67191
- };
67192
- const unwrapTypescriptExpression = (expression) => {
67193
- let currentExpression = expression;
67194
- while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
67195
- return currentExpression;
67196
- };
67197
68103
  const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
67198
68104
  isAnimationFunction: false,
67199
68105
  isMotionComponent: false,
@@ -67749,7 +68655,11 @@ const buildCapabilities = (project) => {
67749
68655
  capabilities.add(project.framework);
67750
68656
  if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
67751
68657
  if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
67752
- if (project.expoVersion !== null) capabilities.add("expo");
68658
+ if (project.expoVersion !== null) {
68659
+ capabilities.add("expo");
68660
+ const expoSdkMajorVersion = getLowestDependencyMajor(project.expoVersion);
68661
+ if (expoSdkMajorVersion !== null && expoSdkMajorVersion >= 54) capabilities.add("expo:54");
68662
+ }
67753
68663
  if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
67754
68664
  if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
67755
68665
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
@@ -67813,6 +68723,11 @@ const buildCapabilities = (project) => {
67813
68723
  if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
67814
68724
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
67815
68725
  if (project.hasReactCompiler) capabilities.add("react-compiler");
68726
+ if (project.reanimatedVersion !== void 0 && project.reanimatedVersion !== null) {
68727
+ capabilities.add("reanimated");
68728
+ const reanimatedMajorVersion = getLowestDependencyMajor(project.reanimatedVersion);
68729
+ if (reanimatedMajorVersion !== null && reanimatedMajorVersion >= 4) capabilities.add("reanimated:4");
68730
+ }
67816
68731
  if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
67817
68732
  if (project.styledComponentsVersion) {
67818
68733
  capabilities.add("styled-components");
@@ -69152,7 +70067,10 @@ var Git = class Git extends Service()("react-doctor/Git") {
69152
70067
  if (argvLengthChars > spawnArgsLengthCap) return yield* foldSpawnFailure(`spawn ENAMETOOLONG (${argvLengthChars} argv chars exceed ${spawnArgsLengthCap})`);
69153
70068
  const handle = yield* spawner.spawn(make$1(input.command, [...input.args], {
69154
70069
  cwd: input.directory,
69155
- env: input.env,
70070
+ env: input.command === "git" ? {
70071
+ ...input.env,
70072
+ GIT_DIR: void 0
70073
+ } : input.env,
69156
70074
  extendEnv: true
69157
70075
  }));
69158
70076
  const maxStdoutBytes = input.maxStdoutBytes;
@@ -69425,7 +70343,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
69425
70343
  "--diff-filter=ACMR",
69426
70344
  "--relative"
69427
70345
  ]).pipe(map$3((result) => {
69428
- if (result.status !== 0) return [];
70346
+ if (result.status !== 0) return null;
69429
70347
  return splitNullSeparated(result.stdout);
69430
70348
  })),
69431
70349
  showStagedContent: (directory, relativePath, options) => runCommand({
@@ -69710,7 +70628,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
69710
70628
  const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
69711
70629
  const normalizeConfigForHash = (config) => {
69712
70630
  const clone = JSON.parse(JSON.stringify(config));
69713
- if (clone?.settings?.["react-doctor"]) clone.settings["react-doctor"].rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
70631
+ if (clone?.settings?.["react-doctor"]) {
70632
+ const reactDoctorSettings = clone.settings["react-doctor"];
70633
+ reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
70634
+ if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
70635
+ }
69714
70636
  if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
69715
70637
  return clone;
69716
70638
  };
@@ -69869,13 +70791,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
69869
70791
  }
69870
70792
  return enabled;
69871
70793
  };
69872
- const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
70794
+ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, runtimeGlobals, unpluginAutoImportGlobalScopes, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
69873
70795
  const hasIncludedTags = includedTags.size > 0;
69874
70796
  const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
69875
70797
  const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
69876
70798
  const jsPlugins = [];
69877
70799
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
69878
70800
  const capabilities = getCapabilities(project);
70801
+ const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
69879
70802
  const enabledReactDoctorRules = {};
69880
70803
  for (const registryEntry of REACT_DOCTOR_RULES) {
69881
70804
  const rule = reactDoctorPlugin.rules[registryEntry.id];
@@ -69921,8 +70844,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
69921
70844
  jsPlugins: [...jsPlugins, pluginPath],
69922
70845
  settings: { "react-doctor": {
69923
70846
  framework: project.framework,
69924
- rootDirectory: resolveSettingsRootDirectory(project.rootDirectory),
70847
+ rootDirectory: settingsRootDirectory,
69925
70848
  capabilities: [...capabilities].sort(),
70849
+ ...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
70850
+ ...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
70851
+ unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
70852
+ unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
70853
+ directory: scope.directory,
70854
+ names: [...scope.names]
70855
+ }))
70856
+ } : {},
69926
70857
  ...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
69927
70858
  ...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
69928
70859
  } },
@@ -69933,6 +70864,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
69933
70864
  }
69934
70865
  };
69935
70866
  };
70867
+ const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
70868
+ const CONFIG_BASENAMES = [
70869
+ "astro.config",
70870
+ "esbuild.config",
70871
+ "rollup.config",
70872
+ "rolldown.config",
70873
+ "rspack.config",
70874
+ "vite.config",
70875
+ "webpack.config"
70876
+ ];
70877
+ const CONFIG_EXTENSIONS = [
70878
+ ".cjs",
70879
+ ".cts",
70880
+ ".js",
70881
+ ".mjs",
70882
+ ".mts",
70883
+ ".ts"
70884
+ ];
70885
+ const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
70886
+ const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
70887
+ const SUPPORTED_GLOBAL_VALUES = new Set([
70888
+ true,
70889
+ false,
70890
+ "readable",
70891
+ "readonly",
70892
+ "writable",
70893
+ "writeable"
70894
+ ]);
70895
+ const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
70896
+ if (ts.isSpreadAssignment(property)) return false;
70897
+ const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
70898
+ return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
70899
+ }) ?? null;
70900
+ const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
70901
+ const getStaticPropertyAssignment = (objectExpression, propertyName) => {
70902
+ const property = getStaticProperty(objectExpression, propertyName);
70903
+ return property && ts.isPropertyAssignment(property) ? property : null;
70904
+ };
70905
+ const getRequireModuleSpecifier = (expression) => {
70906
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
70907
+ if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
70908
+ if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
70909
+ const moduleSpecifier = unwrappedExpression.arguments[0];
70910
+ return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
70911
+ };
70912
+ const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
70913
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
70914
+ return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
70915
+ };
70916
+ const isCommonJsExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
70917
+ const isTopLevelExpression = (node) => {
70918
+ let ancestor = node.parent;
70919
+ while (ancestor && !ts.isSourceFile(ancestor)) {
70920
+ if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
70921
+ if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
70922
+ ancestor = ancestor.parent;
70923
+ }
70924
+ return false;
70925
+ };
70926
+ const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
70927
+ let ancestor = node.parent;
70928
+ let didFindConfigProperty = false;
70929
+ while (ancestor && !ts.isSourceFile(ancestor)) {
70930
+ if (!didFindConfigProperty && !ts.isArrayLiteralExpression(ancestor) && !ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isPropertyAssignment(ancestor)) return false;
70931
+ if (ts.isPropertyAssignment(ancestor)) {
70932
+ const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
70933
+ if (didFindConfigProperty || !isConfigProperty) return false;
70934
+ if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
70935
+ didFindConfigProperty = true;
70936
+ ancestor = ancestor.parent;
70937
+ continue;
70938
+ }
70939
+ if (didFindConfigProperty) {
70940
+ if (ts.isExportAssignment(ancestor)) return true;
70941
+ if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
70942
+ if (propertyName === "plugins" && ts.isCallExpression(ancestor) && (ts.isIdentifier(ancestor.expression) ? esbuildBindings.has(ancestor.expression.text) : ts.isPropertyAccessExpression(ancestor.expression) && ancestor.expression.name.text === "build" && (ts.isIdentifier(ancestor.expression.expression) && esbuildNamespaceBindings.has(ancestor.expression.expression.text) || getRequireModuleSpecifier(ancestor.expression.expression) === "esbuild"))) return isTopLevelExpression(ancestor);
70943
+ if (!(ts.isObjectLiteralExpression(ancestor) || ts.isParenthesizedExpression(ancestor) || ts.isAsExpression(ancestor) || ts.isSatisfiesExpression(ancestor) || ts.isNonNullExpression(ancestor) || ts.isTypeAssertionExpression(ancestor) || ts.isCallExpression(ancestor) && ts.isIdentifier(ancestor.expression) && ancestor.expression.text === "defineConfig")) return false;
70944
+ }
70945
+ ancestor = ancestor.parent;
70946
+ }
70947
+ return false;
70948
+ };
70949
+ const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
70950
+ const optionsExpression = callExpression.arguments[0];
70951
+ if (!optionsExpression) return null;
70952
+ const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
70953
+ if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
70954
+ if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
70955
+ if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
70956
+ const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
70957
+ if (!eslintrcProperty) return null;
70958
+ const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
70959
+ if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
70960
+ if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
70961
+ const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
70962
+ if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
70963
+ const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
70964
+ if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
70965
+ if (!ts.isPropertyAssignment(filepathProperty)) return null;
70966
+ const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
70967
+ return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
70968
+ };
70969
+ const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
70970
+ let sourceText;
70971
+ try {
70972
+ sourceText = NFS.readFileSync(configPath, "utf8");
70973
+ } catch {
70974
+ return {
70975
+ didFindActiveAutoImport: false,
70976
+ globalsPaths: []
70977
+ };
70978
+ }
70979
+ const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
70980
+ const autoImportBindings = /* @__PURE__ */ new Map();
70981
+ const esbuildBindings = /* @__PURE__ */ new Set();
70982
+ const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
70983
+ for (const statement of sourceFile.statements) {
70984
+ if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
70985
+ const moduleSpecifier = statement.moduleSpecifier.text;
70986
+ if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
70987
+ const defaultBinding = statement.importClause?.name;
70988
+ if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
70989
+ }
70990
+ if (moduleSpecifier === "esbuild") {
70991
+ const defaultBinding = statement.importClause?.name;
70992
+ if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
70993
+ const namedBindings = statement.importClause?.namedBindings;
70994
+ if (namedBindings && ts.isNamedImports(namedBindings)) {
70995
+ for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
70996
+ }
70997
+ if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
70998
+ }
70999
+ }
71000
+ if (!ts.isVariableStatement(statement)) continue;
71001
+ for (const declaration of statement.declarationList.declarations) {
71002
+ if (!declaration.initializer) continue;
71003
+ const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
71004
+ const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
71005
+ if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
71006
+ if (moduleSpecifier === "esbuild") {
71007
+ if (declarationName) esbuildNamespaceBindings.add(declarationName);
71008
+ if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
71009
+ const importedName = bindingElement.propertyName ?? bindingElement.name;
71010
+ if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
71011
+ }
71012
+ }
71013
+ if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
71014
+ }
71015
+ }
71016
+ const globalsPaths = /* @__PURE__ */ new Set();
71017
+ let didFindActiveAutoImport = false;
71018
+ let didFindUnsafeActiveAutoImport = false;
71019
+ const visit = (node) => {
71020
+ if (ts.isCallExpression(node)) {
71021
+ const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
71022
+ if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
71023
+ if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
71024
+ didFindActiveAutoImport = true;
71025
+ const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
71026
+ if (globalsPath) globalsPaths.add(globalsPath);
71027
+ else didFindUnsafeActiveAutoImport = true;
71028
+ }
71029
+ }
71030
+ }
71031
+ ts.forEachChild(node, visit);
71032
+ };
71033
+ visit(sourceFile);
71034
+ return {
71035
+ didFindActiveAutoImport,
71036
+ globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
71037
+ };
71038
+ };
71039
+ const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
71040
+ const relativePath = Path.relative(rootDirectory, globalsPath);
71041
+ if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
71042
+ const parsed = failOpenReadJson(globalsPath, null);
71043
+ if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
71044
+ return Object.entries(parsed.globals).filter((entry) => entry[0].length > 0 && (typeof entry[1] === "boolean" || typeof entry[1] === "string") && SUPPORTED_GLOBAL_VALUES.has(entry[1])).map(([name]) => name).sort();
71045
+ };
71046
+ const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
71047
+ let currentDirectory = Path.dirname(absoluteFilePath);
71048
+ const visitedDirectories = [];
71049
+ while (true) {
71050
+ const cachedDirectory = cache.get(currentDirectory);
71051
+ if (cachedDirectory !== void 0) {
71052
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
71053
+ return cachedDirectory;
71054
+ }
71055
+ const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
71056
+ if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
71057
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
71058
+ return null;
71059
+ }
71060
+ visitedDirectories.push(currentDirectory);
71061
+ if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
71062
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
71063
+ return currentDirectory;
71064
+ }
71065
+ if (currentDirectory === rootDirectory) {
71066
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
71067
+ return null;
71068
+ }
71069
+ currentDirectory = Path.dirname(currentDirectory);
71070
+ }
71071
+ };
71072
+ const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
71073
+ let directoryEntries;
71074
+ try {
71075
+ directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
71076
+ } catch {
71077
+ return [];
71078
+ }
71079
+ const configuredGlobalsPaths = [];
71080
+ for (const entry of directoryEntries) {
71081
+ if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
71082
+ const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
71083
+ if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
71084
+ }
71085
+ if (configuredGlobalsPaths.length === 0) return [];
71086
+ const globalsPaths = configuredGlobalsPaths[0];
71087
+ if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
71088
+ const names = /* @__PURE__ */ new Set();
71089
+ for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
71090
+ return [...names].sort();
71091
+ };
71092
+ const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
71093
+ const absoluteRootDirectory = Path.resolve(rootDirectory);
71094
+ const packageDirectoryCache = /* @__PURE__ */ new Map();
71095
+ const packageDirectories = /* @__PURE__ */ new Set();
71096
+ for (const candidateFile of candidateFiles) {
71097
+ const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
71098
+ if (packageDirectory) packageDirectories.add(packageDirectory);
71099
+ }
71100
+ const scopes = [...packageDirectories].map((packageDirectory) => ({
71101
+ directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
71102
+ names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
71103
+ })).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
71104
+ return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
71105
+ };
69936
71106
  const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
69937
71107
  const decodeFileDiagnostics = (raw) => {
69938
71108
  if (!Array.isArray(raw)) return null;
@@ -70255,6 +71425,56 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
70255
71425
  if (!help) return REANIMATED_SHARED_VALUE_HINT;
70256
71426
  return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
70257
71427
  };
71428
+ const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
71429
+ const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
71430
+ let lineStartOffset = boundedOffset;
71431
+ while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
71432
+ return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
71433
+ };
71434
+ const utf8OffsetFromSourcePosition = (sourceBuffer, lineNumber, zeroBasedColumn) => {
71435
+ if (lineNumber < 1 || zeroBasedColumn < 0) return null;
71436
+ const sourceLines = sourceBuffer.toString("utf8").split("\n");
71437
+ const sourceLine = sourceLines[lineNumber - 1];
71438
+ if (sourceLine === void 0 || zeroBasedColumn > sourceLine.length) return null;
71439
+ const precedingLines = sourceLines.slice(0, lineNumber - 1).join("\n");
71440
+ return (lineNumber === 1 ? 0 : Buffer.byteLength(precedingLines) + Buffer.byteLength("\n")) + Buffer.byteLength(sourceLine.slice(0, zeroBasedColumn));
71441
+ };
71442
+ const mapPreparedSourceSpan = (span, preparedSourceMap) => {
71443
+ const generatedLine = lineOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset);
71444
+ const generatedColumn = columnOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset) - 1;
71445
+ const originalStart = originalPositionFor(preparedSourceMap.traceMap, {
71446
+ line: generatedLine,
71447
+ column: generatedColumn
71448
+ });
71449
+ if (originalStart.source === null || originalStart.line === null || originalStart.column === null) return null;
71450
+ const originalOffset = utf8OffsetFromSourcePosition(preparedSourceMap.sourceBuffer, originalStart.line, originalStart.column);
71451
+ if (originalOffset === null) return null;
71452
+ const generatedSpan = preparedSourceMap.generatedBuffer.subarray(span.offset, span.offset + span.length);
71453
+ return {
71454
+ offset: originalOffset,
71455
+ length: preparedSourceMap.sourceBuffer.subarray(originalOffset, originalOffset + generatedSpan.length).equals(generatedSpan) ? generatedSpan.length : 0,
71456
+ line: originalStart.line,
71457
+ column: originalStart.column + 1
71458
+ };
71459
+ };
71460
+ const mapPreparedSourceLabels = (labels, preparedSourceMap) => {
71461
+ const primaryLabel = labels[0];
71462
+ if (primaryLabel === void 0) return null;
71463
+ const primarySpan = mapPreparedSourceSpan(primaryLabel.span, preparedSourceMap);
71464
+ if (primarySpan === null) return null;
71465
+ const mappedLabels = [{
71466
+ ...primaryLabel,
71467
+ span: primarySpan
71468
+ }];
71469
+ for (const relatedLabel of labels.slice(1)) {
71470
+ const relatedSpan = mapPreparedSourceSpan(relatedLabel.span, preparedSourceMap);
71471
+ if (relatedSpan !== null) mappedLabels.push({
71472
+ ...relatedLabel,
71473
+ span: relatedSpan
71474
+ });
71475
+ }
71476
+ return mappedLabels;
71477
+ };
70258
71478
  const REDACTED_PLACEHOLDER = "<redacted>";
70259
71479
  const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
70260
71480
  const KNOWN_SECRET_RULES = [
@@ -70970,7 +72190,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
70970
72190
  * with empty text still carry a useful jump target, so they're kept
70971
72191
  * with a neutral message.
70972
72192
  */
70973
- const buildRelatedLocations = (labels, filePath) => {
72193
+ const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
70974
72194
  if (labels.length <= 1) return [];
70975
72195
  const related = [];
70976
72196
  for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
@@ -70978,8 +72198,8 @@ const buildRelatedLocations = (labels, filePath) => {
70978
72198
  if (!label?.span) continue;
70979
72199
  related.push({
70980
72200
  filePath,
70981
- line: label.span.line ?? 0,
70982
- column: label.span.column ?? 0,
72201
+ line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
72202
+ column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
70983
72203
  offset: label.span.offset,
70984
72204
  length: label.span.length,
70985
72205
  message: label.label ?? ""
@@ -70999,7 +72219,7 @@ const isOxlintOutput = (value) => isRecord(value) && Array.isArray(value.diagnos
70999
72219
  * to the first `{`. Raises `OxlintOutputUnparseable` when the
71000
72220
  * stdout isn't valid JSON or doesn't carry a `diagnostics` array.
71001
72221
  */
71002
- const parseOxlintOutput = (stdout, project, rootDirectory) => {
72222
+ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath) => {
71003
72223
  if (!stdout) return [];
71004
72224
  const jsonStart = stdout.indexOf("{");
71005
72225
  const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
@@ -71016,8 +72236,11 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
71016
72236
  const sourceBufferCache = /* @__PURE__ */ new Map();
71017
72237
  const sourceLinesCache = /* @__PURE__ */ new Map();
71018
72238
  const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
72239
+ const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
72240
+ const resolvePreparedSourceMap = (filename) => sourceMapByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
72241
+ const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
71019
72242
  const readSourceBuffer = (filename) => {
71020
- const absolutePath = resolveAbsolutePath(filename);
72243
+ const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
71021
72244
  const cached = sourceBufferCache.get(absolutePath);
71022
72245
  if (cached !== void 0) return cached;
71023
72246
  let sourceBuffer;
@@ -71030,7 +72253,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
71030
72253
  return sourceBuffer;
71031
72254
  };
71032
72255
  const readSourceLines = (filename) => {
71033
- const absolutePath = resolveAbsolutePath(filename);
72256
+ const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
71034
72257
  const cached = sourceLinesCache.get(absolutePath);
71035
72258
  if (cached !== void 0) return cached;
71036
72259
  const sourceBuffer = readSourceBuffer(filename);
@@ -71039,27 +72262,42 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
71039
72262
  return sourceLines;
71040
72263
  };
71041
72264
  const isMinifiedDiagnosticFile = (filename) => {
71042
- const absolutePath = resolveAbsolutePath(filename);
72265
+ const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
71043
72266
  const cached = minifiedFileCache.get(absolutePath);
71044
72267
  if (cached !== void 0) return cached;
71045
72268
  const minified = isMinifiedSource(absolutePath);
71046
72269
  minifiedFileCache.set(absolutePath, minified);
71047
72270
  return minified;
71048
72271
  };
71049
- return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(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) => {
72272
+ return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.flatMap((diagnostic) => {
72273
+ const preparedSourceMap = resolvePreparedSourceMap(diagnostic.filename);
72274
+ if (preparedSourceMap === void 0) return [diagnostic];
72275
+ const { plugin, rule } = parseRuleCode(diagnostic.code);
72276
+ if (plugin !== "react-doctor" || !reactDoctorPlugin.rules[rule]?.tags?.includes("design")) return [];
72277
+ const labels = mapPreparedSourceLabels(diagnostic.labels, preparedSourceMap);
72278
+ const sourceFilename = resolveMappedSourceFilename(diagnostic.filename);
72279
+ return labels === null || sourceFilename === void 0 ? [] : [{
72280
+ ...diagnostic,
72281
+ filename: sourceFilename,
72282
+ labels
72283
+ }];
72284
+ }).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) => {
71050
72285
  const { plugin, rule } = parseRuleCode(diagnostic.code);
71051
72286
  const primaryLabel = diagnostic.labels[0];
71052
72287
  const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
71053
- const normalizedFilePath = diagnostic.filename.replaceAll("\\", "/");
72288
+ const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
72289
+ const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
71054
72290
  const primarySpan = primaryLabel?.span;
71055
72291
  const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
71056
- const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
72292
+ const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
71057
72293
  const category = resolveDiagnosticCategory(plugin, rule);
71058
72294
  const matchByOccurrence = resolveMatchByOccurrence(rule, category);
71059
72295
  const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
71060
- const primaryLineIndex = primarySpan ? primarySpan.line - 1 : -1;
72296
+ const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
72297
+ const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
72298
+ const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
71061
72299
  const primaryLine = sourceLines?.[primaryLineIndex];
71062
- const primaryColumnIndex = primarySpan ? primarySpan.column - 1 : -1;
72300
+ const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
71063
72301
  const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
71064
72302
  const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
71065
72303
  const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
@@ -71072,8 +72310,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
71072
72310
  message: cleaned.message,
71073
72311
  help: cleaned.help,
71074
72312
  url: diagnostic.url,
71075
- line: primarySpan?.line ?? 0,
71076
- column: primarySpan?.column ?? 0,
72313
+ line: primaryLineNumber,
72314
+ column: primaryColumnNumber,
71077
72315
  ...primarySpan ? {
71078
72316
  offset: primarySpan.offset,
71079
72317
  length: primarySpan.length,
@@ -71261,7 +72499,11 @@ const isParallelismRelatedSpawnError = (error) => {
71261
72499
  * loop with a slimmer config in that case.
71262
72500
  */
71263
72501
  const spawnLintBatches = async (input) => {
71264
- const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
72502
+ const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, sourceMapByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
72503
+ const resolveSourcePath = (filePath) => {
72504
+ const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
72505
+ return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
72506
+ };
71265
72507
  const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
71266
72508
  let rescueDeadlineEpochMs;
71267
72509
  const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
@@ -71281,7 +72523,7 @@ const spawnLintBatches = async (input) => {
71281
72523
  }
71282
72524
  const batchArgs = [...baseArgs, ...batch];
71283
72525
  try {
71284
- return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
72526
+ return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath);
71285
72527
  } catch (error) {
71286
72528
  if (!isSplittableReactDoctorError(error)) throw error;
71287
72529
  if (isPastDeadline()) {
@@ -71387,10 +72629,12 @@ const spawnLintBatches = async (input) => {
71387
72629
  onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
71388
72630
  };
71389
72631
  const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
71390
- reportSkippedFiles(droppedFiles, (fileListPreview) => `${droppedFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
71391
- reportSkippedFiles(outcome.deadlineSkippedFiles, (fileListPreview) => `${outcome.deadlineSkippedFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
72632
+ const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
72633
+ const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
72634
+ reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
72635
+ reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
71392
72636
  const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
71393
- input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
72637
+ input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
71394
72638
  return dedupeDiagnostics(diagnostics);
71395
72639
  };
71396
72640
  let didValidate = false;
@@ -71489,6 +72733,294 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
71489
72733
  }
71490
72734
  return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
71491
72735
  };
72736
+ const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
72737
+ const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
72738
+ const COMMENT_OPEN = "<!--";
72739
+ const COMMENT_CLOSE = "-->";
72740
+ const FRONTMATTER_FENCE = "---";
72741
+ const SCRIPT_TAG_NAME = "script";
72742
+ const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
72743
+ const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
72744
+ const TEMPLATE_TAG_NAME = "template";
72745
+ const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
72746
+ const JAVASCRIPT_MIME_TYPES = new Set([
72747
+ "application/ecmascript",
72748
+ "application/javascript",
72749
+ "application/x-ecmascript",
72750
+ "application/x-javascript",
72751
+ "text/ecmascript",
72752
+ "text/javascript",
72753
+ "text/javascript1.0",
72754
+ "text/javascript1.1",
72755
+ "text/javascript1.2",
72756
+ "text/javascript1.3",
72757
+ "text/javascript1.4",
72758
+ "text/javascript1.5",
72759
+ "text/jscript",
72760
+ "text/livescript",
72761
+ "text/x-ecmascript",
72762
+ "text/x-javascript"
72763
+ ]);
72764
+ const RAW_TEXT_TAG_NAMES = new Set([
72765
+ "iframe",
72766
+ "noembed",
72767
+ "noframes",
72768
+ "noscript",
72769
+ "style",
72770
+ "textarea",
72771
+ "title",
72772
+ "xmp"
72773
+ ]);
72774
+ const PLAINTEXT_TAG_NAME = "plaintext";
72775
+ const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
72776
+ const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
72777
+ const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
72778
+ const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
72779
+ const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
72780
+ const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
72781
+ const TAB_UTF8_BYTE = " ".charCodeAt(0);
72782
+ const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
72783
+ const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
72784
+ const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
72785
+ if (startByte + expected.length > sourceBuffer.length) return false;
72786
+ for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
72787
+ const sourceByte = sourceBuffer[startByte + expectedIndex];
72788
+ if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
72789
+ }
72790
+ return true;
72791
+ };
72792
+ const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
72793
+ const isPotentialTagStart = (byte) => {
72794
+ if (byte === void 0) return false;
72795
+ return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
72796
+ };
72797
+ const findLineEnd = (sourceBuffer, lineStartByte) => {
72798
+ let byteIndex = lineStartByte;
72799
+ while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
72800
+ return byteIndex;
72801
+ };
72802
+ const findNextLineStart = (sourceBuffer, lineStartByte) => {
72803
+ const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
72804
+ if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
72805
+ return Math.min(lineEndByte + 1, sourceBuffer.length);
72806
+ };
72807
+ const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
72808
+ if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
72809
+ const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
72810
+ for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
72811
+ return true;
72812
+ };
72813
+ const findFrontmatterEnd = (sourceBuffer) => {
72814
+ if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
72815
+ const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
72816
+ let lineStartByte = findNextLineStart(sourceBuffer, 0);
72817
+ while (lineStartByte < sourceBuffer.length) {
72818
+ if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
72819
+ lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
72820
+ }
72821
+ return openingFenceEndByte;
72822
+ };
72823
+ const maskByteRange = (maskedBuffer, startByte, endByte) => {
72824
+ for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
72825
+ const byte = maskedBuffer[byteIndex];
72826
+ if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
72827
+ }
72828
+ };
72829
+ const readStartTagName = (sourceBuffer, tagStartByte) => {
72830
+ const firstNameByte = sourceBuffer[tagStartByte + 1];
72831
+ if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
72832
+ let nameEndByte = tagStartByte + 2;
72833
+ while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
72834
+ return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
72835
+ };
72836
+ const findTagEnd = (sourceBuffer, startByte) => {
72837
+ let quoteByte = null;
72838
+ for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
72839
+ const byte = sourceBuffer[byteIndex];
72840
+ if (quoteByte !== null) {
72841
+ if (byte === quoteByte) quoteByte = null;
72842
+ continue;
72843
+ }
72844
+ if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
72845
+ quoteByte = byte;
72846
+ continue;
72847
+ }
72848
+ if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
72849
+ }
72850
+ return sourceBuffer.length;
72851
+ };
72852
+ const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
72853
+ let byteIndex = attributesStartByte;
72854
+ let hasSource = false;
72855
+ let language = null;
72856
+ let scriptType = null;
72857
+ while (byteIndex < tagEndByte) {
72858
+ while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
72859
+ const attributeNameStartByte = byteIndex;
72860
+ while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
72861
+ const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
72862
+ while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
72863
+ let attributeValue = "";
72864
+ if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
72865
+ byteIndex++;
72866
+ while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
72867
+ const quoteByte = sourceBuffer[byteIndex];
72868
+ if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
72869
+ const valueStartByte = byteIndex + 1;
72870
+ byteIndex = valueStartByte;
72871
+ while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
72872
+ attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
72873
+ if (byteIndex < tagEndByte) byteIndex++;
72874
+ } else {
72875
+ const valueStartByte = byteIndex;
72876
+ while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
72877
+ attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
72878
+ }
72879
+ }
72880
+ if (attributeName === "src") hasSource = true;
72881
+ else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
72882
+ else if (attributeName === "language" && language === null) language = attributeValue;
72883
+ }
72884
+ return {
72885
+ hasSource,
72886
+ language,
72887
+ type: scriptType
72888
+ };
72889
+ };
72890
+ const isExecutableScript = (attributes) => {
72891
+ if (attributes.hasSource) return false;
72892
+ const type = attributes.type?.trim().toLowerCase() ?? "";
72893
+ if (type !== "") {
72894
+ const mimeType = type.split(";")[0]?.trim() ?? "";
72895
+ return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
72896
+ }
72897
+ const language = attributes.language?.trim().toLowerCase() ?? "";
72898
+ return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
72899
+ };
72900
+ const findElementClose = (sourceBuffer, startByte, tagName) => {
72901
+ const closeTagStart = `</${tagName}`;
72902
+ for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) if (sourceBuffer[byteIndex] === TAG_OPEN_UTF8_BYTE && matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, closeTagStart) && isTagBoundary(sourceBuffer[byteIndex + closeTagStart.length])) return byteIndex;
72903
+ return sourceBuffer.length;
72904
+ };
72905
+ const prepareHtmlScriptSource = (sourceBuffer) => {
72906
+ const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
72907
+ let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
72908
+ if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
72909
+ const executableScriptBodies = [];
72910
+ let byteIndex = frontmatterEndByte;
72911
+ let templateDepth = 0;
72912
+ while (byteIndex < sourceBuffer.length) {
72913
+ if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
72914
+ byteIndex++;
72915
+ continue;
72916
+ }
72917
+ if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
72918
+ const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
72919
+ byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
72920
+ continue;
72921
+ }
72922
+ if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
72923
+ const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
72924
+ if (templateDepth > 0) templateDepth--;
72925
+ byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
72926
+ continue;
72927
+ }
72928
+ if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
72929
+ if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
72930
+ byteIndex++;
72931
+ continue;
72932
+ }
72933
+ const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
72934
+ const tagName = readStartTagName(sourceBuffer, byteIndex);
72935
+ if (tagName === PLAINTEXT_TAG_NAME) break;
72936
+ if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
72937
+ if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
72938
+ const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
72939
+ if (closeTagStartByte === sourceBuffer.length) break;
72940
+ const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
72941
+ byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
72942
+ continue;
72943
+ }
72944
+ byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
72945
+ continue;
72946
+ }
72947
+ const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
72948
+ if (tagEndByte === sourceBuffer.length) break;
72949
+ const bodyStartByte = tagEndByte + 1;
72950
+ const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
72951
+ const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
72952
+ if (attributes.hasSource || templateDepth > 0) {
72953
+ maskedBuffer ??= Buffer.from(sourceBuffer);
72954
+ maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
72955
+ } else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
72956
+ if (bodyEndByte === sourceBuffer.length) break;
72957
+ const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
72958
+ byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
72959
+ }
72960
+ return {
72961
+ executableScriptBodies,
72962
+ lintBuffer: maskedBuffer ?? sourceBuffer
72963
+ };
72964
+ };
72965
+ const ASTRO_FILE_PATTERN = /\.astro$/;
72966
+ const prepareLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
72967
+ const lintFiles = [];
72968
+ const sourcePathByLintPath = /* @__PURE__ */ new Map();
72969
+ const sourceMapByLintPath = /* @__PURE__ */ new Map();
72970
+ const sizeByLintPath = /* @__PURE__ */ new Map();
72971
+ const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
72972
+ const astroSourcesDirectory = Path.join(temporaryDirectory, "astro-sources");
72973
+ let htmlFileIndex = 0;
72974
+ let astroFileIndex = 0;
72975
+ let hasThreeModuleImport = false;
72976
+ for (const candidateFile of candidateFiles) {
72977
+ if (!HTML_FILE_PATTERN.test(candidateFile) && !ASTRO_FILE_PATTERN.test(candidateFile)) {
72978
+ lintFiles.push(candidateFile);
72979
+ continue;
72980
+ }
72981
+ const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
72982
+ const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
72983
+ if (ASTRO_FILE_PATTERN.test(candidateFile)) {
72984
+ const compilerSourcePath = absoluteSourcePath.replaceAll("\\", "/");
72985
+ const convertedSource = convertToTSX(sourceBuffer.toString("utf8"), {
72986
+ filename: compilerSourcePath,
72987
+ sourcemap: "external",
72988
+ includeScripts: true
72989
+ });
72990
+ if (astroFileIndex === 0) NFS.mkdirSync(astroSourcesDirectory, { recursive: true });
72991
+ const lintPath = Path.join(astroSourcesDirectory, `${astroFileIndex}.tsx`);
72992
+ const generatedBuffer = Buffer.from(convertedSource.code);
72993
+ NFS.writeFileSync(lintPath, generatedBuffer);
72994
+ lintFiles.push(candidateFile);
72995
+ lintFiles.push(lintPath);
72996
+ sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
72997
+ sourceMapByLintPath.set(Path.resolve(lintPath), {
72998
+ traceMap: new TraceMap(JSON.stringify(convertedSource.map)),
72999
+ generatedBuffer,
73000
+ sourceBuffer
73001
+ });
73002
+ sizeByLintPath.set(lintPath, sourceBuffer.length);
73003
+ astroFileIndex++;
73004
+ continue;
73005
+ }
73006
+ const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
73007
+ if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
73008
+ const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
73009
+ NFS.writeFileSync(lintPath, lintBuffer);
73010
+ lintFiles.push(lintPath);
73011
+ sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
73012
+ sizeByLintPath.set(lintPath, sourceBuffer.length);
73013
+ hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
73014
+ htmlFileIndex++;
73015
+ }
73016
+ return {
73017
+ lintFiles,
73018
+ sourcePathByLintPath,
73019
+ sourceMapByLintPath,
73020
+ sizeByLintPath,
73021
+ hasThreeModuleImport
73022
+ };
73023
+ };
71492
73024
  /**
71493
73025
  * Atomically (re)writes the generated oxlintrc.json. Used twice in
71494
73026
  * the runner: once for the primary scan, once for the
@@ -71649,6 +73181,8 @@ const reactHooksJsPluginDropNote = (error) => {
71649
73181
  const runOxlint = async (options) => {
71650
73182
  const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
71651
73183
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
73184
+ const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
73185
+ let unpluginAutoImportGlobalScopes = [];
71652
73186
  const severityControls = buildRuleSeverityControls(userConfig);
71653
73187
  validateRuleRegistration();
71654
73188
  resetManifestCaches();
@@ -71662,21 +73196,6 @@ const runOxlint = async (options) => {
71662
73196
  const pluginPath = resolvePluginPath();
71663
73197
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
71664
73198
  const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
71665
- const buildConfig = (overrides) => createOxlintConfig({
71666
- pluginPath,
71667
- project,
71668
- customRulesOnly,
71669
- extendsPaths: overrides.extendsPaths,
71670
- ignoredTags,
71671
- includedTags,
71672
- includeTagDefaults,
71673
- serverAuthFunctionNames,
71674
- severityControls,
71675
- userPlugins,
71676
- disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
71677
- ruleSelection: overrides.ruleSelection,
71678
- sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
71679
- });
71680
73199
  const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
71681
73200
  const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
71682
73201
  const configPath = Path.join(configDirectory, "oxlintrc.json");
@@ -71712,7 +73231,36 @@ const runOxlint = async (options) => {
71712
73231
  await yieldToEventLoop();
71713
73232
  const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
71714
73233
  const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
73234
+ unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
73235
+ rootDirectory,
73236
+ candidateFiles
73237
+ });
73238
+ const preparedLintSources = prepareLintSources(rootDirectory, configDirectory, candidateFiles);
73239
+ const lintFiles = preparedLintSources.lintFiles;
73240
+ const hasPreparedFiles = preparedLintSources.sourcePathByLintPath.size > 0;
73241
+ const lintProject = !project.hasThree && preparedLintSources.hasThreeModuleImport ? {
73242
+ ...project,
73243
+ hasThree: true
73244
+ } : project;
73245
+ const buildConfig = (overrides) => createOxlintConfig({
73246
+ pluginPath,
73247
+ project: lintProject,
73248
+ customRulesOnly,
73249
+ extendsPaths: overrides.extendsPaths,
73250
+ ignoredTags,
73251
+ includedTags,
73252
+ includeTagDefaults,
73253
+ runtimeGlobals,
73254
+ unpluginAutoImportGlobalScopes,
73255
+ serverAuthFunctionNames,
73256
+ severityControls,
73257
+ userPlugins,
73258
+ disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
73259
+ ruleSelection: overrides.ruleSelection,
73260
+ sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
73261
+ });
71715
73262
  const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
73263
+ if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedLintSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
71716
73264
  const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
71717
73265
  baseArgs: passBaseArgs,
71718
73266
  files: passFiles,
@@ -71741,7 +73289,9 @@ const runOxlint = async (options) => {
71741
73289
  fileBatches: passFileBatches,
71742
73290
  rootDirectory,
71743
73291
  nodeBinaryPath,
71744
- project,
73292
+ project: lintProject,
73293
+ sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
73294
+ sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
71745
73295
  onPartialFailure: reportPartialFailure,
71746
73296
  onAnalyzedFiles: (filePaths) => {
71747
73297
  analyzedFiles = filePaths;
@@ -71776,7 +73326,7 @@ const runOxlint = async (options) => {
71776
73326
  };
71777
73327
  }
71778
73328
  };
71779
- if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
73329
+ if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasPreparedFiles) {
71780
73330
  const rulesetHash = computeRulesetHash({
71781
73331
  config: buildConfig({
71782
73332
  extendsPaths: [],
@@ -71934,14 +73484,16 @@ const runOxlint = async (options) => {
71934
73484
  ]);
71935
73485
  }
71936
73486
  const baseArgs = makeBaseArgs(configPath);
71937
- const fileBatches = buildFileBatches(baseArgs, candidateFiles);
73487
+ const fileBatches = buildFileBatches(baseArgs, lintFiles);
71938
73488
  let analyzedFiles = [];
71939
73489
  const runBatches = () => spawnLintBatches({
71940
73490
  baseArgs,
71941
73491
  fileBatches,
71942
73492
  rootDirectory,
71943
73493
  nodeBinaryPath,
71944
- project,
73494
+ project: lintProject,
73495
+ sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
73496
+ sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
71945
73497
  onPartialFailure,
71946
73498
  onAnalyzedFiles: (filePaths) => {
71947
73499
  analyzedFiles = filePaths;
@@ -73290,10 +74842,14 @@ const materializeSourceTree = (input) => gen(function* () {
73290
74842
  materializedFiles.push(relativePath);
73291
74843
  }
73292
74844
  yield* sync(() => {
73293
- for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
73294
- const sourcePath = path.join(input.directory, configFilename);
73295
- const targetPath = path.join(resolvedTempDirectory, configFilename);
73296
- if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) fs.cpSync(sourcePath, targetPath);
74845
+ for (const subdirectory of ["", ...input.configSubdirectories ?? []]) for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
74846
+ const sourcePath = path.join(input.directory, subdirectory, configFilename);
74847
+ const targetPath = path.resolve(resolvedTempDirectory, subdirectory, configFilename);
74848
+ if (!isPathInsideDirectory(targetPath, resolvedTempDirectory)) continue;
74849
+ if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) {
74850
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
74851
+ fs.cpSync(sourcePath, targetPath);
74852
+ }
73297
74853
  }
73298
74854
  });
73299
74855
  return {
@@ -73314,15 +74870,17 @@ const materializeSourceTree = (input) => gen(function* () {
73314
74870
  static layerNode = effect(StagedFiles, gen(function* () {
73315
74871
  const git = yield* Git;
73316
74872
  return StagedFiles.of({
73317
- discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
73318
- materialize: ({ directory, stagedFiles, tempDirectory }) => materializeSourceTree({
74873
+ discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries === null ? null : entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
74874
+ materialize: ({ directory, stagedFiles, tempDirectory, configSubdirectories }) => materializeSourceTree({
73319
74875
  directory,
73320
74876
  files: stagedFiles,
73321
74877
  tempDirectory,
74878
+ configSubdirectories,
73322
74879
  readContent: (relativePath) => git.showStagedContent(directory, relativePath, { maxBufferBytes: GIT_SHOW_MAX_BUFFER_BYTES })
73323
74880
  }).pipe(map$3((tree) => ({
73324
74881
  tempDirectory: tree.tempDirectory,
73325
74882
  stagedFiles: tree.materializedFiles,
74883
+ unmaterializedFiles: tree.unmaterializedFiles,
73326
74884
  cleanup: tree.cleanup
73327
74885
  })), withSpan("StagedFiles.materialize"))
73328
74886
  });
@@ -73337,6 +74895,7 @@ const materializeSourceTree = (input) => gen(function* () {
73337
74895
  materialize: ({ tempDirectory }) => succeed$2({
73338
74896
  tempDirectory,
73339
74897
  stagedFiles: snapshot.materializedFiles ?? snapshot.sourceFiles ?? [],
74898
+ unmaterializedFiles: [],
73340
74899
  cleanup: () => {}
73341
74900
  })
73342
74901
  }));
@@ -73475,7 +75034,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
73475
75034
  /** Display name used in client-facing messages and progress titles. */
73476
75035
  const SERVER_DISPLAY_NAME = "React Doctor";
73477
75036
  /** Server version reported in `serverInfo`; injected at build, `dev` from source. */
73478
- const SERVER_VERSION = "0.9.1";
75037
+ const SERVER_VERSION = "0.9.2";
73479
75038
  /** `Diagnostic.source` shown next to every published diagnostic. */
73480
75039
  const DIAGNOSTIC_SOURCE = "react-doctor";
73481
75040
  /**
@@ -73517,7 +75076,8 @@ const SCANNABLE_EXTENSIONS = [
73517
75076
  ".js",
73518
75077
  ".jsx",
73519
75078
  ".mts",
73520
- ".mjs"
75079
+ ".mjs",
75080
+ ".html"
73521
75081
  ];
73522
75082
  const SILENT_LOGGER = {
73523
75083
  info: () => {},
@@ -75168,11 +76728,13 @@ const METRIC = {
75168
76728
  cliError: "cli.error",
75169
76729
  cliEnvironmentError: "cli.env_error",
75170
76730
  stagedSnapshotDivergence: "staged.snapshot_divergence",
76731
+ stagedPerProject: "staged.per_project",
75171
76732
  projectDetected: "project.detected",
75172
76733
  projectPathSelected: "project.path_selected",
75173
76734
  projectConfigSelected: "project.config_selected",
75174
76735
  scanCompleted: "scan.completed",
75175
76736
  scanDuration: "scan.duration",
76737
+ scanFeedbackDelay: "scan.feedback_delay",
75176
76738
  scanPhaseDuration: "scan.phase_duration",
75177
76739
  scanFiles: "scan.files",
75178
76740
  scanScore: "scan.score",
@@ -75204,6 +76766,10 @@ const METRIC = {
75204
76766
  lspScanCompleted: "lsp.scan.completed",
75205
76767
  lspScanDuration: "lsp.scan.duration",
75206
76768
  lspScanDiagnostics: "lsp.scan.diagnostics",
76769
+ tuiActionMenuOpened: "tui.action_menu_opened",
76770
+ tuiCompactReportShown: "tui.compact_report_shown",
76771
+ tuiFindingNavigated: "tui.finding_navigated",
76772
+ tuiStackedReportCapped: "tui.stacked_report_capped",
75207
76773
  aiTrainingWarningShown: "ai.training.warning_shown",
75208
76774
  jsonOutUsed: "json.out_used"
75209
76775
  };
@@ -75505,5 +77071,5 @@ const startLanguageServer = () => {
75505
77071
  };
75506
77072
  //#endregion
75507
77073
  export { startLanguageServer };
75508
- !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]="aeb8bc8c-7094-5b26-bb18-e269e2d4318a")}catch(e){}}();
75509
- //# debugId=aeb8bc8c-7094-5b26-bb18-e269e2d4318a
77074
+ !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]="7cb1cf13-9787-536b-856a-49d43fec26a4")}catch(e){}}();
77075
+ //# debugId=7cb1cf13-9787-536b-856a-49d43fec26a4