From 31acb611ab3392479e4419bc0e1ef3aa2beb2099 Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Thu, 11 Jun 2026 18:12:14 +0530 Subject: [PATCH 1/4] Upgrade to Ruby 3.4 / Rails 8.1 and ship Wave 0 SEO fixes. Unblock search crawlers via Rack::Attack throttles, add canonical URLs and JSON-LD, fix sitemap host/caching, and improve local dev (proxy auth, routes, vendored bitquery_logger). Co-authored-by: Cursor --- .ruby-version | 2 +- Dockerfile | 4 +- Gemfile | 15 +- Gemfile.lock | 460 ++++++++++-------- Rakefile | 1 + app/controllers/application_controller.rb | 53 +- .../proxy_eap_graphql_controller.rb | 2 +- app/controllers/proxy_graphql_controller.rb | 2 +- .../proxy_streaming_graphql_controller.rb | 2 +- app/helpers/seo_helper.rb | 66 +++ app/services/streaming_token_service.rb | 11 +- app/views/shared/_footer.html.erb | 6 - app/views/shared/_head.html.erb | 1 + app/views/shared/_seo_meta.html.erb | 16 + app/views/sitemaps/robots.text.erb | 2 +- app/views/utility/errors.html.erb | 8 +- bin/dev-server | 21 + config/application.rb | 2 +- config/environments/production.rb | 6 +- config/initializers/bitquery_logger.rb | 2 - config/initializers/canonical_host.rb | 8 + config/initializers/rack_attack.rb | 69 +-- config/routes.rb | 9 + lib/cached_query.rb | 32 ++ package.json | 2 +- ...ry_logger-233e44a43d4c => bitquery_logger} | 0 yarn.lock | 8 +- 27 files changed, 541 insertions(+), 269 deletions(-) create mode 100644 app/helpers/seo_helper.rb create mode 100644 app/views/shared/_seo_meta.html.erb create mode 100755 bin/dev-server create mode 100644 config/initializers/canonical_host.rb create mode 100644 lib/cached_query.rb rename vendor/{bundle/ruby/3.3.0/bundler/gems/bitquery_logger-233e44a43d4c => bitquery_logger} (100%) diff --git a/.ruby-version b/.ruby-version index 6d5369b9..61a52c91 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -ruby-3.3.4 +ruby-3.4.9 diff --git a/Dockerfile b/Dockerfile index 7355509c..54f4c819 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3.4-alpine AS builder +FROM ruby:3.4.9-alpine AS builder WORKDIR /app ENV RAILS_ENV="production" \ @@ -32,7 +32,7 @@ RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails shakapacker:compile && \ RUN yarn install --production && \ yarn cache clean -FROM ruby:3.3.4-alpine AS runner +FROM ruby:3.4.9-alpine AS runner WORKDIR /app diff --git a/Gemfile b/Gemfile index d123f25e..4cb5b6a9 100644 --- a/Gemfile +++ b/Gemfile @@ -1,14 +1,14 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '~> 3.3.4' +ruby '~> 3.4.0' # gem 'turbo-rails', '~> 2.0.6' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 7.1.3.4' +gem 'rails', '~> 8.1.0' # Use Puma as the app server -gem 'puma', '~> 6.4.3' +gem 'puma', '~> 7.0' # Use SCSS for stylesheets gem 'sass-rails', '>= 6' # Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker @@ -17,8 +17,7 @@ gem 'shakapacker', '~> 8.0.1' # gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.12.0' -# Use Redis adapter to run Action Cable in production -# gem 'redis', '~> 4.0' +gem 'redis', '~> 5.0' # Use Active Model has_secure_password # gem 'bcrypt', '~> 3.1.7' @@ -31,14 +30,14 @@ gem 'feedjira', '~> 3.2.3' gem 'rack-attack' # Logger -gem 'bitquery_logger', git: 'https://github.com/bitquery/bitquery_logger.git', tag: 'v0.7.9' # , path: '../bitquery_logger' -gem 'exception_notification' -gem 'exception_notification-rake', '~> 0.3.1' +gem 'bitquery_logger', path: 'vendor/bitquery_logger' +gem 'exception_notification', '~> 5.0' gem 'lograge' gem 'logstash-event' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '~> 1.18.3', require: false +gem 'csv' group :development do # Access an interactive console on exception pages or by calling 'console' anywhere in the code. diff --git a/Gemfile.lock b/Gemfile.lock index 34536d18..1365ad0a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,8 @@ -GIT - remote: https://github.com/bitquery/bitquery_logger.git - revision: 233e44a43d4c10881197b16dc773a513ab0ae7aa - tag: v0.7.9 +PATH + remote: vendor/bitquery_logger specs: bitquery_logger (0.7.9) - exception_notification (~> 4.5.0) - exception_notification-rake (~> 0.3.1) + exception_notification (>= 4.5.0, < 6) logstash-logger (~> 0.26.1) oj (~> 3.13.16) oj_mimic_json (~> 1.0.1) @@ -13,164 +10,170 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.3.4) - actionpack (= 7.1.3.4) - activesupport (= 7.1.3.4) + action_text-trix (2.1.19) + railties + actioncable (8.1.3) + actionpack (= 8.1.3) + activesupport (= 8.1.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.4) - actionpack (= 7.1.3.4) - activejob (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.3.4) - actionpack (= 7.1.3.4) - actionview (= 7.1.3.4) - activejob (= 7.1.3.4) - activesupport (= 7.1.3.4) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (8.1.3) + actionpack (= 8.1.3) + activejob (= 8.1.3) + activerecord (= 8.1.3) + activestorage (= 8.1.3) + activesupport (= 8.1.3) + mail (>= 2.8.0) + actionmailer (8.1.3) + actionpack (= 8.1.3) + actionview (= 8.1.3) + activejob (= 8.1.3) + activesupport (= 8.1.3) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.3.4) - actionview (= 7.1.3.4) - activesupport (= 7.1.3.4) + actionpack (8.1.3) + actionview (= 8.1.3) + activesupport (= 8.1.3) nokogiri (>= 1.8.5) - racc rack (>= 2.2.4) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3.4) - actionpack (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) + useragent (~> 0.16) + actiontext (8.1.3) + action_text-trix (~> 2.1.15) + actionpack (= 8.1.3) + activerecord (= 8.1.3) + activestorage (= 8.1.3) + activesupport (= 8.1.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.4) - activesupport (= 7.1.3.4) + actionview (8.1.3) + activesupport (= 8.1.3) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.3.4) - activesupport (= 7.1.3.4) + activejob (8.1.3) + activesupport (= 8.1.3) globalid (>= 0.3.6) - activemodel (7.1.3.4) - activesupport (= 7.1.3.4) - activerecord (7.1.3.4) - activemodel (= 7.1.3.4) - activesupport (= 7.1.3.4) + activemodel (8.1.3) + activesupport (= 8.1.3) + activerecord (8.1.3) + activemodel (= 8.1.3) + activesupport (= 8.1.3) timeout (>= 0.4.0) - activestorage (7.1.3.4) - actionpack (= 7.1.3.4) - activejob (= 7.1.3.4) - activerecord (= 7.1.3.4) - activesupport (= 7.1.3.4) + activestorage (8.1.3) + actionpack (= 8.1.3) + activejob (= 8.1.3) + activerecord (= 8.1.3) + activesupport (= 8.1.3) marcel (~> 1.0) - activesupport (7.1.3.4) + activesupport (8.1.3) base64 bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) - airbrussh (1.5.2) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + airbrussh (1.6.1) sshkit (>= 1.6.1, != 1.7.0) - anyway_config (2.6.4) + anyway_config (2.8.0) ruby-next-core (~> 1.0) - ast (2.4.2) - base64 (0.2.0) + ast (2.4.3) + base64 (0.3.0) better_errors (2.10.1) erubi (>= 1.0.0) rack (>= 0.9.0) rouge (>= 1.0.0) - bigdecimal (3.1.8) + bigdecimal (4.1.2) bindex (0.8.1) binding_of_caller (1.0.1) debug_inspector (>= 1.2.0) - bootsnap (1.18.3) + bootsnap (1.18.6) msgpack (~> 1.2) builder (3.3.0) - capistrano (3.19.1) + capistrano (3.19.2) airbrussh (>= 1.0.0) i18n rake (>= 10.0.0) sshkit (>= 1.9.0) - capistrano-bundler (2.1.0) + capistrano-bundler (2.2.0) capistrano (~> 3.1) - capistrano-rails (1.6.3) + capistrano-rails (1.7.0) capistrano (~> 3.1) capistrano-bundler (>= 1.1, < 3) - concurrent-ruby (1.3.3) - connection_pool (2.4.1) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) crass (1.0.6) - date (3.3.4) + csv (3.3.5) + date (3.5.1) debug_inspector (1.2.0) - dotenv (3.1.2) - dotenv-rails (3.1.2) - dotenv (= 3.1.2) + dotenv (3.1.8) + dotenv-rails (3.1.8) + dotenv (= 3.1.8) railties (>= 6.1) - drb (2.2.1) - dry-initializer (3.1.1) - erubi (1.13.0) + drb (2.2.3) + dry-initializer (3.2.0) + erb (6.0.4) + erubi (1.13.1) eventmachine (1.2.7) - exception_notification (4.5.0) - actionmailer (>= 5.2, < 8) - activesupport (>= 5.2, < 8) - exception_notification-rake (0.3.1) - exception_notification (~> 4.3) - rake (>= 0.9.0) + exception_notification (5.0.1) + actionmailer (>= 7.1, < 9) + activesupport (>= 7.1, < 9) faye-websocket (0.12.0) eventmachine (>= 0.12.0) websocket-driver (>= 0.8.0) - feedjira (3.2.3) + feedjira (3.2.6) + logger (>= 1.0, < 2) loofah (>= 2.3.1, < 3) sax-machine (>= 1.0, < 2) - ffi (1.17.0) - ffi (1.17.0-aarch64-linux-gnu) - ffi (1.17.0-aarch64-linux-musl) - ffi (1.17.0-arm-linux-gnu) - ffi (1.17.0-arm-linux-musl) - ffi (1.17.0-arm64-darwin) - ffi (1.17.0-x86-linux-gnu) - ffi (1.17.0-x86-linux-musl) - ffi (1.17.0-x86_64-darwin) - ffi (1.17.0-x86_64-linux-gnu) - ffi (1.17.0-x86_64-linux-musl) - globalid (1.2.1) + ffi (1.17.4) + ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-aarch64-linux-musl) + ffi (1.17.4-arm-linux-gnu) + ffi (1.17.4-arm-linux-musl) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86-linux-gnu) + ffi (1.17.4-x86-linux-musl) + ffi (1.17.4-x86_64-darwin) + ffi (1.17.4-x86_64-linux-gnu) + ffi (1.17.4-x86_64-linux-musl) + fiber-storage (1.0.1) + globalid (1.3.0) activesupport (>= 6.1) - graphql (2.3.10) + graphql (2.6.3) base64 - graphql-client (0.23.0) + fiber-storage + logger + graphql-client (0.26.0) activesupport (>= 3.0) graphql (>= 1.13.0) - i18n (1.14.5) + i18n (1.14.8) concurrent-ruby (~> 1.0) - io-console (0.7.2) - irb (1.14.0) + io-console (0.8.2) + irb (1.18.0) + pp (>= 0.6.0) + prism (>= 1.3.0) rdoc (>= 4.0.0) reline (>= 0.4.2) jbuilder (2.12.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) - json (2.7.2) - language_server-protocol (3.17.0.3) + json (2.19.8) + language_server-protocol (3.17.0.5) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) @@ -179,129 +182,175 @@ GEM logstash-event (1.2.02) logstash-logger (0.26.1) logstash-event (~> 1.2) - loofah (2.22.0) + loofah (2.25.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) - mail (2.8.1) + mail (2.9.0) + logger mini_mime (>= 0.1.1) net-imap net-pop net-smtp - marcel (1.0.4) + marcel (1.2.1) mini_mime (1.1.5) mini_portile2 (2.8.9) - minitest (5.24.1) - msgpack (1.7.2) - mutex_m (0.2.0) - net-imap (0.4.14) + minitest (6.0.6) + drb (~> 2.0) + prism (~> 1.5) + msgpack (1.8.3) + net-imap (0.6.4.1) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-scp (4.0.0) + net-scp (4.1.0) net-ssh (>= 2.6.5, < 8.0.0) net-sftp (4.0.0) net-ssh (>= 5.0.0, < 8.0.0) - net-smtp (0.5.0) + net-smtp (0.5.1) net-protocol - net-ssh (7.2.3) - nio4r (2.7.3) - nokogiri (1.16.6) + net-ssh (7.3.2) + nio4r (2.7.5) + nokogiri (1.19.3) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.16.6-aarch64-linux) + nokogiri (1.19.3-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-aarch64-linux-musl) racc (~> 1.4) - nokogiri (1.16.6-arm-linux) + nokogiri (1.19.3-arm-linux-gnu) racc (~> 1.4) - nokogiri (1.16.6-arm64-darwin) + nokogiri (1.19.3-arm-linux-musl) racc (~> 1.4) - nokogiri (1.16.6-x86-linux) + nokogiri (1.19.3-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.6-x86_64-darwin) + nokogiri (1.19.3-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.6-x86_64-linux) + nokogiri (1.19.3-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-x86_64-linux-musl) racc (~> 1.4) oj (3.13.23) oj_mimic_json (1.0.1) - package_json (0.1.0) - parallel (1.25.1) - parser (3.3.4.0) + ostruct (0.6.3) + package_json (0.2.0) + parallel (1.28.0) + parser (3.3.11.1) ast (~> 2.4.1) racc - prometheus-client-mmap (1.1.1) - rb_sys (~> 0.9.86) - prometheus-client-mmap (1.1.1-aarch64-linux) - rb_sys (~> 0.9.86) - prometheus-client-mmap (1.1.1-arm64-darwin) - rb_sys (~> 0.9.86) - prometheus-client-mmap (1.1.1-x86_64-darwin) - rb_sys (~> 0.9.86) - prometheus-client-mmap (1.1.1-x86_64-linux) - rb_sys (~> 0.9.86) - psych (5.1.2) + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prism (1.9.0) + prometheus-client-mmap (1.5.0) + base64 + bigdecimal + logger + rb_sys (~> 0.9.124) + prometheus-client-mmap (1.5.0-aarch64-linux-gnu) + base64 + bigdecimal + logger + rb_sys (~> 0.9.124) + prometheus-client-mmap (1.5.0-aarch64-linux-musl) + base64 + bigdecimal + logger + rb_sys (~> 0.9.124) + prometheus-client-mmap (1.5.0-arm64-darwin) + base64 + bigdecimal + logger + rb_sys (~> 0.9.124) + prometheus-client-mmap (1.5.0-x86_64-darwin) + base64 + bigdecimal + logger + rb_sys (~> 0.9.124) + prometheus-client-mmap (1.5.0-x86_64-linux-gnu) + base64 + bigdecimal + logger + rb_sys (~> 0.9.124) + prometheus-client-mmap (1.5.0-x86_64-linux-musl) + base64 + bigdecimal + logger + rb_sys (~> 0.9.124) + psych (5.4.0) + date stringio - puma (6.4.3) + puma (7.2.1) nio4r (~> 2.0) - racc (1.8.0) - rack (2.2.9) - rack-attack (6.7.0) + racc (1.8.1) + rack (3.2.6) + rack-attack (6.8.0) rack (>= 1.0, < 4) - rack-proxy (0.7.7) + rack-proxy (0.8.2) rack - rack-session (1.0.2) - rack (< 3) - rack-test (2.1.0) + rack-session (2.1.2) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) rack (>= 1.3) - rackup (1.0.0) - rack (< 3) - webrick - rails (7.1.3.4) - actioncable (= 7.1.3.4) - actionmailbox (= 7.1.3.4) - actionmailer (= 7.1.3.4) - actionpack (= 7.1.3.4) - actiontext (= 7.1.3.4) - actionview (= 7.1.3.4) - activejob (= 7.1.3.4) - activemodel (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) + rackup (2.3.1) + rack (>= 3) + rails (8.1.3) + actioncable (= 8.1.3) + actionmailbox (= 8.1.3) + actionmailer (= 8.1.3) + actionpack (= 8.1.3) + actiontext (= 8.1.3) + actionview (= 8.1.3) + activejob (= 8.1.3) + activemodel (= 8.1.3) + activerecord (= 8.1.3) + activestorage (= 8.1.3) + activesupport (= 8.1.3) bundler (>= 1.15.0) - railties (= 7.1.3.4) - rails-dom-testing (2.2.0) + railties (= 8.1.3) + rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.0) - loofah (~> 2.21) - nokogiri (~> 1.14) - railties (7.1.3.4) - actionpack (= 7.1.3.4) - activesupport (= 7.1.3.4) - irb + rails-html-sanitizer (1.7.0) + loofah (~> 2.25) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (8.1.3) + actionpack (= 8.1.3) + activesupport (= 8.1.3) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.2.1) + rake (13.4.2) + rake-compiler-dock (1.12.0) rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rb_sys (0.9.99) - rdoc (6.7.0) + rb_sys (0.9.128) + rake-compiler-dock (= 1.12.0) + rdoc (7.2.0) + erb psych (>= 4.0.0) - regexp_parser (2.9.2) - reline (0.5.9) + tsort + redis (5.4.1) + redis-client (>= 0.22.0) + redis-client (0.29.0) + connection_pool + regexp_parser (2.12.0) + reline (0.6.3) io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - rexml (3.3.6) - strscan - rouge (4.3.0) + rexml (3.4.4) + rouge (5.0.0) + strscan (~> 3.1) rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) @@ -313,8 +362,9 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.3) - parser (>= 3.3.1.0) + rubocop-ast (1.49.1) + parser (>= 3.3.7.2) + prism (~> 1.7) rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) @@ -323,7 +373,7 @@ GEM rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - ruby-next-core (1.0.3) + ruby-next-core (1.2.0) ruby-progressbar (1.13.0) sass-rails (6.0.0) sassc-rails (~> 2.1, >= 2.1.1) @@ -336,8 +386,9 @@ GEM sprockets-rails tilt sax-machine (1.3.2) - semantic_range (3.0.0) - shakapacker (8.0.1) + securerandom (0.4.1) + semantic_range (3.1.1) + shakapacker (8.0.2) activesupport (>= 5.2) package_json rack-proxy (>= 0.6.1) @@ -350,63 +401,69 @@ GEM spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) spring (>= 4) - sprockets (4.2.1) + sprockets (4.2.2) concurrent-ruby (~> 1.0) + logger rack (>= 2.2.4, < 4) - sprockets-rails (3.5.1) + sprockets-rails (3.5.2) actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) - sshkit (1.23.0) + sshkit (1.25.0) base64 + logger net-scp (>= 1.1.2) net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) + ostruct sshkit-sudo (0.1.0) sshkit (~> 1.8) - stringio (3.1.1) - strscan (3.1.0) - thor (1.3.1) - tilt (2.4.0) - timeout (0.4.1) + stringio (3.2.0) + strscan (3.1.8) + thor (1.5.0) + tilt (2.7.0) + timeout (0.6.1) + tsort (0.2.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2024.1) + tzinfo-data (1.2026.2) tzinfo (>= 1.0.0) - unicode-display_width (2.5.0) + unicode-display_width (2.6.0) + uri (1.1.1) + useragent (0.16.11) web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webrick (1.8.1) - websocket-driver (0.8.0) + websocket-driver (0.8.1) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - yabeda (0.12.0) + yabeda (0.16.0) anyway_config (>= 1.0, < 3) concurrent-ruby dry-initializer - yabeda-graphql (0.2.3) - graphql (>= 1.9, < 3) + yabeda-graphql (0.3.0) + graphql (~> 2.2) yabeda (~> 0.2) - yabeda-http_requests (0.2.1) + yabeda-http_requests (0.3.0) + anyway_config (>= 1.3, < 3.0) sniffer yabeda yabeda-prometheus-mmap (0.4.0) prometheus-client-mmap yabeda (~> 0.10) - yabeda-puma-plugin (0.7.1) + yabeda-puma-plugin (0.9.0) json puma yabeda (~> 0.5) - yabeda-rails (0.9.0) + yabeda-rails (0.11.0) activesupport anyway_config (>= 1.3, < 3) railties yabeda (~> 0.8) - zeitwerk (2.6.16) + zeitwerk (2.8.2) PLATFORMS aarch64-linux @@ -429,9 +486,9 @@ DEPENDENCIES capistrano (~> 3.19.0) capistrano-bundler capistrano-rails + csv dotenv-rails (~> 3.1.2) - exception_notification - exception_notification-rake (~> 0.3.1) + exception_notification (~> 5.0) faye-websocket (~> 0.12.0) feedjira (~> 3.2.3) graphql-client @@ -439,9 +496,10 @@ DEPENDENCIES listen (~> 3.9.0) lograge logstash-event - puma (~> 6.4.3) + puma (~> 7.0) rack-attack - rails (~> 7.1.3.4) + rails (~> 8.1.0) + redis (~> 5.0) rubocop (~> 1.64.1) rubocop-performance (~> 1.21.1) rubocop-rails (~> 2.25.0) @@ -460,7 +518,7 @@ DEPENDENCIES yabeda-rails RUBY VERSION - ruby 3.3.4p94 + ruby 3.4.9 BUNDLED WITH - 2.5.11 + 4.0.8 diff --git a/Rakefile b/Rakefile index e85f9139..8c597e8a 100644 --- a/Rakefile +++ b/Rakefile @@ -2,5 +2,6 @@ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require_relative 'config/application' +require 'exception_notification/rake' Rails.application.load_tasks diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index add05d60..1261dcce 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,9 +1,15 @@ class ApplicationController < ActionController::Base around_action :store_request_for_logging + around_action :cache_sitemap_response, if: :sitemap_index_request? before_action :get_session_streaming_token, :set_locale, :set_theme, :set_date, :set_feed + before_action :set_sitemap_url_options, if: :sitemap_request? def default_url_options - {locale: (I18n.locale == I18n.default_locale) ? nil : I18n.locale} + opts = { locale: (I18n.locale == I18n.default_locale) ? nil : I18n.locale } + if sitemap_request? + opts.merge!(host: CANONICAL_HOST, protocol: CANONICAL_PROTOCOL, port: canonical_port) + end + opts end def innovation_in_blockchain? @@ -117,11 +123,54 @@ def set_feed def get_session_streaming_token token = StreamingTokenService.get payload = StreamingTokenService.payload - + + session["streaming_access_token"] = token @streaming_access_token = token @streaming_token_time_live = payload&.dig(:expires_at) end + def streaming_authorization_header + StreamingTokenService.get + end + + def sitemap_request? + controller_name.in?(%w[sitemap sitemaps]) + end + + def sitemap_index_request? + sitemap_request? && action_name == "index" + end + + def set_sitemap_url_options + Rails.application.routes.default_url_options.merge!( + host: CANONICAL_HOST, + protocol: CANONICAL_PROTOCOL, + port: canonical_port + ) + end + + def canonical_port + CANONICAL_PROTOCOL == "https" ? 443 : 80 + end + + def cache_sitemap_response + cache_key = ["sitemap", "v1", controller_path, params[:blockchain], params[:locale]].compact.join("/") + if (cached = Rails.cache.read(cache_key)) + render plain: cached["body"], content_type: cached["content_type"], layout: false + return + end + + yield + + return unless response.successful? && response.body.present? + + Rails.cache.write( + cache_key, + { "body" => response.body, "content_type" => response.media_type }, + expires_in: 24.hours + ) + end + # def get_streaming_access_token # url = URI("https://oauth2.bitquery.io/oauth2/token") # https = Net::HTTP.new(url.host, url.port) diff --git a/app/controllers/proxy_eap_graphql_controller.rb b/app/controllers/proxy_eap_graphql_controller.rb index cf82e8f6..18055b5b 100644 --- a/app/controllers/proxy_eap_graphql_controller.rb +++ b/app/controllers/proxy_eap_graphql_controller.rb @@ -13,7 +13,7 @@ def index { 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'X-API-KEY' => api_key, - 'Authorization' => session['streaming_access_token'] }) + 'Authorization' => streaming_authorization_header }) unless res.is_a?(Net::HTTPSuccess) Rails.logger.error "EAP GraphQL failed with status #{res.code}: #{res.body}" diff --git a/app/controllers/proxy_graphql_controller.rb b/app/controllers/proxy_graphql_controller.rb index 9f6478e3..53e9f7ee 100644 --- a/app/controllers/proxy_graphql_controller.rb +++ b/app/controllers/proxy_graphql_controller.rb @@ -11,7 +11,7 @@ def index { 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'X-API-KEY' => api_key, - 'Authorization' => session['streaming_access_token'] }) + 'Authorization' => streaming_authorization_header }) respond_to do |format| format.json do diff --git a/app/controllers/proxy_streaming_graphql_controller.rb b/app/controllers/proxy_streaming_graphql_controller.rb index 129e66f4..a2e06327 100644 --- a/app/controllers/proxy_streaming_graphql_controller.rb +++ b/app/controllers/proxy_streaming_graphql_controller.rb @@ -14,7 +14,7 @@ def index { query: params[:query], variables: params[:variables] }.to_json, { 'Content-Type' => 'application/json', 'Accept' => 'application/json', - 'X-API-KEY' => api_key, 'Authorization' => session['streaming_access_token'] }) + 'X-API-KEY' => api_key, 'Authorization' => streaming_authorization_header }) respond_to do |format| format.json do diff --git a/app/helpers/seo_helper.rb b/app/helpers/seo_helper.rb new file mode 100644 index 00000000..fa98cc6d --- /dev/null +++ b/app/helpers/seo_helper.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module SeoHelper + def canonical_page_url + path = request.path + "#{CANONICAL_BASE_URL}#{path}" + end + + def robots_meta_content + if @noindex_entity + "noindex,follow" + else + "index,follow" + end + end + + def page_h1_text + return @page_h1 if @page_h1.present? + return content_for(:title).presence if content_for?(:title) + + @breadcrumbs&.last&.dig(:name) + end + + def breadcrumb_json_ld + return unless @breadcrumbs&.any? + + items = @breadcrumbs.each_with_index.map do |crumb, index| + url = crumb[:url].to_s + url = "#{CANONICAL_BASE_URL}#{url}" unless url.start_with?("http") + + { + "@type" => "ListItem", + "position" => index + 1, + "name" => crumb[:name].to_s.gsub(/<[^>]*>/, ""), + "item" => url + } + end + + { + "@context" => "https://schema.org", + "@type" => "BreadcrumbList", + "itemListElement" => items + }.to_json + end + + def website_json_ld + { + "@context" => "https://schema.org", + "@type" => "WebSite", + "name" => "Bitquery Explorer", + "url" => CANONICAL_BASE_URL, + "potentialAction" => { + "@type" => "SearchAction", + "target" => { + "@type" => "EntryPoint", + "urlTemplate" => "#{CANONICAL_BASE_URL}/search/{search_term_string}" + }, + "query-input" => "required name=search_term_string" + } + }.to_json + end + + def explorer_absolute_url(url_options = {}) + url_for(url_options.merge(host: CANONICAL_HOST, protocol: CANONICAL_PROTOCOL, only_path: false)) + end +end diff --git a/app/services/streaming_token_service.rb b/app/services/streaming_token_service.rb index 4e30f137..1deadd36 100644 --- a/app/services/streaming_token_service.rb +++ b/app/services/streaming_token_service.rb @@ -8,9 +8,18 @@ def self.get return payload[:token] end + static_token = ENV["BITQUERY_ACCESS_TOKEN"].to_s + unless static_token.empty? + token = static_token.start_with?("Bearer ") ? static_token : "Bearer #{static_token}" + data = { token: token, expires_at: 1.year.from_now } + Rails.cache.write(KEY, data, expires_in: 1.year, race_condition_ttl: 10) + Rails.logger.info "[StreamingToken] STATIC token from BITQUERY_ACCESS_TOKEN" + return token + end + cid = ENV["GRAPHQL_CLIENT_ID"]; csec = ENV["GRAPHQL_CLIENT_SECRET"] if cid.to_s.empty? || csec.to_s.empty? - Rails.logger.error "[StreamingToken] MISSING ENV GRAPHQL_CLIENT_ID/SECRET" + Rails.logger.error "[StreamingToken] MISSING ENV GRAPHQL_CLIENT_ID/SECRET or BITQUERY_ACCESS_TOKEN" return payload&.dig(:token) end diff --git a/app/views/shared/_footer.html.erb b/app/views/shared/_footer.html.erb index cb837ea5..11ac6730 100644 --- a/app/views/shared/_footer.html.erb +++ b/app/views/shared/_footer.html.erb @@ -36,12 +36,6 @@ | <%= link_to "Youtube", 'https://www.youtube.com/@bitquery', target: '_blank' %>

-
- <%= link_to 'https://casinomonks.com/', target: '_blank', style: 'display: inline-flex; align-items: center; justify-content: center; text-decoration: none; color: #007bff;' do %> - - Casino Reviews - <% end %> -
diff --git a/app/views/shared/_head.html.erb b/app/views/shared/_head.html.erb index 1c6c4180..9c880b0a 100644 --- a/app/views/shared/_head.html.erb +++ b/app/views/shared/_head.html.erb @@ -11,6 +11,7 @@ <% end %> + <%= render partial: 'shared/seo_meta' %> <%= csrf_meta_tags %> <%= csp_meta_tag %> diff --git a/app/views/shared/_seo_meta.html.erb b/app/views/shared/_seo_meta.html.erb new file mode 100644 index 00000000..8e839bca --- /dev/null +++ b/app/views/shared/_seo_meta.html.erb @@ -0,0 +1,16 @@ + + + + + + + +<% if @breadcrumbs&.any? %> + +<% end %> +<% if controller_name == 'home' && action_name == 'index' %> + +<% end %> +<% if page_h1_text.present? && !content_for?(:visible_h1) %> +

<%= strip_tags(page_h1_text.to_s) %>

+<% end %> diff --git a/app/views/sitemaps/robots.text.erb b/app/views/sitemaps/robots.text.erb index e9533d46..50ba3fbd 100644 --- a/app/views/sitemaps/robots.text.erb +++ b/app/views/sitemaps/robots.text.erb @@ -1,4 +1,4 @@ -Sitemap: https://explorer.bitquery.io/sitemap.xml +Sitemap: <%= CANONICAL_BASE_URL %>/sitemap.xml User-agent: * Disallow: /bsc/token/0x7c47ef5fb27d99f1913d31071ed0bcc6cb331af1/ diff --git a/app/views/utility/errors.html.erb b/app/views/utility/errors.html.erb index daba626f..7b3a6048 100644 --- a/app/views/utility/errors.html.erb +++ b/app/views/utility/errors.html.erb @@ -1,3 +1,9 @@


-

<%= t('errors.no_methods') %>

+

Page not found

+

The requested page does not exist in this explorer.

+

+ Try the home page, + Ethereum explorer, or + Bitcoin explorer. +




\ No newline at end of file diff --git a/bin/dev-server b/bin/dev-server new file mode 100755 index 00000000..4e0abe49 --- /dev/null +++ b/bin/dev-server @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$ROOT" + +export PATH="/opt/homebrew/opt/ruby@3.4/bin:/opt/homebrew/lib/ruby/gems/3.4.0/bin:${PATH}" +export RAILS_ENV=development + +if [[ ! -d node_modules ]]; then + echo "Installing JavaScript dependencies..." + yarn install +fi + +if [[ ! -f public/packs/manifest.json ]]; then + echo "Compiling frontend assets (first run may take a few minutes)..." + bundle exec rails shakapacker:compile +fi + +echo "Starting Bitquery Explorer at http://localhost:${PORT:-3000}" +exec bundle exec rails server -b 0.0.0.0 -p "${PORT:-3000}" diff --git a/config/application.rb b/config/application.rb index c8cda900..b8628381 100644 --- a/config/application.rb +++ b/config/application.rb @@ -22,7 +22,7 @@ module Explorer class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.0 + config.load_defaults 8.0 config.eager_load_paths << Rails.root.join("lib") # Settings in config/environments/* take precedence over those specified here. # Application configuration can go into files in config/initializers diff --git a/config/environments/production.rb b/config/environments/production.rb index e38ce864..5790ca76 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -56,7 +56,11 @@ # Use a different cache store in production. # config.cache_store = :memory_store - config.cache_store = :file_store, Rails.root.join("tmp/cache") + config.cache_store = if ENV["REDIS_URL"].present? + [:redis_cache_store, { url: ENV["REDIS_URL"], reconnect_attempts: 1 }] + else + [:file_store, Rails.root.join("tmp/cache")] + end # Use a real queuing backend for Active Job (and separate queues per environment). # config.active_job.queue_adapter = :resque diff --git a/config/initializers/bitquery_logger.rb b/config/initializers/bitquery_logger.rb index cc3cb2d5..90bfa090 100644 --- a/config/initializers/bitquery_logger.rb +++ b/config/initializers/bitquery_logger.rb @@ -15,8 +15,6 @@ # config.ignore_crawlers %w{Googlebot bingbot} end -ExceptionNotifier::Rake.configure - Rails.application.config.middleware.use ExceptionNotification::Rack, bitquery: {} diff --git a/config/initializers/canonical_host.rb b/config/initializers/canonical_host.rb new file mode 100644 index 00000000..e553070d --- /dev/null +++ b/config/initializers/canonical_host.rb @@ -0,0 +1,8 @@ +Rails.application.configure do + config.canonical_host = ENV.fetch("CANONICAL_HOST", "explorer.bitquery.io") + config.canonical_protocol = ENV.fetch("CANONICAL_PROTOCOL", "https") +end + +CANONICAL_HOST = Rails.application.config.canonical_host +CANONICAL_PROTOCOL = Rails.application.config.canonical_protocol +CANONICAL_BASE_URL = "#{CANONICAL_PROTOCOL}://#{CANONICAL_HOST}" diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index c9e08627..542a2e5b 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -1,50 +1,51 @@ class Rack::Attack - BOT_USER_AGENTS = %w[ - bot - crawler - spider - slurp # Yahoo! Slurp - yandexbot # Яндекс - bingbot # Bing - baiduspider # Baidu - duckduckbot # DuckDuckGo - facebookexternalhit - facebot # Facebook - twitterbot # Twitter - applebot # Applebot (Safari News) - petalbot # Huawei Petal - semrushbot # SEMrush - ahrefsbot # Ahrefs - mj12bot # Majestic - dotbot # Moz - sogou # Sogou - exabot # Exalead - archive.org_bot # Wayback Machine - linkedinbot # LinkedIn - pinterestbot # Pinterest - telegrambot # Telegram - ].join('|').freeze - - blocklist('block known bots') do |req| - req.user_agent.to_s.downcase.match?(/#{BOT_USER_AGENTS}/) + # Aggressive SEO scrapers — block outright. + SCRAPER_USER_AGENTS = %w[ + mj12bot + dotbot + exabot + sogou + ].freeze + + blocklist("block aggressive scrapers") do |req| + ua = req.user_agent.to_s.downcase + SCRAPER_USER_AGENTS.any? { |bot| ua.include?(bot) } + end + + # Rate limits replace the old blanket bot blocklist (which matched Googlebot via "bot"). + throttle("req/ip", limit: 300, period: 5.minutes) do |req| + req.ip unless req.path.start_with?("/assets", "/packs", "/metrics") end - self.blocklisted_response = lambda do |env| - request = Rack::Request.new(env) + throttle("graphql/ip", limit: 60, period: 1.minute) do |req| + req.ip if req.post? && req.path.match?(%r{\A/(proxy_graphql|proxy_streaming_graphql|proxy_eap_graphql)\z}) + end + self.blocklisted_responder = lambda do |request| BitqueryLogger.extra_context( - ip: request.ip, + ip: request.ip, user_agent: request.user_agent, - path: request.fullpath + path: request.fullpath ) BitqueryLogger.warn <<~LOG - ===== Rack::Attack ===== Blocked bot request: + ===== Rack::Attack ===== Blocked request: + • IP: #{request.ip} + • User-Agent: #{request.user_agent.inspect} + • Path: #{request.fullpath} + LOG + + [403, { "Content-Type" => "text/plain" }, ["Forbidden"]] + end + + self.throttled_responder = lambda do |request| + BitqueryLogger.warn <<~LOG + ===== Rack::Attack ===== Throttled request: • IP: #{request.ip} • User-Agent: #{request.user_agent.inspect} • Path: #{request.fullpath} LOG - [403, { 'Content-Type' => 'text/plain' }, ['Forbidden']] + [429, { "Content-Type" => "text/plain", "Retry-After" => "60" }, ["Too Many Requests"]] end end diff --git a/config/routes.rb b/config/routes.rb index d781c1c5..102fa811 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -682,6 +682,15 @@ get "proxy_dbcode/:dashbord_url", to: "proxy_dbcode#index", defaults: { format: :json } get "platform/:action", controller: "home" + + # Home page category tabs link to /smart_contract, /bitcoin, etc. + %w[smart_contract bitcoin cosmos ripple utility testnet cardano graph offchain].each do |action| + get action, to: "home##{action}" + end + + # Common mistaken explorer URLs + get ":blockchain/network/:action", to: redirect("/%{blockchain}/%{action}") + # Disabled GraphQL UI routes # get "graphql(/:param)" => "utility#graphql" # get "graphql/reset(/:token)" => "utility#graphql" diff --git a/lib/cached_query.rb b/lib/cached_query.rb new file mode 100644 index 00000000..a09a139a --- /dev/null +++ b/lib/cached_query.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require "timeout" + +class CachedQuery + QUERY_VERSION = 1 + TIMEOUT_SECONDS = 3 + + class << self + def fetch(key_parts, expires_in:, query:, variables: {}, context: {}, use_eap: false) + cache_key = (["cached_query", QUERY_VERSION] + Array(key_parts)).join(":") + stale_key = "#{cache_key}:stale" + + Rails.cache.fetch(cache_key, expires_in:, race_condition_ttl: 30) do + result = execute(query:, variables:, context:, use_eap:) + Rails.cache.write(stale_key, result, expires_in: expires_in * 2) unless result.nil? + result + end + rescue StandardError => e + Rails.logger.warn("CachedQuery error [#{Array(key_parts).join('/') }]: #{e.message}") + Rails.cache.read(stale_key) + end + + private + + def execute(query:, variables:, context:, use_eap:) + Timeout.timeout(TIMEOUT_SECONDS) do + Graphql::V2.query_with_retry(query, variables:, context:, use_eap:) + end + end + end +end diff --git a/package.json b/package.json index d7086ca7..675aa0a4 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "moment": "^2.30.1", "popper.js": "^1.16.1", "serialize-javascript": "^6.0.2", - "shakapacker": "8.0.1", + "shakapacker": "8.0.2", "tabulator-tables": "^6.2.5", "vega-widgets": "^2.0.4", "vis": "^4.21.0-EOL" diff --git a/vendor/bundle/ruby/3.3.0/bundler/gems/bitquery_logger-233e44a43d4c b/vendor/bitquery_logger similarity index 100% rename from vendor/bundle/ruby/3.3.0/bundler/gems/bitquery_logger-233e44a43d4c rename to vendor/bitquery_logger diff --git a/yarn.lock b/yarn.lock index 2d35c94a..caa4f09f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5746,10 +5746,10 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== -shakapacker@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/shakapacker/-/shakapacker-8.0.1.tgz#96c893ccc414d47aaf86689eb5ef732259c592c7" - integrity sha512-VjIWgJqh4680Kf2NSmupB3h6dWxlOkGvceJJuJZ0az/6wUL5d/ovmKUc2swrpWC8UgBY67YjXI92zT07EQevbQ== +shakapacker@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/shakapacker/-/shakapacker-8.0.2.tgz#064303e09958b57b7a7f98dc38d0c1150a96d3a0" + integrity sha512-nZNAwT7onNiKZ81nMz/l0ihG8qXPZUvfxs4op5586wvn7znpPVQC4mFs131YrdUubmdqUPIjcpZnV0k4ijNtXw== dependencies: js-yaml "^4.1.0" path-complete-extname "^1.0.0" From 12932914ed2f27b535f20cef348a074e1bfd81f4 Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Thu, 11 Jun 2026 18:26:02 +0530 Subject: [PATCH 2/4] Allow search engine crawlers while blocking scrapers and scripted clients. Safelist legitimate search and social preview bots, throttle normal traffic, and return 403 for SEO harvesters, generic bots, and curl/python/scrapy clients. Co-authored-by: Cursor --- config/initializers/rack_attack.rb | 136 ++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 11 deletions(-) diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 542a2e5b..8e7c1431 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -1,24 +1,138 @@ class Rack::Attack - # Aggressive SEO scrapers — block outright. - SCRAPER_USER_AGENTS = %w[ - mj12bot - dotbot - exabot - sogou + # Search engines + social link-preview crawlers: safelisted (skip throttles & bot blocks). + SEARCH_ENGINE_PATTERNS = [ + /googlebot/i, + /bingbot/i, + /duckduckbot/i, + /applebot/i, + /yandexbot/i, + /baiduspider/i, + /sogou/i, + /petalbot/i, + /ia_archiver/i # Internet Archive / Wayback Machine ].freeze - blocklist("block aggressive scrapers") do |req| - ua = req.user_agent.to_s.downcase - SCRAPER_USER_AGENTS.any? { |bot| ua.include?(bot) } + SOCIAL_CRAWLER_PATTERNS = [ + /facebookexternalhit/i, + /facebot/i, + /twitterbot/i, + /linkedinbot/i, + /pinterestbot/i, + /telegrambot/i, + /slackbot/i, + /discordbot/i, + /whatsapp/i, + /embedly/i + ].freeze + + # SEO tools, AI scrapers, and aggressive harvesters — always blocked. + BLOCKED_SCRAPER_PATTERNS = [ + /mj12bot/i, + /dotbot/i, + /semrushbot/i, + /ahrefsbot/i, + /rogerbot/i, + /screaming[\s_-]?frog/i, + /bytespider/i, + /gptbot/i, + /claudebot/i, + /anthropic-ai/i, + /ccbot/i, + /dataforseo/i, + /serpstatbot/i, + /seokicks/i, + /megaindex/i, + /exabot/i, + /blexbot/i, + /petalsearch/i # Huawei Petal SEO spider (distinct from petalbot search crawler) + ].freeze + + # Generic bot/scraper signatures when not safelisted above. + GENERIC_BOT_PATTERN = / + crawler | + spider | + scraper | + httpclient | + libwww | + headlesschrome | + phantomjs | + selenium + /ix + + SCRIPTED_CLIENT_PATTERN = %r{ + \bcurl/ | + \bwget/ | + python- | + \bscrapy | + go-http-client | + java/ | + \bokhttp | + axios/ | + node-fetch | + httpx/ | + ruby/ | + perl/ | + php/ + }ix + + class << self + def allowed_crawler?(req) + ua = req.user_agent.to_s + return false if ua.strip.empty? + + SEARCH_ENGINE_PATTERNS.any? { |pattern| ua.match?(pattern) } || + SOCIAL_CRAWLER_PATTERNS.any? { |pattern| ua.match?(pattern) } + end + end + + # --- Safelist: legitimate search & social crawlers --------------------------------- + + safelist("allow search engines and social crawlers") do |req| + allowed_crawler?(req) + end + + # --- Blocklist: scrapers, SEO bots, scripted clients ------------------------------ + + blocklist("block known scrapers") do |req| + ua = req.user_agent.to_s + BLOCKED_SCRAPER_PATTERNS.any? { |pattern| ua.match?(pattern) } end - # Rate limits replace the old blanket bot blocklist (which matched Googlebot via "bot"). + blocklist("block unlisted bots") do |req| + next false if allowed_crawler?(req) + + ua = req.user_agent.to_s + ua.match?(GENERIC_BOT_PATTERN) || ua.match?(/bot/i) + end + + blocklist("block scripted clients") do |req| + next false if allowed_crawler?(req) + next false if req.path.start_with?("/metrics") + + ua = req.user_agent.to_s + ua.strip.empty? || ua.match?(SCRIPTED_CLIENT_PATTERN) + end + + # --- Throttles: humans & scrapers posing as browsers -------------------------------- + throttle("req/ip", limit: 300, period: 5.minutes) do |req| + next if allowed_crawler?(req) + req.ip unless req.path.start_with?("/assets", "/packs", "/metrics") end + throttle("html burst/ip", limit: 45, period: 1.minute) do |req| + next if allowed_crawler?(req) + next if req.path.start_with?("/assets", "/packs", "/metrics", "/proxy_") + + req.ip + end + throttle("graphql/ip", limit: 60, period: 1.minute) do |req| - req.ip if req.post? && req.path.match?(%r{\A/(proxy_graphql|proxy_streaming_graphql|proxy_eap_graphql)\z}) + next unless req.post? && req.path.match?(%r{\A/(proxy_graphql|proxy_streaming_graphql|proxy_eap_graphql)\z}) + next if allowed_crawler?(req) + + req.ip end self.blocklisted_responder = lambda do |request| From 73601eb6feace1480ea4c52094f2c8456e39e6c3 Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Thu, 11 Jun 2026 20:15:36 +0530 Subject: [PATCH 3/4] Remove Wave 0 caching infrastructure. Drop CachedQuery helper, sitemap response cache, and Redis cache store config; production falls back to file_store only. Co-authored-by: Cursor --- app/controllers/application_controller.rb | 23 ---------------- config/environments/production.rb | 6 +---- lib/cached_query.rb | 32 ----------------------- 3 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 lib/cached_query.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1261dcce..ea93dc9f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,5 @@ class ApplicationController < ActionController::Base around_action :store_request_for_logging - around_action :cache_sitemap_response, if: :sitemap_index_request? before_action :get_session_streaming_token, :set_locale, :set_theme, :set_date, :set_feed before_action :set_sitemap_url_options, if: :sitemap_request? @@ -137,10 +136,6 @@ def sitemap_request? controller_name.in?(%w[sitemap sitemaps]) end - def sitemap_index_request? - sitemap_request? && action_name == "index" - end - def set_sitemap_url_options Rails.application.routes.default_url_options.merge!( host: CANONICAL_HOST, @@ -153,24 +148,6 @@ def canonical_port CANONICAL_PROTOCOL == "https" ? 443 : 80 end - def cache_sitemap_response - cache_key = ["sitemap", "v1", controller_path, params[:blockchain], params[:locale]].compact.join("/") - if (cached = Rails.cache.read(cache_key)) - render plain: cached["body"], content_type: cached["content_type"], layout: false - return - end - - yield - - return unless response.successful? && response.body.present? - - Rails.cache.write( - cache_key, - { "body" => response.body, "content_type" => response.media_type }, - expires_in: 24.hours - ) - end - # def get_streaming_access_token # url = URI("https://oauth2.bitquery.io/oauth2/token") # https = Net::HTTP.new(url.host, url.port) diff --git a/config/environments/production.rb b/config/environments/production.rb index 5790ca76..e38ce864 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -56,11 +56,7 @@ # Use a different cache store in production. # config.cache_store = :memory_store - config.cache_store = if ENV["REDIS_URL"].present? - [:redis_cache_store, { url: ENV["REDIS_URL"], reconnect_attempts: 1 }] - else - [:file_store, Rails.root.join("tmp/cache")] - end + config.cache_store = :file_store, Rails.root.join("tmp/cache") # Use a real queuing backend for Active Job (and separate queues per environment). # config.active_job.queue_adapter = :resque diff --git a/lib/cached_query.rb b/lib/cached_query.rb deleted file mode 100644 index a09a139a..00000000 --- a/lib/cached_query.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require "timeout" - -class CachedQuery - QUERY_VERSION = 1 - TIMEOUT_SECONDS = 3 - - class << self - def fetch(key_parts, expires_in:, query:, variables: {}, context: {}, use_eap: false) - cache_key = (["cached_query", QUERY_VERSION] + Array(key_parts)).join(":") - stale_key = "#{cache_key}:stale" - - Rails.cache.fetch(cache_key, expires_in:, race_condition_ttl: 30) do - result = execute(query:, variables:, context:, use_eap:) - Rails.cache.write(stale_key, result, expires_in: expires_in * 2) unless result.nil? - result - end - rescue StandardError => e - Rails.logger.warn("CachedQuery error [#{Array(key_parts).join('/') }]: #{e.message}") - Rails.cache.read(stale_key) - end - - private - - def execute(query:, variables:, context:, use_eap:) - Timeout.timeout(TIMEOUT_SECONDS) do - Graphql::V2.query_with_retry(query, variables:, context:, use_eap:) - end - end - end -end From b27c69e3d2e9df3678ba8cb916f024097cc51734 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 00:00:15 +0000 Subject: [PATCH 4/4] Bump @babel/core from 7.24.9 to 7.29.6 Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.24.9 to 7.29.6. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.6/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-version: 7.29.6 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yarn.lock | 351 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 196 insertions(+), 155 deletions(-) diff --git a/yarn.lock b/yarn.lock index caa4f09f..9b347b36 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,57 +2,56 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - -"@babel/code-frame@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" - integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== +"@babel/code-frame@^7.29.0", "@babel/code-frame@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.7.tgz#f2fbbfea87c44a21590ec515b778b2c26d8866e7" + integrity sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw== dependencies: - "@babel/highlight" "^7.24.7" - picocolors "^1.0.0" + "@babel/helper-validator-identifier" "^7.29.7" + js-tokens "^4.0.0" + picocolors "^1.1.1" "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.8": version "7.24.9" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.9.tgz#53eee4e68f1c1d0282aa0eb05ddb02d033fc43a0" integrity sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng== +"@babel/compat-data@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.7.tgz#6f0237f0f36d2e51c0570a636faed9d2d0efe629" + integrity sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg== + "@babel/core@7": - version "7.24.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.9.tgz#dc07c9d307162c97fa9484ea997ade65841c7c82" - integrity sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.9" - "@babel/helper-compilation-targets" "^7.24.8" - "@babel/helper-module-transforms" "^7.24.9" - "@babel/helpers" "^7.24.8" - "@babel/parser" "^7.24.8" - "@babel/template" "^7.24.7" - "@babel/traverse" "^7.24.8" - "@babel/types" "^7.24.9" + version "7.29.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.6.tgz#2f2c2ca1728ae73c9b68ece91d1ae6dee18ff83a" + integrity sha512-QdxmAo/ikZqqRGA8s43ww8lcql6naWRvEz0FFrl6MIlc7Gi6TroXnSdWa5U/kq6fzcpqpHesicQxFZIieZbyIA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.6" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helpers" "^7.29.2" + "@babel/parser" "^7.29.3" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.24.8", "@babel/generator@^7.24.9": - version "7.24.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.10.tgz#a4ab681ec2a78bbb9ba22a3941195e28a81d8e76" - integrity sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg== +"@babel/generator@^7.29.6", "@babel/generator@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.7.tgz#cca0b8827e6bcf3ba176788e7f3b180ad6db2fa3" + integrity sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ== dependencies: - "@babel/types" "^7.24.9" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" + "@babel/parser" "^7.29.7" + "@babel/types" "^7.29.7" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" "@babel/helper-annotate-as-pure@^7.24.7": version "7.24.7" @@ -69,14 +68,14 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz#b607c3161cd9d1744977d4f97139572fe778c271" - integrity sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw== +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.28.6": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz#7a1def704302401c47f64fa85589e974ae217042" + integrity sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g== dependencies: - "@babel/compat-data" "^7.24.8" - "@babel/helper-validator-option" "^7.24.8" - browserslist "^4.23.1" + "@babel/compat-data" "^7.29.7" + "@babel/helper-validator-option" "^7.29.7" + browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" @@ -130,6 +129,11 @@ "@babel/template" "^7.24.7" "@babel/types" "^7.24.7" +"@babel/helper-globals@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.29.7.tgz#f04a96fbd8473241b1079243f5b3f03a3010ab7b" + integrity sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA== + "@babel/helper-hoist-variables@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" @@ -153,16 +157,22 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.24.9": - version "7.24.9" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz#e13d26306b89eea569180868e652e7f514de9d29" - integrity sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw== +"@babel/helper-module-imports@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz#ef25048a518e828d7393fac5882ddd73921d7396" + integrity sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g== dependencies: - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/helper-validator-identifier" "^7.24.7" + "@babel/traverse" "^7.29.7" + "@babel/types" "^7.29.7" + +"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.28.6": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz#b062747a5997ba138637201328bbff77960574ae" + integrity sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg== + dependencies: + "@babel/helper-module-imports" "^7.29.7" + "@babel/helper-validator-identifier" "^7.29.7" + "@babel/traverse" "^7.29.7" "@babel/helper-optimise-call-expression@^7.24.7": version "7.24.7" @@ -217,21 +227,31 @@ dependencies: "@babel/types" "^7.24.7" -"@babel/helper-string-parser@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" - integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== +"@babel/helper-string-parser@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz#7f0871d99824d23137d60f86fcf6130fd5a1b51f" + integrity sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw== "@babel/helper-validator-identifier@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== +"@babel/helper-validator-identifier@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz#bd87084ced0c796ec46bda492de6e83d29e89fc2" + integrity sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg== + "@babel/helper-validator-option@^7.24.8": version "7.24.8" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== +"@babel/helper-validator-option@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz#cf315be940213b354eb4abcc0bd01ebe3f73bc2a" + integrity sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw== + "@babel/helper-wrap-function@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz#52d893af7e42edca7c6d2c6764549826336aae1f" @@ -242,28 +262,20 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helpers@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.8.tgz#2820d64d5d6686cca8789dd15b074cd862795873" - integrity sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ== +"@babel/helpers@^7.29.2": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.7.tgz#45abfde7548997e34376c3e69feb475cffb4a607" + integrity sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg== dependencies: - "@babel/template" "^7.24.7" - "@babel/types" "^7.24.8" + "@babel/template" "^7.29.7" + "@babel/types" "^7.29.7" -"@babel/highlight@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" - integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.29.3", "@babel/parser@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.7.tgz#837b87387cbf5ec5530cb634b3c622f68edb9334" + integrity sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg== dependencies: - "@babel/helper-validator-identifier" "^7.24.7" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.24.7", "@babel/parser@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.8.tgz#58a4dbbcad7eb1d48930524a3fd93d93e9084c6f" - integrity sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w== + "@babel/types" "^7.29.7" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.7": version "7.24.7" @@ -936,39 +948,35 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" - integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.8.tgz#6c14ed5232b7549df3371d820fbd9abfcd7dfab7" - integrity sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.8" - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-function-name" "^7.24.7" - "@babel/helper-hoist-variables" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/parser" "^7.24.8" - "@babel/types" "^7.24.8" +"@babel/template@^7.24.7", "@babel/template@^7.28.6", "@babel/template@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.29.7.tgz#4d9d4004f645cdd304de958c725162784ecac700" + integrity sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/types" "^7.29.7" + +"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.29.0", "@babel/traverse@^7.29.7": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.7.tgz#c47b07a41b95da0907d026b5dd894d98de7d2f2d" + integrity sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw== + dependencies: + "@babel/code-frame" "^7.29.7" + "@babel/generator" "^7.29.7" + "@babel/helper-globals" "^7.29.7" + "@babel/parser" "^7.29.7" + "@babel/template" "^7.29.7" + "@babel/types" "^7.29.7" debug "^4.3.1" - globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.24.9", "@babel/types@^7.4.4": - version "7.24.9" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.9.tgz#228ce953d7b0d16646e755acf204f4cf3d08cc73" - integrity sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.29.0", "@babel/types@^7.29.7", "@babel/types@^7.4.4": + version "7.29.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.7.tgz#8005e31d82712ee7adaef6e23c63b71a62770a92" + integrity sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA== dependencies: - "@babel/helper-string-parser" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" - to-fast-properties "^2.0.0" + "@babel/helper-string-parser" "^7.29.7" + "@babel/helper-validator-identifier" "^7.29.7" "@bitquery/graph@^1.0.13": version "1.0.13" @@ -1030,6 +1038,14 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jridgewell/gen-mapping@^0.3.12": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -1039,6 +1055,14 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.24" +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" @@ -1062,6 +1086,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" @@ -1070,6 +1099,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.5" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" @@ -1683,13 +1720,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -1781,6 +1811,11 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +baseline-browser-mapping@^2.10.38: + version "2.10.38" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz#c84d093c4bf7325c5053c279d90f153c66526042" + integrity sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -1913,6 +1948,17 @@ browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.23.0, browserslist@^ node-releases "^2.0.14" update-browserslist-db "^1.1.0" +browserslist@^4.24.0: + version "4.28.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.4.tgz#dd8b8167a32845ff5f8cd6ce13f5abba16cd04c9" + integrity sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw== + dependencies: + baseline-browser-mapping "^2.10.38" + caniuse-lite "^1.0.30001799" + electron-to-chromium "^1.5.376" + node-releases "^2.0.48" + update-browserslist-db "^1.2.3" + buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -2006,6 +2052,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001640: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz#9c004caef315de9452ab970c3da71085f8241dbd" integrity sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg== +caniuse-lite@^1.0.30001799: + version "1.0.30001799" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz#5c909138c27f1a61219d3e092071c1cc7d32dc55" + integrity sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw== + caw@^2.0.0, caw@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" @@ -2016,15 +2067,6 @@ caw@^2.0.0, caw@^2.0.1: tunnel-agent "^0.6.0" url-to-options "^1.0.1" -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -2097,13 +2139,6 @@ clone@~2.1.2: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -2111,11 +2146,6 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -3121,6 +3151,11 @@ electron-to-chromium@^1.4.820: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz#24640bd4dcfaccb6d82bb4c3f4c7311503241581" integrity sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w== +electron-to-chromium@^1.5.376: + version "1.5.378" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.378.tgz#9ce9591ebed23e8a9119970305084b43a2906454" + integrity sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ== + element-resize-event@^3.0.3, element-resize-event@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-3.0.6.tgz#3a18efd4879ad615e979fd8bbf173b014987eb9a" @@ -3205,12 +3240,17 @@ escalade@^3.0.2, escalade@^3.1.2: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== @@ -3825,11 +3865,6 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -4345,10 +4380,10 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== jsesc@~0.5.0: version "0.5.0" @@ -4726,6 +4761,11 @@ node-releases@^2.0.14: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== +node-releases@^2.0.48: + version "2.0.49" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.49.tgz#1a1f4176b683d22614f61adc1c842c187431841a" + integrity sha512-f06bl1D+8ZDkn2oOQQKAh5/otFWqVnM1Q5oerA8Pex7UfT66Tx4IPHIqVVFKqFT3FUtaDstdgkM7yT7JWhqxfw== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -4998,6 +5038,11 @@ picocolors@^1.0.0, picocolors@^1.0.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -5992,13 +6037,6 @@ stylehacks@^7.0.2: browserslist "^4.23.1" postcss-selector-parser "^6.1.0" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -6133,11 +6171,6 @@ to-buffer@^1.1.1: resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -6253,6 +6286,14 @@ update-browserslist-db@^1.1.0: escalade "^3.1.2" picocolors "^1.0.1" +update-browserslist-db@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"