@critiq/rules 0.0.2 → 0.2.0
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 +52 -4
- package/catalog.yaml +1775 -192
- package/package.json +6 -1
- package/rules/go/go.correctness.defer-close-before-check.rule.yaml +44 -0
- package/rules/go/go.correctness.defer-in-loop.rule.yaml +47 -0
- package/rules/go/go.correctness.nil-context-passed.rule.yaml +43 -0
- package/rules/go/go.correctness.nil-map-assignment.rule.yaml +42 -0
- package/rules/go/go.correctness.time-tick-leak.rule.yaml +44 -0
- package/rules/go/go.correctness.unused-append-result.rule.yaml +43 -0
- package/rules/go/go.correctness.waitgroup-add-in-goroutine.rule.yaml +45 -0
- package/rules/go/go.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/go/go.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/go/go.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/go/go.security.bind-all-interfaces.rule.yaml +57 -0
- package/rules/go/go.security.echo-sensitive-binding-without-validation.rule.yaml +56 -0
- package/rules/go/go.security.echo-unsafe-multipart-upload.rule.yaml +55 -0
- package/rules/go/go.security.fiber-sensitive-binding-without-validation.rule.yaml +55 -0
- package/rules/go/go.security.fiber-unsafe-multipart-upload.rule.yaml +55 -0
- package/rules/go/go.security.gin-sensitive-binding-without-validation.rule.yaml +55 -0
- package/rules/go/go.security.gin-trust-all-proxies.rule.yaml +55 -0
- package/rules/go/go.security.gin-wildcard-cors-with-credentials.rule.yaml +57 -0
- package/rules/go/go.security.insecure-rand-seed.rule.yaml +55 -0
- package/rules/go/go.security.insecure-ssh-host-key.rule.yaml +57 -0
- package/rules/go/go.security.insecure-ssl-protocol.rule.yaml +56 -0
- package/rules/go/go.security.insecure-temp-file.rule.yaml +57 -0
- package/rules/go/go.security.jwt-without-verification.rule.yaml +56 -0
- package/rules/go/go.security.net-http-missing-timeouts.rule.yaml +55 -0
- package/rules/go/go.security.pprof-exposed.rule.yaml +56 -0
- package/rules/go/go.security.sensitive-data-egress.rule.yaml +56 -0
- package/rules/go/go.security.tar-path-traversal.rule.yaml +55 -0
- package/rules/go/go.security.template-unescaped-request-value.rule.yaml +55 -0
- package/rules/go/go.security.tls-missing-min-version.rule.yaml +55 -0
- package/rules/go/go.security.unsafe-package-import.rule.yaml +55 -0
- package/rules/go/go.security.weak-bcrypt-cost.rule.yaml +56 -0
- package/rules/go/go.security.weak-crypto-import.rule.yaml +57 -0
- package/rules/go/go.security.weak-rsa-key-size.rule.yaml +57 -0
- package/rules/go/go.security.weak-tls-cipher.rule.yaml +56 -0
- package/rules/go/go.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/go/go.testing.t-skip-without-ticket-reference.rule.yaml +33 -0
- package/rules/go/go.testing.time-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/java/java.correctness.catch-null-pointer.rule.yaml +40 -0
- package/rules/java/java.correctness.empty-catch.rule.yaml +40 -0
- package/rules/java/java.correctness.equals-on-array.rule.yaml +40 -0
- package/rules/java/java.correctness.return-in-finally.rule.yaml +40 -0
- package/rules/java/java.correctness.sync-on-string-literal.rule.yaml +40 -0
- package/rules/java/java.correctness.unsafe-optional-get.rule.yaml +40 -0
- package/rules/java/java.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/java/java.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/java/java.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/java/java.security.android-screenshot-exposure.rule.yaml +48 -0
- package/rules/java/java.security.android-world-readable-mode.rule.yaml +48 -0
- package/rules/java/java.security.hibernate-sql-concatenation.rule.yaml +62 -0
- package/rules/java/java.security.insecure-cipher-mode.rule.yaml +52 -0
- package/rules/java/java.security.insecure-network-protocol.rule.yaml +52 -0
- package/rules/java/java.security.insecure-ssl-context.rule.yaml +52 -0
- package/rules/java/java.security.jpa-concatenated-query.rule.yaml +60 -0
- package/rules/java/java.security.jwt-without-verification.rule.yaml +53 -0
- package/rules/java/java.security.null-cipher.rule.yaml +52 -0
- package/rules/java/java.security.permissive-cors.rule.yaml +53 -0
- package/rules/java/java.security.predictable-securerandom.rule.yaml +59 -0
- package/rules/java/java.security.reflected-output-from-request.rule.yaml +45 -0
- package/rules/java/java.security.servlet-insecure-cookie.rule.yaml +48 -0
- package/rules/java/java.security.shell-runtime-exec.rule.yaml +58 -0
- package/rules/java/java.security.spring-actuator-health-details-always.rule.yaml +53 -0
- package/rules/java/java.security.spring-actuator-sensitive-exposure.rule.yaml +53 -0
- package/rules/java/java.security.spring-csrf-globally-disabled.rule.yaml +62 -0
- package/rules/java/java.security.spring-debug-exposure.rule.yaml +48 -0
- package/rules/java/java.security.spring-permit-all-default.rule.yaml +60 -0
- package/rules/java/java.security.spring-webmvc-unrestricted-data-binding.rule.yaml +60 -0
- package/rules/java/java.security.template-unescaped-user-output.rule.yaml +59 -0
- package/rules/java/java.security.trust-all-certificates.rule.yaml +52 -0
- package/rules/java/java.security.unsafe-jackson-deserialization.rule.yaml +59 -0
- package/rules/java/java.security.weak-rsa-key-size.rule.yaml +54 -0
- package/rules/java/java.security.xxe-document-builder.rule.yaml +59 -0
- package/rules/java/java.security.xxe-xml-input-factory.rule.yaml +59 -0
- package/rules/java/java.testing.disabled-without-ticket-reference.rule.yaml +33 -0
- package/rules/java/java.testing.http-client-in-unit-test.rule.yaml +33 -0
- package/rules/java/java.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/php/php.correctness.duplicate-array-key.rule.yaml +36 -0
- package/rules/php/php.correctness.error-suppression-operator.rule.yaml +36 -0
- package/rules/php/php.correctness.nullsafe-returned-by-reference.rule.yaml +36 -0
- package/rules/php/php.correctness.switch-multiple-default.rule.yaml +36 -0
- package/rules/php/php.correctness.unreachable-after-return.rule.yaml +36 -0
- package/rules/php/php.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/php/php.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/php/php.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/php/php.security.debug-function-exposure.rule.yaml +55 -0
- package/rules/php/php.security.insecure-cors-wildcard-with-credentials.rule.yaml +51 -0
- package/rules/php/php.security.insecure-mail-or-file-transport.rule.yaml +51 -0
- package/rules/php/php.security.insecure-session-id-generation.rule.yaml +51 -0
- package/rules/php/php.security.insecure-session-or-cookie-config.rule.yaml +52 -0
- package/rules/php/php.security.laravel-sensitive-csrf-exclusion.rule.yaml +55 -0
- package/rules/php/php.security.laravel-unsafe-blade-output.rule.yaml +55 -0
- package/rules/php/php.security.laravel-unsafe-mass-assignment.rule.yaml +58 -0
- package/rules/php/php.security.no-dynamic-eval.rule.yaml +52 -0
- package/rules/php/php.security.sensitive-data-egress.rule.yaml +52 -0
- package/rules/php/php.security.symfony-csrf-disabled.rule.yaml +55 -0
- package/rules/php/php.security.symfony-debug-exposure.rule.yaml +57 -0
- package/rules/php/php.security.unsafe-file-upload-handling.rule.yaml +51 -0
- package/rules/php/php.security.unsafe-include-with-user-input.rule.yaml +52 -0
- package/rules/php/php.security.weak-cipher.rule.yaml +51 -0
- package/rules/php/php.security.wordpress-missing-nonce-or-capability.rule.yaml +55 -0
- package/rules/php/php.security.wordpress-unprepared-sql.rule.yaml +55 -0
- package/rules/php/php.security.xml-external-entity.rule.yaml +53 -0
- package/rules/php/php.testing.curl-in-unit-test.rule.yaml +33 -0
- package/rules/php/php.testing.mark-test-skipped-without-ticket-reference.rule.yaml +33 -0
- package/rules/php/php.testing.sleep-in-unit-test.rule.yaml +33 -0
- package/rules/python/py.correctness.assert-on-tuple.rule.yaml +33 -0
- package/rules/python/py.correctness.bare-except.rule.yaml +33 -0
- package/rules/python/py.correctness.broad-exception-handler.rule.yaml +33 -0
- package/rules/python/py.correctness.dangerous-mutable-default.rule.yaml +33 -0
- package/rules/python/py.correctness.duplicate-dict-key.rule.yaml +33 -0
- package/rules/python/py.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/python/py.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/python/py.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/python/py.security.bind-all-interfaces.rule.yaml +55 -0
- package/rules/python/py.security.debugger-import.rule.yaml +55 -0
- package/rules/python/py.security.django-csrf-exempt-state-changing.rule.yaml +59 -0
- package/rules/python/py.security.django-format-html-unsafe.rule.yaml +56 -0
- package/rules/python/py.security.django-mark-safe.rule.yaml +56 -0
- package/rules/python/py.security.django-missing-csrf-middleware.rule.yaml +60 -0
- package/rules/python/py.security.django-security-middleware-missing.rule.yaml +60 -0
- package/rules/python/py.security.django-unsafe-production-settings.rule.yaml +60 -0
- package/rules/python/py.security.drf-allow-any-default.rule.yaml +59 -0
- package/rules/python/py.security.drf-allow-any-unsafe-method.rule.yaml +59 -0
- package/rules/python/py.security.dynamic-code-execution.rule.yaml +55 -0
- package/rules/python/py.security.fastapi-insecure-cors.rule.yaml +56 -0
- package/rules/python/py.security.flask-debug-enabled.rule.yaml +56 -0
- package/rules/python/py.security.flask-missing-upload-body-limit.rule.yaml +57 -0
- package/rules/python/py.security.flask-unsafe-html-output.rule.yaml +57 -0
- package/rules/python/py.security.flask-unsafe-upload-filename.rule.yaml +57 -0
- package/rules/python/py.security.insecure-temp-file.rule.yaml +55 -0
- package/rules/python/py.security.insecure-yaml-load.rule.yaml +55 -0
- package/rules/python/py.security.jinja-autoescape-disabled.rule.yaml +58 -0
- package/rules/python/py.security.subprocess-shell-enabled.rule.yaml +55 -0
- package/rules/python/py.testing.pytest-skip-without-ticket-reference.rule.yaml +33 -0
- package/rules/python/py.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/python/py.testing.time-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/ruby/ruby.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/ruby/ruby.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/ruby/ruby.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/ruby/ruby.security.rails-csrf-disabled.rule.yaml +58 -0
- package/rules/ruby/ruby.security.rails-detailed-exceptions-enabled.rule.yaml +57 -0
- package/rules/ruby/ruby.security.rails-open-redirect.rule.yaml +58 -0
- package/rules/ruby/ruby.security.rails-unsafe-html-output.rule.yaml +59 -0
- package/rules/ruby/ruby.security.rails-unsafe-render.rule.yaml +58 -0
- package/rules/ruby/ruby.security.rails-unsafe-session-or-cookie-store.rule.yaml +58 -0
- package/rules/ruby/ruby.security.rails-unsafe-strong-parameters.rule.yaml +59 -0
- package/rules/ruby/ruby.security.sensitive-data-egress.rule.yaml +55 -0
- package/rules/ruby/ruby.security.sidekiq-web-unauthenticated-mount.rule.yaml +55 -0
- package/rules/ruby/ruby.testing.focused-example.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.pending-without-ticket-reference.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.skip-without-ticket-reference.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.sleep-in-unit-test.rule.yaml +33 -0
- package/rules/rust/rust.correctness.block-on-in-async.rule.yaml +48 -0
- package/rules/rust/rust.correctness.forget-join-handle.rule.yaml +48 -0
- package/rules/rust/rust.correctness.mutex-held-across-await.rule.yaml +48 -0
- package/rules/rust/rust.correctness.std-mutex-in-async-fn.rule.yaml +48 -0
- package/rules/rust/rust.correctness.thread-sleep-in-async.rule.yaml +48 -0
- package/rules/rust/rust.correctness.unbounded-channel.rule.yaml +49 -0
- package/rules/rust/rust.correctness.unchecked-index.rule.yaml +46 -0
- package/rules/rust/rust.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/rust/rust.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/rust/rust.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/rust/rust.security.actix-wildcard-cors-with-credentials.rule.yaml +60 -0
- package/rules/rust/rust.security.axum-body-limit-disabled.rule.yaml +58 -0
- package/rules/rust/rust.security.axum-insecure-cors-with-credentials.rule.yaml +60 -0
- package/rules/rust/rust.security.bind-all-interfaces.rule.yaml +57 -0
- package/rules/rust/rust.security.insecure-ssh-host-key.rule.yaml +57 -0
- package/rules/rust/rust.security.insecure-ssl-protocol.rule.yaml +57 -0
- package/rules/rust/rust.security.insecure-temp-file.rule.yaml +57 -0
- package/rules/rust/rust.security.insecure-yaml-load.rule.yaml +57 -0
- package/rules/rust/rust.security.jwt-without-verification.rule.yaml +57 -0
- package/rules/rust/rust.security.panic-in-async-handler.rule.yaml +57 -0
- package/rules/rust/rust.security.rocket-panic-prone-request-handler.rule.yaml +58 -0
- package/rules/rust/rust.security.rocket-unsafe-template-output.rule.yaml +60 -0
- package/rules/rust/rust.security.shell-command-spawn.rule.yaml +57 -0
- package/rules/rust/rust.security.sqlx-diesel-raw-interpolated-query.rule.yaml +60 -0
- package/rules/rust/rust.security.template-unescaped-request-value.rule.yaml +57 -0
- package/rules/rust/rust.security.tls-missing-min-version.rule.yaml +57 -0
- package/rules/rust/rust.security.warp-blocking-or-panic-in-async-handler.rule.yaml +58 -0
- package/rules/rust/rust.security.weak-crypto-import.rule.yaml +55 -0
- package/rules/rust/rust.security.weak-rsa-key-size.rule.yaml +57 -0
- package/rules/rust/rust.security.weak-tls-cipher.rule.yaml +57 -0
- package/rules/rust/rust.testing.ignore-without-ticket-reference.rule.yaml +33 -0
- package/rules/rust/rust.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/rust/rust.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/shared/security.archive-path-traversal.rule.yaml +51 -0
- package/rules/shared/security.external-file-upload.rule.yaml +50 -0
- package/rules/shared/security.insecure-http-transport.rule.yaml +10 -0
- package/rules/shared/security.no-command-execution-with-request-input.rule.yaml +10 -0
- package/rules/shared/security.no-hardcoded-credentials.rule.yaml +10 -0
- package/rules/shared/security.no-request-path-file-read.rule.yaml +10 -0
- package/rules/shared/security.no-sensitive-data-in-logs-and-telemetry.rule.yaml +10 -0
- package/rules/shared/security.no-sql-interpolation.rule.yaml +10 -0
- package/rules/shared/security.permissive-file-permissions.rule.yaml +50 -0
- package/rules/shared/security.sensitive-data-egress.rule.yaml +46 -0
- package/rules/shared/security.tls-verification-disabled.rule.yaml +10 -0
- package/rules/shared/security.unsafe-deserialization.rule.yaml +10 -0
- package/rules/shared/security.weak-hash-algorithm.rule.yaml +10 -0
- package/rules/typescript/ts.correctness.array-callback-missing-return.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.array-sort-without-compare.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.assignment-in-condition.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.assignment-to-import-binding.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.async-promise-executor.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.control-flow-in-finally.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.duplicate-function-parameter.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.duplicate-if-else-condition.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.duplicate-import-source.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.duplicate-object-key.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.duplicate-switch-case.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.empty-block-statement.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.for-in-on-array.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.identical-comparison-operands.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.infinite-loop.rule.yaml +32 -0
- package/rules/typescript/ts.correctness.invalid-await-expression.rule.yaml +32 -0
- package/rules/typescript/ts.correctness.invalid-typeof-comparison.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.missing-async-on-promise-method.rule.yaml +32 -0
- package/rules/typescript/ts.correctness.missing-super-call.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.no-floating-promise-in-function.rule.yaml +32 -0
- package/rules/typescript/ts.correctness.no-misused-promises.rule.yaml +32 -0
- package/rules/typescript/ts.correctness.promise-reject-non-error.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.reassign-catch-binding.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.regexp-pattern-unusual-control-character.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.self-assignment.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.this-before-super.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.unnecessary-return-await.rule.yaml +32 -0
- package/rules/typescript/ts.correctness.use-number-is-nan.rule.yaml +35 -0
- package/rules/typescript/ts.next.server-action-missing-local-auth.rule.yaml +48 -0
- package/rules/typescript/ts.performance.no-array-spread-in-hot-loop.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-await-in-loop.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-cache-miss-from-unstable-key.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-expensive-sort-in-render-path.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-json-parse-stringify-clone.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-large-object-spread-in-loop.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-n-plus-one-await-in-map.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-redundant-network-fetch.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-regex-construction-in-loop.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-sync-fs-in-request-path.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-unbounded-concurrency.rule.yaml +32 -0
- package/rules/typescript/ts.quality.no-ambiguous-abbreviations.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-barrel-file-cycle.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-boolean-parameter-trap.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-dead-export.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-empty-function.rule.yaml +32 -0
- package/rules/typescript/ts.quality.no-hidden-side-effect-import.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-inconsistent-error-shape.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-mixed-abstraction-level.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-primitive-obsession-in-domain-model.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-temporal-coupling.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-wide-public-surface.rule.yaml +27 -0
- package/rules/typescript/ts.react.no-accessibility-label-missing.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-activedescendant-on-non-focusable-host.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-bind-in-jsx-props.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-children-prop.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-click-without-keyboard-handler.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-deprecated-create-factory.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-deprecated-react-dom-root-api.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-derived-state-from-props.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-direct-state-mutation.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-duplicate-jsx-attributes.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-effect-fetch-without-cancellation.rule.yaml +35 -0
- package/rules/typescript/ts.react.no-find-dom-node.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-img-missing-alt-text.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-index-as-key-in-dynamic-list.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-interactive-role-on-static-semantics.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-invalid-anchor-href.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-jsx-props-spread.rule.yaml +35 -0
- package/rules/typescript/ts.react.no-keyboard-interaction-without-widget-role.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-legacy-lifecycle.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-missing-error-boundary.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-positive-tabindex.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-set-state-in-component-did-mount.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-set-state-in-component-did-update.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-static-element-with-synthetic-handlers.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-string-ref.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-target-blank-without-rel.rule.yaml +46 -0
- package/rules/typescript/ts.react.no-this-in-function-component.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-uncontrolled-to-controlled-input.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-widget-role-without-tabindex.rule.yaml +36 -0
- package/rules/typescript/ts.runtime.no-process-exit.rule.yaml +44 -0
- package/rules/typescript/ts.security.ajv-insecure-configuration.rule.yaml +44 -0
- package/rules/typescript/ts.security.angular-dom-sanitizer-bypass-untrusted-input.rule.yaml +48 -0
- package/rules/typescript/ts.security.apollo-server-csrf-disabled.rule.yaml +52 -0
- package/rules/typescript/ts.security.apollo-server-graphql-dev-tooling-exposure.rule.yaml +52 -0
- package/rules/typescript/ts.security.apollo-server-introspection-exposure.rule.yaml +51 -0
- package/rules/typescript/ts.security.apollo-server-missing-query-limits.rule.yaml +51 -0
- package/rules/typescript/ts.security.astro-vite-public-secret-define.rule.yaml +52 -0
- package/rules/typescript/ts.security.bind-to-all-interfaces.rule.yaml +10 -0
- package/rules/typescript/ts.security.browser-token-storage.rule.yaml +10 -0
- package/rules/typescript/ts.security.dangerous-insert-html.rule.yaml +10 -0
- package/rules/typescript/ts.security.dangerously-set-inner-html.rule.yaml +10 -0
- package/rules/typescript/ts.security.datadog-browser-track-user-interactions.rule.yaml +10 -0
- package/rules/typescript/ts.security.debug-mode-enabled.rule.yaml +10 -0
- package/rules/typescript/ts.security.debug-statement-in-source.rule.yaml +46 -0
- package/rules/typescript/ts.security.dynamodb-query-injection.rule.yaml +10 -0
- package/rules/typescript/ts.security.electron-dangerous-webpreferences.rule.yaml +45 -0
- package/rules/typescript/ts.security.electron-insecure-local-state.rule.yaml +45 -0
- package/rules/typescript/ts.security.electron-missing-ipc-origin-check.rule.yaml +45 -0
- package/rules/typescript/ts.security.electron-shell-open-external-unvalidated.rule.yaml +48 -0
- package/rules/typescript/ts.security.exposed-directory-listing.rule.yaml +10 -0
- package/rules/typescript/ts.security.express-cookie-missing-http-only.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-default-cookie-config.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-default-session-config.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-error-handler-information-disclosure.rule.yaml +51 -0
- package/rules/typescript/ts.security.express-insecure-cookie.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-missing-helmet.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-nosql-injection.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-permissive-cookie-config.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-permissive-cors.rule.yaml +52 -0
- package/rules/typescript/ts.security.express-reduce-fingerprint.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-static-assets-after-session.rule.yaml +16 -0
- package/rules/typescript/ts.security.express-static-dotfiles-allow.rule.yaml +51 -0
- package/rules/typescript/ts.security.express-unbounded-body-parser.rule.yaml +50 -0
- package/rules/typescript/ts.security.express-user-controlled-static-mount.rule.yaml +51 -0
- package/rules/typescript/ts.security.external-file-upload.rule.yaml +10 -0
- package/rules/typescript/ts.security.fastify-excessive-body-limit.rule.yaml +50 -0
- package/rules/typescript/ts.security.fastify-public-bind-without-trust-proxy.rule.yaml +54 -0
- package/rules/typescript/ts.security.file-generation.rule.yaml +10 -0
- package/rules/typescript/ts.security.format-string-using-user-input.rule.yaml +10 -0
- package/rules/typescript/ts.security.frontend-only-authorization.rule.yaml +10 -0
- package/rules/typescript/ts.security.graphql-upload-without-csrf-guard.rule.yaml +52 -0
- package/rules/typescript/ts.security.handlebars-no-escape.rule.yaml +10 -0
- package/rules/typescript/ts.security.hardcoded-auth-secret.rule.yaml +10 -0
- package/rules/typescript/ts.security.iframe-missing-sandbox-attribute.rule.yaml +45 -0
- package/rules/typescript/ts.security.import-using-user-input.rule.yaml +10 -0
- package/rules/typescript/ts.security.information-leakage.rule.yaml +10 -0
- package/rules/typescript/ts.security.insecure-allow-origin.rule.yaml +10 -0
- package/rules/typescript/ts.security.insecure-auth-cookie-flags.rule.yaml +10 -0
- package/rules/typescript/ts.security.insecure-content-security-policy-literal.rule.yaml +45 -0
- package/rules/typescript/ts.security.insecure-helmet-hardening-options.rule.yaml +46 -0
- package/rules/typescript/ts.security.insecure-password-hash-configuration.rule.yaml +10 -0
- package/rules/typescript/ts.security.insecure-websocket-transport.rule.yaml +10 -0
- package/rules/typescript/ts.security.insufficiently-random-values.rule.yaml +10 -0
- package/rules/typescript/ts.security.jwt-insecure-signing-algorithm.rule.yaml +45 -0
- package/rules/typescript/ts.security.jwt-not-revoked.rule.yaml +10 -0
- package/rules/typescript/ts.security.jwt-sensitive-claims.rule.yaml +10 -0
- package/rules/typescript/ts.security.legacy-buffer-constructor.rule.yaml +45 -0
- package/rules/typescript/ts.security.log-injection.rule.yaml +46 -0
- package/rules/typescript/ts.security.manual-html-sanitization.rule.yaml +10 -0
- package/rules/typescript/ts.security.missing-authorization-before-sensitive-action.rule.yaml +10 -0
- package/rules/typescript/ts.security.missing-integrity-check.rule.yaml +10 -0
- package/rules/typescript/ts.security.missing-message-origin-check.rule.yaml +10 -0
- package/rules/typescript/ts.security.missing-ownership-validation.rule.yaml +10 -0
- package/rules/typescript/ts.security.missing-request-timeout-or-retry.rule.yaml +10 -0
- package/rules/typescript/ts.security.nestjs-helmet-after-route-mount.rule.yaml +50 -0
- package/rules/typescript/ts.security.nestjs-missing-global-validation-pipe.rule.yaml +51 -0
- package/rules/typescript/ts.security.nestjs-skip-throttle-sensitive-route.rule.yaml +51 -0
- package/rules/typescript/ts.security.nestjs-validation-pipe-without-whitelist.rule.yaml +52 -0
- package/rules/typescript/ts.security.no-alert-confirm-prompt.rule.yaml +44 -0
- package/rules/typescript/ts.security.no-arguments-callee.rule.yaml +44 -0
- package/rules/typescript/ts.security.no-assign-mutable-export.rule.yaml +45 -0
- package/rules/typescript/ts.security.no-dynamic-execution.rule.yaml +10 -0
- package/rules/typescript/ts.security.no-fs-readfile-sync-in-handler.rule.yaml +46 -0
- package/rules/typescript/ts.security.no-global-native-reassignment.rule.yaml +44 -0
- package/rules/typescript/ts.security.no-innerhtml-assignment.rule.yaml +10 -0
- package/rules/typescript/ts.security.no-javascript-url.rule.yaml +44 -0
- package/rules/typescript/ts.security.no-native-prototype-extension.rule.yaml +44 -0
- package/rules/typescript/ts.security.no-sync-child-process-exec.rule.yaml +45 -0
- package/rules/typescript/ts.security.no-throw-literal.rule.yaml +44 -0
- package/rules/typescript/ts.security.no-with-statement.rule.yaml +44 -0
- package/rules/typescript/ts.security.non-literal-fs-filename.rule.yaml +10 -0
- package/rules/typescript/ts.security.nuxt-public-runtime-secret.rule.yaml +51 -0
- package/rules/typescript/ts.security.observable-timing-discrepancy.rule.yaml +10 -0
- package/rules/typescript/ts.security.open-redirect.rule.yaml +12 -0
- package/rules/typescript/ts.security.permissive-allow-origin.rule.yaml +10 -0
- package/rules/typescript/ts.security.permissive-file-permissions.rule.yaml +10 -0
- package/rules/typescript/ts.security.postmessage-wildcard-origin.rule.yaml +10 -0
- package/rules/typescript/ts.security.predictable-token-generation.rule.yaml +10 -0
- package/rules/typescript/ts.security.raw-html-using-user-input.rule.yaml +10 -0
- package/rules/typescript/ts.security.request-driven-array-index-access.rule.yaml +43 -0
- package/rules/typescript/ts.security.sensitive-data-egress.rule.yaml +11 -0
- package/rules/typescript/ts.security.sensitive-data-in-exception.rule.yaml +10 -0
- package/rules/typescript/ts.security.sensitive-data-written-to-file.rule.yaml +10 -0
- package/rules/typescript/ts.security.ssrf.rule.yaml +11 -0
- package/rules/typescript/ts.security.token-or-session-not-validated.rule.yaml +10 -0
- package/rules/typescript/ts.security.ui-redress.rule.yaml +10 -0
- package/rules/typescript/ts.security.unsafe-dirname-path-concat.rule.yaml +44 -0
- package/rules/typescript/ts.security.unsafe-dompurify-version.rule.yaml +46 -0
- package/rules/typescript/ts.security.unsafe-marked-version.rule.yaml +46 -0
- package/rules/typescript/ts.security.unsanitized-http-response.rule.yaml +10 -0
- package/rules/typescript/ts.security.unvalidated-external-input.rule.yaml +10 -0
- package/rules/typescript/ts.security.user-controlled-sendfile.rule.yaml +10 -0
- package/rules/typescript/ts.security.user-controlled-view-render.rule.yaml +10 -0
- package/rules/typescript/ts.security.weak-cipher-or-mode.rule.yaml +10 -0
- package/rules/typescript/ts.security.weak-key-strength.rule.yaml +10 -0
- package/rules/typescript/ts.security.weak-tls-version.rule.yaml +10 -0
- package/rules/typescript/ts.security.xml-parse-string-with-untrusted-input.rule.yaml +45 -0
- package/rules/typescript/ts.testing.no-flaky-timer-test.rule.yaml +38 -0
- package/rules/typescript/ts.testing.no-focused-test.rule.yaml +34 -0
- package/rules/typescript/ts.testing.no-missing-edge-case-tests.rule.yaml +35 -0
- package/rules/typescript/ts.testing.no-network-call-in-unit-test.rule.yaml +38 -0
- package/rules/typescript/ts.testing.no-skipped-test-without-ticket.rule.yaml +34 -0
- package/rules/typescript/ts.testing.no-snapshot-without-intent.rule.yaml +34 -0
- package/rules/typescript/ts.testing.no-test-only-code-in-production.rule.yaml +38 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-children-prop
|
|
5
|
+
title: Prefer nested JSX children over the children prop
|
|
6
|
+
summary: Passing `children` as a named prop is harder to read than composing elements between opening and closing tags.
|
|
7
|
+
rationale: Nested children match React composition idioms and keep component APIs consistent across the tree.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.children-prop
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: maintainability.ui
|
|
25
|
+
severity: low
|
|
26
|
+
confidence: 0.8
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Nest JSX children instead of using the children prop
|
|
32
|
+
summary: "`${captures.issue.text}` passes children through a prop attribute."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Place child elements between the component tags or accept `children` through normal function parameters without a JSX prop.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-click-without-keyboard-handler
|
|
5
|
+
title: Support keyboard interaction for click handlers
|
|
6
|
+
summary: "Non-interactive JSX elements that respond to clicks also need an equivalent keyboard path."
|
|
7
|
+
rationale: Mouse-only interaction blocks keyboard users and creates inaccessible custom controls that do not behave like native UI elements.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- accessibility
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: function
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.click-without-keyboard-handler
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: correctness.ui
|
|
26
|
+
severity: high
|
|
27
|
+
confidence: 0.84
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- accessibility
|
|
31
|
+
- ui
|
|
32
|
+
message:
|
|
33
|
+
title: Add keyboard support to click-driven UI
|
|
34
|
+
summary: "`${captures.issue.text}` handles clicks without an equivalent keyboard event."
|
|
35
|
+
remediation:
|
|
36
|
+
summary: Prefer native buttons or links, or add the necessary role, focus behavior, and keyboard handlers for the same action.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-deprecated-create-factory
|
|
5
|
+
title: Avoid React.createFactory
|
|
6
|
+
summary: "`createFactory` is a legacy helper for pre-JSX code and is removed from modern React typings and guidance."
|
|
7
|
+
rationale: Function components and JSX provide clearer element construction without the indirection and weaker typing of factory helpers.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.deprecated-create-factory
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: low
|
|
26
|
+
confidence: 0.86
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Replace createFactory with JSX or createElement
|
|
32
|
+
summary: "`${captures.issue.text}` relies on the deprecated `createFactory` helper."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Inline JSX, call `React.createElement` with explicit props, or convert the call site to a small function component.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-deprecated-react-dom-root-api
|
|
5
|
+
title: Migrate off legacy ReactDOM render entrypoints
|
|
6
|
+
summary: "`render`, `hydrate`, and `unmountComponentAtNode` from `react-dom` are legacy APIs replaced by the `createRoot` and `hydrateRoot` clients."
|
|
7
|
+
rationale: The concurrent renderer expects roots created through the client API; legacy entrypoints block adoption of React 18 streaming and suspense features.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.deprecated-react-dom-root-api
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.88
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Switch to createRoot or hydrateRoot
|
|
32
|
+
summary: "`${captures.issue.text}` calls a deprecated ReactDOM mounting API."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Import `createRoot` or `hydrateRoot` from `react-dom/client`, create a root once, and use `root.render` for updates instead of legacy `ReactDOM.render`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-derived-state-from-props
|
|
5
|
+
title: Avoid initializing state directly from props
|
|
6
|
+
summary: Duplicating props into useState without an explicit sync strategy hides updates and confuses controlled versus uncontrolled boundaries.
|
|
7
|
+
rationale: Props-driven initial state goes stale when props change unless you synchronize intentionally or lift state up.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.derived-state-from-props
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.72
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Derive values from props without fragile state copies
|
|
32
|
+
summary: "`${captures.issue.text}` initializes state from incoming props."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Prefer controlled props, derive with useMemo, or synchronize with useEffect when props legitimately own the value.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-direct-state-mutation
|
|
5
|
+
title: Do not mutate React state directly
|
|
6
|
+
summary: Assigning to `this.state` bypasses React change detection and produces stale UI.
|
|
7
|
+
rationale: State updates must flow through setState or hooks so React can schedule renders and enforce immutability guarantees.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.direct-state-mutation
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: high
|
|
26
|
+
confidence: 0.88
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Update React state with setState
|
|
32
|
+
summary: "`${captures.issue.text}` mutates state directly."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Call setState with the next value or replace the state object immutably instead of assigning into this.state.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-duplicate-jsx-attributes
|
|
5
|
+
title: Remove duplicate JSX attributes
|
|
6
|
+
summary: Repeating the same prop on a JSX element makes the last value win silently and hides author intent.
|
|
7
|
+
rationale: Duplicate attributes are usually copy-paste mistakes that change runtime behavior without type errors.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.duplicate-jsx-attribute
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.9
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Keep only one JSX attribute with the same name
|
|
32
|
+
summary: "`${captures.issue.text}` appears more than once on the same JSX element."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Remove the duplicate attribute or merge the values into a single prop expression.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-effect-fetch-without-cancellation
|
|
5
|
+
title: Cancel inflight fetches inside React effects
|
|
6
|
+
summary: React effects that fetch remote data should attach AbortSignal wiring so stale responses cannot commit after dependencies change.
|
|
7
|
+
rationale: Race conditions from abandoned requests produce inconsistent UI state and duplicated side effects when identifiers or routes change quickly.
|
|
8
|
+
tags:
|
|
9
|
+
- performance
|
|
10
|
+
- react
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: performance.react-effect-fetch-without-cancellation
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: performance.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.74
|
|
27
|
+
tags:
|
|
28
|
+
- performance
|
|
29
|
+
- react
|
|
30
|
+
message:
|
|
31
|
+
title: Abort stale fetch responses inside effects
|
|
32
|
+
summary: "`${captures.issue.text}` loads remote data without an AbortSignal or comparable cancellation guard."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: >-
|
|
35
|
+
Thread AbortController.signal through fetch or axios calls and abort inside the effect cleanup, or migrate to a data library that manages cancellation.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-find-dom-node
|
|
5
|
+
title: Avoid ReactDOM.findDOMNode
|
|
6
|
+
summary: "`findDOMNode` reaches through component boundaries with a deprecated escape hatch that breaks strict mode migrations."
|
|
7
|
+
rationale: Direct DOM lookups make React trees harder to refactor and fail to model multi-node or fragment-based rendering safely.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.find-dom-node
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.8
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: "Replace `findDOMNode` with direct refs"
|
|
32
|
+
summary: "`${captures.issue.text}` uses the deprecated `findDOMNode` API."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Attach a ref directly to the rendered element, or forward refs through component boundaries instead of reading DOM nodes imperatively.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-img-missing-alt-text
|
|
5
|
+
title: Add alt text to meaningful images
|
|
6
|
+
summary: "JSX images need a meaningful `alt` value, or an explicit empty string when the image is decorative."
|
|
7
|
+
rationale: Missing alternative text hides visual meaning from screen reader users and creates avoidable accessibility regressions.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- accessibility
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: function
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.missing-alt-text
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: correctness.ui
|
|
26
|
+
severity: high
|
|
27
|
+
confidence: 0.87
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- accessibility
|
|
31
|
+
- ui
|
|
32
|
+
message:
|
|
33
|
+
title: Add alternative text to images
|
|
34
|
+
summary: "`${captures.issue.text}` renders without alternative text."
|
|
35
|
+
remediation:
|
|
36
|
+
summary: "Add a meaningful `alt` string, or set `alt=\"\"` only when the image is purely decorative and redundant."
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-index-as-key-in-dynamic-list
|
|
5
|
+
title: Avoid array index keys in dynamic lists
|
|
6
|
+
summary: Using the map index as a React key breaks reconciliation when lists reorder, filter, or insert items.
|
|
7
|
+
rationale: Stable keys help React preserve component state and reduce subtle UI bugs when list membership changes.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.index-key-in-list
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.78
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Replace index keys with stable identifiers
|
|
32
|
+
summary: "`${captures.issue.text}` uses a list index as a React key."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Use a stable business identifier from each item, or derive a stable key when the dataset truly never mutates order.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-interactive-role-on-static-semantics
|
|
5
|
+
title: Keep interactive roles off static semantics
|
|
6
|
+
summary: "Headings, captions, and phrasing content should not pretend to be buttons or tabs without restructuring the markup."
|
|
7
|
+
rationale: Mixing document roles with widget roles confuses assistive technologies and usually signals a heading or label that should stay static while a real control sits nearby.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- accessibility
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: function
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.semantic-static-with-interactive-role
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: correctness.ui
|
|
26
|
+
severity: medium
|
|
27
|
+
confidence: 0.78
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- accessibility
|
|
31
|
+
- ui
|
|
32
|
+
message:
|
|
33
|
+
title: Avoid widget roles on semantic text elements
|
|
34
|
+
summary: "`${captures.issue.text}` assigns an interactive ARIA role to a semantic text element."
|
|
35
|
+
remediation:
|
|
36
|
+
summary: Move the interaction to a sibling `button` or link, keep the heading for structure only, and wire behaviour with IDs or aria-controls instead of overloading roles.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-invalid-anchor-href
|
|
5
|
+
title: Use real destinations for anchor elements
|
|
6
|
+
summary: "Links need a concrete `href` so navigation, keyboard activation, and assistive technologies behave predictably."
|
|
7
|
+
rationale: Placeholder anchors and `javascript:` URLs break expectations for links, harm accessibility, and often hide ad-hoc click handlers that should be buttons instead.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- accessibility
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: function
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.anchor-with-invalid-href
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: correctness.ui
|
|
26
|
+
severity: medium
|
|
27
|
+
confidence: 0.82
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- accessibility
|
|
31
|
+
- ui
|
|
32
|
+
message:
|
|
33
|
+
title: Give anchors a valid href
|
|
34
|
+
summary: "`${captures.issue.text}` is an anchor without a usable navigation target."
|
|
35
|
+
remediation:
|
|
36
|
+
summary: Point `href` at a real URL or in-page fragment, use a native button for actions, or add an explicit widget role with keyboard support when mimicking controls.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-jsx-props-spread
|
|
5
|
+
title: Avoid spreading props onto JSX elements
|
|
6
|
+
summary: Unfiltered prop spreads hide which attributes reach the DOM and defeat static analysis of event handlers and accessibility props.
|
|
7
|
+
rationale: Explicit prop forwarding documents the component contract and avoids accidentally passing invalid or sensitive attributes downstream.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- performance
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: function
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.jsx-props-spread
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: maintainability.ui
|
|
26
|
+
severity: low
|
|
27
|
+
confidence: 0.75
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- ui
|
|
31
|
+
message:
|
|
32
|
+
title: Forward JSX props explicitly
|
|
33
|
+
summary: "`${captures.issue.text}` spreads props onto a JSX element."
|
|
34
|
+
remediation:
|
|
35
|
+
summary: Destructure the props you intend to pass, whitelist safe attributes, or use a typed wrapper component.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-keyboard-interaction-without-widget-role
|
|
5
|
+
title: Declare a widget role when mixing click and key handlers
|
|
6
|
+
summary: "Elements that handle both clicks and key events behave like custom controls and should advertise an appropriate ARIA role."
|
|
7
|
+
rationale: Assistive technologies cannot infer widget behaviour from events alone; an explicit role pairs keyboard support with the correct accessibility tree semantics.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- accessibility
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: function
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.keyboard-interaction-without-widget-role
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: correctness.ui
|
|
26
|
+
severity: medium
|
|
27
|
+
confidence: 0.8
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- accessibility
|
|
31
|
+
- ui
|
|
32
|
+
message:
|
|
33
|
+
title: Add a widget role for custom controls
|
|
34
|
+
summary: "`${captures.issue.text}` combines click and keyboard handlers without a widget role."
|
|
35
|
+
remediation:
|
|
36
|
+
summary: Set `role="button"` or another fitting widget role, ensure focusability, and mirror native control keyboard patterns.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-legacy-lifecycle
|
|
5
|
+
title: Avoid legacy React lifecycle methods
|
|
6
|
+
summary: Legacy class lifecycle hooks are brittle in strict mode and block migration toward modern React patterns.
|
|
7
|
+
rationale: Deprecated lifecycle methods are easy to misuse during async rendering and create noisy upgrade work across older React codebases.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.legacy-lifecycle
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.76
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Replace legacy React lifecycle methods
|
|
32
|
+
summary: "`${captures.issue.text}` is a legacy React lifecycle method."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: "Prefer modern lifecycle alternatives, hooks, or an explicit `UNSAFE_` migration name only as a short-lived bridge."
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-missing-error-boundary
|
|
5
|
+
title: Add a route-level error boundary for Next.js App Router segments
|
|
6
|
+
summary: Next.js route segments should declare an error.tsx handler so async and client failures surface safely.
|
|
7
|
+
rationale: Without a segment error boundary, failures in pages or layouts can crash the entire subtree without recovery UI.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- next
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: project
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.missing-error-boundary
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: correctness.framework
|
|
26
|
+
severity: medium
|
|
27
|
+
confidence: 0.75
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- next
|
|
31
|
+
- ui
|
|
32
|
+
message:
|
|
33
|
+
title: Provide error.tsx for App Router segments
|
|
34
|
+
summary: "`${captures.issue.text}` is missing a sibling error boundary file for its route segment."
|
|
35
|
+
remediation:
|
|
36
|
+
summary: Add error.tsx next to the segment’s page or layout, or hoist shared handling to a parent segment.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-positive-tabindex
|
|
5
|
+
title: Avoid positive tabIndex values
|
|
6
|
+
summary: "Positive `tabIndex` values create a custom keyboard order that is fragile and usually less accessible than DOM order."
|
|
7
|
+
rationale: Manual focus sequencing is easy to break as layouts evolve and makes keyboard navigation less predictable for assistive-technology users.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- accessibility
|
|
11
|
+
- ui
|
|
12
|
+
- rules-catalog
|
|
13
|
+
stability: experimental
|
|
14
|
+
appliesTo: function
|
|
15
|
+
scope:
|
|
16
|
+
languages:
|
|
17
|
+
- typescript
|
|
18
|
+
- javascript
|
|
19
|
+
match:
|
|
20
|
+
fact:
|
|
21
|
+
kind: ui.react.positive-tabindex
|
|
22
|
+
bind: issue
|
|
23
|
+
emit:
|
|
24
|
+
finding:
|
|
25
|
+
category: correctness.ui
|
|
26
|
+
severity: medium
|
|
27
|
+
confidence: 0.85
|
|
28
|
+
tags:
|
|
29
|
+
- react
|
|
30
|
+
- accessibility
|
|
31
|
+
- ui
|
|
32
|
+
message:
|
|
33
|
+
title: Keep keyboard focus order natural
|
|
34
|
+
summary: "`${captures.issue.text}` uses a positive `tabIndex` value."
|
|
35
|
+
remediation:
|
|
36
|
+
summary: "Prefer source-order focus flow, use `tabIndex={0}` only when needed, and reserve negative values for programmatic focus targets."
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
apiVersion: critiq.dev/v1alpha1
|
|
2
|
+
kind: Rule
|
|
3
|
+
metadata:
|
|
4
|
+
id: ts.react.no-set-state-in-component-did-mount
|
|
5
|
+
title: Avoid setState in componentDidMount
|
|
6
|
+
summary: Synchronous state updates during mount trigger an extra render before the browser paints the initial tree.
|
|
7
|
+
rationale: Initial state belongs in the constructor or class field initializers so the first render already reflects the mounted view.
|
|
8
|
+
tags:
|
|
9
|
+
- react
|
|
10
|
+
- ui
|
|
11
|
+
- rules-catalog
|
|
12
|
+
stability: experimental
|
|
13
|
+
appliesTo: function
|
|
14
|
+
scope:
|
|
15
|
+
languages:
|
|
16
|
+
- typescript
|
|
17
|
+
- javascript
|
|
18
|
+
match:
|
|
19
|
+
fact:
|
|
20
|
+
kind: ui.react.set-state-in-component-did-mount
|
|
21
|
+
bind: issue
|
|
22
|
+
emit:
|
|
23
|
+
finding:
|
|
24
|
+
category: correctness.ui
|
|
25
|
+
severity: medium
|
|
26
|
+
confidence: 0.82
|
|
27
|
+
tags:
|
|
28
|
+
- react
|
|
29
|
+
- ui
|
|
30
|
+
message:
|
|
31
|
+
title: Initialize state before mount completes
|
|
32
|
+
summary: "`${captures.issue.text}` calls setState inside componentDidMount."
|
|
33
|
+
remediation:
|
|
34
|
+
summary: Move the initial value into state initialization or derive it from props with a guarded update strategy.
|