react-doctor 0.9.13-dev.ff7dd67 → 0.9.14-dev.922616f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/_react-doctor_require-typescript-DXQDYeWK.js +16 -0
  2. package/dist/{active-run-trace-dlIZeEvb.js → active-run-trace-Dewycxda.js} +3 -3
  3. package/dist/{active-scan-abort-registry-DwG6tSPy.js → active-scan-abort-registry-CCTgal0O.js} +3 -3
  4. package/dist/build-section-divider-CNFcGNYm.js +81 -0
  5. package/dist/{ci-ByM_SFTq.js → ci-CbTOIIel.js} +14 -13
  6. package/dist/cli.js +31 -30
  7. package/dist/constants-CW_854PH.js +1035 -0
  8. package/dist/constants-DNh19qg9.js +23 -0
  9. package/dist/{design-2hjOmtV1.js → design-CPav17ye.js} +4 -4
  10. package/dist/{devtools-CC2PAZ85.js → devtools-D20sefkm.js} +3 -3
  11. package/dist/duplicate-jsx-worker.d.ts +1 -0
  12. package/dist/duplicate-jsx-worker.js +636 -0
  13. package/dist/{exit-gracefully-niPFXq9Y.js → exit-gracefully-De_DePvj.js} +7 -7
  14. package/dist/fs-utils-C88IbqFa.js +45 -0
  15. package/dist/{get-east-asian-width-Bv2TD3Xj.js → get-east-asian-width-DRPy7dqz.js} +4 -4
  16. package/dist/{handle-error-D-4lexec.js → handle-error-B3GWdtbq.js} +6 -5
  17. package/dist/index.d.ts +8511 -8509
  18. package/dist/index.js +61693 -60580
  19. package/dist/{inspect-BrctG7ql.js → inspect-vT3G27FR.js} +38 -27
  20. package/dist/{install-CcFc56OK.js → install-C-_xdS80.js} +10 -9
  21. package/dist/{install-doctor-script-Coa2ErCg.js → install-doctor-script-BFv3Iiwe.js} +17 -8
  22. package/dist/{install-github-workflow-DlfdrYkQ.js → install-github-workflow-C-rhKOiP.js} +10 -10
  23. package/dist/{install-react-doctor-BWxqZMX-.js → install-react-doctor-BvU99j_I.js} +15 -11
  24. package/dist/is-cache-globally-disabled-CoHiYz2i.js +10 -0
  25. package/dist/{jsx-runtime-Njm7vAoN.js → jsx-runtime-CiJj554e.js} +11 -10
  26. package/dist/oxlint-worker.d.ts +1 -0
  27. package/dist/oxlint-worker.js +225 -0
  28. package/dist/{path-format-DnHpmJwG.js → path-format-By20mo8A.js} +3 -3
  29. package/dist/{print-branded-header-DFkeG4BS.js → print-branded-header-DJMuy9Hr.js} +4 -4
  30. package/dist/project-analysis-worker.js +461 -480
  31. package/dist/{prompt-runtime-scan-url-BenBNq25.js → prompt-runtime-scan-url-1YpMskOr.js} +6 -6
  32. package/dist/react-compiler-detection-worker.d.ts +1 -0
  33. package/dist/react-compiler-detection-worker.js +1029 -0
  34. package/dist/{read-object-file-CqMtxcfF.js → read-object-file-CWvQd5ls.js} +4 -4
  35. package/dist/{record-metric-Bkorhx43.js → record-metric-DSQY-qOh.js} +12998 -12770
  36. package/dist/{report-error-DPjmfRi9.js → report-error-C1g5jtl7.js} +9 -8
  37. package/dist/{report-workflow-result-CBL6CrLY.js → report-workflow-result-it0G879R.js} +24 -11
  38. package/dist/{resolve-scope-BFloAClV.js → resolve-scope-DmsEUxUn.js} +7 -7
  39. package/dist/{rules-BKNy9YIl.js → rules-BXkqekjc.js} +8 -7
  40. package/dist/{run-scan-app-Bc70ozp-.js → run-scan-app-wCfH8LdA.js} +30 -23
  41. package/dist/{runtime-scan-ODrdp5mV.js → runtime-scan-CXmDoQ2W.js} +13 -12
  42. package/dist/{sanitize-runtime-url-BYOmPSdm.js → sanitize-runtime-url-kA6U9dQF.js} +4 -4
  43. package/dist/{scan-BfcGHHkI.js → scan-Dd-VVq_7.js} +10 -9
  44. package/dist/{semver-DFtnEmN-.js → semver-BZIuy1gP.js} +3 -3
  45. package/dist/{should-fail-scan-gate-CCPDoHaM.js → should-fail-scan-gate-YK9VAFNu.js} +1339 -1283
  46. package/dist/{should-skip-prompts-D-ClPHHR.js → should-skip-prompts-SdC04R_e.js} +4 -4
  47. package/dist/{should-use-tui-BaCVIPPN.js → should-use-tui-D2fEl9q2.js} +4 -4
  48. package/dist/start-scan-preamble-D0QepYZ_.js +68 -0
  49. package/dist/start-scan-preamble-DVhXIPc0.d.ts +1 -0
  50. package/dist/start-scan-preamble.d.ts +1 -0
  51. package/dist/start-scan-preamble.js +4 -0
  52. package/dist/{telemetry-runtime-BGWa_GB9.js → telemetry-runtime-DOCJCTsL.js} +154 -5
  53. package/dist/{unref-stdin-SK3WfwxS.js → unref-stdin-D-NZBFpg.js} +3 -3
  54. package/dist/unwrap-typescript-expression-CrEPQUWz.js +14 -0
  55. package/dist/{version-DN1N-oZy.js → version-WpL8zILr.js} +5 -4
  56. package/dist/{why-CyioXUF2.js → why-CnQMoK2D.js} +4 -4
  57. package/dist/{with-run-span-GsCWW2_X.js → with-run-span-B0SMAP_Z.js} +7 -6
  58. package/package.json +9 -7
  59. package/dist/build-section-divider-BRuN44fL.js +0 -216
@@ -0,0 +1,1035 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7063ad56-037f-53c5-a0e5-2e75a803c2ef")}catch(e){}}();
3
+ import { createRequire } from "node:module";
4
+ import * as fs$1 from "node:fs";
5
+ import fs from "node:fs";
6
+ import * as path$1 from "node:path";
7
+ import { execFile, execFileSync, spawn } from "node:child_process";
8
+ import { fileURLToPath } from "node:url";
9
+ import * as os$1 from "node:os";
10
+ import os from "node:os";
11
+ import crypto from "node:crypto";
12
+ import { Worker } from "node:worker_threads";
13
+ import * as net from "node:net";
14
+ //#region ../core/dist/constants-BSFmmAxO.js
15
+ const HTML_FILE_PATTERN = /\.html$/i;
16
+ const SOURCE_FILE_PATTERN = /\.(?:astro|tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
17
+ const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
18
+ const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
19
+ const TAILWIND_POSTCSS7_COMPAT_ALIAS = "npm:@tailwindcss/postcss7-compat";
20
+ const MINIFIED_SNIFF_BYTES = 65536;
21
+ const GIT_LS_FILES_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
22
+ const GIT_SOURCE_LISTING_ARGUMENTS = [
23
+ "ls-files",
24
+ "-z",
25
+ "--stage",
26
+ "--others",
27
+ "--exclude-standard"
28
+ ];
29
+ const GIT_CHECK_ATTR_MAX_BUFFER_BYTES = GIT_LS_FILES_MAX_BUFFER_BYTES;
30
+ const SCANNED_DOT_DIRECTORIES = new Set([".dumi", ".storybook"]);
31
+ const IGNORED_DIRECTORIES = new Set([
32
+ ".angular",
33
+ ".astro",
34
+ ".cache",
35
+ ".contentlayer",
36
+ ".direnv",
37
+ ".docusaurus",
38
+ ".expo",
39
+ ".firebase",
40
+ ".git",
41
+ ".gradle",
42
+ ".hg",
43
+ ".next",
44
+ ".nuxt",
45
+ ".nx",
46
+ ".output",
47
+ ".parcel-cache",
48
+ ".serverless",
49
+ ".svelte-kit",
50
+ ".svn",
51
+ ".terraform",
52
+ ".turbo",
53
+ ".venv",
54
+ ".vercel",
55
+ ".wrangler",
56
+ ".yarn",
57
+ "build",
58
+ "coverage",
59
+ "dist",
60
+ "node_modules",
61
+ "out",
62
+ "storybook-static"
63
+ ]);
64
+ const JSX_FILE_PATTERN = /\.(tsx|jsx)$/;
65
+ const TYPESCRIPT_DECLARATION_FILE_PATTERN = /\.d\.(?:ts|mts|cts)$/;
66
+ const OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES = new Set([
67
+ "TS(1036)",
68
+ "TS(1038)",
69
+ "TS(1183)",
70
+ "TS(1319)"
71
+ ]);
72
+ const MILLISECONDS_PER_SECOND = 1e3;
73
+ const PROJECT_ANALYSIS_WORKER_TIMEOUT_MS = 12e4;
74
+ const PROJECT_ANALYSIS_WORKER_TIMEOUT_CEILING_MS = 6e5;
75
+ const PROJECT_ANALYSIS_WORKER_MAX_OLD_SPACE_MB = 8192;
76
+ const PROJECT_ANALYSIS_WORKER_MEMORY_BUDGET_BYTES = 2 * 1024 * 1024 * 1024;
77
+ const REACT_ROUTER_CAPABILITY_THRESHOLDS = [
78
+ {
79
+ capability: "react-router:6.4",
80
+ major: 6,
81
+ minor: 4
82
+ },
83
+ {
84
+ capability: "react-router:6.7",
85
+ major: 6,
86
+ minor: 7
87
+ },
88
+ {
89
+ capability: "react-router:6.9",
90
+ major: 6,
91
+ minor: 9
92
+ },
93
+ {
94
+ capability: "react-router:6.19",
95
+ major: 6,
96
+ minor: 19
97
+ },
98
+ {
99
+ capability: "react-router:7",
100
+ major: 7,
101
+ minor: 0
102
+ },
103
+ {
104
+ capability: "react-router:7.8",
105
+ major: 7,
106
+ minor: 8
107
+ },
108
+ {
109
+ capability: "react-router:7.9",
110
+ major: 7,
111
+ minor: 9
112
+ },
113
+ {
114
+ capability: "react-router:7.10",
115
+ major: 7,
116
+ minor: 10
117
+ },
118
+ {
119
+ capability: "react-router:7.15",
120
+ major: 7,
121
+ minor: 15
122
+ },
123
+ {
124
+ capability: "react-router:8",
125
+ major: 8,
126
+ minor: 0
127
+ }
128
+ ];
129
+ const SCORE_API_URL = "https://www.react.doctor/api/score";
130
+ const AXIOM_DEFAULT_DOMAIN = "https://api.axiom.co";
131
+ const AXIOM_TRACES_PATH = "/v1/traces";
132
+ const AXIOM_METRICS_PATH = "/v1/metrics";
133
+ const AXIOM_DATASET_HEADER = "X-Axiom-Dataset";
134
+ const AXIOM_METRICS_DATASET_HEADER = "x-axiom-metrics-dataset";
135
+ const TELEMETRY_EXPORT_INTERVAL_MS = 6e5;
136
+ const TELEMETRY_SHUTDOWN_TIMEOUT_MS = 1e3;
137
+ const ENTERPRISE_CONTACT_URL = "https://react.doctor/enterprise";
138
+ const SHARE_BASE_URL = "https://react.doctor/share";
139
+ const CI_URL = "https://react.doctor/ci";
140
+ const GITHUB_ACTIONS_SETUP_URL = "https://www.react.doctor/docs/ci-and-prs/github-actions-setup";
141
+ const DOCS_URL = "https://react.doctor/docs";
142
+ const DOCS_RULES_BASE_URL = `${DOCS_URL}/rules`;
143
+ const CONFIG_SCHEMA_URL = "https://react.doctor/schema/config.json";
144
+ const FETCH_TIMEOUT_MS = 1e4;
145
+ const GITHUB_VIEWER_PERMISSION_TIMEOUT_MS = 2e3;
146
+ const SPAWN_ARGS_MAX_LENGTH_CHARS = 24e3;
147
+ const SPAWN_ARGS_MAX_LENGTH_CHARS_POSIX = 15e5;
148
+ const SPAWN_ARGS_MAX_LENGTH_CHARS_DARWIN = 8e5;
149
+ const NODE_VERSION_PROBE_TIMEOUT_MS = 5e3;
150
+ const PER_WORKER_MEM_BUDGET_BYTES = 1024 * 1024 * 1024;
151
+ const DEFAULT_BRANCH_CANDIDATES = ["main", "master"];
152
+ const ADOPTABLE_LINT_CONFIG_FILENAMES = [".oxlintrc.json", ".eslintrc.json"];
153
+ const OXLINT_NODE_REQUIREMENT = "^20.19.0 || >=22.12.0";
154
+ const GIT_SHOW_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
155
+ const UNKNOWN_FUTURE_ES_YEAR = 9999;
156
+ const TARGET_BLANK_BROWSER_SUPPORT = [
157
+ {
158
+ browserName: "chrome",
159
+ supportsTargetBlankBrowsingContext: true,
160
+ explicitNoreferrerVersion: 16,
161
+ explicitNoopenerVersion: 49,
162
+ implicitNoopenerVersion: 88
163
+ },
164
+ {
165
+ browserName: "and_chr",
166
+ supportsTargetBlankBrowsingContext: true,
167
+ explicitNoreferrerVersion: 16,
168
+ explicitNoopenerVersion: 49,
169
+ implicitNoopenerVersion: 88
170
+ },
171
+ {
172
+ browserName: "android",
173
+ supportsTargetBlankBrowsingContext: true,
174
+ explicitNoreferrerVersion: 2.3,
175
+ explicitNoopenerVersion: 49,
176
+ implicitNoopenerVersion: 88
177
+ },
178
+ {
179
+ browserName: "edge",
180
+ supportsTargetBlankBrowsingContext: true,
181
+ explicitNoreferrerVersion: 13,
182
+ explicitNoopenerVersion: 79,
183
+ implicitNoopenerVersion: 88
184
+ },
185
+ {
186
+ browserName: "firefox",
187
+ supportsTargetBlankBrowsingContext: true,
188
+ explicitNoreferrerVersion: 33,
189
+ explicitNoopenerVersion: 52,
190
+ implicitNoopenerVersion: 79
191
+ },
192
+ {
193
+ browserName: "and_ff",
194
+ supportsTargetBlankBrowsingContext: true,
195
+ explicitNoreferrerVersion: 33,
196
+ explicitNoopenerVersion: 52,
197
+ implicitNoopenerVersion: 79
198
+ },
199
+ {
200
+ browserName: "kaios",
201
+ supportsTargetBlankBrowsingContext: true,
202
+ explicitNoreferrerVersion: 2.5,
203
+ explicitNoopenerVersion: 3,
204
+ implicitNoopenerVersion: 3
205
+ },
206
+ {
207
+ browserName: "safari",
208
+ supportsTargetBlankBrowsingContext: true,
209
+ explicitNoreferrerVersion: 5,
210
+ explicitNoopenerVersion: 10.1,
211
+ implicitNoopenerVersion: 12.1
212
+ },
213
+ {
214
+ browserName: "ios_saf",
215
+ supportsTargetBlankBrowsingContext: true,
216
+ explicitNoreferrerVersion: 4,
217
+ explicitNoopenerVersion: 10.3,
218
+ implicitNoopenerVersion: 12.2
219
+ },
220
+ {
221
+ browserName: "opera",
222
+ supportsTargetBlankBrowsingContext: true,
223
+ explicitNoreferrerVersion: 15,
224
+ explicitNoopenerVersion: 36,
225
+ implicitNoopenerVersion: 74
226
+ },
227
+ {
228
+ browserName: "op_mob",
229
+ supportsTargetBlankBrowsingContext: true,
230
+ explicitNoreferrerVersion: 80,
231
+ explicitNoopenerVersion: 80,
232
+ implicitNoopenerVersion: 80
233
+ },
234
+ {
235
+ browserName: "op_mini",
236
+ supportsTargetBlankBrowsingContext: false,
237
+ explicitNoreferrerVersion: null,
238
+ explicitNoopenerVersion: null,
239
+ implicitNoopenerVersion: null
240
+ },
241
+ {
242
+ browserName: "samsung",
243
+ supportsTargetBlankBrowsingContext: true,
244
+ explicitNoreferrerVersion: 4,
245
+ explicitNoopenerVersion: 5,
246
+ implicitNoopenerVersion: 15
247
+ },
248
+ {
249
+ browserName: "and_uc",
250
+ supportsTargetBlankBrowsingContext: true,
251
+ explicitNoreferrerVersion: 15.5,
252
+ explicitNoopenerVersion: 15.5,
253
+ implicitNoopenerVersion: null
254
+ },
255
+ {
256
+ browserName: "and_qq",
257
+ supportsTargetBlankBrowsingContext: true,
258
+ explicitNoreferrerVersion: 14.9,
259
+ explicitNoopenerVersion: 14.9,
260
+ implicitNoopenerVersion: null
261
+ },
262
+ {
263
+ browserName: "baidu",
264
+ supportsTargetBlankBrowsingContext: true,
265
+ explicitNoreferrerVersion: 13.52,
266
+ explicitNoopenerVersion: 13.52,
267
+ implicitNoopenerVersion: null
268
+ },
269
+ {
270
+ browserName: "ie",
271
+ supportsTargetBlankBrowsingContext: true,
272
+ explicitNoreferrerVersion: null,
273
+ explicitNoopenerVersion: null,
274
+ implicitNoopenerVersion: null
275
+ },
276
+ {
277
+ browserName: "ie_mob",
278
+ supportsTargetBlankBrowsingContext: true,
279
+ explicitNoreferrerVersion: null,
280
+ explicitNoopenerVersion: null,
281
+ implicitNoopenerVersion: null
282
+ }
283
+ ];
284
+ const ES_TARGET_YEAR_BY_NAME = {
285
+ es3: 1999,
286
+ es5: 2009,
287
+ es6: 2015,
288
+ es2015: 2015,
289
+ es2016: 2016,
290
+ es2017: 2017,
291
+ es2018: 2018,
292
+ es2019: 2019,
293
+ es2020: 2020,
294
+ es2021: 2021,
295
+ es2022: 2022,
296
+ es2023: 2023,
297
+ es2024: 2024,
298
+ es2025: 2025,
299
+ esnext: UNKNOWN_FUTURE_ES_YEAR
300
+ };
301
+ /**
302
+ * tsconfig filenames probed when resolving a project's TypeScript
303
+ * compiler options — the root config first, then a monorepo base config.
304
+ */
305
+ const TSCONFIG_FILENAMES = ["tsconfig.json", "tsconfig.base.json"];
306
+ const DISABLE_DIRECTIVE_BACKUP_DIRECTORY_SEGMENTS = [".react-doctor", "audit-backups"];
307
+ /**
308
+ * Project-config files that `StagedFiles.materialize` copies into
309
+ * the temp directory alongside staged sources so oxlint resolves
310
+ * `tsconfig` / `package.json` / lint configs the same way it would
311
+ * in the working tree. Hoisted out of the staged-files helper so
312
+ * the constant lives next to the rest of the IO budget knobs.
313
+ */
314
+ const STAGED_FILES_PROJECT_CONFIG_FILENAMES = [
315
+ "tsconfig.json",
316
+ "tsconfig.base.json",
317
+ "package.json",
318
+ "doctor.config.ts",
319
+ "doctor.config.mts",
320
+ "doctor.config.cts",
321
+ "doctor.config.js",
322
+ "doctor.config.mjs",
323
+ "doctor.config.cjs",
324
+ "doctor.config.json",
325
+ "doctor.config.jsonc",
326
+ "oxlint.json",
327
+ ".oxlintrc.json"
328
+ ];
329
+ const CONFIG_FINGERPRINT_FILENAMES = [
330
+ "doctor.config.ts",
331
+ "doctor.config.mts",
332
+ "doctor.config.cts",
333
+ "doctor.config.js",
334
+ "doctor.config.mjs",
335
+ "doctor.config.cjs",
336
+ "doctor.config.json",
337
+ "doctor.config.jsonc",
338
+ "react-doctor.config.json",
339
+ "package.json",
340
+ "pnpm-workspace.yaml",
341
+ "tsconfig.json",
342
+ "tsconfig.base.json",
343
+ ".oxlintrc.json",
344
+ ".eslintrc.json",
345
+ "pnpm-lock.yaml",
346
+ "package-lock.json",
347
+ "yarn.lock",
348
+ "bun.lock",
349
+ "bun.lockb",
350
+ ".gitignore"
351
+ ];
352
+ const CANONICAL_GITHUB_URL = "https://github.com/millionco/react-doctor";
353
+ const CANONICAL_DISCORD_URL = "https://react.doctor/discord";
354
+ const SKILL_NAME = "react-doctor";
355
+ const OXLINT_OUTPUT_MAX_BYTES = 50 * 1024 * 1024;
356
+ const OXLINT_SPAWN_TIMEOUT_MS = 6e4;
357
+ const NODE_COMPILE_CACHE_DIR_NAME = "node-compile-cache";
358
+ const OXLINT_SPLIT_TOTAL_BUDGET_MS = 18e4;
359
+ const ABORT_EXIT_CODES = new Set([134, 3221226505]);
360
+ const OXLINT_WORKER_JOB_END_MARKER = "__REACT_DOCTOR_OXLINT_JOB_END__";
361
+ const DUPLICATE_JSX_WORKER_IDLE_TIMEOUT_MS = 3e4;
362
+ const REACT_COMPILER_DETECTION_WORKER_IDLE_TIMEOUT_MS = 3e4;
363
+ const OXLINT_WORKER_TURBOFAN_INVOCATION_COUNT = 3e4;
364
+ const OXLINT_WORKER_OLD_SPACE_MB_PER_NATIVE_THREAD = 4352;
365
+ const OXLINT_OOM_RESCUE_BUDGET_MS = 6e4;
366
+ const RECOMMENDED_PNPM_MINIMUM_RELEASE_AGE_MINUTES = 10080;
367
+ const REACT_SERVER_DOM_PACKAGES = [
368
+ "react-server-dom-webpack",
369
+ "react-server-dom-parcel",
370
+ "react-server-dom-turbopack"
371
+ ];
372
+ const REACT_BLOG_RSC_ADVISORY_URL = "https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components";
373
+ const VERCEL_NEXTJS_SECURITY_RELEASE_URL = "https://vercel.com/changelog/next-js-may-2026-security-release";
374
+ const DIAGNOSTIC_CATEGORY_BUCKETS = [
375
+ "Security",
376
+ "Bugs",
377
+ "Performance",
378
+ "Accessibility",
379
+ "Maintainability"
380
+ ];
381
+ const OCCURRENCE_MATCHED_CATEGORIES = new Set(["Accessibility"]);
382
+ const CATEGORY_IMPACT_BY_NAME = new Map(Object.entries({
383
+ Security: "An attacker can read user data, act as your users, or run code you never shipped.",
384
+ Bugs: "Real users hit crashes, wrong output, or state that silently corrupts.",
385
+ Performance: "Users feel extra latency and wasted renders on every interaction.",
386
+ Accessibility: "Users on screen readers, keyboards, or assistive tech get locked out.",
387
+ Maintainability: "Every future change gets slower and riskier to make."
388
+ }));
389
+ const getCategoryImpact = (category) => CATEGORY_IMPACT_BY_NAME.get(category);
390
+ const APP_ONLY_RULE_KEYS = new Set([
391
+ "react-hooks-js/static-components",
392
+ "react-doctor/no-render-prop-children",
393
+ "react-doctor/prefer-explicit-variants"
394
+ ]);
395
+ const COMPILER_CLEANUP_BUCKET = "compiler-cleanup";
396
+ const COMPILER_CLEANUP_RULE_KEYS = new Set(["react-doctor/react-compiler-no-manual-memoization"]);
397
+ const ROOT_CAUSE_GROUPABLE_RULE_KEYS = new Set([
398
+ "react-doctor/no-derived-state",
399
+ "react-doctor/no-derived-state-effect",
400
+ "react-doctor/no-derived-useState",
401
+ "react-doctor/no-adjust-state-on-prop-change",
402
+ "react-doctor/no-reset-all-state-on-prop-change"
403
+ ]);
404
+ const MAX_GLOB_PATTERN_LENGTH_CHARS = 1024;
405
+ const CONFIG_CACHE_TTL_MS = 300 * 1e3;
406
+ const SOCKET_FREE_PURL_API_BASE = "https://firewall-api.socket.dev/purl";
407
+ const SOCKET_PACKAGE_PAGE_BASE = "https://socket.dev/npm/package";
408
+ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
409
+ const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
410
+ const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
411
+ const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
412
+ const SUPPLY_CHAIN_PLUGIN = "socket";
413
+ const SUPPLY_CHAIN_RULE = "low-supply-chain-score";
414
+ const SUPPLY_CHAIN_CATEGORY = "Security";
415
+ const SUPPLY_CHAIN_OVERLAP_TIMEOUT_MS = 9e4;
416
+ const SUPPLY_CHAIN_CACHE_TTL_MS = 864e5;
417
+ const SUPPLY_CHAIN_CACHE_SUBDIR = "supply-chain";
418
+ const SUPPLY_CHAIN_IGNORED_PACKAGES = new Set(["next"]);
419
+ const JSX_DUPLICATION_SOURCE_FILE_PATTERN = /\.[cm]?(?:jsx?|tsx)$/;
420
+ const MAINTAINABILITY_SOURCE_FILE_PATTERN = /\.[cm]?[jt]sx?$/;
421
+ const MAINTAINABILITY_PLUGIN = "react-doctor";
422
+ const MAINTAINABILITY_DUPLICATE_JSX_RULE = "duplicate-jsx-subtree";
423
+ const MAINTAINABILITY_CATEGORY = "Maintainability";
424
+ //#endregion
425
+ //#region ../core/dist/react-compiler-detection-worker-protocol-Dp5LlrE8.js
426
+ const isReactCompilerDetectionReply = (value) => typeof value === "object" && value !== null && "id" in value && typeof value.id === "number" && "hasReactCompiler" in value && (typeof value.hasReactCompiler === "boolean" || value.hasReactCompiler === null);
427
+ //#endregion
428
+ //#region ../core/dist/react-compiler-detection-client-oLGVwDHK.js
429
+ const pendingOutputsByRequestKey = /* @__PURE__ */ new Map();
430
+ const toRequestKey = (request) => [
431
+ request.directory,
432
+ String(request.maxBufferBytes),
433
+ ...request.args
434
+ ].join("\0");
435
+ const runGitCommand = (request, signal) => new Promise((resolve) => {
436
+ execFile("git", [...request.args], {
437
+ cwd: request.directory,
438
+ encoding: "utf-8",
439
+ killSignal: "SIGKILL",
440
+ maxBuffer: request.maxBufferBytes,
441
+ signal
442
+ }, (error, stdout) => resolve(error ? null : stdout));
443
+ });
444
+ const prefetchGitCommand = (request) => {
445
+ const requestKey = toRequestKey(request);
446
+ if (pendingOutputsByRequestKey.has(requestKey)) return;
447
+ pendingOutputsByRequestKey.set(requestKey, runGitCommand(request));
448
+ };
449
+ const takePrefetchedGitCommand = (request) => {
450
+ const requestKey = toRequestKey(request);
451
+ const pendingOutput = pendingOutputsByRequestKey.get(requestKey) ?? null;
452
+ if (pendingOutput !== null) pendingOutputsByRequestKey.delete(requestKey);
453
+ return pendingOutput;
454
+ };
455
+ /** The prefetched output when the identical command was started early, otherwise a fresh run. */
456
+ const resolveGitCommand = (request, signal) => takePrefetchedGitCommand(request) ?? runGitCommand(request, signal);
457
+ const discardPrefetchedGitCommands = () => {
458
+ pendingOutputsByRequestKey.clear();
459
+ };
460
+ const buildGitSourceListingRequest = (directory) => ({
461
+ directory,
462
+ args: GIT_SOURCE_LISTING_ARGUMENTS,
463
+ maxBufferBytes: GIT_LS_FILES_MAX_BUFFER_BYTES
464
+ });
465
+ const CGROUP_V2_MEMORY_MAX_PATH = "/sys/fs/cgroup/memory.max";
466
+ const CGROUP_V1_MEMORY_LIMIT_PATH = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
467
+ const CGROUP_UNLIMITED_SENTINEL_BYTES = Number.MAX_SAFE_INTEGER;
468
+ /**
469
+ * Parses one raw cgroup memory-limit file value into a positive byte count, or
470
+ * `undefined` when it represents "no limit" (the v2 `"max"` literal, an empty
471
+ * read, a non-positive / non-finite value, or v1's near-2^63 unlimited
472
+ * sentinel). Pure and exported so the classification is unit-testable without
473
+ * touching the filesystem.
474
+ */
475
+ const parseCgroupMemoryLimitBytes = (raw) => {
476
+ if (raw === void 0) return void 0;
477
+ const trimmed = raw.trim();
478
+ if (trimmed === "" || trimmed === "max") return void 0;
479
+ const parsed = Number(trimmed);
480
+ if (!Number.isFinite(parsed) || parsed <= 0 || parsed >= CGROUP_UNLIMITED_SENTINEL_BYTES) return;
481
+ return parsed;
482
+ };
483
+ const CGROUP_MEMORY_LIMIT_PATHS = [CGROUP_V2_MEMORY_MAX_PATH, CGROUP_V1_MEMORY_LIMIT_PATH];
484
+ /**
485
+ * Reads this process's cgroup memory limit in bytes from the first candidate
486
+ * path that yields a real limit, or `undefined` when none does — no cgroup, no
487
+ * limit, or the files are unreadable (e.g. macOS / Windows dev machines).
488
+ * `os.totalmem()` reports the HOST total and ignores cgroup memory limits, so a
489
+ * memory-constrained container over-reports total memory; `resolveAutoScan-
490
+ * Concurrency` takes `min(totalmem, this)` to honor the limit.
491
+ *
492
+ * The cgroup v2 read is the mount-root `memory.max`, which IS the container's
493
+ * limit under the standard cgroup-namespace setup CI runners use (the
494
+ * container's own cgroup is the root of its namespaced view). A process in a
495
+ * non-namespaced nested/delegated cgroup whose root reads `"max"` is not
496
+ * detected here and falls back to the host total; the EAGAIN/ENOMEM serial
497
+ * replay in `spawnLintBatches` remains the runtime backstop for that case.
498
+ *
499
+ * `candidatePaths` is injectable so tests exercise the v2-wins-over-v1
500
+ * precedence, the skip-unreadable fallback, and the all-missing case without a
501
+ * real `/sys/fs/cgroup`.
502
+ */
503
+ const readCgroupMemoryLimitBytes = (candidatePaths = CGROUP_MEMORY_LIMIT_PATHS) => {
504
+ for (const limitPath of candidatePaths) {
505
+ let raw;
506
+ try {
507
+ raw = fs.readFileSync(limitPath, "utf8");
508
+ } catch {
509
+ continue;
510
+ }
511
+ const limitBytes = parseCgroupMemoryLimitBytes(raw);
512
+ if (limitBytes !== void 0) return limitBytes;
513
+ }
514
+ };
515
+ const readSystemConcurrencyFacts = () => ({
516
+ availableCores: os.availableParallelism(),
517
+ totalMemoryBytes: os.totalmem(),
518
+ cgroupMemoryLimitBytes: readCgroupMemoryLimitBytes()
519
+ });
520
+ /**
521
+ * Clamps a requested lint worker count to `[MIN_SCAN_CONCURRENCY,
522
+ * HARD_MAX_SCAN_CONCURRENCY]` as a finite integer. This is the explicit-pin and
523
+ * spawn-boundary clamp — the memory-and-core-budgeted auto count comes from
524
+ * `resolveAutoScanConcurrency`. Out-of-range or non-finite requests degrade to
525
+ * `MIN_SCAN_CONCURRENCY` rather than oversubscribing or running zero workers.
526
+ */
527
+ const resolveScanConcurrency = (requested) => {
528
+ if (!Number.isFinite(requested) || requested < 1) return 1;
529
+ return Math.min(Math.floor(requested), 32);
530
+ };
531
+ /**
532
+ * Auto lint-worker count: the smaller of the (cgroup-CPU-aware) core count and
533
+ * the number of `PER_WORKER_MEM_BUDGET_BYTES` workers that fit in available
534
+ * memory, and the measured automatic parallel-efficiency ceiling, then clamped
535
+ * to `[MIN, HARD_MAX]` by `resolveScanConcurrency`.
536
+ *
537
+ * `os.availableParallelism()` already respects cgroup CPU quotas, so the core
538
+ * term needs no help. Available memory is `os.totalmem()` floored by the cgroup
539
+ * memory limit — `os.freemem()` is deliberately NOT used: it excludes
540
+ * reclaimable page cache and reads near-zero on macOS / cache-heavy Linux, which
541
+ * would collapse the auto path to a single worker. `os.totalmem()` reports the
542
+ * host total even inside a container, so the cgroup limit (read directly,
543
+ * because Node doesn't fold it into `totalmem()`) is the real ceiling there.
544
+ *
545
+ * `facts` is injectable so tests exercise core-bound, memory-bound, cgroup-
546
+ * limited, and ceiling cases without mocking `os` or the filesystem.
547
+ */
548
+ const resolveAutoScanConcurrency = (facts = readSystemConcurrencyFacts()) => {
549
+ const availableMemoryBytes = Math.min(facts.totalMemoryBytes, facts.cgroupMemoryLimitBytes ?? Number.POSITIVE_INFINITY);
550
+ const memoryBoundedWorkers = Math.floor(availableMemoryBytes / PER_WORKER_MEM_BUDGET_BYTES);
551
+ return resolveScanConcurrency(Math.min(facts.availableCores, memoryBoundedWorkers, 10));
552
+ };
553
+ const resolveConfiguredScanConcurrency = () => {
554
+ const raw = process.env["REACT_DOCTOR_PARALLEL"];
555
+ if (raw === void 0) return resolveAutoScanConcurrency();
556
+ const normalized = raw.trim().toLowerCase();
557
+ if (normalized === "0" || normalized === "false" || normalized === "off") return 1;
558
+ const parsed = Number.parseInt(normalized, 10);
559
+ if (Number.isInteger(parsed) && parsed > 0) return resolveScanConcurrency(parsed);
560
+ return resolveAutoScanConcurrency();
561
+ };
562
+ const buildOxlintChildEnv = (sourceEnv) => {
563
+ const childEnv = {};
564
+ for (const [name, value] of Object.entries(sourceEnv)) {
565
+ if (name === "NODE_OPTIONS" || name === "NODE_DEBUG") continue;
566
+ if (name.startsWith("npm_config_")) continue;
567
+ childEnv[name] = value;
568
+ }
569
+ const isCompileCacheDisabled = Boolean(sourceEnv.NODE_DISABLE_COMPILE_CACHE);
570
+ const isCompileCacheAlreadySet = childEnv.NODE_COMPILE_CACHE !== void 0;
571
+ if (!isCompileCacheDisabled && !isCompileCacheAlreadySet) childEnv.NODE_COMPILE_CACHE = path$1.join(os.tmpdir(), NODE_COMPILE_CACHE_DIR_NAME);
572
+ return childEnv;
573
+ };
574
+ const setStreamRef = (stream, shouldRef) => {
575
+ if (!(stream instanceof net.Socket)) return;
576
+ if (shouldRef) stream.ref();
577
+ else stream.unref();
578
+ };
579
+ const setChildProcessRef = (child, shouldRef) => {
580
+ if (shouldRef) {
581
+ child.ref();
582
+ child.channel?.ref();
583
+ } else {
584
+ child.unref();
585
+ child.channel?.unref();
586
+ }
587
+ setStreamRef(child.stdout, shouldRef);
588
+ setStreamRef(child.stderr, shouldRef);
589
+ };
590
+ const NODE_VERSION_PATTERN = /^v(\d+)\./;
591
+ const supportsTieringFlags = (childNodeVersion) => {
592
+ const match = NODE_VERSION_PATTERN.exec(childNodeVersion);
593
+ return match !== null && Number(match[1]) >= 22;
594
+ };
595
+ const buildOxlintWorkerNodeArguments = ({ childNodeVersion, nativeThreadCount }) => [`--max-old-space-size=${nativeThreadCount * OXLINT_WORKER_OLD_SPACE_MB_PER_NATIVE_THREAD}`, ...supportsTieringFlags(childNodeVersion) ? [`--invocation-count-for-turbofan=${OXLINT_WORKER_TURBOFAN_INVOCATION_COUNT}`] : []];
596
+ const lowerChildProcessPriority = (processId) => {
597
+ if (processId === void 0) return;
598
+ try {
599
+ os$1.setPriority(processId, os$1.constants.priority.PRIORITY_BELOW_NORMAL);
600
+ } catch {}
601
+ };
602
+ const resolveOxlintThreadCount = (workerCount, availableCores = os.availableParallelism()) => Math.max(1, Math.floor(availableCores / workerCount));
603
+ const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
604
+ const fingerprintFileContents = (filePath, fingerprintLength) => {
605
+ const fileStats = fs$1.statSync(filePath, { bigint: true });
606
+ const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
607
+ if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
608
+ const fingerprint = crypto.createHash("sha256").update(fs$1.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
609
+ fingerprintCacheByFilePath.set(filePath, {
610
+ fingerprint,
611
+ modifiedTimeNanoseconds: fileStats.mtimeNs,
612
+ sizeBytes: fileStats.size
613
+ });
614
+ return fingerprint;
615
+ };
616
+ const bundledRequire = createRequire(import.meta.url);
617
+ const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
618
+ const resolveChildNodeVersion = (nodeBinaryPath) => {
619
+ if (nodeBinaryPath === process.execPath) return process.version;
620
+ const cachedVersion = childNodeVersionByBinaryPath.get(nodeBinaryPath);
621
+ if (cachedVersion !== void 0) return cachedVersion;
622
+ let version;
623
+ try {
624
+ version = execFileSync(nodeBinaryPath, ["--version"], {
625
+ encoding: "utf8",
626
+ timeout: NODE_VERSION_PROBE_TIMEOUT_MS
627
+ }).trim();
628
+ } catch {
629
+ version = `unknown:${nodeBinaryPath}`;
630
+ }
631
+ childNodeVersionByBinaryPath.set(nodeBinaryPath, version);
632
+ return version;
633
+ };
634
+ const TOOLCHAIN_PACKAGE_SPECIFIERS = [
635
+ "oxlint/package.json",
636
+ "oxlint-plugin-react-doctor/package.json",
637
+ "eslint-plugin-react-hooks/package.json"
638
+ ];
639
+ const resolvePluginFingerprint = () => {
640
+ try {
641
+ return fingerprintFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor"), 16);
642
+ } catch {
643
+ return "unresolved";
644
+ }
645
+ };
646
+ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
647
+ const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
648
+ for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
649
+ const packageJson = bundledRequire(specifier);
650
+ const version = typeof packageJson.version === "string" ? packageJson.version : "unknown";
651
+ versions.push(`${specifier}=${version}`);
652
+ } catch {
653
+ versions.push(`${specifier}=missing`);
654
+ }
655
+ versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
656
+ return versions;
657
+ };
658
+ const prespawnedBySpecKey = /* @__PURE__ */ new Map();
659
+ const buildOxlintWorkerSpawnSpec = (input) => ({
660
+ nodeBinaryPath: input.nodeBinaryPath,
661
+ args: [
662
+ ...buildOxlintWorkerNodeArguments({
663
+ childNodeVersion: resolveChildNodeVersion(input.nodeBinaryPath),
664
+ nativeThreadCount: resolveOxlintThreadCount(input.maxWorkers)
665
+ }),
666
+ input.workerScriptPath,
667
+ input.oxlintPackageDirectory,
668
+ ...input.pluginPath === null ? [] : [input.pluginPath]
669
+ ],
670
+ environment: input.environment
671
+ });
672
+ const toSpecKey = (spec) => JSON.stringify([
673
+ spec.nodeBinaryPath,
674
+ spec.args,
675
+ Object.entries(spec.environment).sort(([firstName], [secondName]) => firstName.localeCompare(secondName))
676
+ ]);
677
+ const spawnOxlintWorkerProcess = (spec) => {
678
+ const child = spawn(spec.nodeBinaryPath, [...spec.args], {
679
+ env: spec.environment,
680
+ stdio: [
681
+ "ignore",
682
+ "pipe",
683
+ "pipe",
684
+ "ipc"
685
+ ],
686
+ windowsHide: true
687
+ });
688
+ lowerChildProcessPriority(child.pid);
689
+ return child;
690
+ };
691
+ const prespawnOne = (spec) => {
692
+ const child = spawnOxlintWorkerProcess(spec);
693
+ const onMessage = (message) => {
694
+ if (record.bootMessage === null) record.bootMessage = message;
695
+ };
696
+ const onError = (error) => {
697
+ if (record.spawnError === null) record.spawnError = error;
698
+ };
699
+ const onClose = (code, signal) => {
700
+ record.exit = {
701
+ code,
702
+ signal
703
+ };
704
+ };
705
+ const record = {
706
+ child,
707
+ bootMessage: null,
708
+ spawnError: null,
709
+ exit: null,
710
+ detach: () => {
711
+ child.off("message", onMessage);
712
+ child.off("error", onError);
713
+ child.off("close", onClose);
714
+ }
715
+ };
716
+ child.on("message", onMessage);
717
+ child.on("error", onError);
718
+ child.on("close", onClose);
719
+ setChildProcessRef(child, false);
720
+ return record;
721
+ };
722
+ const prespawnOxlintWorkers = (spec, count) => {
723
+ const specKey = toSpecKey(spec);
724
+ const records = prespawnedBySpecKey.get(specKey) ?? [];
725
+ while (records.length < count) records.push(prespawnOne(spec));
726
+ prespawnedBySpecKey.set(specKey, records);
727
+ };
728
+ const killUnadoptedOxlintWorkers = () => {
729
+ for (const records of prespawnedBySpecKey.values()) for (const record of records) {
730
+ record.detach();
731
+ record.child.kill("SIGKILL");
732
+ }
733
+ prespawnedBySpecKey.clear();
734
+ };
735
+ const takePrespawnedOxlintWorker = (spec) => {
736
+ const record = prespawnedBySpecKey.get(toSpecKey(spec))?.shift();
737
+ if (record === void 0) return null;
738
+ record.detach();
739
+ setChildProcessRef(record.child, true);
740
+ return record;
741
+ };
742
+ const esmRequire = createRequire(import.meta.url);
743
+ const resolveOxlintPackageDirectory = () => {
744
+ const oxlintMainPath = esmRequire.resolve("oxlint");
745
+ return path$1.resolve(path$1.dirname(oxlintMainPath), "..");
746
+ };
747
+ const resolveOxlintBinary = () => path$1.join(resolveOxlintPackageDirectory(), "bin", "oxlint");
748
+ const resolvePluginPath = () => esmRequire.resolve("oxlint-plugin-react-doctor");
749
+ const resolveTsConfigRelativePath = (rootDirectory) => {
750
+ for (const filename of TSCONFIG_FILENAMES) if (fs$1.existsSync(path$1.join(rootDirectory, filename))) return `./${filename}`;
751
+ return null;
752
+ };
753
+ const LEGACY_SPAWN_ENV_NAMES = [
754
+ "REACT_DOCTOR_CPU_PROFILE_DIR",
755
+ "REACT_DOCTOR_HEAP_PROFILE_DIR",
756
+ "REACT_DOCTOR_OXLINT_TIMINGS_DIR",
757
+ "REACT_DOCTOR_RULE_TIMINGS_DIR",
758
+ "REACT_DOCTOR_DISABLE_OXLINT_WORKER_POOL"
759
+ ];
760
+ const OXLINT_INTERNAL_MODULES = [
761
+ "cli.js",
762
+ "bindings.js",
763
+ "plugins.js",
764
+ "workspace.js"
765
+ ];
766
+ const resolveOptionalPluginPath = () => {
767
+ try {
768
+ return resolvePluginPath();
769
+ } catch {
770
+ return null;
771
+ }
772
+ };
773
+ const isLegacySpawnForced = (environment) => LEGACY_SPAWN_ENV_NAMES.some((name) => Boolean(environment[name]));
774
+ const resolveOxlintWorkerRuntime = (environment = process.env) => {
775
+ if (isLegacySpawnForced(environment)) return null;
776
+ const workerScriptPath = path$1.join(path$1.dirname(fileURLToPath(import.meta.url)), "oxlint-worker.js");
777
+ if (!fs$1.existsSync(workerScriptPath)) return null;
778
+ const oxlintPackageDirectory = resolveOxlintPackageDirectory();
779
+ if (!OXLINT_INTERNAL_MODULES.every((fileName) => fs$1.existsSync(path$1.join(oxlintPackageDirectory, "dist", fileName)))) return null;
780
+ return {
781
+ workerScriptPath,
782
+ oxlintPackageDirectory,
783
+ pluginPath: resolveOptionalPluginPath()
784
+ };
785
+ };
786
+ const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
787
+ const resolveReactDoctorCacheDir = (projectDirectory) => {
788
+ const cacheDirOverride = process.env["REACT_DOCTOR_CACHE_DIR"]?.trim();
789
+ if (cacheDirOverride) return path$1.join(cacheDirOverride, projectCacheSubdir(projectDirectory));
790
+ const nodeModulesDirectory = path$1.join(projectDirectory, "node_modules");
791
+ if (fs$1.existsSync(nodeModulesDirectory)) return path$1.join(nodeModulesDirectory, ".cache", "react-doctor");
792
+ return path$1.join(os.tmpdir(), `react-doctor-cache-${resolveUserCacheScope()}`, projectCacheSubdir(projectDirectory));
793
+ };
794
+ const resolveUserCacheScope = () => {
795
+ try {
796
+ return String(process.getuid?.() ?? os.userInfo().username);
797
+ } catch {
798
+ return "shared";
799
+ }
800
+ };
801
+ const DEFAULT_WORKER_SCRIPT_PATH = path$1.join(path$1.dirname(fileURLToPath(import.meta.url)), "react-compiler-detection-worker.js");
802
+ const pendingDetectionsByDirectory = /* @__PURE__ */ new Map();
803
+ let sharedWorker = null;
804
+ let nextRequestId = 0;
805
+ const retireWorker = (shared) => {
806
+ if (shared.idleTimer !== null) clearTimeout(shared.idleTimer);
807
+ shared.idleTimer = null;
808
+ if (sharedWorker === shared) sharedWorker = null;
809
+ if (shared.isDead) return;
810
+ shared.isDead = true;
811
+ for (const resolve of shared.resolveById.values()) resolve(null);
812
+ shared.resolveById.clear();
813
+ shared.worker.terminate();
814
+ };
815
+ const settleIdleState = (shared) => {
816
+ if (shared.resolveById.size > 0) {
817
+ if (shared.idleTimer !== null) clearTimeout(shared.idleTimer);
818
+ shared.idleTimer = null;
819
+ shared.worker.ref();
820
+ return;
821
+ }
822
+ shared.worker.unref();
823
+ shared.idleTimer ??= setTimeout(() => retireWorker(shared), REACT_COMPILER_DETECTION_WORKER_IDLE_TIMEOUT_MS);
824
+ shared.idleTimer.unref();
825
+ };
826
+ const acquireSharedWorker = (scriptPath) => {
827
+ if (sharedWorker !== null && !sharedWorker.isDead) return sharedWorker;
828
+ let worker;
829
+ try {
830
+ worker = new Worker(scriptPath);
831
+ } catch {
832
+ return null;
833
+ }
834
+ const shared = {
835
+ worker,
836
+ resolveById: /* @__PURE__ */ new Map(),
837
+ idleTimer: null,
838
+ isDead: false
839
+ };
840
+ worker.on("message", (message) => {
841
+ if (!isReactCompilerDetectionReply(message)) return;
842
+ const resolve = shared.resolveById.get(message.id);
843
+ if (resolve === void 0) return;
844
+ shared.resolveById.delete(message.id);
845
+ resolve(message.hasReactCompiler);
846
+ settleIdleState(shared);
847
+ });
848
+ worker.once("error", () => retireWorker(shared));
849
+ worker.once("exit", () => retireWorker(shared));
850
+ sharedWorker = shared;
851
+ return shared;
852
+ };
853
+ const detectInWorker = (shared, directory) => new Promise((resolve) => {
854
+ const request = {
855
+ id: nextRequestId++,
856
+ directory
857
+ };
858
+ shared.resolveById.set(request.id, resolve);
859
+ settleIdleState(shared);
860
+ shared.worker.postMessage(request);
861
+ });
862
+ const warmReactCompilerDetection = (directory, scriptPath = DEFAULT_WORKER_SCRIPT_PATH) => {
863
+ if (pendingDetectionsByDirectory.has(directory) || !fs$1.existsSync(scriptPath)) return;
864
+ const shared = acquireSharedWorker(scriptPath);
865
+ if (shared === null) return;
866
+ pendingDetectionsByDirectory.set(directory, detectInWorker(shared, directory));
867
+ };
868
+ const takeReactCompilerDetection = (directory) => {
869
+ const pending = pendingDetectionsByDirectory.get(directory) ?? null;
870
+ if (pending !== null) pendingDetectionsByDirectory.delete(directory);
871
+ return pending;
872
+ };
873
+ //#endregion
874
+ //#region src/cli/utils/constants.ts
875
+ const REACT_DOCTOR_CONFIG_PROJECT_NAME = "react-doctor";
876
+ const STAGED_FILES_TEMP_DIR_PREFIX = "react-doctor-staged-";
877
+ const STAGED_SNAPSHOT_ADDITIONAL_CONFIG_FILENAMES = [
878
+ ".babelrc",
879
+ ".babelrc.json",
880
+ ".eslintignore",
881
+ ".eslintrc.json",
882
+ ".oxlintignore",
883
+ "app.config.cjs",
884
+ "app.config.js",
885
+ "app.config.json",
886
+ "app.config.mjs",
887
+ "app.config.ts",
888
+ "app.json",
889
+ "babel.config.cjs",
890
+ "babel.config.js",
891
+ "babel.config.json",
892
+ "babel.config.mjs",
893
+ "eslint.config.cjs",
894
+ "eslint.config.cts",
895
+ "eslint.config.js",
896
+ "eslint.config.mjs",
897
+ "eslint.config.mts",
898
+ "eslint.config.ts",
899
+ "next.config.cjs",
900
+ "next.config.js",
901
+ "next.config.mjs",
902
+ "next.config.ts",
903
+ "oxlint.config.json",
904
+ "react-doctor.config.json",
905
+ "vite.config.cjs",
906
+ "vite.config.cts",
907
+ "vite.config.js",
908
+ "vite.config.mjs",
909
+ "vite.config.mts",
910
+ "vite.config.ts",
911
+ "vitest.config.js",
912
+ "vitest.config.ts"
913
+ ];
914
+ const BASELINE_FILES_TEMP_DIR_PREFIX = "react-doctor-baseline-";
915
+ const SCAN_RESULT_CACHE_FILENAME = "scan-cache.json";
916
+ const SCAN_RESULT_CACHE_MAX_HASHED_FILE_SIZE_BYTES = 10 * 1024 * 1024;
917
+ const RUN_GIT_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
918
+ const HEAD_SHA_GIT_ARGUMENTS = ["rev-parse", "HEAD"];
919
+ const REPOSITORY_ROOT_GIT_ARGUMENTS = ["rev-parse", "--show-toplevel"];
920
+ const TRACKED_FILE_FLAGS_GIT_ARGUMENTS = ["ls-files", "-v"];
921
+ const WORKTREE_STATUS_GIT_ARGUMENTS = [
922
+ "status",
923
+ "--porcelain=v1",
924
+ "-z",
925
+ "--untracked-files=all"
926
+ ];
927
+ const SCAN_RESULT_CACHE_GIT_ARGUMENTS = [
928
+ TRACKED_FILE_FLAGS_GIT_ARGUMENTS,
929
+ REPOSITORY_ROOT_GIT_ARGUMENTS,
930
+ WORKTREE_STATUS_GIT_ARGUMENTS,
931
+ HEAD_SHA_GIT_ARGUMENTS
932
+ ];
933
+ const CACHE_DISABLED_VALUES = new Set(["1", "true"]);
934
+ const SCAN_PREAMBLE_SKIP_FLAGS = new Set([
935
+ "-h",
936
+ "--help",
937
+ "-v",
938
+ "-V",
939
+ "--version",
940
+ "--staged"
941
+ ]);
942
+ const GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS = 5e3;
943
+ const TUI_REPORT_COMPACT_MAX_ROWS = 23;
944
+ const TUI_REPORT_DETAIL_WIDTH_FRACTION = .6;
945
+ const CI_TRUST_COMPANIES = "PayPal, Rippling, and Alibaba";
946
+ const MINIMUM_VTE_VERSION_FOR_HYPERLINKS = 5e3;
947
+ const INTERNAL_ERROR_JSON_FALLBACK = "{\"schemaVersion\":3,\"version\":\"unknown\",\"ok\":false,\"directory\":\"\",\"mode\":\"full\",\"diff\":null,\"projects\":[],\"diagnostics\":[],\"summary\":{\"errorCount\":0,\"warningCount\":0,\"affectedFileCount\":0,\"totalDiagnosticCount\":0,\"score\":null,\"scoreLabel\":null},\"elapsedMilliseconds\":0,\"error\":{\"message\":\"Internal error\",\"name\":\"Error\",\"chain\":[]}}\n";
948
+ const SENTRY_DSN = "https://f253d570240a59b8dbd77b7a548ef133@o4510226365743104.ingest.us.sentry.io/4511487817809920";
949
+ const AXIOM_INGEST_TOKEN = "xaat-31b59107-855d-4917-8fab-6dc29fb459ce";
950
+ const NANOSECONDS_PER_MILLISECOND = 1000000n;
951
+ const AXIOM_TRACES_DATASET = "react-doctor";
952
+ const AXIOM_METRICS_DATASET = "react-doctor-metrics";
953
+ const SENTRY_RELEASE_PREFIX = "react-doctor";
954
+ const SENTRY_FLUSH_TIMEOUT_MS = 2e3;
955
+ const METRIC_DISTRIBUTION_BOUNDARIES = [
956
+ 0,
957
+ 1,
958
+ 2,
959
+ 5,
960
+ 10,
961
+ 25,
962
+ 50,
963
+ 100,
964
+ 250,
965
+ 500,
966
+ 1e3,
967
+ 2500,
968
+ 5e3,
969
+ 1e4,
970
+ 3e4,
971
+ 6e4,
972
+ 3e5,
973
+ 6e5
974
+ ];
975
+ const METRIC = {
976
+ cliInvoked: "cli.invoked",
977
+ cliError: "cli.error",
978
+ cliEnvironmentError: "cli.env_error",
979
+ stagedSnapshotDivergence: "staged.snapshot_divergence",
980
+ stagedPerProject: "staged.per_project",
981
+ projectDetected: "project.detected",
982
+ projectPathSelected: "project.path_selected",
983
+ projectConfigSelected: "project.config_selected",
984
+ scanCompleted: "scan.completed",
985
+ scanDuration: "scan.duration",
986
+ scanFeedbackDelay: "scan.feedback_delay",
987
+ scanPhaseDuration: "scan.phase_duration",
988
+ scanFiles: "scan.files",
989
+ scanScore: "scan.score",
990
+ scanScoreRetry: "scan.score_retry",
991
+ scanClean: "scan.clean",
992
+ scanCheckSkipped: "scan.check_skipped",
993
+ scanProjectSkipped: "scan.project_skipped",
994
+ scanWorkspaceMaintainabilityShared: "scan.workspace_maintainability_shared",
995
+ scanNoReactDetected: "scan.no_react_detected",
996
+ baselineDegraded: "baseline.degraded",
997
+ ruleFired: "rule.fired",
998
+ ruleDisabled: "rule.disabled",
999
+ ruleSuppressed: "rule.suppressed",
1000
+ lintFailed: "lint.failed",
1001
+ maintainabilityFailed: "maintainability.failed",
1002
+ scoreUnavailable: "score.unavailable",
1003
+ oxlintWorkers: "oxlint.workers",
1004
+ agentHandoff: "agent.handoff",
1005
+ agentInstallHintShown: "agent.install_hint_shown",
1006
+ installCompleted: "install.completed",
1007
+ installAgent: "install.agent",
1008
+ installGitHook: "install.git_hook",
1009
+ installWorkflow: "install.workflow",
1010
+ installAgentHooks: "install.agent_hooks",
1011
+ installDependency: "install.dependency",
1012
+ ciScaffolded: "ci.scaffolded",
1013
+ ciUpgraded: "ci.upgraded",
1014
+ ciConfigured: "ci.configured",
1015
+ rulesChanged: "rules.changed",
1016
+ rulesQueried: "rules.queried",
1017
+ runtimeScanUrlPromptShown: "runtime_scan.url_prompt_shown",
1018
+ tuiCompactReportShown: "tui.compact_report_shown",
1019
+ tuiFindingNavigated: "tui.finding_navigated",
1020
+ tuiIssueStreamShown: "tui.issue_stream_shown",
1021
+ tuiProjectPathContextShown: "tui.project_path_context_shown",
1022
+ tuiProjectSelectShown: "tui.project_select_shown",
1023
+ tuiCiRecommendationShown: "tui.ci_recommendation_shown",
1024
+ tuiReportActionSelected: "tui.report_action_selected",
1025
+ tuiCancelled: "tui.cancelled",
1026
+ tuiScanInlineShown: "tui.scan_inline_shown",
1027
+ tuiStackedReportCapped: "tui.stacked_report_capped",
1028
+ aiTrainingWarningShown: "ai.training.warning_shown",
1029
+ jsonOutUsed: "json.out_used"
1030
+ };
1031
+ //#endregion
1032
+ export { warmReactCompilerDetection as $, OXLINT_WORKER_JOB_END_MARKER as $t, buildGitSourceListingRequest as A, TARGET_BLANK_BROWSER_SUPPORT as An, GITHUB_VIEWER_PERMISSION_TIMEOUT_MS as At, resolveGitCommand as B, MAINTAINABILITY_DUPLICATE_JSX_RULE as Bt, SENTRY_RELEASE_PREFIX as C, SUPPLY_CHAIN_CACHE_TTL_MS as Cn, ES_TARGET_YEAR_BY_NAME as Ct, TUI_REPORT_COMPACT_MAX_ROWS as D, SUPPLY_CHAIN_PLUGIN as Dn, GENERATED_BUNDLE_FILE_PATTERN as Dt, TRACKED_FILE_FLAGS_GIT_ARGUMENTS as E, SUPPLY_CHAIN_OVERLAP_TIMEOUT_MS as En, FILE_LINT_CACHE_MAX_FILE_COUNT as Et, lowerChildProcessPriority as F, VERCEL_NEXTJS_SECURITY_RELEASE_URL as Fn, HTML_FILE_PATTERN as Ft, resolvePluginPath as G, MINIFIED_SNIFF_BYTES as Gt, resolveOxlintThreadCount as H, MAINTAINABILITY_SOURCE_FILE_PATTERN as Ht, prefetchGitCommand as I, getCategoryImpact as In, IGNORED_DIRECTORIES as It, resolveTsConfigRelativePath as J, OXLINT_NODE_REQUIREMENT as Jt, resolveReactDoctorCacheDir as K, OCCURRENCE_MATCHED_CATEGORIES as Kt, prespawnOxlintWorkers as L, JSX_DUPLICATION_SOURCE_FILE_PATTERN as Lt, buildOxlintWorkerSpawnSpec as M, TELEMETRY_SHUTDOWN_TIMEOUT_MS as Mn, GIT_LS_FILES_MAX_BUFFER_BYTES as Mt, discardPrefetchedGitCommands as N, TSCONFIG_FILENAMES as Nn, GIT_SHOW_MAX_BUFFER_BYTES as Nt, TUI_REPORT_DETAIL_WIDTH_FRACTION as O, SUPPLY_CHAIN_RULE as On, GENERATED_SOURCE_DIRECTORY_PATTERN as Ot, killUnadoptedOxlintWorkers as P, TYPESCRIPT_DECLARATION_FILE_PATTERN as Pn, GIT_SOURCE_LISTING_ARGUMENTS as Pt, takeReactCompilerDetection as Q, OXLINT_SPLIT_TOTAL_BUDGET_MS as Qt, readSystemConcurrencyFacts as R, JSX_FILE_PATTERN as Rt, SENTRY_FLUSH_TIMEOUT_MS as S, SUPPLY_CHAIN_CACHE_SUBDIR as Sn, ENTERPRISE_CONTACT_URL as St, STAGED_SNAPSHOT_ADDITIONAL_CONFIG_FILENAMES as T, SUPPLY_CHAIN_IGNORED_PACKAGES as Tn, FILE_LINT_CACHE_FILENAME as Tt, resolveOxlintToolchainVersions as U, MAX_GLOB_PATTERN_LENGTH_CHARS as Ut, resolveOxlintBinary as V, MAINTAINABILITY_PLUGIN as Vt, resolveOxlintWorkerRuntime as W, MILLISECONDS_PER_SECOND as Wt, spawnOxlintWorkerProcess as X, OXLINT_OUTPUT_MAX_BYTES as Xt, setChildProcessRef as Y, OXLINT_OOM_RESCUE_BUDGET_MS as Yt, takePrespawnedOxlintWorker as Z, OXLINT_SPAWN_TIMEOUT_MS as Zt, SCAN_PREAMBLE_SKIP_FLAGS as _, SOURCE_FILE_PATTERN as _n, DIAGNOSTIC_CATEGORY_BUCKETS as _t, CACHE_DISABLED_VALUES as a, REACT_ROUTER_CAPABILITY_THRESHOLDS as an, AXIOM_METRICS_DATASET_HEADER as at, SCAN_RESULT_CACHE_MAX_HASHED_FILE_SIZE_BYTES as b, SPAWN_ARGS_MAX_LENGTH_CHARS_POSIX as bn, DOCS_URL as bt, HEAD_SHA_GIT_ARGUMENTS as c, ROOT_CAUSE_GROUPABLE_RULE_KEYS as cn, CANONICAL_DISCORD_URL as ct, METRIC_DISTRIBUTION_BOUNDARIES as d, SHARE_BASE_URL as dn, COMPILER_CLEANUP_BUCKET as dt, PROJECT_ANALYSIS_WORKER_MAX_OLD_SPACE_MB as en, ABORT_EXIT_CODES as et, MINIMUM_VTE_VERSION_FOR_HYPERLINKS as f, SIDECAR_LINT_CACHE_FILENAME as fn, COMPILER_CLEANUP_RULE_KEYS as ft, RUN_GIT_MAX_BUFFER_BYTES as g, SOCKET_PACKAGE_PAGE_BASE as gn, DEFAULT_BRANCH_CANDIDATES as gt, REPOSITORY_ROOT_GIT_ARGUMENTS as h, SOCKET_FREE_USER_AGENT as hn, CONFIG_SCHEMA_URL as ht, BASELINE_FILES_TEMP_DIR_PREFIX as i, REACT_BLOG_RSC_ADVISORY_URL as in, AXIOM_DEFAULT_DOMAIN as it, buildOxlintChildEnv as j, TELEMETRY_EXPORT_INTERVAL_MS as jn, GIT_CHECK_ATTR_MAX_BUFFER_BYTES as jt, WORKTREE_STATUS_GIT_ARGUMENTS as k, TAILWIND_POSTCSS7_COMPAT_ALIAS as kn, GITHUB_ACTIONS_SETUP_URL as kt, INTERNAL_ERROR_JSON_FALLBACK as l, SCANNED_DOT_DIRECTORIES as ln, CANONICAL_GITHUB_URL as lt, REACT_DOCTOR_CONFIG_PROJECT_NAME as m, SOCKET_FREE_PURL_API_BASE as mn, CONFIG_FINGERPRINT_FILENAMES as mt, AXIOM_METRICS_DATASET as n, PROJECT_ANALYSIS_WORKER_TIMEOUT_CEILING_MS as nn, APP_ONLY_RULE_KEYS as nt, CI_TRUST_COMPANIES as o, REACT_SERVER_DOM_PACKAGES as on, AXIOM_METRICS_PATH as ot, NANOSECONDS_PER_MILLISECOND as p, SKILL_NAME as pn, CONFIG_CACHE_TTL_MS as pt, resolveScanConcurrency as q, OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES as qt, AXIOM_TRACES_DATASET as r, PROJECT_ANALYSIS_WORKER_TIMEOUT_MS as rn, AXIOM_DATASET_HEADER as rt, GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS as s, RECOMMENDED_PNPM_MINIMUM_RELEASE_AGE_MINUTES as sn, AXIOM_TRACES_PATH as st, AXIOM_INGEST_TOKEN as t, PROJECT_ANALYSIS_WORKER_MEMORY_BUDGET_BYTES as tn, ADOPTABLE_LINT_CONFIG_FILENAMES as tt, METRIC as u, SCORE_API_URL as un, CI_URL as ut, SCAN_RESULT_CACHE_FILENAME as v, SPAWN_ARGS_MAX_LENGTH_CHARS as vn, DISABLE_DIRECTIVE_BACKUP_DIRECTORY_SEGMENTS as vt, STAGED_FILES_TEMP_DIR_PREFIX as w, SUPPLY_CHAIN_CATEGORY as wn, FETCH_TIMEOUT_MS as wt, SENTRY_DSN as x, STAGED_FILES_PROJECT_CONFIG_FILENAMES as xn, DUPLICATE_JSX_WORKER_IDLE_TIMEOUT_MS as xt, SCAN_RESULT_CACHE_GIT_ARGUMENTS as y, SPAWN_ARGS_MAX_LENGTH_CHARS_DARWIN as yn, DOCS_RULES_BASE_URL as yt, resolveConfiguredScanConcurrency as z, MAINTAINABILITY_CATEGORY as zt };
1033
+
1034
+ //# sourceMappingURL=constants-CW_854PH.js.map
1035
+ //# debugId=7063ad56-037f-53c5-a0e5-2e75a803c2ef