main
js 663 lines 20.6 KB
Raw
1 'use strict';
2
3 const {
4 es5Paths,
5 esNextPaths,
6 } = require('./scripts/shared/pathsByLanguageVersion');
7
8 const restrictedGlobals = require('confusing-browser-globals');
9
10 const OFF = 0;
11 const WARNING = 1;
12 const ERROR = 2;
13
14 module.exports = {
15 extends: ['prettier', 'plugin:jest/recommended'],
16
17 // Stop ESLint from looking for a configuration file in parent folders
18 root: true,
19
20 reportUnusedDisableDirectives: true,
21
22 plugins: [
23 'babel',
24 'ft-flow',
25 'jest',
26 'es',
27 'no-for-of-loops',
28 'no-function-declare-after-return',
29 'react',
30 'react-internal',
31 ],
32
33 parser: 'hermes-eslint',
34 parserOptions: {
35 ecmaVersion: 9,
36 sourceType: 'script',
37 },
38
39 // We're stricter than the default config, mostly. We'll override a few rules
40 // and then enable some React specific ones.
41 rules: {
42 'ft-flow/array-style-complex-type': [OFF, 'verbose'],
43 'ft-flow/array-style-simple-type': [OFF, 'verbose'], // TODO should be WARNING
44 'ft-flow/boolean-style': ERROR,
45 'ft-flow/no-dupe-keys': ERROR,
46 'ft-flow/no-primitive-constructor-types': ERROR,
47 'ft-flow/no-types-missing-file-annotation': OFF, // TODO should be ERROR
48 'ft-flow/no-unused-expressions': ERROR,
49 // 'ft-flow/no-weak-types': WARNING,
50 // 'ft-flow/require-valid-file-annotation': ERROR,
51 'es/no-optional-chaining': ERROR,
52 'no-cond-assign': OFF,
53 'no-constant-condition': OFF,
54 'no-control-regex': OFF,
55 'no-debugger': ERROR,
56 'no-dupe-args': ERROR,
57 'no-dupe-keys': ERROR,
58 'no-duplicate-case': WARNING,
59 'no-empty-character-class': WARNING,
60 'no-empty': OFF,
61 'no-ex-assign': WARNING,
62 'no-extra-boolean-cast': WARNING,
63 'no-func-assign': ERROR,
64 'no-invalid-regexp': WARNING,
65 'no-irregular-whitespace': WARNING,
66 'no-negated-in-lhs': ERROR,
67 'no-obj-calls': ERROR,
68 'no-regex-spaces': WARNING,
69 'no-sparse-arrays': ERROR,
70 'no-unreachable': ERROR,
71 'use-isnan': ERROR,
72 'valid-jsdoc': OFF,
73 'block-scoped-var': OFF,
74 complexity: OFF,
75 'default-case': OFF,
76 'guard-for-in': OFF,
77 'no-alert': OFF,
78 'no-caller': ERROR,
79 'no-case-declarations': OFF,
80 'no-div-regex': OFF,
81 'no-else-return': OFF,
82 'no-empty-pattern': WARNING,
83 'no-eq-null': OFF,
84 'no-eval': ERROR,
85 'no-extend-native': WARNING,
86 'no-extra-bind': WARNING,
87 'no-fallthrough': WARNING,
88 'no-implicit-coercion': OFF,
89 'no-implied-eval': ERROR,
90 'no-invalid-this': OFF,
91 'no-iterator': OFF,
92 'no-labels': [ERROR, {allowLoop: true, allowSwitch: true}],
93 'no-lone-blocks': WARNING,
94 'no-loop-func': OFF,
95 'no-magic-numbers': OFF,
96 'no-multi-str': ERROR,
97 'no-native-reassign': [ERROR, {exceptions: ['Map', 'Set']}],
98 'no-new-func': ERROR,
99 'no-new': WARNING,
100 'no-new-wrappers': WARNING,
101 'no-octal-escape': WARNING,
102 'no-octal': WARNING,
103 'no-param-reassign': OFF,
104 'no-process-env': OFF,
105 'no-proto': ERROR,
106 'no-redeclare': OFF, // TODO should be WARNING?
107 'no-return-assign': OFF,
108 'no-script-url': ERROR,
109 'no-self-compare': WARNING,
110 'no-sequences': WARNING,
111 'no-throw-literal': ERROR,
112 'no-useless-call': WARNING,
113 'no-void': OFF,
114 'no-warning-comments': OFF,
115 'no-with': OFF,
116 radix: WARNING,
117 'vars-on-top': OFF,
118 yoda: OFF,
119 'init-declarations': OFF,
120 'no-catch-shadow': ERROR,
121 'no-delete-var': ERROR,
122 'no-label-var': WARNING,
123 'no-shadow-restricted-names': WARNING,
124 'no-undef-init': OFF,
125 'no-undef': ERROR,
126 'no-undefined': OFF,
127 'callback-return': OFF,
128 'global-require': OFF,
129 'handle-callback-err': OFF,
130 'no-mixed-requires': OFF,
131 'no-new-require': OFF,
132 'no-path-concat': OFF,
133 'no-process-exit': OFF,
134 'no-restricted-modules': OFF,
135 'no-sync': OFF,
136 camelcase: [OFF, {properties: 'always'}],
137 'consistent-this': [OFF, 'self'],
138 'func-names': OFF,
139 'func-style': [OFF, 'declaration'],
140 'id-length': OFF,
141 'id-match': OFF,
142 'max-depth': OFF,
143 'max-nested-callbacks': OFF,
144 'max-params': OFF,
145 'max-statements': OFF,
146 'new-cap': OFF,
147 'newline-after-var': OFF,
148 'no-array-constructor': ERROR,
149 'no-continue': OFF,
150 'no-inline-comments': OFF,
151 'no-lonely-if': OFF,
152 'no-negated-condition': OFF,
153 'no-nested-ternary': OFF,
154 'no-new-object': WARNING,
155 'no-plusplus': OFF,
156 'no-ternary': OFF,
157 'no-underscore-dangle': OFF,
158 'no-unneeded-ternary': WARNING,
159 'one-var': [WARNING, {initialized: 'never'}],
160 'operator-assignment': [WARNING, 'always'],
161 'require-jsdoc': OFF,
162 'sort-vars': OFF,
163 'spaced-comment': [
164 OFF,
165 'always',
166 {exceptions: ['jshint', 'jslint', 'eslint', 'global']},
167 ],
168 'constructor-super': ERROR,
169 'no-class-assign': WARNING,
170 'no-const-assign': ERROR,
171 'no-dupe-class-members': ERROR,
172 'no-this-before-super': ERROR,
173 'object-shorthand': OFF,
174 'prefer-const': OFF,
175 'prefer-spread': OFF,
176 'prefer-reflect': OFF,
177 'prefer-template': OFF,
178 'require-yield': OFF,
179 'babel/generator-star-spacing': OFF,
180 'babel/new-cap': OFF,
181 'babel/array-bracket-spacing': OFF,
182 'babel/object-curly-spacing': OFF,
183 'babel/object-shorthand': OFF,
184 'babel/arrow-parens': OFF,
185 'babel/no-await-in-loop': OFF,
186 'babel/flow-object-type': OFF,
187 'react/display-name': OFF,
188 'react/forbid-prop-types': OFF,
189 'react/jsx-closing-bracket-location': OFF,
190 'react/jsx-curly-spacing': OFF,
191 'react/jsx-equals-spacing': WARNING,
192 'react/jsx-filename-extension': OFF,
193 'react/jsx-first-prop-new-line': OFF,
194 'react/jsx-handler-names': OFF,
195 'react/jsx-indent': OFF,
196 'react/jsx-indent-props': OFF,
197 'react/jsx-key': OFF,
198 'react/jsx-max-props-per-line': OFF,
199 'react/jsx-no-bind': OFF,
200 'react/jsx-no-duplicate-props': ERROR,
201 'react/jsx-no-literals': OFF,
202 'react/jsx-no-target-blank': OFF,
203 'react/jsx-pascal-case': OFF,
204 'react/jsx-sort-props': OFF,
205 'react/jsx-uses-vars': ERROR,
206 'react/no-comment-textnodes': OFF,
207 'react/no-danger': OFF,
208 'react/no-deprecated': OFF,
209 'react/no-did-mount-set-state': OFF,
210 'react/no-did-update-set-state': OFF,
211 'react/no-direct-mutation-state': OFF,
212 'react/no-multi-comp': OFF,
213 'react/no-render-return-value': OFF,
214 'react/no-set-state': OFF,
215 'react/no-string-refs': OFF,
216 'react/no-unknown-property': OFF,
217 'react/prefer-es6-class': OFF,
218 'react/prefer-stateless-function': OFF,
219 'react/prop-types': OFF,
220 'react/require-extension': OFF,
221 'react/require-optimization': OFF,
222 'react/require-render-return': OFF,
223 'react/sort-comp': OFF,
224 'react/sort-prop-types': OFF,
225
226 'accessor-pairs': OFF,
227 'brace-style': [ERROR, '1tbs'],
228 'consistent-return': OFF,
229 'dot-location': [ERROR, 'property'],
230 // We use console['error']() as a signal to not transform it:
231 'dot-notation': [ERROR, {allowPattern: '^(error|warn)$'}],
232 'eol-last': ERROR,
233 eqeqeq: [ERROR, 'allow-null'],
234 indent: OFF,
235 'jsx-quotes': [ERROR, 'prefer-double'],
236 'keyword-spacing': [ERROR, {after: true, before: true}],
237 'no-bitwise': OFF,
238 'no-console': OFF,
239 'no-inner-declarations': [ERROR, 'functions'],
240 'no-multi-spaces': ERROR,
241 'no-restricted-globals': [ERROR].concat(restrictedGlobals),
242 'no-restricted-syntax': [
243 ERROR,
244 'WithStatement',
245 {
246 selector: 'MemberExpression[property.name=/^(?:substring|substr)$/]',
247 message: 'Prefer string.slice() over .substring() and .substr().',
248 },
249 ],
250 'no-shadow': ERROR,
251 'no-unused-vars': [ERROR, {args: 'none', ignoreRestSiblings: true}],
252 'no-use-before-define': OFF,
253 'no-useless-concat': OFF,
254 quotes: [ERROR, 'single', {avoidEscape: true, allowTemplateLiterals: true}],
255 'space-before-blocks': ERROR,
256 'space-before-function-paren': OFF,
257 'valid-typeof': [ERROR, {requireStringLiterals: true}],
258 // Flow fails with non-string literal keys
259 'no-useless-computed-key': OFF,
260
261 // We apply these settings to files that should run on Node.
262 // They can't use JSX or ES6 modules, and must be in strict mode.
263 // They can, however, use other ES6 features.
264 // (Note these rules are overridden later for source files.)
265 'no-var': ERROR,
266 strict: ERROR,
267
268 // Enforced by Prettier
269 // TODO: Prettier doesn't handle long strings or long comments. Not a big
270 // deal. But I turned it off because loading the plugin causes some obscure
271 // syntax error and it didn't seem worth investigating.
272 'max-len': OFF,
273
274 // React & JSX
275 // Our transforms set this automatically
276 'react/jsx-boolean-value': [ERROR, 'always'],
277 'react/jsx-no-undef': ERROR,
278 // We don't care to do this
279 'react/jsx-sort-prop-types': OFF,
280 'react/jsx-space-before-closing': ERROR,
281 'react/jsx-uses-react': ERROR,
282 'react/no-is-mounted': OFF,
283 // This isn't useful in our test code
284 'react/react-in-jsx-scope': ERROR,
285 'react/self-closing-comp': ERROR,
286 // We don't care to do this
287 'react/jsx-wrap-multilines': [
288 ERROR,
289 {declaration: false, assignment: false},
290 ],
291
292 // Prevent for...of loops because they require a Symbol polyfill.
293 // You can disable this rule for code that isn't shipped (e.g. build scripts and tests).
294 'no-for-of-loops/no-for-of-loops': ERROR,
295
296 // Prevent function declarations after return statements
297 'no-function-declare-after-return/no-function-declare-after-return': ERROR,
298
299 // CUSTOM RULES
300 // the second argument of warning/invariant should be a literal string
301 'react-internal/no-primitive-constructors': ERROR,
302 'react-internal/safe-string-coercion': [
303 ERROR,
304 {isProductionUserAppCode: true},
305 ],
306 'react-internal/warning-args': ERROR,
307 'react-internal/no-production-logging': ERROR,
308 },
309
310 overrides: [
311 {
312 // By default, anything error message that appears the packages directory
313 // must have a corresponding error code. The exceptions are defined
314 // in the next override entry.
315 files: ['packages/**/*.js'],
316 rules: {
317 'react-internal/prod-error-codes': ERROR,
318 },
319 },
320 {
321 // These are files where it's OK to have unminified error messages. These
322 // are environments where bundle size isn't a concern, like tests
323 // or Node.
324 files: [
325 'packages/react-dom/src/test-utils/**/*.js',
326 'packages/react-devtools-shared/**/*.js',
327 'packages/react-noop-renderer/**/*.js',
328 'packages/react-refresh/**/*.js',
329 'packages/react-server-dom-esm/**/*.js',
330 'packages/react-server-dom-webpack/**/*.js',
331 'packages/react-server-dom-turbopack/**/*.js',
332 'packages/react-server-dom-parcel/**/*.js',
333 'packages/react-server-dom-fb/**/*.js',
334 'packages/react-flight-server-fb/**/*.js',
335 'packages/react-server-dom-unbundled/**/*.js',
336 'packages/react-test-renderer/**/*.js',
337 'packages/react-debug-tools/**/*.js',
338 'packages/react-devtools-extensions/**/*.js',
339 'packages/react-devtools-facade/**/*.js',
340 'packages/react-native-renderer/**/*.js',
341 'packages/eslint-plugin-react-hooks/**/*.js',
342 'packages/jest-react/**/*.js',
343 'packages/internal-test-utils/**/*.js',
344 'packages/**/__tests__/*.js',
345 'packages/**/npm/*.js',
346 ],
347 rules: {
348 'react-internal/prod-error-codes': OFF,
349 },
350 },
351 {
352 // We apply these settings to files that we ship through npm.
353 // They must be ES5.
354 files: es5Paths,
355 parser: 'espree',
356 parserOptions: {
357 ecmaVersion: 5,
358 sourceType: 'script',
359 },
360 rules: {
361 'no-var': OFF,
362 strict: ERROR,
363 },
364 },
365 {
366 // We apply these settings to the source files that get compiled.
367 // They can use all features including JSX (but shouldn't use `var`).
368 files: esNextPaths,
369 parser: 'hermes-eslint',
370 parserOptions: {
371 ecmaVersion: 8,
372 sourceType: 'module',
373 },
374 rules: {
375 'no-var': ERROR,
376 'prefer-const': ERROR,
377 strict: OFF,
378 },
379 },
380 {
381 files: ['**/__tests__/*.js'],
382 rules: {
383 // https://github.com/jest-community/eslint-plugin-jest
384 // Meh, who cares.
385 'jest/consistent-test-it': OFF,
386 // Meh, we have a lot of these, who cares.
387 'jest/no-alias-methods': OFF,
388 // We do conditions based on feature flags.
389 'jest/no-conditional-expect': OFF,
390 // We have our own assertion helpers.
391 'jest/expect-expect': OFF,
392 // Lame rule that fires in itRender helpers or in render methods.
393 'jest/no-standalone-expect': OFF,
394 },
395 },
396 {
397 // Rules specific to test setup helper files.
398 files: [
399 '**/setupTests.js',
400 '**/setupEnv.js',
401 '**/jest/TestFlags.js',
402 '**/dom-event-testing-library/testHelpers.js',
403 '**/utils/ReactDOMServerIntegrationTestUtils.js',
404 '**/babel/transform-react-version-pragma.js',
405 '**/babel/transform-test-gate-pragma.js',
406 ],
407 rules: {
408 // Some helpers intentionally focus tests.
409 'jest/no-focused-tests': OFF,
410 // Test fn helpers don't use static text names.
411 'jest/valid-title': OFF,
412 // We have our own assertion helpers.
413 'jest/expect-expect': OFF,
414 // Some helpers intentionally disable tests.
415 'jest/no-disabled-tests': OFF,
416 // Helpers export text function helpers.
417 'jest/no-export': OFF,
418 // The examples in comments trigger false errors.
419 'jest/no-commented-out-tests': OFF,
420 },
421 },
422 {
423 files: ['**/jest/TestFlags.js'],
424 rules: {
425 // The examples in comments trigger false errors.
426 'jest/no-commented-out-tests': OFF,
427 },
428 },
429 {
430 files: [
431 '**/__tests__/**/*.js',
432 'scripts/**/*.js',
433 'packages/*/npm/**/*.js',
434 'packages/dom-event-testing-library/**/*.js',
435 'packages/react-devtools*/**/*.js',
436 'fixtures',
437 'packages/react-dom/src/test-utils/*.js',
438 ],
439 rules: {
440 'es/no-optional-chaining': OFF,
441 'react-internal/no-production-logging': OFF,
442 'react-internal/warning-args': OFF,
443 'react-internal/safe-string-coercion': [
444 ERROR,
445 {isProductionUserAppCode: false},
446 ],
447 },
448 },
449 {
450 files: ['scripts/eslint-rules/*.js'],
451 plugins: ['eslint-plugin'],
452 rules: {
453 'eslint-plugin/prefer-object-rule': ERROR,
454 'eslint-plugin/require-meta-fixable': [
455 ERROR,
456 {catchNoFixerButFixableProperty: true},
457 ],
458 'eslint-plugin/require-meta-has-suggestions': ERROR,
459 },
460 },
461 {
462 files: ['packages/react-native-renderer/**/*.js'],
463 globals: {
464 nativeFabricUIManager: 'readonly',
465 RN$isNativeEventTargetEventDispatchingEnabled: 'readonly',
466 },
467 },
468 {
469 files: ['packages/react-server-dom-webpack/**/*.js'],
470 globals: {
471 __webpack_chunk_load__: 'readonly',
472 __webpack_get_script_filename__: 'readonly',
473 __webpack_require__: 'readonly',
474 },
475 },
476 {
477 files: ['packages/react-server-dom-turbopack/**/*.js'],
478 globals: {
479 __turbopack_load_by_url__: 'readonly',
480 __turbopack_require__: 'readonly',
481 },
482 },
483 {
484 files: ['packages/react-server-dom-parcel/**/*.js'],
485 globals: {
486 parcelRequire: 'readonly',
487 },
488 },
489 {
490 files: ['packages/scheduler/**/*.js'],
491 globals: {
492 TaskController: 'readonly',
493 },
494 },
495 {
496 files: [
497 'packages/react-devtools-extensions/**/*.js',
498 'packages/react-devtools-shared/src/devtools/views/**/*.js',
499 'packages/react-devtools-shared/src/hook.js',
500 'packages/react-devtools-shared/src/backend/console.js',
501 'packages/react-devtools-shared/src/backend/fiber/renderer.js',
502 'packages/react-devtools-shared/src/backend/shared/DevToolsComponentStackFrame.js',
503 'packages/react-devtools-shared/src/frontend/utils/withPermissionsCheck.js',
504 ],
505 globals: {
506 __IS_CHROME__: 'readonly',
507 __IS_FIREFOX__: 'readonly',
508 __IS_EDGE__: 'readonly',
509 __IS_NATIVE__: 'readonly',
510 __IS_INTERNAL_VERSION__: 'readonly',
511 chrome: 'readonly',
512 },
513 },
514 {
515 files: ['packages/react-devtools-shared/**/*.js'],
516 globals: {
517 __IS_INTERNAL_VERSION__: 'readonly',
518 },
519 },
520 {
521 files: ['packages/react-devtools-*/**/*.js'],
522 excludedFiles: '**/__tests__/**/*.js',
523 plugins: ['eslint-plugin-react-hooks-published'],
524 rules: {
525 'react-hooks-published/rules-of-hooks': ERROR,
526 },
527 },
528 {
529 files: ['packages/eslint-plugin-react-hooks/src/**/*'],
530 extends: ['plugin:@typescript-eslint/recommended'],
531 parser: '@typescript-eslint/parser',
532 plugins: ['@typescript-eslint', 'eslint-plugin'],
533 rules: {
534 '@typescript-eslint/no-explicit-any': OFF,
535 '@typescript-eslint/no-non-null-assertion': OFF,
536 '@typescript-eslint/array-type': [ERROR, {default: 'generic'}],
537
538 'es/no-optional-chaining': OFF,
539
540 'eslint-plugin/prefer-object-rule': ERROR,
541 'eslint-plugin/require-meta-fixable': [
542 ERROR,
543 {catchNoFixerButFixableProperty: true},
544 ],
545 'eslint-plugin/require-meta-has-suggestions': ERROR,
546 },
547 },
548 ],
549
550 env: {
551 browser: true,
552 es6: true,
553 node: true,
554 jest: true,
555 },
556
557 globals: {
558 $Flow$ModuleRef: 'readonly',
559 $FlowFixMe: 'readonly',
560 $Keys: 'readonly',
561 $NonMaybeType: 'readonly',
562 $ReadOnly: 'readonly',
563 $ReadOnlyArray: 'readonly',
564 $ArrayBufferView: 'readonly',
565 $Shape: 'readonly',
566 CallSite: 'readonly',
567 ConsoleTask: 'readonly', // TOOD: Figure out what the official name of this will be.
568 Readonly: 'readonly',
569 ReturnType: 'readonly',
570 AggregateError: 'readonly',
571 AnimationFrameID: 'readonly',
572 WeakRef: 'readonly',
573 // For Flow type annotation. Only `BigInt` is valid at runtime.
574 bigint: 'readonly',
575 BigInt: 'readonly',
576 BigInt64Array: 'readonly',
577 BigUint64Array: 'readonly',
578 CacheType: 'readonly',
579 Class: 'readonly',
580 ClientRect: 'readonly',
581 CopyInspectedElementPath: 'readonly',
582 DOMHighResTimeStamp: 'readonly',
583 EventListener: 'readonly',
584 // Flow type
585 FormDataEntryValue: 'readonly',
586 Iterable: 'readonly',
587 AsyncIterable: 'readonly',
588 $AsyncIterable: 'readonly',
589 $AsyncIterator: 'readonly',
590 Iterator: 'readonly',
591 AsyncIterator: 'readonly',
592 IntervalID: 'readonly',
593 IteratorResult: 'readonly',
594 JSONValue: 'readonly',
595 JSResourceReference: 'readonly',
596 mixin$Animatable: 'readonly',
597 MouseEventHandler: 'readonly',
598 NavigateEvent: 'readonly',
599 Partial: 'readonly',
600 PerformanceMeasureOptions: 'readonly',
601 PropagationPhases: 'readonly',
602 PropertyDescriptor: 'readonly',
603 PropertyDescriptorMap: 'readonly',
604 Proxy$traps: 'readonly',
605 React$Component: 'readonly',
606 React$Config: 'readonly',
607 React$Context: 'readonly',
608 React$Element: 'readonly',
609 React$ElementConfig: 'readonly',
610 React$ElementProps: 'readonly',
611 React$ElementRef: 'readonly',
612 React$ElementType: 'readonly',
613 React$Key: 'readonly',
614 React$Node: 'readonly',
615 React$Portal: 'readonly',
616 React$Ref: 'readonly',
617 React$RefSetter: 'readonly',
618 ReadableStreamController: 'readonly',
619 ReadableStreamReader: 'readonly',
620 RequestInfo: 'readonly',
621 RequestOptions: 'readonly',
622 Required: 'readonly',
623 StoreAsGlobal: 'readonly',
624 symbol: 'readonly',
625 SyntheticEvent: 'readonly',
626 SyntheticMouseEvent: 'readonly',
627 SyntheticPointerEvent: 'readonly',
628 Thenable: 'readonly',
629 TimeoutID: 'readonly',
630 WheelEventHandler: 'readonly',
631 FinalizationRegistry: 'readonly',
632 Exclude: 'readonly',
633 Omit: 'readonly',
634 Pick: 'readonly',
635 Keyframe: 'readonly',
636 PropertyIndexedKeyframes: 'readonly',
637 KeyframeAnimationOptions: 'readonly',
638 GetAnimationsOptions: 'readonly',
639 ScrollTimeline: 'readonly',
640 EventListenerOptionsOrUseCapture: 'readonly',
641 FocusOptions: 'readonly',
642 OptionalEffectTiming: 'readonly',
643
644 __REACT_ROOT_PATH_TEST__: 'readonly',
645 spyOnDev: 'readonly',
646 spyOnDevAndProd: 'readonly',
647 spyOnProd: 'readonly',
648 __DEV__: 'readonly',
649 __EXPERIMENTAL__: 'readonly',
650 __EXTENSION__: 'readonly',
651 __PROFILE__: 'readonly',
652 __TEST__: 'readonly',
653 __VARIANT__: 'readonly',
654 __unmockReact: 'readonly',
655 gate: 'readonly',
656 trustedTypes: 'readonly',
657 IS_REACT_ACT_ENVIRONMENT: 'readonly',
658 AsyncLocalStorage: 'readonly',
659 async_hooks: 'readonly',
660 globalThis: 'readonly',
661 navigation: 'readonly',
662 },
663 };