react-doctor 0.9.1 → 0.9.2-dev.075865f
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/README.md +3 -1
- package/dist/cli.js +2170 -344
- package/dist/index.d.ts +11 -5
- package/dist/index.js +1844 -241
- package/dist/lsp.js +1833 -238
- package/dist/{run-scan-app-DZ5jGWFf.js → run-scan-app-DHRvqfkX.js} +288 -216
- package/package.json +9 -7
package/dist/lsp.js
CHANGED
|
@@ -5,17 +5,19 @@ import * as OS from "node:os";
|
|
|
5
5
|
import os from "node:os";
|
|
6
6
|
import * as Path from "node:path";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import
|
|
8
|
+
import { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, REACT_DOCTOR_RULE_REGISTRY, REACT_DOCTOR_SCAN_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor/core";
|
|
9
9
|
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
|
|
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.
|
|
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
|
|
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 (
|
|
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$
|
|
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) =>
|
|
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$
|
|
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))
|
|
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
|
-
|
|
62502
|
-
|
|
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
|
|
62518
|
-
return
|
|
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
|
-
|
|
62553
|
-
|
|
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
|
|
62559
|
-
return
|
|
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$
|
|
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
|
|
62583
|
-
return
|
|
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$
|
|
62593
|
-
|
|
62594
|
-
|
|
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
|
|
62608
|
-
return
|
|
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$
|
|
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$
|
|
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) =>
|
|
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
|
|
62754
|
-
return Boolean(
|
|
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
|
-
|
|
62762
|
-
|
|
62763
|
-
|
|
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 (
|
|
62777
|
-
const
|
|
62778
|
-
|
|
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
|
|
62783
|
-
|
|
62784
|
-
|
|
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$
|
|
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$
|
|
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)
|
|
62808
|
-
|
|
62809
|
-
|
|
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$
|
|
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$
|
|
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 (
|
|
62841
|
-
|
|
62842
|
-
|
|
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
|
-
|
|
62847
|
-
|
|
62848
|
-
|
|
62849
|
-
|
|
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 (
|
|
62861
|
-
|
|
62862
|
-
|
|
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
|
|
62869
|
-
return Boolean(
|
|
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 (
|
|
62875
|
-
|
|
62876
|
-
|
|
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
|
-
|
|
62892
|
-
|
|
62893
|
-
|
|
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 = (
|
|
62933
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -65126,7 +65726,7 @@ const evaluateSuppression = (lines, diagnosticLineIndex, ruleId) => {
|
|
|
65126
65726
|
const getDiagnosticRuleIdentity = (diagnostic) => ({
|
|
65127
65727
|
ruleKey: `${diagnostic.plugin}/${diagnostic.rule}`,
|
|
65128
65728
|
category: diagnostic.category,
|
|
65129
|
-
tags: diagnostic.plugin === "react-doctor" ?
|
|
65729
|
+
tags: diagnostic.plugin === "react-doctor" ? REACT_DOCTOR_RULE_REGISTRY[diagnostic.rule]?.tags ?? [] : []
|
|
65130
65730
|
});
|
|
65131
65731
|
const compileIgnoredFilePatterns = (userConfig) => {
|
|
65132
65732
|
const files = userConfig?.ignore?.files;
|
|
@@ -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(/^\.\//, "")}`;
|
|
@@ -65472,7 +66074,7 @@ const buildDiagnosticPipeline = (input) => {
|
|
|
65472
66074
|
};
|
|
65473
66075
|
const shouldAutoSuppress = (diagnostic) => {
|
|
65474
66076
|
if (diagnostic.plugin !== "react-doctor") return false;
|
|
65475
|
-
const rule =
|
|
66077
|
+
const rule = REACT_DOCTOR_RULE_REGISTRY[diagnostic.rule];
|
|
65476
66078
|
if (!rule?.tags?.includes("test-noise")) return false;
|
|
65477
66079
|
if (rule.tags.includes("migration-hint")) return false;
|
|
65478
66080
|
return getFileContext(diagnostic.filePath) !== "production";
|
|
@@ -65882,6 +66484,7 @@ var OxlintConcurrency = class extends Reference("react-doctor/OxlintConcurrency"
|
|
|
65882
66484
|
if (Number.isInteger(parsed) && parsed > 0) return resolveScanConcurrency(parsed);
|
|
65883
66485
|
return resolveAutoScanConcurrency();
|
|
65884
66486
|
} }) {};
|
|
66487
|
+
var OxlintSpawnSlots = class extends Reference("react-doctor/OxlintSpawnSlots", { defaultValue: () => null }) {};
|
|
65885
66488
|
/**
|
|
65886
66489
|
* Three-state control for overlapping the dead-code pass with the lint pass —
|
|
65887
66490
|
* forking dead-code as a child fiber that runs DURING lint instead of strictly
|
|
@@ -66165,7 +66768,7 @@ const warn = (message) => {
|
|
|
66165
66768
|
runSync(warn$1(message));
|
|
66166
66769
|
};
|
|
66167
66770
|
const CONFIG_BASENAME = "doctor.config";
|
|
66168
|
-
const CONFIG_EXTENSIONS = [
|
|
66771
|
+
const CONFIG_EXTENSIONS$1 = [
|
|
66169
66772
|
"ts",
|
|
66170
66773
|
"mts",
|
|
66171
66774
|
"cts",
|
|
@@ -66269,7 +66872,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
66269
66872
|
};
|
|
66270
66873
|
const loadConfigFromDirectory = async (directory) => {
|
|
66271
66874
|
let sawBrokenConfigFile = false;
|
|
66272
|
-
for (const extension of CONFIG_EXTENSIONS) {
|
|
66875
|
+
for (const extension of CONFIG_EXTENSIONS$1) {
|
|
66273
66876
|
const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
|
|
66274
66877
|
if (!isFile(filePath)) continue;
|
|
66275
66878
|
const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
|
|
@@ -66956,6 +67559,316 @@ const buildReactNativeDiagnostic = (input) => ({
|
|
|
66956
67559
|
column: input.column ?? 0,
|
|
66957
67560
|
category: input.category ?? "Correctness"
|
|
66958
67561
|
});
|
|
67562
|
+
const ANDROID_APP_BUILD_FILE_NAMES = ["build.gradle", "build.gradle.kts"];
|
|
67563
|
+
const BUILD_TYPES_BLOCK_PATTERN = /\bbuildTypes\s*\{/g;
|
|
67564
|
+
const RELEASE_STRING_MARKER = "__RD_RELEASE__";
|
|
67565
|
+
const RELEASE_BLOCK_PATTERNS = [/\brelease\s*\{/g, /\b(?:getByName|named)\s*\(\s*(?:["']release["']|__RD_RELEASE__)\s*\)\s*\{/g];
|
|
67566
|
+
const MINIFY_ASSIGNMENT_PATTERN = /\b(?:isMinifyEnabled|minifyEnabled)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67567
|
+
const SHRINK_RESOURCES_ASSIGNMENT_PATTERN = /\b(?:isShrinkResources|shrinkResources)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67568
|
+
const stripGradleComments = (contents) => {
|
|
67569
|
+
let result = "";
|
|
67570
|
+
let index = 0;
|
|
67571
|
+
let quote = null;
|
|
67572
|
+
while (index < contents.length) {
|
|
67573
|
+
const character = contents[index];
|
|
67574
|
+
const nextCharacter = contents[index + 1];
|
|
67575
|
+
if (quote !== null) {
|
|
67576
|
+
result += character;
|
|
67577
|
+
if (character === "\\") {
|
|
67578
|
+
result += nextCharacter ?? "";
|
|
67579
|
+
index += 2;
|
|
67580
|
+
continue;
|
|
67581
|
+
}
|
|
67582
|
+
if (character === quote) quote = null;
|
|
67583
|
+
index += 1;
|
|
67584
|
+
continue;
|
|
67585
|
+
}
|
|
67586
|
+
if (character === "\"" || character === "'") {
|
|
67587
|
+
quote = character;
|
|
67588
|
+
result += character;
|
|
67589
|
+
index += 1;
|
|
67590
|
+
continue;
|
|
67591
|
+
}
|
|
67592
|
+
if (character === "/" && nextCharacter === "/") {
|
|
67593
|
+
while (index < contents.length && contents[index] !== "\n") {
|
|
67594
|
+
result += " ";
|
|
67595
|
+
index += 1;
|
|
67596
|
+
}
|
|
67597
|
+
continue;
|
|
67598
|
+
}
|
|
67599
|
+
if (character === "/" && nextCharacter === "*") {
|
|
67600
|
+
result += " ";
|
|
67601
|
+
index += 2;
|
|
67602
|
+
while (index < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
|
|
67603
|
+
result += contents[index] === "\n" ? "\n" : " ";
|
|
67604
|
+
index += 1;
|
|
67605
|
+
}
|
|
67606
|
+
if (index < contents.length) {
|
|
67607
|
+
result += " ";
|
|
67608
|
+
index += 2;
|
|
67609
|
+
}
|
|
67610
|
+
continue;
|
|
67611
|
+
}
|
|
67612
|
+
result += character;
|
|
67613
|
+
index += 1;
|
|
67614
|
+
}
|
|
67615
|
+
return result;
|
|
67616
|
+
};
|
|
67617
|
+
const maskGradleStrings = (contents) => {
|
|
67618
|
+
let result = "";
|
|
67619
|
+
let index = 0;
|
|
67620
|
+
let quote = null;
|
|
67621
|
+
while (index < contents.length) {
|
|
67622
|
+
const character = contents[index];
|
|
67623
|
+
if (quote === null) {
|
|
67624
|
+
if (character === "\"" || character === "'") {
|
|
67625
|
+
quote = character;
|
|
67626
|
+
result += " ";
|
|
67627
|
+
} else result += character;
|
|
67628
|
+
index += 1;
|
|
67629
|
+
continue;
|
|
67630
|
+
}
|
|
67631
|
+
if (character === "\\") {
|
|
67632
|
+
result += " ";
|
|
67633
|
+
index += 2;
|
|
67634
|
+
continue;
|
|
67635
|
+
}
|
|
67636
|
+
if (character === quote) quote = null;
|
|
67637
|
+
result += character === "\n" ? "\n" : " ";
|
|
67638
|
+
index += 1;
|
|
67639
|
+
}
|
|
67640
|
+
return result;
|
|
67641
|
+
};
|
|
67642
|
+
const findBlockContents = (contents, pattern) => {
|
|
67643
|
+
const blocks = [];
|
|
67644
|
+
pattern.lastIndex = 0;
|
|
67645
|
+
let match = pattern.exec(contents);
|
|
67646
|
+
while (match !== null) {
|
|
67647
|
+
const openingBraceIndex = pattern.lastIndex - 1;
|
|
67648
|
+
let depth = 1;
|
|
67649
|
+
let index = openingBraceIndex + 1;
|
|
67650
|
+
let quote = null;
|
|
67651
|
+
while (index < contents.length && depth > 0) {
|
|
67652
|
+
const character = contents[index];
|
|
67653
|
+
if (quote !== null) {
|
|
67654
|
+
if (character === "\\") {
|
|
67655
|
+
index += 2;
|
|
67656
|
+
continue;
|
|
67657
|
+
}
|
|
67658
|
+
if (character === quote) quote = null;
|
|
67659
|
+
} else if (character === "\"" || character === "'") quote = character;
|
|
67660
|
+
else if (character === "{") depth += 1;
|
|
67661
|
+
else if (character === "}") depth -= 1;
|
|
67662
|
+
index += 1;
|
|
67663
|
+
}
|
|
67664
|
+
if (depth === 0) blocks.push(contents.slice(openingBraceIndex + 1, index - 1));
|
|
67665
|
+
match = pattern.exec(contents);
|
|
67666
|
+
}
|
|
67667
|
+
return blocks;
|
|
67668
|
+
};
|
|
67669
|
+
const getFinalStaticBoolean = (contents, pattern) => {
|
|
67670
|
+
pattern.lastIndex = 0;
|
|
67671
|
+
let finalValue = null;
|
|
67672
|
+
let match = pattern.exec(contents);
|
|
67673
|
+
while (match !== null) {
|
|
67674
|
+
const staticValue = match[1]?.trim().replace(/\)$/, "").trim();
|
|
67675
|
+
if (staticValue === "true") finalValue = true;
|
|
67676
|
+
else if (staticValue === "false") finalValue = false;
|
|
67677
|
+
else finalValue = null;
|
|
67678
|
+
match = pattern.exec(contents);
|
|
67679
|
+
}
|
|
67680
|
+
return finalValue;
|
|
67681
|
+
};
|
|
67682
|
+
const getReleaseBlocks = (contents) => findBlockContents(contents, BUILD_TYPES_BLOCK_PATTERN).flatMap((buildTypesBlock) => RELEASE_BLOCK_PATTERNS.flatMap((pattern) => findBlockContents(buildTypesBlock, pattern)));
|
|
67683
|
+
const readAndroidReleaseShrinking = (rootDirectory) => {
|
|
67684
|
+
for (const buildFileName of ANDROID_APP_BUILD_FILE_NAMES) {
|
|
67685
|
+
const filePath = Path.posix.join("android", "app", buildFileName);
|
|
67686
|
+
const absoluteFilePath = Path.join(rootDirectory, filePath);
|
|
67687
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67688
|
+
let contents;
|
|
67689
|
+
try {
|
|
67690
|
+
contents = stripGradleComments(NFS.readFileSync(absoluteFilePath, "utf-8"));
|
|
67691
|
+
} catch {
|
|
67692
|
+
return null;
|
|
67693
|
+
}
|
|
67694
|
+
const releaseBlocks = getReleaseBlocks(maskGradleStrings(contents.replace(/(["'])release\1/g, RELEASE_STRING_MARKER)));
|
|
67695
|
+
const [releaseBlock] = releaseBlocks;
|
|
67696
|
+
if (releaseBlock === void 0 || releaseBlocks.length !== 1) return null;
|
|
67697
|
+
const hasDisabledMinification = getFinalStaticBoolean(releaseBlock, MINIFY_ASSIGNMENT_PATTERN) === false;
|
|
67698
|
+
const hasDisabledResourceShrinking = getFinalStaticBoolean(releaseBlock, SHRINK_RESOURCES_ASSIGNMENT_PATTERN) === false;
|
|
67699
|
+
if (!hasDisabledMinification && !hasDisabledResourceShrinking) return null;
|
|
67700
|
+
return {
|
|
67701
|
+
filePath,
|
|
67702
|
+
hasDisabledMinification,
|
|
67703
|
+
hasDisabledResourceShrinking
|
|
67704
|
+
};
|
|
67705
|
+
}
|
|
67706
|
+
return null;
|
|
67707
|
+
};
|
|
67708
|
+
const checkReactNativeAndroidReleaseShrinking = (rootDirectory) => {
|
|
67709
|
+
const releaseShrinking = readAndroidReleaseShrinking(rootDirectory);
|
|
67710
|
+
if (releaseShrinking === null) return [];
|
|
67711
|
+
const disabledFeatures = [releaseShrinking.hasDisabledMinification ? "code minification" : null, releaseShrinking.hasDisabledResourceShrinking ? "resource shrinking" : null].filter((feature) => feature !== null);
|
|
67712
|
+
return [buildReactNativeDiagnostic({
|
|
67713
|
+
filePath: releaseShrinking.filePath,
|
|
67714
|
+
rule: "rn-android-release-shrinking-disabled",
|
|
67715
|
+
category: "Performance",
|
|
67716
|
+
message: `The Android release build explicitly disables ${disabledFeatures.join(" and ")}, leaving unreachable code or resources in the shipped app.`,
|
|
67717
|
+
help: "Enable release code minification and resource shrinking, then test the optimized build and add keep rules for libraries that require them."
|
|
67718
|
+
})];
|
|
67719
|
+
};
|
|
67720
|
+
const getTypescriptScriptKind = (fileName) => {
|
|
67721
|
+
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
67722
|
+
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
67723
|
+
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
67724
|
+
return ts.ScriptKind.JS;
|
|
67725
|
+
};
|
|
67726
|
+
const BABEL_CONFIG_FILE_NAMES$1 = [
|
|
67727
|
+
"babel.config.js",
|
|
67728
|
+
"babel.config.cjs",
|
|
67729
|
+
"babel.config.mjs",
|
|
67730
|
+
"babel.config.ts",
|
|
67731
|
+
"babel.config.cts",
|
|
67732
|
+
"babel.config.json",
|
|
67733
|
+
".babelrc",
|
|
67734
|
+
".babelrc.js",
|
|
67735
|
+
".babelrc.cjs",
|
|
67736
|
+
".babelrc.mjs",
|
|
67737
|
+
".babelrc.cts",
|
|
67738
|
+
".babelrc.json"
|
|
67739
|
+
];
|
|
67740
|
+
const readUnknownPluginNames = (value) => {
|
|
67741
|
+
if (!Array.isArray(value)) return null;
|
|
67742
|
+
const pluginNames = [];
|
|
67743
|
+
for (const entry of value) {
|
|
67744
|
+
if (typeof entry === "string") {
|
|
67745
|
+
pluginNames.push(entry);
|
|
67746
|
+
continue;
|
|
67747
|
+
}
|
|
67748
|
+
if (Array.isArray(entry) && typeof entry[0] === "string") {
|
|
67749
|
+
pluginNames.push(entry[0]);
|
|
67750
|
+
continue;
|
|
67751
|
+
}
|
|
67752
|
+
return null;
|
|
67753
|
+
}
|
|
67754
|
+
return pluginNames;
|
|
67755
|
+
};
|
|
67756
|
+
const getStaticPropertyName$1 = (propertyName) => {
|
|
67757
|
+
if (ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName)) return propertyName.text;
|
|
67758
|
+
return null;
|
|
67759
|
+
};
|
|
67760
|
+
const getStaticPluginName = (expression) => {
|
|
67761
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
67762
|
+
if (ts.isStringLiteralLike(unwrappedExpression)) return unwrappedExpression.text;
|
|
67763
|
+
if (!ts.isArrayLiteralExpression(unwrappedExpression)) return null;
|
|
67764
|
+
const pluginExpression = unwrappedExpression.elements[0];
|
|
67765
|
+
return pluginExpression && ts.isStringLiteralLike(pluginExpression) ? pluginExpression.text : null;
|
|
67766
|
+
};
|
|
67767
|
+
const getPluginNamesFromObject = (objectExpression) => {
|
|
67768
|
+
if (objectExpression.properties.some((property) => ts.isSpreadAssignment(property))) return null;
|
|
67769
|
+
const pluginProperties = objectExpression.properties.filter((property) => ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "plugins");
|
|
67770
|
+
if (pluginProperties.length !== 1) return pluginProperties.length === 0 ? [] : null;
|
|
67771
|
+
const pluginListExpression = unwrapTypescriptExpression(pluginProperties[0].initializer);
|
|
67772
|
+
if (!ts.isArrayLiteralExpression(pluginListExpression)) return null;
|
|
67773
|
+
const pluginNames = [];
|
|
67774
|
+
for (const element of pluginListExpression.elements) {
|
|
67775
|
+
if (ts.isSpreadElement(element)) return null;
|
|
67776
|
+
const pluginName = getStaticPluginName(element);
|
|
67777
|
+
if (pluginName === null) return null;
|
|
67778
|
+
pluginNames.push(pluginName);
|
|
67779
|
+
}
|
|
67780
|
+
return pluginNames;
|
|
67781
|
+
};
|
|
67782
|
+
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";
|
|
67783
|
+
const getDirectExportedObject = (sourceFile) => {
|
|
67784
|
+
const exportedExpressions = [];
|
|
67785
|
+
for (const statement of sourceFile.statements) {
|
|
67786
|
+
if (ts.isExportAssignment(statement)) {
|
|
67787
|
+
exportedExpressions.push(statement.expression);
|
|
67788
|
+
continue;
|
|
67789
|
+
}
|
|
67790
|
+
if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExports(statement.expression.left)) exportedExpressions.push(statement.expression.right);
|
|
67791
|
+
}
|
|
67792
|
+
if (exportedExpressions.length !== 1) return null;
|
|
67793
|
+
const exportedExpression = unwrapTypescriptExpression(exportedExpressions[0]);
|
|
67794
|
+
return ts.isObjectLiteralExpression(exportedExpression) ? exportedExpression : null;
|
|
67795
|
+
};
|
|
67796
|
+
const parseConfigPluginNames = (filePath, contents) => {
|
|
67797
|
+
try {
|
|
67798
|
+
const parsedJson = JSON.parse(contents);
|
|
67799
|
+
return isPlainObject(parsedJson) ? readUnknownPluginNames(parsedJson.plugins) : null;
|
|
67800
|
+
} catch {
|
|
67801
|
+
if (ts.transpileModule(contents, {
|
|
67802
|
+
fileName: filePath,
|
|
67803
|
+
reportDiagnostics: true,
|
|
67804
|
+
compilerOptions: { allowJs: true }
|
|
67805
|
+
}).diagnostics?.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) return null;
|
|
67806
|
+
const exportedObject = getDirectExportedObject(ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filePath)));
|
|
67807
|
+
return exportedObject === null ? null : getPluginNamesFromObject(exportedObject);
|
|
67808
|
+
}
|
|
67809
|
+
};
|
|
67810
|
+
const readStaticBabelPluginNames = (rootDirectory) => {
|
|
67811
|
+
for (const fileName of BABEL_CONFIG_FILE_NAMES$1) {
|
|
67812
|
+
const absoluteFilePath = Path.join(rootDirectory, fileName);
|
|
67813
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67814
|
+
try {
|
|
67815
|
+
return {
|
|
67816
|
+
filePath: fileName,
|
|
67817
|
+
pluginNames: parseConfigPluginNames(fileName, NFS.readFileSync(absoluteFilePath, "utf-8"))
|
|
67818
|
+
};
|
|
67819
|
+
} catch {
|
|
67820
|
+
return {
|
|
67821
|
+
filePath: fileName,
|
|
67822
|
+
pluginNames: null
|
|
67823
|
+
};
|
|
67824
|
+
}
|
|
67825
|
+
}
|
|
67826
|
+
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
67827
|
+
if (!isPlainObject(packageJson.babel)) return null;
|
|
67828
|
+
return {
|
|
67829
|
+
filePath: "package.json",
|
|
67830
|
+
pluginNames: readUnknownPluginNames(packageJson.babel.plugins)
|
|
67831
|
+
};
|
|
67832
|
+
};
|
|
67833
|
+
const REACT_COMPILER_PLUGIN_NAMES = new Set(["babel-plugin-react-compiler", "react-compiler"]);
|
|
67834
|
+
const REANIMATED_PLUGIN_NAME = "react-native-reanimated/plugin";
|
|
67835
|
+
const WORKLETS_PLUGIN_NAME = "react-native-worklets/plugin";
|
|
67836
|
+
const checkReactCompilerPluginOrder = (filePath, pluginNames) => {
|
|
67837
|
+
if (pluginNames.findIndex((pluginName) => REACT_COMPILER_PLUGIN_NAMES.has(pluginName)) <= 0) return [];
|
|
67838
|
+
return [buildReactNativeDiagnostic({
|
|
67839
|
+
filePath,
|
|
67840
|
+
rule: "rn-react-compiler-plugin-first",
|
|
67841
|
+
category: "Performance",
|
|
67842
|
+
message: "The React Compiler Babel plugin is not first, so an earlier transform can change component or hook code before the compiler analyzes it.",
|
|
67843
|
+
help: "Move `babel-plugin-react-compiler` to the first entry in the Babel `plugins` array."
|
|
67844
|
+
})];
|
|
67845
|
+
};
|
|
67846
|
+
const checkReanimatedPluginOrder = (project, filePath, pluginNames) => {
|
|
67847
|
+
const reanimatedMajorVersion = project.reanimatedVersion === null || project.reanimatedVersion === void 0 ? null : getLowestDependencyMajor(project.reanimatedVersion);
|
|
67848
|
+
if (reanimatedMajorVersion === null || reanimatedMajorVersion < 4) return [];
|
|
67849
|
+
const diagnostics = [];
|
|
67850
|
+
if (pluginNames.includes(REANIMATED_PLUGIN_NAME)) diagnostics.push(buildReactNativeDiagnostic({
|
|
67851
|
+
filePath,
|
|
67852
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67853
|
+
category: "Performance",
|
|
67854
|
+
message: "This Reanimated 4 project still uses `react-native-reanimated/plugin`, which was renamed to the Worklets Babel plugin.",
|
|
67855
|
+
help: "Replace it with `react-native-worklets/plugin` and keep that plugin last in the Babel `plugins` array."
|
|
67856
|
+
}));
|
|
67857
|
+
const workletsPluginIndex = pluginNames.lastIndexOf(WORKLETS_PLUGIN_NAME);
|
|
67858
|
+
if (workletsPluginIndex !== -1 && workletsPluginIndex !== pluginNames.length - 1) diagnostics.push(buildReactNativeDiagnostic({
|
|
67859
|
+
filePath,
|
|
67860
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67861
|
+
category: "Performance",
|
|
67862
|
+
message: "`react-native-worklets/plugin` is not last in the Babel `plugins` array, so later transforms can prevent worklets from being compiled correctly.",
|
|
67863
|
+
help: "Move `react-native-worklets/plugin` to the final entry in the Babel `plugins` array."
|
|
67864
|
+
}));
|
|
67865
|
+
return diagnostics;
|
|
67866
|
+
};
|
|
67867
|
+
const checkReactNativeBabelPluginOrder = (rootDirectory, project) => {
|
|
67868
|
+
const babelPlugins = readStaticBabelPluginNames(rootDirectory);
|
|
67869
|
+
if (babelPlugins === null || babelPlugins.pluginNames === null) return [];
|
|
67870
|
+
return [...checkReactCompilerPluginOrder(babelPlugins.filePath, babelPlugins.pluginNames), ...checkReanimatedPluginOrder(project, babelPlugins.filePath, babelPlugins.pluginNames)];
|
|
67871
|
+
};
|
|
66959
67872
|
const BUILDER_BOB_PACKAGE = "react-native-builder-bob";
|
|
66960
67873
|
const isBuilderBobLibrary = (packageJson) => {
|
|
66961
67874
|
const bobConfig = packageJson[BUILDER_BOB_PACKAGE];
|
|
@@ -67032,7 +67945,12 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
67032
67945
|
const isReactNativeProject = (project) => project.framework === "react-native" || project.framework === "expo" || project.hasReactNativeWorkspace || project.expoVersion !== null;
|
|
67033
67946
|
const checkReactNativeProject = (rootDirectory, project) => {
|
|
67034
67947
|
if (!isReactNativeProject(project)) return [];
|
|
67035
|
-
return [
|
|
67948
|
+
return [
|
|
67949
|
+
...checkReactNativeMetroBabelPreset(rootDirectory),
|
|
67950
|
+
...checkReactNativeBabelPluginOrder(rootDirectory, project),
|
|
67951
|
+
...checkReactNativeAndroidReleaseShrinking(rootDirectory),
|
|
67952
|
+
...checkReactNativeLibraryDependencies(rootDirectory)
|
|
67953
|
+
];
|
|
67036
67954
|
};
|
|
67037
67955
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
67038
67956
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
@@ -67183,17 +68101,6 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
|
|
|
67183
68101
|
}
|
|
67184
68102
|
return diagnostics;
|
|
67185
68103
|
};
|
|
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
68104
|
const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
|
|
67198
68105
|
isAnimationFunction: false,
|
|
67199
68106
|
isMotionComponent: false,
|
|
@@ -67749,7 +68656,11 @@ const buildCapabilities = (project) => {
|
|
|
67749
68656
|
capabilities.add(project.framework);
|
|
67750
68657
|
if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
|
|
67751
68658
|
if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
|
|
67752
|
-
if (project.expoVersion !== null)
|
|
68659
|
+
if (project.expoVersion !== null) {
|
|
68660
|
+
capabilities.add("expo");
|
|
68661
|
+
const expoSdkMajorVersion = getLowestDependencyMajor(project.expoVersion);
|
|
68662
|
+
if (expoSdkMajorVersion !== null && expoSdkMajorVersion >= 54) capabilities.add("expo:54");
|
|
68663
|
+
}
|
|
67753
68664
|
if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
|
|
67754
68665
|
if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
|
|
67755
68666
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
@@ -67813,6 +68724,11 @@ const buildCapabilities = (project) => {
|
|
|
67813
68724
|
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
67814
68725
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
67815
68726
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
68727
|
+
if (project.reanimatedVersion !== void 0 && project.reanimatedVersion !== null) {
|
|
68728
|
+
capabilities.add("reanimated");
|
|
68729
|
+
const reanimatedMajorVersion = getLowestDependencyMajor(project.reanimatedVersion);
|
|
68730
|
+
if (reanimatedMajorVersion !== null && reanimatedMajorVersion >= 4) capabilities.add("reanimated:4");
|
|
68731
|
+
}
|
|
67816
68732
|
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
67817
68733
|
if (project.styledComponentsVersion) {
|
|
67818
68734
|
capabilities.add("styled-components");
|
|
@@ -67843,8 +68759,8 @@ const getCapabilities = (project) => {
|
|
|
67843
68759
|
const cached = capabilitiesByProject.get(project);
|
|
67844
68760
|
if (cached !== void 0) return cached;
|
|
67845
68761
|
const capabilities = new Set(buildCapabilities(project));
|
|
67846
|
-
const
|
|
67847
|
-
const targetBlankOpenerProtection = detectTargetBlankOpenerProtection(
|
|
68762
|
+
const capabilityRootDirectory = isFile(Path.join(project.rootDirectory, "package.json")) ? project.rootDirectory : findNearestAncestorPackageJson(project.rootDirectory) ?? project.rootDirectory;
|
|
68763
|
+
const targetBlankOpenerProtection = detectTargetBlankOpenerProtection(capabilityRootDirectory, readPackageJson(Path.join(capabilityRootDirectory, "package.json")));
|
|
67848
68764
|
if (targetBlankOpenerProtection !== void 0) capabilities.add("target-blank-needs-explicit-protection");
|
|
67849
68765
|
if (targetBlankOpenerProtection === "noreferrer") capabilities.add("target-blank-needs-noreferrer");
|
|
67850
68766
|
capabilitiesByProject.set(project, capabilities);
|
|
@@ -67874,7 +68790,7 @@ const createSecurityScanSession = (rootDirectory, options) => {
|
|
|
67874
68790
|
const capabilities = options.project ? getCapabilities(options.project) : /* @__PURE__ */ new Set();
|
|
67875
68791
|
const ignoredTags = options.ignoredTags ?? /* @__PURE__ */ new Set();
|
|
67876
68792
|
const includedTags = options.includedTags ?? /* @__PURE__ */ new Set();
|
|
67877
|
-
const enabledScanRules =
|
|
68793
|
+
const enabledScanRules = REACT_DOCTOR_SCAN_RULES.flatMap((entry) => {
|
|
67878
68794
|
const rule = entry.rule;
|
|
67879
68795
|
const scan = rule.scan;
|
|
67880
68796
|
if (typeof scan !== "function") return [];
|
|
@@ -68319,47 +69235,55 @@ const resolveDeadCodeConcurrency = (facts = readSystemFacts()) => {
|
|
|
68319
69235
|
const memoryBoundedWorkers = Math.floor(availableMemoryBytes / DEAD_CODE_WORKER_MEM_BUDGET_BYTES);
|
|
68320
69236
|
return Math.max(1, Math.min(facts.availableCores, memoryBoundedWorkers));
|
|
68321
69237
|
};
|
|
68322
|
-
|
|
68323
|
-
|
|
68324
|
-
const
|
|
68325
|
-
const
|
|
68326
|
-
|
|
68327
|
-
|
|
69238
|
+
const createWorkerSlots = (input) => {
|
|
69239
|
+
let availableSlotCount = input.slotCount;
|
|
69240
|
+
const waiters = [];
|
|
69241
|
+
const releaseSlot = () => {
|
|
69242
|
+
const nextWaiter = waiters.shift();
|
|
69243
|
+
if (nextWaiter === void 0) {
|
|
69244
|
+
availableSlotCount += 1;
|
|
69245
|
+
return;
|
|
69246
|
+
}
|
|
69247
|
+
nextWaiter.abortSignal?.removeEventListener("abort", nextWaiter.onAbort);
|
|
69248
|
+
nextWaiter.resolve();
|
|
69249
|
+
};
|
|
69250
|
+
const acquireSlot = async (abortSignal) => {
|
|
69251
|
+
if (abortSignal?.aborted) throw input.createAbortError();
|
|
69252
|
+
if (availableSlotCount > 0) {
|
|
69253
|
+
availableSlotCount -= 1;
|
|
69254
|
+
return;
|
|
69255
|
+
}
|
|
69256
|
+
await new Promise((resolve, reject) => {
|
|
69257
|
+
const onAbort = () => {
|
|
69258
|
+
const waiterIndex = waiters.indexOf(waiter);
|
|
69259
|
+
if (waiterIndex !== -1) waiters.splice(waiterIndex, 1);
|
|
69260
|
+
reject(input.createAbortError());
|
|
69261
|
+
};
|
|
69262
|
+
const waiter = {
|
|
69263
|
+
resolve,
|
|
69264
|
+
abortSignal,
|
|
69265
|
+
onAbort
|
|
69266
|
+
};
|
|
69267
|
+
waiters.push(waiter);
|
|
69268
|
+
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
69269
|
+
});
|
|
69270
|
+
};
|
|
69271
|
+
return { run: async (task, abortSignal) => {
|
|
69272
|
+
await acquireSlot(abortSignal);
|
|
69273
|
+
try {
|
|
69274
|
+
return await task();
|
|
69275
|
+
} finally {
|
|
69276
|
+
releaseSlot();
|
|
69277
|
+
}
|
|
69278
|
+
} };
|
|
68328
69279
|
};
|
|
68329
|
-
|
|
68330
|
-
* Runs `task` once a dead-code worker slot is free, releasing the slot when the
|
|
68331
|
-
* task settles (success or failure). With a high cap (roomy machine) every
|
|
68332
|
-
* caller proceeds immediately; with a low cap (constrained runner) callers
|
|
68333
|
-
* queue and run as slots free.
|
|
68334
|
-
*
|
|
68335
|
-
* `abortSignal` short-circuits the WAIT: if it's already aborted, or fires while
|
|
68336
|
-
* this caller is queued, the call rejects without acquiring a slot or running
|
|
68337
|
-
* `task` — so a cancelled scan (e.g. lint failed) doesn't sit in the queue and
|
|
68338
|
-
* then spawn a child only to tear it down. A queued caller that aborts removes
|
|
68339
|
-
* its own waiter so a later release never hands a slot to a dead request.
|
|
68340
|
-
*/
|
|
69280
|
+
let deadCodeWorkerSlots = null;
|
|
68341
69281
|
const withDeadCodeWorkerSlot = async (task, abortSignal) => {
|
|
68342
|
-
|
|
68343
|
-
|
|
68344
|
-
|
|
68345
|
-
else await new Promise((resolve, reject) => {
|
|
68346
|
-
const waiter = () => {
|
|
68347
|
-
abortSignal?.removeEventListener("abort", onAbort);
|
|
68348
|
-
resolve();
|
|
68349
|
-
};
|
|
68350
|
-
const onAbort = () => {
|
|
68351
|
-
const queuedIndex = waiters.indexOf(waiter);
|
|
68352
|
-
if (queuedIndex !== -1) waiters.splice(queuedIndex, 1);
|
|
68353
|
-
reject(/* @__PURE__ */ new Error("Dead-code worker aborted."));
|
|
68354
|
-
};
|
|
68355
|
-
waiters.push(waiter);
|
|
68356
|
-
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
69282
|
+
deadCodeWorkerSlots ??= createWorkerSlots({
|
|
69283
|
+
slotCount: resolveDeadCodeConcurrency(),
|
|
69284
|
+
createAbortError: () => /* @__PURE__ */ new Error("Dead-code worker aborted.")
|
|
68357
69285
|
});
|
|
68358
|
-
|
|
68359
|
-
return await task();
|
|
68360
|
-
} finally {
|
|
68361
|
-
releaseSlot();
|
|
68362
|
-
}
|
|
69286
|
+
return deadCodeWorkerSlots.run(task, abortSignal);
|
|
68363
69287
|
};
|
|
68364
69288
|
const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
|
|
68365
69289
|
const resolveReactDoctorCacheDir = (projectDirectory) => {
|
|
@@ -69152,7 +70076,10 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
69152
70076
|
if (argvLengthChars > spawnArgsLengthCap) return yield* foldSpawnFailure(`spawn ENAMETOOLONG (${argvLengthChars} argv chars exceed ${spawnArgsLengthCap})`);
|
|
69153
70077
|
const handle = yield* spawner.spawn(make$1(input.command, [...input.args], {
|
|
69154
70078
|
cwd: input.directory,
|
|
69155
|
-
env: input.
|
|
70079
|
+
env: input.command === "git" ? {
|
|
70080
|
+
...input.env,
|
|
70081
|
+
GIT_DIR: void 0
|
|
70082
|
+
} : input.env,
|
|
69156
70083
|
extendEnv: true
|
|
69157
70084
|
}));
|
|
69158
70085
|
const maxStdoutBytes = input.maxStdoutBytes;
|
|
@@ -69425,7 +70352,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
69425
70352
|
"--diff-filter=ACMR",
|
|
69426
70353
|
"--relative"
|
|
69427
70354
|
]).pipe(map$3((result) => {
|
|
69428
|
-
if (result.status !== 0) return
|
|
70355
|
+
if (result.status !== 0) return null;
|
|
69429
70356
|
return splitNullSeparated(result.stdout);
|
|
69430
70357
|
})),
|
|
69431
70358
|
showStagedContent: (directory, relativePath, options) => runCommand({
|
|
@@ -69710,7 +70637,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
69710
70637
|
const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
|
|
69711
70638
|
const normalizeConfigForHash = (config) => {
|
|
69712
70639
|
const clone = JSON.parse(JSON.stringify(config));
|
|
69713
|
-
if (clone?.settings?.["react-doctor"])
|
|
70640
|
+
if (clone?.settings?.["react-doctor"]) {
|
|
70641
|
+
const reactDoctorSettings = clone.settings["react-doctor"];
|
|
70642
|
+
reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
|
|
70643
|
+
if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
|
|
70644
|
+
}
|
|
69714
70645
|
if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
|
|
69715
70646
|
return clone;
|
|
69716
70647
|
};
|
|
@@ -69869,21 +70800,22 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
69869
70800
|
}
|
|
69870
70801
|
return enabled;
|
|
69871
70802
|
};
|
|
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 }) => {
|
|
70803
|
+
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
70804
|
const hasIncludedTags = includedTags.size > 0;
|
|
69874
70805
|
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
69875
70806
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
69876
70807
|
const jsPlugins = [];
|
|
69877
70808
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
69878
70809
|
const capabilities = getCapabilities(project);
|
|
70810
|
+
const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
|
|
69879
70811
|
const enabledReactDoctorRules = {};
|
|
69880
70812
|
for (const registryEntry of REACT_DOCTOR_RULES) {
|
|
69881
|
-
const rule =
|
|
70813
|
+
const rule = REACT_DOCTOR_RULE_REGISTRY[registryEntry.id];
|
|
69882
70814
|
if (!rule) continue;
|
|
69883
70815
|
if (ruleSelection === "cacheable" && CROSS_FILE_RULE_IDS.has(registryEntry.id)) continue;
|
|
69884
70816
|
if (ruleSelection === "sidecar" && !CROSS_FILE_RULE_IDS.has(registryEntry.id)) continue;
|
|
69885
70817
|
if (ruleSelection === "sidecar" && sidecarRuleIdFilter !== void 0 && !sidecarRuleIdFilter.has(registryEntry.id)) continue;
|
|
69886
|
-
if (rule.
|
|
70818
|
+
if (rule.isScanRule) continue;
|
|
69887
70819
|
if (customRulesOnly && registryEntry.originallyExternal) continue;
|
|
69888
70820
|
if (rule.framework !== "global" && !rule.requires) continue;
|
|
69889
70821
|
if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
|
|
@@ -69921,8 +70853,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69921
70853
|
jsPlugins: [...jsPlugins, pluginPath],
|
|
69922
70854
|
settings: { "react-doctor": {
|
|
69923
70855
|
framework: project.framework,
|
|
69924
|
-
rootDirectory:
|
|
70856
|
+
rootDirectory: settingsRootDirectory,
|
|
69925
70857
|
capabilities: [...capabilities].sort(),
|
|
70858
|
+
...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
|
|
70859
|
+
...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
|
|
70860
|
+
unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
|
|
70861
|
+
unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
|
|
70862
|
+
directory: scope.directory,
|
|
70863
|
+
names: [...scope.names]
|
|
70864
|
+
}))
|
|
70865
|
+
} : {},
|
|
69926
70866
|
...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
|
|
69927
70867
|
...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
|
|
69928
70868
|
} },
|
|
@@ -69933,6 +70873,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69933
70873
|
}
|
|
69934
70874
|
};
|
|
69935
70875
|
};
|
|
70876
|
+
const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
|
|
70877
|
+
const CONFIG_BASENAMES = [
|
|
70878
|
+
"astro.config",
|
|
70879
|
+
"esbuild.config",
|
|
70880
|
+
"rollup.config",
|
|
70881
|
+
"rolldown.config",
|
|
70882
|
+
"rspack.config",
|
|
70883
|
+
"vite.config",
|
|
70884
|
+
"webpack.config"
|
|
70885
|
+
];
|
|
70886
|
+
const CONFIG_EXTENSIONS = [
|
|
70887
|
+
".cjs",
|
|
70888
|
+
".cts",
|
|
70889
|
+
".js",
|
|
70890
|
+
".mjs",
|
|
70891
|
+
".mts",
|
|
70892
|
+
".ts"
|
|
70893
|
+
];
|
|
70894
|
+
const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
|
|
70895
|
+
const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
|
|
70896
|
+
const SUPPORTED_GLOBAL_VALUES = new Set([
|
|
70897
|
+
true,
|
|
70898
|
+
false,
|
|
70899
|
+
"readable",
|
|
70900
|
+
"readonly",
|
|
70901
|
+
"writable",
|
|
70902
|
+
"writeable"
|
|
70903
|
+
]);
|
|
70904
|
+
const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
|
|
70905
|
+
if (ts.isSpreadAssignment(property)) return false;
|
|
70906
|
+
const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
|
|
70907
|
+
return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
|
|
70908
|
+
}) ?? null;
|
|
70909
|
+
const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
|
|
70910
|
+
const getStaticPropertyAssignment = (objectExpression, propertyName) => {
|
|
70911
|
+
const property = getStaticProperty(objectExpression, propertyName);
|
|
70912
|
+
return property && ts.isPropertyAssignment(property) ? property : null;
|
|
70913
|
+
};
|
|
70914
|
+
const getRequireModuleSpecifier = (expression) => {
|
|
70915
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70916
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
|
|
70917
|
+
if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
|
|
70918
|
+
const moduleSpecifier = unwrappedExpression.arguments[0];
|
|
70919
|
+
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
70920
|
+
};
|
|
70921
|
+
const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
|
|
70922
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70923
|
+
return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
|
|
70924
|
+
};
|
|
70925
|
+
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");
|
|
70926
|
+
const isTopLevelExpression = (node) => {
|
|
70927
|
+
let ancestor = node.parent;
|
|
70928
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70929
|
+
if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
|
|
70930
|
+
if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
|
|
70931
|
+
ancestor = ancestor.parent;
|
|
70932
|
+
}
|
|
70933
|
+
return false;
|
|
70934
|
+
};
|
|
70935
|
+
const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
|
|
70936
|
+
let ancestor = node.parent;
|
|
70937
|
+
let didFindConfigProperty = false;
|
|
70938
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70939
|
+
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;
|
|
70940
|
+
if (ts.isPropertyAssignment(ancestor)) {
|
|
70941
|
+
const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
|
|
70942
|
+
if (didFindConfigProperty || !isConfigProperty) return false;
|
|
70943
|
+
if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
|
|
70944
|
+
didFindConfigProperty = true;
|
|
70945
|
+
ancestor = ancestor.parent;
|
|
70946
|
+
continue;
|
|
70947
|
+
}
|
|
70948
|
+
if (didFindConfigProperty) {
|
|
70949
|
+
if (ts.isExportAssignment(ancestor)) return true;
|
|
70950
|
+
if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
|
|
70951
|
+
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);
|
|
70952
|
+
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;
|
|
70953
|
+
}
|
|
70954
|
+
ancestor = ancestor.parent;
|
|
70955
|
+
}
|
|
70956
|
+
return false;
|
|
70957
|
+
};
|
|
70958
|
+
const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
|
|
70959
|
+
const optionsExpression = callExpression.arguments[0];
|
|
70960
|
+
if (!optionsExpression) return null;
|
|
70961
|
+
const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
|
|
70962
|
+
if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
|
|
70963
|
+
if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
|
|
70964
|
+
if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
|
|
70965
|
+
const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
|
|
70966
|
+
if (!eslintrcProperty) return null;
|
|
70967
|
+
const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
|
|
70968
|
+
if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
|
|
70969
|
+
if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
|
|
70970
|
+
const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
|
|
70971
|
+
if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
|
|
70972
|
+
const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
|
|
70973
|
+
if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
|
|
70974
|
+
if (!ts.isPropertyAssignment(filepathProperty)) return null;
|
|
70975
|
+
const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
|
|
70976
|
+
return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
|
|
70977
|
+
};
|
|
70978
|
+
const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
|
|
70979
|
+
let sourceText;
|
|
70980
|
+
try {
|
|
70981
|
+
sourceText = NFS.readFileSync(configPath, "utf8");
|
|
70982
|
+
} catch {
|
|
70983
|
+
return {
|
|
70984
|
+
didFindActiveAutoImport: false,
|
|
70985
|
+
globalsPaths: []
|
|
70986
|
+
};
|
|
70987
|
+
}
|
|
70988
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
70989
|
+
const autoImportBindings = /* @__PURE__ */ new Map();
|
|
70990
|
+
const esbuildBindings = /* @__PURE__ */ new Set();
|
|
70991
|
+
const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
|
|
70992
|
+
for (const statement of sourceFile.statements) {
|
|
70993
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
70994
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
70995
|
+
if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70996
|
+
const defaultBinding = statement.importClause?.name;
|
|
70997
|
+
if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
|
|
70998
|
+
}
|
|
70999
|
+
if (moduleSpecifier === "esbuild") {
|
|
71000
|
+
const defaultBinding = statement.importClause?.name;
|
|
71001
|
+
if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
|
|
71002
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
71003
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
71004
|
+
for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
|
|
71005
|
+
}
|
|
71006
|
+
if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
|
|
71007
|
+
}
|
|
71008
|
+
}
|
|
71009
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
71010
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
71011
|
+
if (!declaration.initializer) continue;
|
|
71012
|
+
const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
|
|
71013
|
+
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
71014
|
+
if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
|
|
71015
|
+
if (moduleSpecifier === "esbuild") {
|
|
71016
|
+
if (declarationName) esbuildNamespaceBindings.add(declarationName);
|
|
71017
|
+
if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
|
|
71018
|
+
const importedName = bindingElement.propertyName ?? bindingElement.name;
|
|
71019
|
+
if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
|
|
71020
|
+
}
|
|
71021
|
+
}
|
|
71022
|
+
if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
|
|
71023
|
+
}
|
|
71024
|
+
}
|
|
71025
|
+
const globalsPaths = /* @__PURE__ */ new Set();
|
|
71026
|
+
let didFindActiveAutoImport = false;
|
|
71027
|
+
let didFindUnsafeActiveAutoImport = false;
|
|
71028
|
+
const visit = (node) => {
|
|
71029
|
+
if (ts.isCallExpression(node)) {
|
|
71030
|
+
const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
|
|
71031
|
+
if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
71032
|
+
if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
|
|
71033
|
+
didFindActiveAutoImport = true;
|
|
71034
|
+
const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
|
|
71035
|
+
if (globalsPath) globalsPaths.add(globalsPath);
|
|
71036
|
+
else didFindUnsafeActiveAutoImport = true;
|
|
71037
|
+
}
|
|
71038
|
+
}
|
|
71039
|
+
}
|
|
71040
|
+
ts.forEachChild(node, visit);
|
|
71041
|
+
};
|
|
71042
|
+
visit(sourceFile);
|
|
71043
|
+
return {
|
|
71044
|
+
didFindActiveAutoImport,
|
|
71045
|
+
globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
|
|
71046
|
+
};
|
|
71047
|
+
};
|
|
71048
|
+
const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
|
|
71049
|
+
const relativePath = Path.relative(rootDirectory, globalsPath);
|
|
71050
|
+
if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
|
|
71051
|
+
const parsed = failOpenReadJson(globalsPath, null);
|
|
71052
|
+
if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
|
|
71053
|
+
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();
|
|
71054
|
+
};
|
|
71055
|
+
const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
|
|
71056
|
+
let currentDirectory = Path.dirname(absoluteFilePath);
|
|
71057
|
+
const visitedDirectories = [];
|
|
71058
|
+
while (true) {
|
|
71059
|
+
const cachedDirectory = cache.get(currentDirectory);
|
|
71060
|
+
if (cachedDirectory !== void 0) {
|
|
71061
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
|
|
71062
|
+
return cachedDirectory;
|
|
71063
|
+
}
|
|
71064
|
+
const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
|
|
71065
|
+
if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
|
|
71066
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
71067
|
+
return null;
|
|
71068
|
+
}
|
|
71069
|
+
visitedDirectories.push(currentDirectory);
|
|
71070
|
+
if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
|
|
71071
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
|
|
71072
|
+
return currentDirectory;
|
|
71073
|
+
}
|
|
71074
|
+
if (currentDirectory === rootDirectory) {
|
|
71075
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
71076
|
+
return null;
|
|
71077
|
+
}
|
|
71078
|
+
currentDirectory = Path.dirname(currentDirectory);
|
|
71079
|
+
}
|
|
71080
|
+
};
|
|
71081
|
+
const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
|
|
71082
|
+
let directoryEntries;
|
|
71083
|
+
try {
|
|
71084
|
+
directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
|
|
71085
|
+
} catch {
|
|
71086
|
+
return [];
|
|
71087
|
+
}
|
|
71088
|
+
const configuredGlobalsPaths = [];
|
|
71089
|
+
for (const entry of directoryEntries) {
|
|
71090
|
+
if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
|
|
71091
|
+
const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
|
|
71092
|
+
if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
|
|
71093
|
+
}
|
|
71094
|
+
if (configuredGlobalsPaths.length === 0) return [];
|
|
71095
|
+
const globalsPaths = configuredGlobalsPaths[0];
|
|
71096
|
+
if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
|
|
71097
|
+
const names = /* @__PURE__ */ new Set();
|
|
71098
|
+
for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
|
|
71099
|
+
return [...names].sort();
|
|
71100
|
+
};
|
|
71101
|
+
const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
|
|
71102
|
+
const absoluteRootDirectory = Path.resolve(rootDirectory);
|
|
71103
|
+
const packageDirectoryCache = /* @__PURE__ */ new Map();
|
|
71104
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
71105
|
+
for (const candidateFile of candidateFiles) {
|
|
71106
|
+
const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
|
|
71107
|
+
if (packageDirectory) packageDirectories.add(packageDirectory);
|
|
71108
|
+
}
|
|
71109
|
+
const scopes = [...packageDirectories].map((packageDirectory) => ({
|
|
71110
|
+
directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
|
|
71111
|
+
names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
|
|
71112
|
+
})).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
|
|
71113
|
+
return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
|
|
71114
|
+
};
|
|
69936
71115
|
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
69937
71116
|
const decodeFileDiagnostics = (raw) => {
|
|
69938
71117
|
if (!Array.isArray(raw)) return null;
|
|
@@ -70255,6 +71434,56 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
|
|
|
70255
71434
|
if (!help) return REANIMATED_SHARED_VALUE_HINT;
|
|
70256
71435
|
return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
|
|
70257
71436
|
};
|
|
71437
|
+
const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
|
|
71438
|
+
const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
|
|
71439
|
+
let lineStartOffset = boundedOffset;
|
|
71440
|
+
while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
|
|
71441
|
+
return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
|
|
71442
|
+
};
|
|
71443
|
+
const utf8OffsetFromSourcePosition = (sourceBuffer, lineNumber, zeroBasedColumn) => {
|
|
71444
|
+
if (lineNumber < 1 || zeroBasedColumn < 0) return null;
|
|
71445
|
+
const sourceLines = sourceBuffer.toString("utf8").split("\n");
|
|
71446
|
+
const sourceLine = sourceLines[lineNumber - 1];
|
|
71447
|
+
if (sourceLine === void 0 || zeroBasedColumn > sourceLine.length) return null;
|
|
71448
|
+
const precedingLines = sourceLines.slice(0, lineNumber - 1).join("\n");
|
|
71449
|
+
return (lineNumber === 1 ? 0 : Buffer.byteLength(precedingLines) + Buffer.byteLength("\n")) + Buffer.byteLength(sourceLine.slice(0, zeroBasedColumn));
|
|
71450
|
+
};
|
|
71451
|
+
const mapPreparedSourceSpan = (span, preparedSourceMap) => {
|
|
71452
|
+
const generatedLine = lineOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset);
|
|
71453
|
+
const generatedColumn = columnOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset) - 1;
|
|
71454
|
+
const originalStart = originalPositionFor(preparedSourceMap.traceMap, {
|
|
71455
|
+
line: generatedLine,
|
|
71456
|
+
column: generatedColumn
|
|
71457
|
+
});
|
|
71458
|
+
if (originalStart.source === null || originalStart.line === null || originalStart.column === null) return null;
|
|
71459
|
+
const originalOffset = utf8OffsetFromSourcePosition(preparedSourceMap.sourceBuffer, originalStart.line, originalStart.column);
|
|
71460
|
+
if (originalOffset === null) return null;
|
|
71461
|
+
const generatedSpan = preparedSourceMap.generatedBuffer.subarray(span.offset, span.offset + span.length);
|
|
71462
|
+
return {
|
|
71463
|
+
offset: originalOffset,
|
|
71464
|
+
length: preparedSourceMap.sourceBuffer.subarray(originalOffset, originalOffset + generatedSpan.length).equals(generatedSpan) ? generatedSpan.length : 0,
|
|
71465
|
+
line: originalStart.line,
|
|
71466
|
+
column: originalStart.column + 1
|
|
71467
|
+
};
|
|
71468
|
+
};
|
|
71469
|
+
const mapPreparedSourceLabels = (labels, preparedSourceMap) => {
|
|
71470
|
+
const primaryLabel = labels[0];
|
|
71471
|
+
if (primaryLabel === void 0) return null;
|
|
71472
|
+
const primarySpan = mapPreparedSourceSpan(primaryLabel.span, preparedSourceMap);
|
|
71473
|
+
if (primarySpan === null) return null;
|
|
71474
|
+
const mappedLabels = [{
|
|
71475
|
+
...primaryLabel,
|
|
71476
|
+
span: primarySpan
|
|
71477
|
+
}];
|
|
71478
|
+
for (const relatedLabel of labels.slice(1)) {
|
|
71479
|
+
const relatedSpan = mapPreparedSourceSpan(relatedLabel.span, preparedSourceMap);
|
|
71480
|
+
if (relatedSpan !== null) mappedLabels.push({
|
|
71481
|
+
...relatedLabel,
|
|
71482
|
+
span: relatedSpan
|
|
71483
|
+
});
|
|
71484
|
+
}
|
|
71485
|
+
return mappedLabels;
|
|
71486
|
+
};
|
|
70258
71487
|
const REDACTED_PLACEHOLDER = "<redacted>";
|
|
70259
71488
|
const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
|
|
70260
71489
|
const KNOWN_SECRET_RULES = [
|
|
@@ -70897,7 +72126,7 @@ const PLUGIN_CATEGORY_MAP = {
|
|
|
70897
72126
|
};
|
|
70898
72127
|
const lookupOwnString = (record, key) => Object.hasOwn(record, key) ? record[key] : void 0;
|
|
70899
72128
|
const getRuleRecommendation = (ruleName, project) => {
|
|
70900
|
-
const rule =
|
|
72129
|
+
const rule = REACT_DOCTOR_RULE_REGISTRY[ruleName];
|
|
70901
72130
|
if (!rule) return void 0;
|
|
70902
72131
|
if (rule.recommendationFor) {
|
|
70903
72132
|
const capabilities = getCapabilities(project);
|
|
@@ -70906,8 +72135,8 @@ const getRuleRecommendation = (ruleName, project) => {
|
|
|
70906
72135
|
}
|
|
70907
72136
|
return rule.recommendation;
|
|
70908
72137
|
};
|
|
70909
|
-
const getRuleCategory = (ruleName) =>
|
|
70910
|
-
const getRuleTitle = (ruleName) =>
|
|
72138
|
+
const getRuleCategory = (ruleName) => REACT_DOCTOR_RULE_REGISTRY[ruleName]?.category;
|
|
72139
|
+
const getRuleTitle = (ruleName) => REACT_DOCTOR_RULE_REGISTRY[ruleName]?.title;
|
|
70911
72140
|
const resolveDiagnosticTitle = (plugin, rule) => {
|
|
70912
72141
|
if (plugin !== "react-hooks-js") return getRuleTitle(rule);
|
|
70913
72142
|
if (rule === "error-boundaries") return REACT_ERROR_BOUNDARY_TITLE;
|
|
@@ -70962,7 +72191,7 @@ const resolveDiagnosticCategory = (plugin, rule) => {
|
|
|
70962
72191
|
if (plugin === "react-hooks-js" && rule === "error-boundaries") return "Bugs";
|
|
70963
72192
|
return getRuleCategory(rule) ?? lookupOwnString(PLUGIN_CATEGORY_MAP, plugin) ?? "Bugs";
|
|
70964
72193
|
};
|
|
70965
|
-
const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORIES.has(category) || Boolean(
|
|
72194
|
+
const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORIES.has(category) || Boolean(REACT_DOCTOR_RULE_REGISTRY[rule]?.matchByOccurrence);
|
|
70966
72195
|
/**
|
|
70967
72196
|
* Maps oxlint's non-primary labels (`labels[1..]`) into related source
|
|
70968
72197
|
* locations. Editors surface these as a diagnostic's
|
|
@@ -70970,7 +72199,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
|
|
|
70970
72199
|
* with empty text still carry a useful jump target, so they're kept
|
|
70971
72200
|
* with a neutral message.
|
|
70972
72201
|
*/
|
|
70973
|
-
const buildRelatedLocations = (labels, filePath) => {
|
|
72202
|
+
const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
|
|
70974
72203
|
if (labels.length <= 1) return [];
|
|
70975
72204
|
const related = [];
|
|
70976
72205
|
for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
|
|
@@ -70978,8 +72207,8 @@ const buildRelatedLocations = (labels, filePath) => {
|
|
|
70978
72207
|
if (!label?.span) continue;
|
|
70979
72208
|
related.push({
|
|
70980
72209
|
filePath,
|
|
70981
|
-
line: label.span.line ?? 0,
|
|
70982
|
-
column: label.span.column ?? 0,
|
|
72210
|
+
line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
72211
|
+
column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
70983
72212
|
offset: label.span.offset,
|
|
70984
72213
|
length: label.span.length,
|
|
70985
72214
|
message: label.label ?? ""
|
|
@@ -70999,7 +72228,7 @@ const isOxlintOutput = (value) => isRecord(value) && Array.isArray(value.diagnos
|
|
|
70999
72228
|
* to the first `{`. Raises `OxlintOutputUnparseable` when the
|
|
71000
72229
|
* stdout isn't valid JSON or doesn't carry a `diagnostics` array.
|
|
71001
72230
|
*/
|
|
71002
|
-
const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
72231
|
+
const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath) => {
|
|
71003
72232
|
if (!stdout) return [];
|
|
71004
72233
|
const jsonStart = stdout.indexOf("{");
|
|
71005
72234
|
const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
|
|
@@ -71016,8 +72245,11 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71016
72245
|
const sourceBufferCache = /* @__PURE__ */ new Map();
|
|
71017
72246
|
const sourceLinesCache = /* @__PURE__ */ new Map();
|
|
71018
72247
|
const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
72248
|
+
const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
72249
|
+
const resolvePreparedSourceMap = (filename) => sourceMapByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
72250
|
+
const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
|
|
71019
72251
|
const readSourceBuffer = (filename) => {
|
|
71020
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
72252
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71021
72253
|
const cached = sourceBufferCache.get(absolutePath);
|
|
71022
72254
|
if (cached !== void 0) return cached;
|
|
71023
72255
|
let sourceBuffer;
|
|
@@ -71030,7 +72262,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71030
72262
|
return sourceBuffer;
|
|
71031
72263
|
};
|
|
71032
72264
|
const readSourceLines = (filename) => {
|
|
71033
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
72265
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71034
72266
|
const cached = sourceLinesCache.get(absolutePath);
|
|
71035
72267
|
if (cached !== void 0) return cached;
|
|
71036
72268
|
const sourceBuffer = readSourceBuffer(filename);
|
|
@@ -71039,27 +72271,42 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71039
72271
|
return sourceLines;
|
|
71040
72272
|
};
|
|
71041
72273
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
71042
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
72274
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71043
72275
|
const cached = minifiedFileCache.get(absolutePath);
|
|
71044
72276
|
if (cached !== void 0) return cached;
|
|
71045
72277
|
const minified = isMinifiedSource(absolutePath);
|
|
71046
72278
|
minifiedFileCache.set(absolutePath, minified);
|
|
71047
72279
|
return minified;
|
|
71048
72280
|
};
|
|
71049
|
-
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.
|
|
72281
|
+
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.flatMap((diagnostic) => {
|
|
72282
|
+
const preparedSourceMap = resolvePreparedSourceMap(diagnostic.filename);
|
|
72283
|
+
if (preparedSourceMap === void 0) return [diagnostic];
|
|
72284
|
+
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
72285
|
+
if (plugin !== "react-doctor" || !REACT_DOCTOR_RULE_REGISTRY[rule]?.tags?.includes("design")) return [];
|
|
72286
|
+
const labels = mapPreparedSourceLabels(diagnostic.labels, preparedSourceMap);
|
|
72287
|
+
const sourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
72288
|
+
return labels === null || sourceFilename === void 0 ? [] : [{
|
|
72289
|
+
...diagnostic,
|
|
72290
|
+
filename: sourceFilename,
|
|
72291
|
+
labels
|
|
72292
|
+
}];
|
|
72293
|
+
}).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
72294
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
71051
72295
|
const primaryLabel = diagnostic.labels[0];
|
|
71052
72296
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
71053
|
-
const
|
|
72297
|
+
const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
72298
|
+
const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
|
|
71054
72299
|
const primarySpan = primaryLabel?.span;
|
|
71055
72300
|
const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
|
|
71056
|
-
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
|
|
72301
|
+
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
|
|
71057
72302
|
const category = resolveDiagnosticCategory(plugin, rule);
|
|
71058
72303
|
const matchByOccurrence = resolveMatchByOccurrence(rule, category);
|
|
71059
72304
|
const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
|
|
71060
|
-
const
|
|
72305
|
+
const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
|
|
72306
|
+
const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
|
|
72307
|
+
const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
|
|
71061
72308
|
const primaryLine = sourceLines?.[primaryLineIndex];
|
|
71062
|
-
const primaryColumnIndex = primarySpan ?
|
|
72309
|
+
const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
|
|
71063
72310
|
const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
|
|
71064
72311
|
const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
|
|
71065
72312
|
const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
|
|
@@ -71072,8 +72319,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71072
72319
|
message: cleaned.message,
|
|
71073
72320
|
help: cleaned.help,
|
|
71074
72321
|
url: diagnostic.url,
|
|
71075
|
-
line:
|
|
71076
|
-
column:
|
|
72322
|
+
line: primaryLineNumber,
|
|
72323
|
+
column: primaryColumnNumber,
|
|
71077
72324
|
...primarySpan ? {
|
|
71078
72325
|
offset: primarySpan.offset,
|
|
71079
72326
|
length: primarySpan.length,
|
|
@@ -71121,11 +72368,12 @@ const SANITIZED_ENV = buildOxlintChildEnv(process.env);
|
|
|
71121
72368
|
* The first three are splittable (the caller's binary-split retry
|
|
71122
72369
|
* shrinks the batch and re-spawns); the fourth isn't.
|
|
71123
72370
|
*/
|
|
71124
|
-
const spawnOxlint = (args, rootDirectory, nodeBinaryPath, spawnTimeoutMs = OXLINT_SPAWN_TIMEOUT_MS, outputMaxBytes = OXLINT_OUTPUT_MAX_BYTES, abortSignal) => new Promise((resolve, reject) => {
|
|
72371
|
+
const spawnOxlint = (args, rootDirectory, nodeBinaryPath, spawnTimeoutMs = OXLINT_SPAWN_TIMEOUT_MS, outputMaxBytes = OXLINT_OUTPUT_MAX_BYTES, abortSignal, onSpawn) => new Promise((resolve, reject) => {
|
|
71125
72372
|
if (abortSignal?.aborted) {
|
|
71126
72373
|
reject(new ReactDoctorError({ reason: new OxlintSpawnFailed({ cause: "lint phase aborted" }) }));
|
|
71127
72374
|
return;
|
|
71128
72375
|
}
|
|
72376
|
+
onSpawn?.();
|
|
71129
72377
|
const child = spawn(nodeBinaryPath, buildProfiledNodeArguments({
|
|
71130
72378
|
argumentsList: args,
|
|
71131
72379
|
cpuProfileDirectory: SANITIZED_ENV.REACT_DOCTOR_CPU_PROFILE_DIR,
|
|
@@ -71261,7 +72509,11 @@ const isParallelismRelatedSpawnError = (error) => {
|
|
|
71261
72509
|
* loop with a slimmer config in that case.
|
|
71262
72510
|
*/
|
|
71263
72511
|
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;
|
|
72512
|
+
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, sourceMapByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
72513
|
+
const resolveSourcePath = (filePath) => {
|
|
72514
|
+
const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
|
|
72515
|
+
return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
|
|
72516
|
+
};
|
|
71265
72517
|
const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
|
|
71266
72518
|
let rescueDeadlineEpochMs;
|
|
71267
72519
|
const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
|
|
@@ -71281,7 +72533,21 @@ const spawnLintBatches = async (input) => {
|
|
|
71281
72533
|
}
|
|
71282
72534
|
const batchArgs = [...baseArgs, ...batch];
|
|
71283
72535
|
try {
|
|
71284
|
-
|
|
72536
|
+
const spawnBatch = () => {
|
|
72537
|
+
if (isPastDeadline()) {
|
|
72538
|
+
deadlineSkippedFiles.push(...batch);
|
|
72539
|
+
batchState.deadlineSkippedFileCount += batch.length;
|
|
72540
|
+
return Promise.resolve(null);
|
|
72541
|
+
}
|
|
72542
|
+
return spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal, () => {
|
|
72543
|
+
if (batchState.didStart) return;
|
|
72544
|
+
batchState.didStart = true;
|
|
72545
|
+
startedFileCount += batchState.initialFileCount;
|
|
72546
|
+
});
|
|
72547
|
+
};
|
|
72548
|
+
const stdout = input.spawnSlots === void 0 ? await spawnBatch() : await input.spawnSlots.run(spawnBatch, signal);
|
|
72549
|
+
if (stdout === null) return [];
|
|
72550
|
+
return parseOxlintOutput(stdout, project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath);
|
|
71285
72551
|
} catch (error) {
|
|
71286
72552
|
if (!isSplittableReactDoctorError(error)) throw error;
|
|
71287
72553
|
if (isPastDeadline()) {
|
|
@@ -71325,14 +72591,15 @@ const spawnLintBatches = async (input) => {
|
|
|
71325
72591
|
deadlineSkippedFiles.push(...batch);
|
|
71326
72592
|
return [];
|
|
71327
72593
|
}
|
|
71328
|
-
startedFileCount += batch.length;
|
|
71329
72594
|
const batchState = {
|
|
71330
72595
|
deadlineMs: null,
|
|
71331
|
-
deadlineSkippedFileCount: 0
|
|
72596
|
+
deadlineSkippedFileCount: 0,
|
|
72597
|
+
didStart: false,
|
|
72598
|
+
initialFileCount: batch.length
|
|
71332
72599
|
};
|
|
71333
72600
|
const batchDiagnostics = await spawnLintBatch(batch, 0, batchState);
|
|
71334
72601
|
scannedFileCount += batch.length - batchState.deadlineSkippedFileCount;
|
|
71335
|
-
if (passOnFileProgress) {
|
|
72602
|
+
if (passOnFileProgress && batchState.didStart) {
|
|
71336
72603
|
displayedFileCount = Math.min(Math.max(displayedFileCount, scannedFileCount), totalFileCount);
|
|
71337
72604
|
passOnFileProgress(displayedFileCount, totalFileCount);
|
|
71338
72605
|
}
|
|
@@ -71387,10 +72654,12 @@ const spawnLintBatches = async (input) => {
|
|
|
71387
72654
|
onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
|
|
71388
72655
|
};
|
|
71389
72656
|
const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
|
|
71390
|
-
|
|
71391
|
-
|
|
72657
|
+
const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
|
|
72658
|
+
const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
|
|
72659
|
+
reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
|
|
72660
|
+
reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
|
|
71392
72661
|
const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
|
|
71393
|
-
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
|
|
72662
|
+
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
|
|
71394
72663
|
return dedupeDiagnostics(diagnostics);
|
|
71395
72664
|
};
|
|
71396
72665
|
let didValidate = false;
|
|
@@ -71414,8 +72683,8 @@ const validateRuleRegistration = () => {
|
|
|
71414
72683
|
for (const fullKey of ALL_REACT_DOCTOR_RULE_KEYS) {
|
|
71415
72684
|
const ruleName = fullKey.replace(/^react-doctor\//, "");
|
|
71416
72685
|
if (!getRuleCategory(ruleName)) missingCategory.push(fullKey);
|
|
71417
|
-
if (!
|
|
71418
|
-
if (FRAMEWORK_SPECIFIC_RULE_KEYS.has(fullKey) && !
|
|
72686
|
+
if (!REACT_DOCTOR_RULE_REGISTRY[ruleName]?.recommendation) missingHelp.push(fullKey);
|
|
72687
|
+
if (FRAMEWORK_SPECIFIC_RULE_KEYS.has(fullKey) && !REACT_DOCTOR_RULE_REGISTRY[ruleName]?.requires) missingMetadata.push(fullKey);
|
|
71419
72688
|
}
|
|
71420
72689
|
if (missingCategory.length === 0 && missingHelp.length === 0 && missingMetadata.length === 0) return;
|
|
71421
72690
|
const detail = [
|
|
@@ -71489,6 +72758,294 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
71489
72758
|
}
|
|
71490
72759
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
71491
72760
|
};
|
|
72761
|
+
const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
|
|
72762
|
+
const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
|
|
72763
|
+
const COMMENT_OPEN = "<!--";
|
|
72764
|
+
const COMMENT_CLOSE = "-->";
|
|
72765
|
+
const FRONTMATTER_FENCE = "---";
|
|
72766
|
+
const SCRIPT_TAG_NAME = "script";
|
|
72767
|
+
const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
|
|
72768
|
+
const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
|
|
72769
|
+
const TEMPLATE_TAG_NAME = "template";
|
|
72770
|
+
const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
|
|
72771
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
72772
|
+
"application/ecmascript",
|
|
72773
|
+
"application/javascript",
|
|
72774
|
+
"application/x-ecmascript",
|
|
72775
|
+
"application/x-javascript",
|
|
72776
|
+
"text/ecmascript",
|
|
72777
|
+
"text/javascript",
|
|
72778
|
+
"text/javascript1.0",
|
|
72779
|
+
"text/javascript1.1",
|
|
72780
|
+
"text/javascript1.2",
|
|
72781
|
+
"text/javascript1.3",
|
|
72782
|
+
"text/javascript1.4",
|
|
72783
|
+
"text/javascript1.5",
|
|
72784
|
+
"text/jscript",
|
|
72785
|
+
"text/livescript",
|
|
72786
|
+
"text/x-ecmascript",
|
|
72787
|
+
"text/x-javascript"
|
|
72788
|
+
]);
|
|
72789
|
+
const RAW_TEXT_TAG_NAMES = new Set([
|
|
72790
|
+
"iframe",
|
|
72791
|
+
"noembed",
|
|
72792
|
+
"noframes",
|
|
72793
|
+
"noscript",
|
|
72794
|
+
"style",
|
|
72795
|
+
"textarea",
|
|
72796
|
+
"title",
|
|
72797
|
+
"xmp"
|
|
72798
|
+
]);
|
|
72799
|
+
const PLAINTEXT_TAG_NAME = "plaintext";
|
|
72800
|
+
const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
|
|
72801
|
+
const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
|
|
72802
|
+
const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
|
|
72803
|
+
const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
|
|
72804
|
+
const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
|
|
72805
|
+
const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
|
|
72806
|
+
const TAB_UTF8_BYTE = " ".charCodeAt(0);
|
|
72807
|
+
const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
|
|
72808
|
+
const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
|
|
72809
|
+
const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
|
|
72810
|
+
if (startByte + expected.length > sourceBuffer.length) return false;
|
|
72811
|
+
for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
|
|
72812
|
+
const sourceByte = sourceBuffer[startByte + expectedIndex];
|
|
72813
|
+
if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
|
|
72814
|
+
}
|
|
72815
|
+
return true;
|
|
72816
|
+
};
|
|
72817
|
+
const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
|
|
72818
|
+
const isPotentialTagStart = (byte) => {
|
|
72819
|
+
if (byte === void 0) return false;
|
|
72820
|
+
return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
|
|
72821
|
+
};
|
|
72822
|
+
const findLineEnd = (sourceBuffer, lineStartByte) => {
|
|
72823
|
+
let byteIndex = lineStartByte;
|
|
72824
|
+
while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
|
|
72825
|
+
return byteIndex;
|
|
72826
|
+
};
|
|
72827
|
+
const findNextLineStart = (sourceBuffer, lineStartByte) => {
|
|
72828
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72829
|
+
if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
|
|
72830
|
+
return Math.min(lineEndByte + 1, sourceBuffer.length);
|
|
72831
|
+
};
|
|
72832
|
+
const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
|
|
72833
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
|
|
72834
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72835
|
+
for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
|
|
72836
|
+
return true;
|
|
72837
|
+
};
|
|
72838
|
+
const findFrontmatterEnd = (sourceBuffer) => {
|
|
72839
|
+
if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
|
|
72840
|
+
const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
|
|
72841
|
+
let lineStartByte = findNextLineStart(sourceBuffer, 0);
|
|
72842
|
+
while (lineStartByte < sourceBuffer.length) {
|
|
72843
|
+
if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
|
|
72844
|
+
lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
|
|
72845
|
+
}
|
|
72846
|
+
return openingFenceEndByte;
|
|
72847
|
+
};
|
|
72848
|
+
const maskByteRange = (maskedBuffer, startByte, endByte) => {
|
|
72849
|
+
for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
|
|
72850
|
+
const byte = maskedBuffer[byteIndex];
|
|
72851
|
+
if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
|
|
72852
|
+
}
|
|
72853
|
+
};
|
|
72854
|
+
const readStartTagName = (sourceBuffer, tagStartByte) => {
|
|
72855
|
+
const firstNameByte = sourceBuffer[tagStartByte + 1];
|
|
72856
|
+
if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
|
|
72857
|
+
let nameEndByte = tagStartByte + 2;
|
|
72858
|
+
while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
|
|
72859
|
+
return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
|
|
72860
|
+
};
|
|
72861
|
+
const findTagEnd = (sourceBuffer, startByte) => {
|
|
72862
|
+
let quoteByte = null;
|
|
72863
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
|
|
72864
|
+
const byte = sourceBuffer[byteIndex];
|
|
72865
|
+
if (quoteByte !== null) {
|
|
72866
|
+
if (byte === quoteByte) quoteByte = null;
|
|
72867
|
+
continue;
|
|
72868
|
+
}
|
|
72869
|
+
if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72870
|
+
quoteByte = byte;
|
|
72871
|
+
continue;
|
|
72872
|
+
}
|
|
72873
|
+
if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
|
|
72874
|
+
}
|
|
72875
|
+
return sourceBuffer.length;
|
|
72876
|
+
};
|
|
72877
|
+
const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
|
|
72878
|
+
let byteIndex = attributesStartByte;
|
|
72879
|
+
let hasSource = false;
|
|
72880
|
+
let language = null;
|
|
72881
|
+
let scriptType = null;
|
|
72882
|
+
while (byteIndex < tagEndByte) {
|
|
72883
|
+
while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
|
|
72884
|
+
const attributeNameStartByte = byteIndex;
|
|
72885
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72886
|
+
const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
|
|
72887
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72888
|
+
let attributeValue = "";
|
|
72889
|
+
if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
|
|
72890
|
+
byteIndex++;
|
|
72891
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72892
|
+
const quoteByte = sourceBuffer[byteIndex];
|
|
72893
|
+
if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72894
|
+
const valueStartByte = byteIndex + 1;
|
|
72895
|
+
byteIndex = valueStartByte;
|
|
72896
|
+
while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
|
|
72897
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72898
|
+
if (byteIndex < tagEndByte) byteIndex++;
|
|
72899
|
+
} else {
|
|
72900
|
+
const valueStartByte = byteIndex;
|
|
72901
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72902
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72903
|
+
}
|
|
72904
|
+
}
|
|
72905
|
+
if (attributeName === "src") hasSource = true;
|
|
72906
|
+
else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
|
|
72907
|
+
else if (attributeName === "language" && language === null) language = attributeValue;
|
|
72908
|
+
}
|
|
72909
|
+
return {
|
|
72910
|
+
hasSource,
|
|
72911
|
+
language,
|
|
72912
|
+
type: scriptType
|
|
72913
|
+
};
|
|
72914
|
+
};
|
|
72915
|
+
const isExecutableScript = (attributes) => {
|
|
72916
|
+
if (attributes.hasSource) return false;
|
|
72917
|
+
const type = attributes.type?.trim().toLowerCase() ?? "";
|
|
72918
|
+
if (type !== "") {
|
|
72919
|
+
const mimeType = type.split(";")[0]?.trim() ?? "";
|
|
72920
|
+
return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
|
|
72921
|
+
}
|
|
72922
|
+
const language = attributes.language?.trim().toLowerCase() ?? "";
|
|
72923
|
+
return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
|
|
72924
|
+
};
|
|
72925
|
+
const findElementClose = (sourceBuffer, startByte, tagName) => {
|
|
72926
|
+
const closeTagStart = `</${tagName}`;
|
|
72927
|
+
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;
|
|
72928
|
+
return sourceBuffer.length;
|
|
72929
|
+
};
|
|
72930
|
+
const prepareHtmlScriptSource = (sourceBuffer) => {
|
|
72931
|
+
const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
|
|
72932
|
+
let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
|
|
72933
|
+
if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
|
|
72934
|
+
const executableScriptBodies = [];
|
|
72935
|
+
let byteIndex = frontmatterEndByte;
|
|
72936
|
+
let templateDepth = 0;
|
|
72937
|
+
while (byteIndex < sourceBuffer.length) {
|
|
72938
|
+
if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
|
|
72939
|
+
byteIndex++;
|
|
72940
|
+
continue;
|
|
72941
|
+
}
|
|
72942
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
|
|
72943
|
+
const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
|
|
72944
|
+
byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
|
|
72945
|
+
continue;
|
|
72946
|
+
}
|
|
72947
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
|
|
72948
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
|
|
72949
|
+
if (templateDepth > 0) templateDepth--;
|
|
72950
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72951
|
+
continue;
|
|
72952
|
+
}
|
|
72953
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
|
|
72954
|
+
if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
|
|
72955
|
+
byteIndex++;
|
|
72956
|
+
continue;
|
|
72957
|
+
}
|
|
72958
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
|
|
72959
|
+
const tagName = readStartTagName(sourceBuffer, byteIndex);
|
|
72960
|
+
if (tagName === PLAINTEXT_TAG_NAME) break;
|
|
72961
|
+
if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
|
|
72962
|
+
if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
72963
|
+
const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
|
|
72964
|
+
if (closeTagStartByte === sourceBuffer.length) break;
|
|
72965
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
|
|
72966
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72967
|
+
continue;
|
|
72968
|
+
}
|
|
72969
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72970
|
+
continue;
|
|
72971
|
+
}
|
|
72972
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
|
|
72973
|
+
if (tagEndByte === sourceBuffer.length) break;
|
|
72974
|
+
const bodyStartByte = tagEndByte + 1;
|
|
72975
|
+
const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
|
|
72976
|
+
const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
|
|
72977
|
+
if (attributes.hasSource || templateDepth > 0) {
|
|
72978
|
+
maskedBuffer ??= Buffer.from(sourceBuffer);
|
|
72979
|
+
maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
|
|
72980
|
+
} else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
|
|
72981
|
+
if (bodyEndByte === sourceBuffer.length) break;
|
|
72982
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
|
|
72983
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72984
|
+
}
|
|
72985
|
+
return {
|
|
72986
|
+
executableScriptBodies,
|
|
72987
|
+
lintBuffer: maskedBuffer ?? sourceBuffer
|
|
72988
|
+
};
|
|
72989
|
+
};
|
|
72990
|
+
const ASTRO_FILE_PATTERN = /\.astro$/;
|
|
72991
|
+
const prepareLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
|
|
72992
|
+
const lintFiles = [];
|
|
72993
|
+
const sourcePathByLintPath = /* @__PURE__ */ new Map();
|
|
72994
|
+
const sourceMapByLintPath = /* @__PURE__ */ new Map();
|
|
72995
|
+
const sizeByLintPath = /* @__PURE__ */ new Map();
|
|
72996
|
+
const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
|
|
72997
|
+
const astroSourcesDirectory = Path.join(temporaryDirectory, "astro-sources");
|
|
72998
|
+
let htmlFileIndex = 0;
|
|
72999
|
+
let astroFileIndex = 0;
|
|
73000
|
+
let hasThreeModuleImport = false;
|
|
73001
|
+
for (const candidateFile of candidateFiles) {
|
|
73002
|
+
if (!HTML_FILE_PATTERN.test(candidateFile) && !ASTRO_FILE_PATTERN.test(candidateFile)) {
|
|
73003
|
+
lintFiles.push(candidateFile);
|
|
73004
|
+
continue;
|
|
73005
|
+
}
|
|
73006
|
+
const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
|
|
73007
|
+
const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
|
|
73008
|
+
if (ASTRO_FILE_PATTERN.test(candidateFile)) {
|
|
73009
|
+
const compilerSourcePath = absoluteSourcePath.replaceAll("\\", "/");
|
|
73010
|
+
const convertedSource = convertToTSX(sourceBuffer.toString("utf8"), {
|
|
73011
|
+
filename: compilerSourcePath,
|
|
73012
|
+
sourcemap: "external",
|
|
73013
|
+
includeScripts: true
|
|
73014
|
+
});
|
|
73015
|
+
if (astroFileIndex === 0) NFS.mkdirSync(astroSourcesDirectory, { recursive: true });
|
|
73016
|
+
const lintPath = Path.join(astroSourcesDirectory, `${astroFileIndex}.tsx`);
|
|
73017
|
+
const generatedBuffer = Buffer.from(convertedSource.code);
|
|
73018
|
+
NFS.writeFileSync(lintPath, generatedBuffer);
|
|
73019
|
+
lintFiles.push(candidateFile);
|
|
73020
|
+
lintFiles.push(lintPath);
|
|
73021
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
73022
|
+
sourceMapByLintPath.set(Path.resolve(lintPath), {
|
|
73023
|
+
traceMap: new TraceMap(JSON.stringify(convertedSource.map)),
|
|
73024
|
+
generatedBuffer,
|
|
73025
|
+
sourceBuffer
|
|
73026
|
+
});
|
|
73027
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
73028
|
+
astroFileIndex++;
|
|
73029
|
+
continue;
|
|
73030
|
+
}
|
|
73031
|
+
const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
|
|
73032
|
+
if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
|
|
73033
|
+
const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
|
|
73034
|
+
NFS.writeFileSync(lintPath, lintBuffer);
|
|
73035
|
+
lintFiles.push(lintPath);
|
|
73036
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
73037
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
73038
|
+
hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
|
|
73039
|
+
htmlFileIndex++;
|
|
73040
|
+
}
|
|
73041
|
+
return {
|
|
73042
|
+
lintFiles,
|
|
73043
|
+
sourcePathByLintPath,
|
|
73044
|
+
sourceMapByLintPath,
|
|
73045
|
+
sizeByLintPath,
|
|
73046
|
+
hasThreeModuleImport
|
|
73047
|
+
};
|
|
73048
|
+
};
|
|
71492
73049
|
/**
|
|
71493
73050
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
71494
73051
|
* the runner: once for the primary scan, once for the
|
|
@@ -71649,6 +73206,8 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
71649
73206
|
const runOxlint = async (options) => {
|
|
71650
73207
|
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
73208
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
73209
|
+
const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
73210
|
+
let unpluginAutoImportGlobalScopes = [];
|
|
71652
73211
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
71653
73212
|
validateRuleRegistration();
|
|
71654
73213
|
resetManifestCaches();
|
|
@@ -71662,21 +73221,6 @@ const runOxlint = async (options) => {
|
|
|
71662
73221
|
const pluginPath = resolvePluginPath();
|
|
71663
73222
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
71664
73223
|
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
73224
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
71681
73225
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
71682
73226
|
const configPath = Path.join(configDirectory, "oxlintrc.json");
|
|
@@ -71712,7 +73256,36 @@ const runOxlint = async (options) => {
|
|
|
71712
73256
|
await yieldToEventLoop();
|
|
71713
73257
|
const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
|
|
71714
73258
|
const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
|
|
73259
|
+
unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
|
|
73260
|
+
rootDirectory,
|
|
73261
|
+
candidateFiles
|
|
73262
|
+
});
|
|
73263
|
+
const preparedLintSources = prepareLintSources(rootDirectory, configDirectory, candidateFiles);
|
|
73264
|
+
const lintFiles = preparedLintSources.lintFiles;
|
|
73265
|
+
const hasPreparedFiles = preparedLintSources.sourcePathByLintPath.size > 0;
|
|
73266
|
+
const lintProject = !project.hasThree && preparedLintSources.hasThreeModuleImport ? {
|
|
73267
|
+
...project,
|
|
73268
|
+
hasThree: true
|
|
73269
|
+
} : project;
|
|
73270
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
73271
|
+
pluginPath,
|
|
73272
|
+
project: lintProject,
|
|
73273
|
+
customRulesOnly,
|
|
73274
|
+
extendsPaths: overrides.extendsPaths,
|
|
73275
|
+
ignoredTags,
|
|
73276
|
+
includedTags,
|
|
73277
|
+
includeTagDefaults,
|
|
73278
|
+
runtimeGlobals,
|
|
73279
|
+
unpluginAutoImportGlobalScopes,
|
|
73280
|
+
serverAuthFunctionNames,
|
|
73281
|
+
severityControls,
|
|
73282
|
+
userPlugins,
|
|
73283
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
73284
|
+
ruleSelection: overrides.ruleSelection,
|
|
73285
|
+
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
73286
|
+
});
|
|
71715
73287
|
const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
|
|
73288
|
+
if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedLintSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
|
|
71716
73289
|
const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
|
|
71717
73290
|
baseArgs: passBaseArgs,
|
|
71718
73291
|
files: passFiles,
|
|
@@ -71741,7 +73314,9 @@ const runOxlint = async (options) => {
|
|
|
71741
73314
|
fileBatches: passFileBatches,
|
|
71742
73315
|
rootDirectory,
|
|
71743
73316
|
nodeBinaryPath,
|
|
71744
|
-
project,
|
|
73317
|
+
project: lintProject,
|
|
73318
|
+
sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
|
|
73319
|
+
sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
|
|
71745
73320
|
onPartialFailure: reportPartialFailure,
|
|
71746
73321
|
onAnalyzedFiles: (filePaths) => {
|
|
71747
73322
|
analyzedFiles = filePaths;
|
|
@@ -71750,6 +73325,7 @@ const runOxlint = async (options) => {
|
|
|
71750
73325
|
spawnTimeoutMs,
|
|
71751
73326
|
outputMaxBytes,
|
|
71752
73327
|
concurrency: options.concurrency,
|
|
73328
|
+
spawnSlots: options.spawnSlots,
|
|
71753
73329
|
signal: options.signal,
|
|
71754
73330
|
deadlineEpochMs: options.deadlineEpochMs
|
|
71755
73331
|
});
|
|
@@ -71776,7 +73352,7 @@ const runOxlint = async (options) => {
|
|
|
71776
73352
|
};
|
|
71777
73353
|
}
|
|
71778
73354
|
};
|
|
71779
|
-
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
|
|
73355
|
+
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasPreparedFiles) {
|
|
71780
73356
|
const rulesetHash = computeRulesetHash({
|
|
71781
73357
|
config: buildConfig({
|
|
71782
73358
|
extendsPaths: [],
|
|
@@ -71934,14 +73510,16 @@ const runOxlint = async (options) => {
|
|
|
71934
73510
|
]);
|
|
71935
73511
|
}
|
|
71936
73512
|
const baseArgs = makeBaseArgs(configPath);
|
|
71937
|
-
const fileBatches = buildFileBatches(baseArgs,
|
|
73513
|
+
const fileBatches = buildFileBatches(baseArgs, lintFiles);
|
|
71938
73514
|
let analyzedFiles = [];
|
|
71939
73515
|
const runBatches = () => spawnLintBatches({
|
|
71940
73516
|
baseArgs,
|
|
71941
73517
|
fileBatches,
|
|
71942
73518
|
rootDirectory,
|
|
71943
73519
|
nodeBinaryPath,
|
|
71944
|
-
project,
|
|
73520
|
+
project: lintProject,
|
|
73521
|
+
sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
|
|
73522
|
+
sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
|
|
71945
73523
|
onPartialFailure,
|
|
71946
73524
|
onAnalyzedFiles: (filePaths) => {
|
|
71947
73525
|
analyzedFiles = filePaths;
|
|
@@ -71950,6 +73528,7 @@ const runOxlint = async (options) => {
|
|
|
71950
73528
|
spawnTimeoutMs,
|
|
71951
73529
|
outputMaxBytes,
|
|
71952
73530
|
concurrency: options.concurrency,
|
|
73531
|
+
spawnSlots: options.spawnSlots,
|
|
71953
73532
|
signal: options.signal,
|
|
71954
73533
|
deadlineEpochMs: options.deadlineEpochMs
|
|
71955
73534
|
});
|
|
@@ -72044,6 +73623,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
|
|
|
72044
73623
|
const spawnTimeoutMs = yield* OxlintSpawnTimeoutMs;
|
|
72045
73624
|
const outputMaxBytes = yield* OxlintOutputMaxBytes;
|
|
72046
73625
|
const concurrency = yield* OxlintConcurrency;
|
|
73626
|
+
const spawnSlots = yield* OxlintSpawnSlots;
|
|
72047
73627
|
const lintBatchOrdering = yield* LintBatchOrdering;
|
|
72048
73628
|
const perFileLintCacheEnabled = yield* PerFileLintCacheEnabled;
|
|
72049
73629
|
const sidecarLintCacheEnabled = yield* SidecarLintCacheEnabled;
|
|
@@ -72073,6 +73653,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
|
|
|
72073
73653
|
onSidecarStats: input.onSidecarStats,
|
|
72074
73654
|
spawnTimeoutMs,
|
|
72075
73655
|
outputMaxBytes,
|
|
73656
|
+
spawnSlots: spawnSlots ?? void 0,
|
|
72076
73657
|
concurrency,
|
|
72077
73658
|
signal,
|
|
72078
73659
|
lintBatchOrdering,
|
|
@@ -73290,10 +74871,14 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
73290
74871
|
materializedFiles.push(relativePath);
|
|
73291
74872
|
}
|
|
73292
74873
|
yield* sync(() => {
|
|
73293
|
-
for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
|
|
73294
|
-
const sourcePath = path.join(input.directory, configFilename);
|
|
73295
|
-
const targetPath = path.
|
|
73296
|
-
if (
|
|
74874
|
+
for (const subdirectory of ["", ...input.configSubdirectories ?? []]) for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
|
|
74875
|
+
const sourcePath = path.join(input.directory, subdirectory, configFilename);
|
|
74876
|
+
const targetPath = path.resolve(resolvedTempDirectory, subdirectory, configFilename);
|
|
74877
|
+
if (!isPathInsideDirectory(targetPath, resolvedTempDirectory)) continue;
|
|
74878
|
+
if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) {
|
|
74879
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
74880
|
+
fs.cpSync(sourcePath, targetPath);
|
|
74881
|
+
}
|
|
73297
74882
|
}
|
|
73298
74883
|
});
|
|
73299
74884
|
return {
|
|
@@ -73314,15 +74899,17 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
73314
74899
|
static layerNode = effect(StagedFiles, gen(function* () {
|
|
73315
74900
|
const git = yield* Git;
|
|
73316
74901
|
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({
|
|
74902
|
+
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries === null ? null : entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
|
|
74903
|
+
materialize: ({ directory, stagedFiles, tempDirectory, configSubdirectories }) => materializeSourceTree({
|
|
73319
74904
|
directory,
|
|
73320
74905
|
files: stagedFiles,
|
|
73321
74906
|
tempDirectory,
|
|
74907
|
+
configSubdirectories,
|
|
73322
74908
|
readContent: (relativePath) => git.showStagedContent(directory, relativePath, { maxBufferBytes: GIT_SHOW_MAX_BUFFER_BYTES })
|
|
73323
74909
|
}).pipe(map$3((tree) => ({
|
|
73324
74910
|
tempDirectory: tree.tempDirectory,
|
|
73325
74911
|
stagedFiles: tree.materializedFiles,
|
|
74912
|
+
unmaterializedFiles: tree.unmaterializedFiles,
|
|
73326
74913
|
cleanup: tree.cleanup
|
|
73327
74914
|
})), withSpan("StagedFiles.materialize"))
|
|
73328
74915
|
});
|
|
@@ -73337,6 +74924,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
73337
74924
|
materialize: ({ tempDirectory }) => succeed$2({
|
|
73338
74925
|
tempDirectory,
|
|
73339
74926
|
stagedFiles: snapshot.materializedFiles ?? snapshot.sourceFiles ?? [],
|
|
74927
|
+
unmaterializedFiles: [],
|
|
73340
74928
|
cleanup: () => {}
|
|
73341
74929
|
})
|
|
73342
74930
|
}));
|
|
@@ -73436,7 +75024,7 @@ const runEditorScan = async (input) => {
|
|
|
73436
75024
|
* other `clear*` helpers.
|
|
73437
75025
|
*/
|
|
73438
75026
|
const clearAutoSuppressionCaches = () => {};
|
|
73439
|
-
const lookupOwnRule = (rule) => Object.hasOwn(
|
|
75027
|
+
const lookupOwnRule = (rule) => Object.hasOwn(REACT_DOCTOR_RULE_REGISTRY, rule) ? REACT_DOCTOR_RULE_REGISTRY[rule] : void 0;
|
|
73440
75028
|
/**
|
|
73441
75029
|
* Returns presentation metadata for `<plugin>/<rule>`, or `null` when the
|
|
73442
75030
|
* rule is not part of the bundled react-doctor plugin (e.g. an adopted
|
|
@@ -73475,7 +75063,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
|
|
|
73475
75063
|
/** Display name used in client-facing messages and progress titles. */
|
|
73476
75064
|
const SERVER_DISPLAY_NAME = "React Doctor";
|
|
73477
75065
|
/** Server version reported in `serverInfo`; injected at build, `dev` from source. */
|
|
73478
|
-
const SERVER_VERSION = "0.9.
|
|
75066
|
+
const SERVER_VERSION = "0.9.2";
|
|
73479
75067
|
/** `Diagnostic.source` shown next to every published diagnostic. */
|
|
73480
75068
|
const DIAGNOSTIC_SOURCE = "react-doctor";
|
|
73481
75069
|
/**
|
|
@@ -73517,7 +75105,8 @@ const SCANNABLE_EXTENSIONS = [
|
|
|
73517
75105
|
".js",
|
|
73518
75106
|
".jsx",
|
|
73519
75107
|
".mts",
|
|
73520
|
-
".mjs"
|
|
75108
|
+
".mjs",
|
|
75109
|
+
".html"
|
|
73521
75110
|
];
|
|
73522
75111
|
const SILENT_LOGGER = {
|
|
73523
75112
|
info: () => {},
|
|
@@ -75168,11 +76757,13 @@ const METRIC = {
|
|
|
75168
76757
|
cliError: "cli.error",
|
|
75169
76758
|
cliEnvironmentError: "cli.env_error",
|
|
75170
76759
|
stagedSnapshotDivergence: "staged.snapshot_divergence",
|
|
76760
|
+
stagedPerProject: "staged.per_project",
|
|
75171
76761
|
projectDetected: "project.detected",
|
|
75172
76762
|
projectPathSelected: "project.path_selected",
|
|
75173
76763
|
projectConfigSelected: "project.config_selected",
|
|
75174
76764
|
scanCompleted: "scan.completed",
|
|
75175
76765
|
scanDuration: "scan.duration",
|
|
76766
|
+
scanFeedbackDelay: "scan.feedback_delay",
|
|
75176
76767
|
scanPhaseDuration: "scan.phase_duration",
|
|
75177
76768
|
scanFiles: "scan.files",
|
|
75178
76769
|
scanScore: "scan.score",
|
|
@@ -75204,6 +76795,10 @@ const METRIC = {
|
|
|
75204
76795
|
lspScanCompleted: "lsp.scan.completed",
|
|
75205
76796
|
lspScanDuration: "lsp.scan.duration",
|
|
75206
76797
|
lspScanDiagnostics: "lsp.scan.diagnostics",
|
|
76798
|
+
tuiActionMenuOpened: "tui.action_menu_opened",
|
|
76799
|
+
tuiCompactReportShown: "tui.compact_report_shown",
|
|
76800
|
+
tuiFindingNavigated: "tui.finding_navigated",
|
|
76801
|
+
tuiStackedReportCapped: "tui.stacked_report_capped",
|
|
75207
76802
|
aiTrainingWarningShown: "ai.training.warning_shown",
|
|
75208
76803
|
jsonOutUsed: "json.out_used"
|
|
75209
76804
|
};
|
|
@@ -75505,5 +77100,5 @@ const startLanguageServer = () => {
|
|
|
75505
77100
|
};
|
|
75506
77101
|
//#endregion
|
|
75507
77102
|
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]="
|
|
75509
|
-
//# debugId=
|
|
77103
|
+
!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]="ec49e114-f0f3-593d-b3c1-8b1a04d065a6")}catch(e){}}();
|
|
77104
|
+
//# debugId=ec49e114-f0f3-593d-b3c1-8b1a04d065a6
|