From 665bd6dd3da32722cc2a829de5dc2ffb5ad4fdc3 Mon Sep 17 00:00:00 2001 From: reesericci Date: Tue, 26 Dec 2023 17:50:18 +0000 Subject: [PATCH 1/7] Caching Records with Solid Cache (updated gemfile bundled with 7.1 update) --- app/models/domain.rb | 16 +++++ app/models/record.rb | 38 ++++++++---- app/views/domains/_domain.html.erb | 26 +++++++++ app/views/domains/index.html.erb | 5 +- app/views/domains/settings.html.erb | 7 ++- app/views/records/index.html.erb | 8 +-- config/environments/production.rb | 58 ++++++++++--------- ..._create_solid_cache_entries.solid_cache.rb | 12 ++++ ..._to_active_storage_blobs.active_storage.rb | 22 +++++++ ..._storage_variant_records.active_storage.rb | 27 +++++++++ ...e_storage_blobs_checksum.active_storage.rb | 8 +++ db/schema.rb | 9 ++- 12 files changed, 187 insertions(+), 49 deletions(-) create mode 100644 app/views/domains/_domain.html.erb create mode 100644 db/migrate/20231222053923_create_solid_cache_entries.solid_cache.rb create mode 100644 db/migrate/20231222071308_add_service_name_to_active_storage_blobs.active_storage.rb create mode 100644 db/migrate/20231222071309_create_active_storage_variant_records.active_storage.rb create mode 100644 db/migrate/20231222071310_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb diff --git a/app/models/domain.rb b/app/models/domain.rb index 884711a..e99bc76 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -15,4 +15,20 @@ class Domain < ApplicationRecord def to_param host end + + + def top_records + records = [] + all_records = Record.where_host(host) + + if all_records.length > 3 + records[0] = all_records[0] + records[1] = all_records[1] + records[2] = all_records[2] + else + records = all_records + end + + records + end end diff --git a/app/models/record.rb b/app/models/record.rb index 344f0f4..35c0831 100644 --- a/app/models/record.rb +++ b/app/models/record.rb @@ -37,17 +37,22 @@ def self.create(attributes={}) obj end - - def self.where_host(host) - domain = Domain.find_by(host: host) - records = [] - for r in self.all + def self.filter_dnsimple_host(host, domains) + domain = Domain.find_by(host: host) + Rails.cache.fetch([domain, "records"], expires_in: 1.week) do + records = [] + for r in domains if r.domain_id == domain.id records.push(r) end - end + end - records + records + end + end + + def self.where_host(host) + self.filter_dnsimple_host(host, self.all) end def self.dnsimple_to_record(obj) @@ -81,6 +86,8 @@ def save changes_applied broadcast_replace_to('records:main', partial: "records/record") + Rails.cache.delete("records") + domain.update(updated_at: Time.now) end def persisted? @@ -106,10 +113,11 @@ def self.destroy_all_host!(host) def self.all - dnsimple_records = client.zones.all_zone_records(Rails.application.credentials.dnsimple.account_id, Rails.application.config.domain).data.select { |record| !record.system_record } + Rails.cache.fetch "records", expires_in: 2.minutes do + dnsimple_records = client.zones.all_zone_records(Rails.application.credentials.dnsimple.account_id, Rails.application.config.domain).data.select { |record| !record.system_record } - records = [] - for r in dnsimple_records + records = [] + for r in dnsimple_records if !r.name.blank? record = self.dnsimple_to_record(r) @@ -120,6 +128,7 @@ def self.all end records + end end def self.find(id) @@ -208,6 +217,8 @@ def persist end @_persisted = true + + Rails.cache.delete("records") end def update_record @@ -231,12 +242,17 @@ def update_record priority = record.data.priority end + domain.update(updated_at: Time.now) + Rails.cache.delete("records") + end def destroy_record + domain.update(updated_at: Time.now) + Rails.cache.delete("records") client.zones.delete_zone_record(Rails.application.credentials.dnsimple.account_id, Rails.application.config.domain, id) @_persisted = false true end -end \ No newline at end of file +end diff --git a/app/views/domains/_domain.html.erb b/app/views/domains/_domain.html.erb new file mode 100644 index 0000000..4abc6f7 --- /dev/null +++ b/app/views/domains/_domain.html.erb @@ -0,0 +1,26 @@ + +

+ <%= domain.host + "." + Rails.application.config.domain %> +

+
+ <% if domain.top_records.length > 0 %> + <% domain.top_records.each do |r| %> +
+ <%= r.type%> + <%= r.name %> → <%= r.content %> +
+ <% end %> + <% else %> +

No Records

+ <% end %> + +
+
+
+ Live + Manage → +
+
+
+ + diff --git a/app/views/domains/index.html.erb b/app/views/domains/index.html.erb index 248a6d9..ed94dd2 100644 --- a/app/views/domains/index.html.erb +++ b/app/views/domains/index.html.erb @@ -4,9 +4,8 @@
<% @domains.each do |domain| %> - <%= turbo_frame_tag dom_id(domain), src: show_domain_path(domain), loading: "lazy", "data-turbo-permanent": "true" do %> - - + <% cache domain do %> + <%= render domain %> <% end %> <% end %> diff --git a/app/views/domains/settings.html.erb b/app/views/domains/settings.html.erb index 4e1b945..3756031 100644 --- a/app/views/domains/settings.html.erb +++ b/app/views/domains/settings.html.erb @@ -7,6 +7,11 @@ <% if @_current_user.admin? %>
+ +

Info

+

Last updated: <%= @domain.updated_at %>

+

First created: <%= @domain.created_at %>

+

Transfer

Current user: <%= @domain.user_users_id %>, <%= User::User.find_by(id: @domain.user_users_id).email %>

@@ -19,4 +24,4 @@ <% end %>
-<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/records/index.html.erb b/app/views/records/index.html.erb index f4fef9a..05c0187 100644 --- a/app/views/records/index.html.erb +++ b/app/views/records/index.html.erb @@ -1,10 +1,6 @@

Records

-
+<%= form_with url: records_path(@domain), method: :post, class: "flex flex-wrap flex-row gap-4 gap-y-4 items-end" do |form| %>
@@ -32,7 +28,7 @@
-
+<% end %>
diff --git a/config/environments/production.rb b/config/environments/production.rb index b56a0f4..4b5677a 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -4,7 +4,7 @@ # Settings specified here will take precedence over those in config/application.rb. # Code is not reloaded between requests. - config.cache_classes = true + config.enable_reloading = false # Eager load code on boot. This eager loads most of Rails and # your application in memory, allowing both threaded web servers @@ -13,22 +13,21 @@ config.eager_load = true # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false + config.consider_all_requests_local = false config.action_controller.perform_caching = true - # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] - # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). # config.require_master_key = true - # Disable serving static files from the `/public` folder by default since - # Apache or NGINX already handles this. - config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. + # config.public_file_server.enabled = false # Compress CSS using a preprocessor. # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. - config.assets.compile = true + config.assets.compile = false # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" @@ -45,21 +44,31 @@ # config.action_cable.url = "wss://example.com/cable" # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true + config.force_ssl = true - # Include generic and useful information about system operation, but avoid logging too much - # information to avoid inadvertent exposure of personally identifiable information (PII). - config.log_level = :info + # Log to STDOUT by default + config.logger = ActiveSupport::Logger.new("#{Rails.root}/log/production.log") + .tap { |logger| logger.formatter = ::Logger::Formatter.new } + .then { |logger| ActiveSupport::TaggedLogging.new(logger) } # Prepend all log lines with the following tags. config.log_tags = [ :request_id ] + # Info include generic and useful information about system operation, but avoids logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). If you + # want to log everything, set the level to "debug". + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + # Use a different cache store in production. - # config.cache_store = :mem_cache_store + config.cache_store = :solid_cache_store # Use a real queuing backend for Active Job (and separate queues per environment). - # config.active_job.queue_adapter = :resque + # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "admin_obl_ong_production" config.action_mailer.perform_caching = false @@ -75,19 +84,14 @@ # Don't log any deprecations. config.active_support.report_deprecations = false - # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new - - # Use a different logger for distributed setups. - # require "syslog/logger" - # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") - - if ENV["RAILS_LOG_TO_STDOUT"].present? - logger = ActiveSupport::Logger.new(STDOUT) - logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) - end - # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } end diff --git a/db/migrate/20231222053923_create_solid_cache_entries.solid_cache.rb b/db/migrate/20231222053923_create_solid_cache_entries.solid_cache.rb new file mode 100644 index 0000000..4ff1fbd --- /dev/null +++ b/db/migrate/20231222053923_create_solid_cache_entries.solid_cache.rb @@ -0,0 +1,12 @@ +# This migration comes from solid_cache (originally 20230724121448) +class CreateSolidCacheEntries < ActiveRecord::Migration[7.0] + def change + create_table :solid_cache_entries do |t| + t.binary :key, null: false, limit: 1024 + t.binary :value, null: false, limit: 512.megabytes + t.datetime :created_at, null: false + + t.index :key, unique: true + end + end +end diff --git a/db/migrate/20231222071308_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20231222071308_add_service_name_to_active_storage_blobs.active_storage.rb new file mode 100644 index 0000000..a15c6ce --- /dev/null +++ b/db/migrate/20231222071308_add_service_name_to_active_storage_blobs.active_storage.rb @@ -0,0 +1,22 @@ +# This migration comes from active_storage (originally 20190112182829) +class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] + def up + return unless table_exists?(:active_storage_blobs) + + unless column_exists?(:active_storage_blobs, :service_name) + add_column :active_storage_blobs, :service_name, :string + + if configured_service = ActiveStorage::Blob.service.name + ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) + end + + change_column :active_storage_blobs, :service_name, :string, null: false + end + end + + def down + return unless table_exists?(:active_storage_blobs) + + remove_column :active_storage_blobs, :service_name + end +end diff --git a/db/migrate/20231222071309_create_active_storage_variant_records.active_storage.rb b/db/migrate/20231222071309_create_active_storage_variant_records.active_storage.rb new file mode 100644 index 0000000..94ac83a --- /dev/null +++ b/db/migrate/20231222071309_create_active_storage_variant_records.active_storage.rb @@ -0,0 +1,27 @@ +# This migration comes from active_storage (originally 20191206030411) +class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + # Use Active Record's configured type for primary key + create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| + t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type + t.string :variation_digest, null: false + + t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_key_type + config = Rails.configuration.generators + config.options[config.orm][:primary_key_type] || :primary_key + end + + def blobs_primary_key_type + pkey_name = connection.primary_key(:active_storage_blobs) + pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name } + pkey_column.bigint? ? :bigint : pkey_column.type + end +end diff --git a/db/migrate/20231222071310_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/db/migrate/20231222071310_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb new file mode 100644 index 0000000..93c8b85 --- /dev/null +++ b/db/migrate/20231222071310_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb @@ -0,0 +1,8 @@ +# This migration comes from active_storage (originally 20211119233751) +class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + change_column_null(:active_storage_blobs, :checksum, true) + end +end diff --git a/db/schema.rb b/db/schema.rb index 8fa1cf5..b3ed356 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_08_13_182334) do +ActiveRecord::Schema[7.0].define(version: 2023_12_22_053923) do create_table "domains", force: :cascade do |t| t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -19,6 +19,13 @@ t.index ["user_users_id"], name: "index_domains_on_user_users_id" end + create_table "solid_cache_entries", force: :cascade do |t| + t.binary "key", limit: 1024, null: false + t.binary "value", limit: 536870912, null: false + t.datetime "created_at", null: false + t.index ["key"], name: "index_solid_cache_entries_on_key", unique: true + end + create_table "user_credentials", force: :cascade do |t| t.string "webauthn_id" t.string "public_key" From 3534e838739a48491fb2f95bb97f5b4779a30213 Mon Sep 17 00:00:00 2001 From: reesericci Date: Tue, 26 Dec 2023 17:54:01 +0000 Subject: [PATCH 2/7] 7.1 update & asset pipeline changes (migration to propshaft, etc) --- .gitignore | 8 +- Gemfile | 21 +- Gemfile.lock | 412 ++--- Procfile.dev | 3 +- app/assets/config/manifest.js | 5 - app/assets/stylesheets/application.css | 95 -- .../stylesheets/application.tailwind.css | 89 +- app/javascript/application.js | 3 +- app/javascript/controllers/application.js | 3 - .../controllers/empty_controller.js | 1 + .../controllers/hello_controller.js | 7 + app/views/layouts/application.html.erb | 5 +- bin/dev | 3 + bin/setup | 2 +- bun.lockb | Bin 0 -> 47250 bytes config/application.rb | 4 +- config/environments/development.rb | 8 + config/environments/test.rb | 20 +- config/importmap.rails_admin.rb | 11 - config/importmap.rb | 2 +- config/initializers/assets.rb | 3 +- .../initializers/content_security_policy.rb | 4 +- .../initializers/filter_parameter_logging.rb | 6 +- .../new_framework_defaults_7_1.rb | 283 ++++ config/initializers/permissions_policy.rb | 20 +- config/routes.rb | 3 + package-lock.json | 1416 +++++++++++++++++ package.json | 15 + tailwind.config.js | 8 + 29 files changed, 2110 insertions(+), 350 deletions(-) delete mode 100644 app/assets/config/manifest.js delete mode 100644 app/assets/stylesheets/application.css create mode 100644 app/javascript/controllers/hello_controller.js create mode 100755 bun.lockb delete mode 100644 config/importmap.rails_admin.rb create mode 100644 config/initializers/new_framework_defaults_7_1.rb create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 tailwind.config.js diff --git a/.gitignore b/.gitignore index eb12343..0a9b780 100644 --- a/.gitignore +++ b/.gitignore @@ -34,10 +34,14 @@ # Ignore master key for decrypting credentials and more. /config/master.key -/app/assets/builds/* -!/app/assets/builds/.keep +#/app/assets/builds/* # different for diff development machines config/credentials.yml.enc dump.rdb + +/node_modules + +/app/assets/builds/* +!/app/assets/builds/.keep diff --git a/Gemfile b/Gemfile index feaccd0..ad24dc0 100644 --- a/Gemfile +++ b/Gemfile @@ -4,19 +4,18 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby "3.1.2" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.0.4" +gem "rails", "~> 7.1.2" # The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] -gem "sprockets-rails" +#gem "sprockets-rails" # Use sqlite3 as the database for Active Record gem "sqlite3", "~> 1.4" # Use the Puma web server [https://github.com/puma/puma] -gem "puma", "~> 5.0" +gem "puma", "~> 6.0" # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] -gem "importmap-rails" # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] gem "turbo-rails" @@ -80,12 +79,9 @@ group :test do gem "webdrivers" end -gem "jsbundling-rails", "~> 1.0" gem "dnsimple", "~> 8.1" -gem "tailwindcss-rails", "~> 2.0" - gem "dalli", "~> 3.2" gem "rails_nestable_layouts", path: "gems/rails_nestable_layouts" @@ -104,3 +100,14 @@ gem 'pg' gem "sentry", "~> 0.5.3" gem "sentry-rails", "~> 5.13" + +gem "solid_cache", "~> 0.2.0" + +gem "importmap-rails", "~> 1.2" + +gem "tailwindcss-rails", "~> 2.1" + +gem "cssbundling-rails", "~> 1.3" + + +gem "propshaft" diff --git a/Gemfile.lock b/Gemfile.lock index 1002af8..26f1651 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,84 +9,95 @@ PATH GEM remote: https://rubygems.org/ specs: - actioncable (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) + actioncable (7.1.2) + actionpack (= 7.1.2) + activesupport (= 7.1.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + zeitwerk (~> 2.6) + actionmailbox (7.1.2) + actionpack (= 7.1.2) + activejob (= 7.1.2) + activerecord (= 7.1.2) + activestorage (= 7.1.2) + activesupport (= 7.1.2) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.4.2) - actionpack (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionmailer (7.1.2) + actionpack (= 7.1.2) + actionview (= 7.1.2) + activejob (= 7.1.2) + activesupport (= 7.1.2) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp - rails-dom-testing (~> 2.0) - actionpack (7.0.4.2) - actionview (= 7.0.4.2) - activesupport (= 7.0.4.2) - rack (~> 2.0, >= 2.2.0) + rails-dom-testing (~> 2.2) + actionpack (7.1.2) + actionview (= 7.1.2) + activesupport (= 7.1.2) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.4.2) - actionpack (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.2) + actionpack (= 7.1.2) + activerecord (= 7.1.2) + activestorage (= 7.1.2) + activesupport (= 7.1.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.4.2) - activesupport (= 7.0.4.2) + actionview (7.1.2) + activesupport (= 7.1.2) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.4.2) - activesupport (= 7.0.4.2) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.1.2) + activesupport (= 7.1.2) globalid (>= 0.3.6) - activemodel (7.0.4.2) - activesupport (= 7.0.4.2) - activerecord (7.0.4.2) - activemodel (= 7.0.4.2) - activesupport (= 7.0.4.2) - activestorage (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activesupport (= 7.0.4.2) + activemodel (7.1.2) + activesupport (= 7.1.2) + activerecord (7.1.2) + activemodel (= 7.1.2) + activesupport (= 7.1.2) + timeout (>= 0.4.0) + activestorage (7.1.2) + actionpack (= 7.1.2) + activejob (= 7.1.2) + activerecord (= 7.1.2) + activesupport (= 7.1.2) marcel (~> 1.0) - mini_mime (>= 1.1.0) - activesupport (7.0.4.2) + activesupport (7.1.2) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) minitest (>= 5.1) + mutex_m tzinfo (~> 2.0) - addressable (2.8.1) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) android_key_attestation (0.3.0) ast (2.4.2) awrence (1.2.1) backport (1.2.0) - benchmark (0.2.1) + base64 (0.2.0) + benchmark (0.3.0) + bigdecimal (3.1.5) bindata (2.4.15) bindex (0.8.1) - bootsnap (1.16.0) + bootsnap (1.17.0) msgpack (~> 1.2) builder (3.2.4) - capybara (3.38.0) + capybara (3.39.2) addressable matrix mini_mime (>= 0.1.3) @@ -97,58 +108,64 @@ GEM xpath (~> 3.2) cbor (0.5.9.6) concurrent-ruby (1.2.2) + connection_pool (2.4.1) cose (1.3.0) cbor (~> 0.5.9) openssl-signature_algorithm (~> 1.0) crass (1.0.6) - dalli (3.2.4) - date (3.3.3) - debug (1.7.1) - irb (>= 1.5.0) - reline (>= 0.3.1) + cssbundling-rails (1.3.3) + railties (>= 6.0.0) + dalli (3.2.6) + date (3.3.4) + debug (1.9.1) + irb (~> 1.10) + reline (>= 0.3.8) diff-lcs (1.5.0) - dnsimple (8.1.0) + dnsimple (8.7.1) httparty dotenv (2.8.1) dotenv-rails (2.8.1) dotenv (= 2.8.1) railties (>= 3.2) + drb (2.2.0) + ruby2_keywords e2mmap (0.1.0) - erb-formatter (0.4.2) - syntax_tree (~> 5.0) + erb-formatter (0.6.0) + syntax_tree (~> 6.0) erubi (1.12.0) - ffi (1.15.5) - globalid (1.1.0) - activesupport (>= 5.0) + ffi (1.16.3) + globalid (1.2.1) + activesupport (>= 6.1) httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - i18n (1.12.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) - importmap-rails (1.1.5) + importmap-rails (1.2.3) actionpack (>= 6.0.0) + activesupport (>= 6.0.0) railties (>= 6.0.0) - io-console (0.6.0) - irb (1.6.2) - reline (>= 0.3.0) - jaro_winkler (1.5.4) + io-console (0.7.1) + irb (1.11.0) + rdoc + reline (>= 0.3.8) + jaro_winkler (1.5.6) jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) - jsbundling-rails (1.1.1) - railties (>= 6.0.0) - json (2.6.3) + json (2.7.1) jwt (2.7.1) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) + language_server-protocol (3.17.0.3) listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.19.1) + loofah (2.22.0) crass (~> 1.0.2) - nokogiri (>= 1.5.9) + nokogiri (>= 1.12.0) mail (2.8.1) mini_mime (>= 0.1.1) net-imap @@ -156,191 +173,206 @@ GEM net-smtp marcel (1.0.2) matrix (0.4.2) - method_source (1.0.0) - mini_mime (1.1.2) - minitest (5.17.0) - msgpack (1.6.0) + mini_mime (1.1.5) + minitest (5.20.0) + msgpack (1.7.2) multi_xml (0.6.0) - net-imap (0.3.4) + mutex_m (0.2.0) + net-imap (0.4.8) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.4.0) net-protocol netrc (0.11.0) - nio4r (2.5.8) - nokogiri (1.14.2-x86_64-darwin) + nio4r (2.7.0) + nokogiri (1.15.5-x86_64-darwin) racc (~> 1.4) - nokogiri (1.14.2-x86_64-linux) + nokogiri (1.15.5-x86_64-linux) racc (~> 1.4) - openssl (3.1.0) + openssl (3.2.0) openssl-signature_algorithm (1.3.0) openssl (> 2.0) - parallel (1.22.1) - parser (3.2.1.0) + parallel (1.24.0) + parser (3.2.2.4) ast (~> 2.4.1) - pg (1.5.3) - postmark (1.24.0) + racc + pg (1.5.4) + postmark (1.25.0) json postmark-rails (0.22.1) actionmailer (>= 3.0.0) postmark (>= 1.21.3, < 2.0) - prettier_print (1.2.0) - public_suffix (5.0.1) - puma (5.6.5) + prettier_print (1.2.1) + prism (0.19.0) + propshaft (0.8.0) + actionpack (>= 7.0.0) + activesupport (>= 7.0.0) + rack + railties (>= 7.0.0) + psych (5.1.2) + stringio + public_suffix (5.0.4) + puma (6.4.0) nio4r (~> 2.0) - racc (1.6.2) - rack (2.2.6.2) - rack-test (2.0.2) + racc (1.7.3) + rack (3.0.8) + rack-session (2.0.0) + rack (>= 3.0.0) + rack-test (2.1.0) rack (>= 1.3) - rails (7.0.4.2) - actioncable (= 7.0.4.2) - actionmailbox (= 7.0.4.2) - actionmailer (= 7.0.4.2) - actionpack (= 7.0.4.2) - actiontext (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activemodel (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails (7.1.2) + actioncable (= 7.1.2) + actionmailbox (= 7.1.2) + actionmailer (= 7.1.2) + actionpack (= 7.1.2) + actiontext (= 7.1.2) + actionview (= 7.1.2) + activejob (= 7.1.2) + activemodel (= 7.1.2) + activerecord (= 7.1.2) + activestorage (= 7.1.2) + activesupport (= 7.1.2) bundler (>= 1.15.0) - railties (= 7.0.4.2) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + railties (= 7.1.2) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.5.0) - loofah (~> 2.19, >= 2.19.1) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) rails_hotreload (0.1.2) listen rails turbo-rails - railties (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) - method_source + railties (7.1.2) + actionpack (= 7.1.2) + activesupport (= 7.1.2) + irb + rackup (>= 1.0.0) rake (>= 12.2) - thor (~> 1.0) - zeitwerk (~> 2.5) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.0.6) + rake (13.1.0) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rbi (0.0.16) - ast - parser (>= 2.6.4.0) + rbi (0.1.6) + prism (>= 0.18.0, < 0.20) sorbet-runtime (>= 0.5.9204) - unparser + rbs (2.8.4) + rdoc (6.6.2) + psych (>= 4.0.0) redis (4.8.1) - regexp_parser (2.7.0) - reline (0.3.2) + regexp_parser (2.8.3) + reline (0.4.1) io-console (~> 0.5) reverse_markdown (2.1.1) nokogiri - rexml (3.2.5) - rotp (6.2.2) - rubocop (1.46.0) + rexml (3.2.6) + rotp (6.3.0) + rubocop (1.59.0) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.0.0) + parser (>= 3.2.2.4) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.26.0, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.27.0) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) - ruby-progressbar (1.11.0) + ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) rubyzip (2.3.2) safety_net_attestation (0.4.0) jwt (~> 2.0) - selenium-webdriver (4.8.1) + selenium-webdriver (4.10.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) sentry (0.5.3) - sentry-rails (5.13.0) + sentry-rails (5.15.2) railties (>= 5.0) - sentry-ruby (~> 5.13.0) - sentry-ruby (5.13.0) + sentry-ruby (~> 5.15.2) + sentry-ruby (5.15.2) concurrent-ruby (~> 1.0, >= 1.0.2) - solargraph (0.48.0) + solargraph (0.50.0) backport (~> 1.2) benchmark - bundler (>= 1.17.2) + bundler (~> 2.0) diff-lcs (~> 1.4) e2mmap jaro_winkler (~> 1.5) kramdown (~> 2.3) kramdown-parser-gfm (~> 1.1) parser (~> 3.0) - reverse_markdown (>= 1.0.5, < 3) - rubocop (>= 0.52) + rbs (~> 2.0) + reverse_markdown (~> 2.0) + rubocop (~> 1.38) thor (~> 1.0) tilt (~> 2.0) yard (~> 0.9, >= 0.9.24) - sorbet (0.5.10696) - sorbet-static (= 0.5.10696) - sorbet-runtime (0.5.10696) - sorbet-static (0.5.10696-universal-darwin-21) - sorbet-static (0.5.10696-x86_64-linux) - sorbet-static-and-runtime (0.5.10696) - sorbet (= 0.5.10696) - sorbet-runtime (= 0.5.10696) - spoom (1.1.16) - sorbet (>= 0.5.10187) - sorbet-runtime (>= 0.5.9204) + solid_cache (0.2.0) + rails (>= 7) + sorbet (0.5.11163) + sorbet-static (= 0.5.11163) + sorbet-runtime (0.5.11163) + sorbet-static (0.5.11163-universal-darwin) + sorbet-static (0.5.11163-x86_64-linux) + sorbet-static-and-runtime (0.5.11163) + sorbet (= 0.5.11163) + sorbet-runtime (= 0.5.11163) + spoom (1.2.4) + erubi (>= 1.10.0) + sorbet-static-and-runtime (>= 0.5.10187) + syntax_tree (>= 6.1.1) thor (>= 0.19.2) - sprockets (4.2.0) - concurrent-ruby (~> 1.0) - rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - sprockets (>= 3.0.0) - sqlite3 (1.6.1-x86_64-darwin) - sqlite3 (1.6.1-x86_64-linux) - stimulus-rails (1.2.1) + sqlite3 (1.6.9-x86_64-darwin) + sqlite3 (1.6.9-x86_64-linux) + stimulus-rails (1.3.0) railties (>= 6.0.0) - syntax_tree (5.3.0) + stringio (3.1.0) + syntax_tree (6.2.0) prettier_print (>= 1.2.0) - tailwindcss-rails (2.0.23-x86_64-darwin) + tailwindcss-rails (2.1.0-x86_64-darwin) railties (>= 6.0.0) - tailwindcss-rails (2.0.23-x86_64-linux) + tailwindcss-rails (2.1.0-x86_64-linux) railties (>= 6.0.0) - tapioca (0.11.1) - bundler (>= 1.17.3) + tapioca (0.11.14) + bundler (>= 2.2.25) netrc (>= 0.11.0) parallel (>= 1.21.0) - rbi (~> 0.0.0, >= 0.0.16) + rbi (>= 0.1.4, < 0.2) sorbet-static-and-runtime (>= 0.5.10187) - spoom (~> 1.1.0, >= 1.1.11) + spoom (~> 1.2.0, >= 1.2.0) thor (>= 1.2.0) yard-sorbet - thor (1.2.1) - tilt (2.1.0) - timeout (0.3.2) + thor (1.3.0) + tilt (2.3.0) + timeout (0.4.1) tpm-key_attestation (0.12.0) bindata (~> 2.4) openssl (> 2.0) openssl-signature_algorithm (~> 1.0) - turbo-rails (1.3.3) + turbo-rails (1.5.0) actionpack (>= 6.0.0) activejob (>= 6.0.0) railties (>= 6.0.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.4.2) - unparser (0.6.7) - diff-lcs (~> 1.3) - parser (>= 3.2.0) - web-console (4.2.0) + unicode-display_width (2.5.0) + web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) @@ -354,23 +386,22 @@ GEM openssl (>= 2.2) safety_net_attestation (~> 0.4.0) tpm-key_attestation (~> 0.12.0) - webdrivers (5.2.0) + webdrivers (5.3.1) nokogiri (~> 1.6) rubyzip (>= 1.3.0) - selenium-webdriver (~> 4.0) - webrick (1.7.0) - websocket (1.2.9) - websocket-driver (0.7.5) + selenium-webdriver (~> 4.0, < 4.11) + webrick (1.8.1) + websocket (1.2.10) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.28) - webrick (~> 1.7.0) - yard-sorbet (0.8.0) + yard (0.9.34) + yard-sorbet (0.8.1) sorbet-runtime (>= 0.5) yard (>= 0.9) - zeitwerk (2.6.7) + zeitwerk (2.6.12) PLATFORMS x86_64-darwin-21 @@ -379,18 +410,19 @@ PLATFORMS DEPENDENCIES bootsnap capybara + cssbundling-rails (~> 1.3) dalli (~> 3.2) debug dnsimple (~> 8.1) dotenv-rails erb-formatter - importmap-rails + importmap-rails (~> 1.2) jbuilder - jsbundling-rails (~> 1.0) pg postmark-rails - puma (~> 5.0) - rails (~> 7.0.4) + propshaft + puma (~> 6.0) + rails (~> 7.1.2) rails_hotreload rails_nestable_layouts! redis (~> 4.0) @@ -400,12 +432,12 @@ DEPENDENCIES sentry (~> 0.5.3) sentry-rails (~> 5.13) solargraph + solid_cache (~> 0.2.0) sorbet sorbet-runtime - sprockets-rails sqlite3 (~> 1.4) stimulus-rails - tailwindcss-rails (~> 2.0) + tailwindcss-rails (~> 2.1) tapioca turbo-rails tzinfo-data @@ -417,4 +449,4 @@ RUBY VERSION ruby 3.1.2p20 BUNDLED WITH - 2.4.7 + 2.5.2 diff --git a/Procfile.dev b/Procfile.dev index e24aa8d..16cfeb3 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,3 +1,4 @@ web: rdbg -n --open=vscode -c -- bin/rails server -p 3000 css: bin/rails tailwindcss:watch -rails_hotreload: bin/rails rails_hotreload:start app/views,app/assets,app/javascript \ No newline at end of file +rails_hotreload: bin/rails rails_hotreload:start app/views,app/assets,app/javascriptjs: yarn build --watch +css: bun run build:css --watch diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js deleted file mode 100644 index b06fc42..0000000 --- a/app/assets/config/manifest.js +++ /dev/null @@ -1,5 +0,0 @@ -//= link_tree ../images -//= link_directory ../stylesheets .css -//= link_tree ../../javascript .js -//= link_tree ../../../vendor/javascript .js -//= link_tree ../builds diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css deleted file mode 100644 index 10207bb..0000000 --- a/app/assets/stylesheets/application.css +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's - * vendor/assets/stylesheets directory can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any other CSS - * files in this directory. Styles in this file should be added after the last require_* statement. - * It is generally better to create a new file per style scope. - * - *= require_tree . - *= require_self -*/ - -:root { - --winter-sky: #FF206E; - --cultured: #F5F5F5; - --bg: #343434; - --lemon-glacier: #FBFF12; -} -h1 { - font-size: larger; - font-weight: 800; -} - -button, input[type=submit] { - background-color: var(--winter-sky); - border-radius: 999999px; - display: inline-flex; - padding: 0.625rem 0.90625rem; - justify-content: center; - align-items: center; - gap: 0.625rem; - color: var(--cultured, #F5F5F5); - font-size: 1.25rem; - font-family: "Telegraf"; - line-height: 100%; - min-width: min-content; -} - -input[type=text], input[type=email], input[type=number] { - background-color: rgba(245, 245, 245, 0.1) !important; - border: 1.5px solid var(--cultured)!important; - border-radius: 5px !important; - min-width: 350px; - color: white; -} - -input[type=number] { - min-width: 100px !important; - width: 100px !important; -} - -.admin { - border: 2px dashed skyblue; -} - -.flash { - padding: 0.625rem 0.90625rem; - border-radius: 10000000px; - width: fit-content; - margin-left: auto; - margin-right: auto; - margin-bottom: 2rem; - position: fixed; - left: calc(50vw - 50cqw); - right: calc(50vw - 50cqw); - container-type: normal; - bottom: 0; -} -.flash-notice { - background-color: cornflowerblue; -} - -.hidden { - display: none; -} - -.record-edit { - min-width: unset !important; - width: 150px; -} - -.outline-pink-border { - background-color: transparent !important; - background: transparent !important; - border: 2px solid var(--winter-sky); - transition: ease-in-out 0.1s; -} - -.outline-pink-border:hover { - background-color: var(--winter-sky) !important; -} \ No newline at end of file diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 9e9650a..fbe8a3f 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -21,7 +21,7 @@ */ @font-face { font-family: "Telegraf"; - src: url("fonts/PPTelegraf-Variable.woff2"); + src: url("/fonts/PPTelegraf-Variable.woff2"); font-weight: 200 900; unicode-range: U+0020-007E, U+00A1-00A3, U+00A5-00A9, U+00AB-00AC, U+00AE-00B1, U+00B4-00B8, U+00BB, U+00BF-0107, U+010A-0113, @@ -139,7 +139,7 @@ */ @font-face { font-family: "Telegraf SemiBold"; - src: url("fonts/PPTelegraf-SemiBold.ttf"); + src: url("/fonts/PPTelegraf-SemiBold.ttf"); unicode-range: U+0020-007E, U+00A1-00A3, U+00A5-00A9, U+00AB-00AC, U+00AE-00B1, U+00B4-00B8, U+00BB, U+00BF-0107, U+010A-0113, U+0116-011B, U+011E-0123, U+0126-0127, U+012A-012B, U+012E-0131, @@ -160,7 +160,7 @@ */ @font-face { font-family: "PP Charlevoix Regular"; - src: url("fonts/PPCharlevoix-Regular.woff2"); + src: url("/fonts/PPCharlevoix-Regular.woff2"); unicode-range: U+0020-005F, U+0061-007E, U+00A1-00A5, U+00A9, U+00AB-00AC, U+00AE, U+00B0-00B1, U+00B7, U+00BB, U+00BF-0107, U+010A-0113, U+0116-011B, U+011E-0123, U+0126-0127, U+012A-012B, @@ -240,4 +240,85 @@ } #dns_records > [data-empty="false"] > :first-child { @apply hidden; -} \ No newline at end of file +} + + +:root { + --winter-sky: #FF206E; + --cultured: #F5F5F5; + --bg: #343434; + --lemon-glacier: #FBFF12; +} +h1 { + font-size: larger; + font-weight: 800; +} + +button, input[type=submit] { + background-color: var(--winter-sky); + border-radius: 999999px; + display: inline-flex; + padding: 0.625rem 0.90625rem; + justify-content: center; + align-items: center; + gap: 0.625rem; + color: var(--cultured, #F5F5F5); + font-size: 1.25rem; + font-family: "Telegraf"; + line-height: 100%; + min-width: min-content; +} + +input[type=text], input[type=email], input[type=number] { + background-color: rgba(245, 245, 245, 0.1) !important; + border: 1.5px solid var(--cultured)!important; + border-radius: 5px !important; + min-width: 350px; + color: white; +} + +input[type=number] { + min-width: 100px !important; + width: 100px !important; +} + +.admin { + border: 2px dashed skyblue; +} + +.flash { + padding: 0.625rem 0.90625rem; + border-radius: 10000000px; + width: fit-content; + margin-left: auto; + margin-right: auto; + margin-bottom: 2rem; + position: fixed; + left: calc(50vw - 50cqw); + right: calc(50vw - 50cqw); + container-type: normal; + bottom: 0; +} +.flash-notice { + background-color: cornflowerblue; +} + +.hidden { + display: none; +} + +.record-edit { + min-width: unset !important; + width: 150px; +} + +.outline-pink-border { + background-color: transparent !important; + background: transparent !important; + border: 2px solid var(--winter-sky); + transition: ease-in-out 0.1s; +} + +.outline-pink-border:hover { + background-color: var(--winter-sky) !important; +} diff --git a/app/javascript/application.js b/app/javascript/application.js index 0d7b494..5221498 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,3 +1,2 @@ -// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails -import "@hotwired/turbo-rails" import "controllers" +import "@hotwired/turbo-rails" \ No newline at end of file diff --git a/app/javascript/controllers/application.js b/app/javascript/controllers/application.js index 69ac914..1213e85 100644 --- a/app/javascript/controllers/application.js +++ b/app/javascript/controllers/application.js @@ -1,7 +1,4 @@ import { Application } from "@hotwired/stimulus" -import "@hotwired/turbo-rails" - -Turbo.setProgressBarDelay(200) const application = Application.start() diff --git a/app/javascript/controllers/empty_controller.js b/app/javascript/controllers/empty_controller.js index 482b03a..b1ec280 100644 --- a/app/javascript/controllers/empty_controller.js +++ b/app/javascript/controllers/empty_controller.js @@ -12,6 +12,7 @@ export default class extends Controller { }); this.update(); + console.log("empty controller") } watchedTargetConnected() { diff --git a/app/javascript/controllers/hello_controller.js b/app/javascript/controllers/hello_controller.js new file mode 100644 index 0000000..5975c07 --- /dev/null +++ b/app/javascript/controllers/hello_controller.js @@ -0,0 +1,7 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + connect() { + this.element.textContent = "Hello World!" + } +} diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 49c14e1..4037280 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -6,11 +6,8 @@ <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %> - <%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %> - <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %> - - <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> + <%= javascript_include_tag "application", "data-turbo-track": "reload" %> diff --git a/bin/dev b/bin/dev index 74ade16..a4e05fa 100755 --- a/bin/dev +++ b/bin/dev @@ -5,4 +5,7 @@ if ! gem list foreman -i --silent; then gem install foreman fi +# Default to port 3000 if not specified +export PORT="${PORT:-3000}" + exec foreman start -f Procfile.dev "$@" diff --git a/bin/setup b/bin/setup index ec47b79..3cd5a9d 100755 --- a/bin/setup +++ b/bin/setup @@ -5,7 +5,7 @@ require "fileutils" APP_ROOT = File.expand_path("..", __dir__) def system!(*args) - system(*args) || abort("\n== Command #{args} failed ==") + system(*args, exception: true) end FileUtils.chdir APP_ROOT do diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..7ec5363298ae0259ef2f0a014b0b64172431b5ae GIT binary patch literal 47250 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 literal 0 HcmV?d00001 diff --git a/config/application.rb b/config/application.rb index 59be41a..1e299b7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,7 @@ module AdminOblOng class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.0 + config.load_defaults 7.1 # Configuration for the application, engines, and railties goes here. # @@ -46,5 +46,7 @@ class Application < Rails::Application # Change to the domain where you're registering subdomains config.domain = "obl.ong" + + config.assets.paths << Rails.root.join('app', 'javascript') end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 63849c0..b9b26da 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -70,4 +70,12 @@ # Origin for the WebAuthn RP config.webauthn_origin = "http://localhost:3000" + + + config.action_controller.raise_on_missing_callback_actions = true + + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + + config.enable_reloading = true end diff --git a/config/environments/test.rb b/config/environments/test.rb index 6ea4d1e..adbb4a6 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -8,12 +8,13 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # Turn false under Spring and add config.action_view.cache_template_loading = true. - config.cache_classes = true + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false - # Eager loading loads your whole application. When running a single test locally, - # this probably isn't necessary. It's a good idea to do in a continuous integration - # system, or in some way before deploying your code. + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. config.eager_load = ENV["CI"].present? # Configure public file server for tests with Cache-Control for performance. @@ -23,12 +24,12 @@ } # Show full error reports and disable caching. - config.consider_all_requests_local = true + config.consider_all_requests_local = true config.action_controller.perform_caching = false config.cache_store = :null_store - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false @@ -57,4 +58,7 @@ # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true + + # Raise error when a before_action's only/except options reference missing actions + config.action_controller.raise_on_missing_callback_actions = true end diff --git a/config/importmap.rails_admin.rb b/config/importmap.rails_admin.rb deleted file mode 100644 index 0519dbd..0000000 --- a/config/importmap.rails_admin.rb +++ /dev/null @@ -1,11 +0,0 @@ -pin "rails_admin", preload: true -pin "rails_admin/src/rails_admin/base", to: "https://ga.jspm.io/npm:rails_admin@3.1.2/src/rails_admin/base.js" -pin "@hotwired/turbo", to: "https://ga.jspm.io/npm:@hotwired/turbo@7.3.0/dist/turbo.es2017-esm.js" -pin "@hotwired/turbo-rails", to: "https://ga.jspm.io/npm:@hotwired/turbo-rails@7.3.0/app/javascript/turbo/index.js" -pin "@popperjs/core", to: "https://ga.jspm.io/npm:@popperjs/core@2.11.8/dist/esm/popper.js" -pin "@rails/actioncable/src", to: "https://ga.jspm.io/npm:@rails/actioncable@7.0.5/src/index.js" -pin "@rails/ujs", to: "https://ga.jspm.io/npm:@rails/ujs@6.1.7/lib/assets/compiled/rails-ujs.js" -pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@5.3.0/dist/js/bootstrap.esm.js" -pin "flatpickr", to: "https://ga.jspm.io/npm:flatpickr@4.6.13/dist/esm/index.js" -pin "jquery", to: "https://ga.jspm.io/npm:jquery@3.7.0/dist/jquery.js" -pin "jquery-ui/", to: "https://ga.jspm.io/npm:jquery-ui@1.13.2/" \ No newline at end of file diff --git a/config/importmap.rb b/config/importmap.rb index 5eb30a7..5609f04 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -1,9 +1,9 @@ # Pin npm packages by running ./bin/importmap -pin "application", preload: true pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true pin_all_from "app/javascript/controllers", under: "controllers" pin "@github/webauthn-json/browser-ponyfill", to: "https://ga.jspm.io/npm:@github/webauthn-json@2.1.1/dist/esm/webauthn-json.browser-ponyfill.js" pin "url-safe-base64", to: "https://ga.jspm.io/npm:url-safe-base64@1.3.0/src/index.js" +pin_all_from "app/javascript" \ No newline at end of file diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index ad09396..742be09 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -10,4 +10,5 @@ # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. # Rails.application.config.assets.precompile += %w( admin.js admin.css ) -Rails.application.config.assets.paths << Rails.root.join("node_modules/@fortawesome/fontawesome-free/webfonts") + +Rails.application.config.assets.debug = true \ No newline at end of file diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 54f47cf..b3076b3 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -16,9 +16,9 @@ # # policy.report_uri "/csp-violation-report-endpoint" # end # -# # Generate session nonces for permitted importmap and inline scripts +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } -# config.content_security_policy_nonce_directives = %w(script-src) +# config.content_security_policy_nonce_directives = %w(script-src style-src) # # # Report violations without enforcing the policy. # # config.content_security_policy_report_only = true diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index adc6568..c2d89e2 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -1,8 +1,8 @@ # Be sure to restart your server when you modify this file. -# Configure parameters to be filtered from the log file. Use this to limit dissemination of -# sensitive information. See the ActiveSupport::ParameterFilter documentation for supported -# notations and behaviors. +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += [ :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn ] diff --git a/config/initializers/new_framework_defaults_7_1.rb b/config/initializers/new_framework_defaults_7_1.rb new file mode 100644 index 0000000..e18bbf3 --- /dev/null +++ b/config/initializers/new_framework_defaults_7_1.rb @@ -0,0 +1,283 @@ +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 7.1 framework defaults upgrade. +# +# Uncomment each configuration one by one to switch to the new default. +# Once your application is ready to run with all new defaults, you can remove +# this file and set the `config.load_defaults` to `7.1`. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html + +### +# No longer add autoloaded paths into `$LOAD_PATH`. This means that you won't be able +# to manually require files that are managed by the autoloader, which you shouldn't do anyway. +# +# This will reduce the size of the load path, making `require` faster if you don't use bootsnap, or reduce the size +# of the bootsnap cache if you use it. +#++ +# Rails.application.config.add_autoload_paths_to_load_path = false + +### +# Remove the default X-Download-Options headers since it is used only by Internet Explorer. +# If you need to support Internet Explorer, add back `"X-Download-Options" => "noopen"`. +#++ +# Rails.application.config.action_dispatch.default_headers = { +# "X-Frame-Options" => "SAMEORIGIN", +# "X-XSS-Protection" => "0", +# "X-Content-Type-Options" => "nosniff", +# "X-Permitted-Cross-Domain-Policies" => "none", +# "Referrer-Policy" => "strict-origin-when-cross-origin" +# } + +### +# Do not treat an `ActionController::Parameters` instance +# as equal to an equivalent `Hash` by default. +#++ +# Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false + +### +# Active Record Encryption now uses SHA-256 as its hash digest algorithm. +# +# There are 3 scenarios to consider. +# +# 1. If you have data encrypted with previous Rails versions, and you have +# +config.active_support.key_generator_hash_digest_class+ configured as SHA1 (the default +# before Rails 7.0), you need to configure SHA-1 for Active Record Encryption too: +#++ +# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1 +# +# 2. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA256 (the new default +# in 7.0), then you need to configure SHA-256 for Active Record Encryption: +#++ +# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256 +# +# 3. If you don't currently have data encrypted with Active Record encryption, you can disable this setting to +# configure the default behavior starting 7.1+: +#++ +# Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = false + +### +# No longer run after_commit callbacks on the first of multiple Active Record +# instances to save changes to the same database row within a transaction. +# Instead, run these callbacks on the instance most likely to have internal +# state which matches what was committed to the database, typically the last +# instance to save. +#++ +# Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false + +### +# Configures SQLite with a strict strings mode, which disables double-quoted string literals. +# +# SQLite has some quirks around double-quoted string literals. +# It first tries to consider double-quoted strings as identifier names, but if they don't exist +# it then considers them as string literals. Because of this, typos can silently go unnoticed. +# For example, it is possible to create an index for a non existing column. +# See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details. +#++ +# Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true + +### +# Disable deprecated singular associations names. +#++ +# Rails.application.config.active_record.allow_deprecated_singular_associations_name = false + +### +# Enable the Active Job `BigDecimal` argument serializer, which guarantees +# roundtripping. Without this serializer, some queue adapters may serialize +# `BigDecimal` arguments as simple (non-roundtrippable) strings. +# +# When deploying an application with multiple replicas, old (pre-Rails 7.1) +# replicas will not be able to deserialize `BigDecimal` arguments from this +# serializer. Therefore, this setting should only be enabled after all replicas +# have been successfully upgraded to Rails 7.1. +#++ +# Rails.application.config.active_job.use_big_decimal_serializer = true + +### +# Specify if an `ArgumentError` should be raised if `Rails.cache` `fetch` or +# `write` are given an invalid `expires_at` or `expires_in` time. +# Options are `true`, and `false`. If `false`, the exception will be reported +# as `handled` and logged instead. +#++ +# Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true + +### +# Specify whether Query Logs will format tags using the SQLCommenter format +# (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format. +# Options are `:legacy` and `:sqlcommenter`. +#++ +# Rails.application.config.active_record.query_log_tags_format = :sqlcommenter + +### +# Specify the default serializer used by `MessageEncryptor` and `MessageVerifier` +# instances. +# +# The legacy default is `:marshal`, which is a potential vector for +# deserialization attacks in cases where a message signing secret has been +# leaked. +# +# In Rails 7.1, the new default is `:json_allow_marshal` which serializes and +# deserializes with `ActiveSupport::JSON`, but can fall back to deserializing +# with `Marshal` so that legacy messages can still be read. +# +# In Rails 7.2, the default will become `:json` which serializes and +# deserializes with `ActiveSupport::JSON` only. +# +# Alternatively, you can choose `:message_pack` or `:message_pack_allow_marshal`, +# which serialize with `ActiveSupport::MessagePack`. `ActiveSupport::MessagePack` +# can roundtrip some Ruby types that are not supported by JSON, and may provide +# improved performance, but it requires the `msgpack` gem. +# +# For more information, see +# https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer +# +# If you are performing a rolling deploy of a Rails 7.1 upgrade, wherein servers +# that have not yet been upgraded must be able to read messages from upgraded +# servers, first deploy without changing the serializer, then set the serializer +# in a subsequent deploy. +#++ +# Rails.application.config.active_support.message_serializer = :json_allow_marshal + +### +# Enable a performance optimization that serializes message data and metadata +# together. This changes the message format, so messages serialized this way +# cannot be read by older versions of Rails. However, messages that use the old +# format can still be read, regardless of whether this optimization is enabled. +# +# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have +# not yet been upgraded must be able to read messages from upgraded servers, +# leave this optimization off on the first deploy, then enable it on a +# subsequent deploy. +#++ +# Rails.application.config.active_support.use_message_serializer_for_metadata = true + +### +# Set the maximum size for Rails log files. +# +# `config.load_defaults 7.1` does not set this value for environments other than +# development and test. +#++ +# if Rails.env.local? +# Rails.application.config.log_file_size = 100 * 1024 * 1024 +# end + +### +# Enable raising on assignment to attr_readonly attributes. The previous +# behavior would allow assignment but silently not persist changes to the +# database. +#++ +# Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true + +### +# Enable validating only parent-related columns for presence when the parent is mandatory. +# The previous behavior was to validate the presence of the parent record, which performed an extra query +# to get the parent every time the child record was updated, even when parent has not changed. +#++ +# Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false + +### +# Enable precompilation of `config.filter_parameters`. Precompilation can +# improve filtering performance, depending on the quantity and types of filters. +#++ +# Rails.application.config.precompile_filter_parameters = true + +### +# Enable before_committed! callbacks on all enrolled records in a transaction. +# The previous behavior was to only run the callbacks on the first copy of a record +# if there were multiple copies of the same record enrolled in the transaction. +#++ +# Rails.application.config.active_record.before_committed_on_all_records = true + +### +# Disable automatic column serialization into YAML. +# To keep the historic behavior, you can set it to `YAML`, however it is +# recommended to explicitly define the serialization method for each column +# rather than to rely on a global default. +#++ +# Rails.application.config.active_record.default_column_serializer = nil + +### +# Enable a performance optimization that serializes Active Record models +# in a faster and more compact way. +# +# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have +# not yet been upgraded must be able to read caches from upgraded servers, +# leave this optimization off on the first deploy, then enable it on a +# subsequent deploy. +#++ +# Rails.application.config.active_record.marshalling_format_version = 7.1 + +### +# Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model. +# This matches the behaviour of all other callbacks. +# In previous versions of Rails, they ran in the inverse order. +#++ +# Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true + +### +# Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`. +#++ +# Rails.application.config.active_record.commit_transaction_on_non_local_return = true + +### +# Controls when to generate a value for has_secure_token declarations. +#++ +# Rails.application.config.active_record.generate_secure_token_on = :initialize + +### +# ** Please read carefully, this must be configured in config/application.rb ** +# +# Change the format of the cache entry. +# +# Changing this default means that all new cache entries added to the cache +# will have a different format that is not supported by Rails 7.0 +# applications. +# +# Only change this value after your application is fully deployed to Rails 7.1 +# and you have no plans to rollback. +# When you're ready to change format, add this to `config/application.rb` (NOT +# this file): +# config.active_support.cache_format_version = 7.1 + + +### +# Configure Action View to use HTML5 standards-compliant sanitizers when they are supported on your +# platform. +# +# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action View to use HTML5-compliant +# sanitizers if they are supported, else fall back to HTML4 sanitizers. +# +# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor. +#++ +# Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor + + +### +# Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your +# platform. +# +# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action Text to use HTML5-compliant +# sanitizers if they are supported, else fall back to HTML4 sanitizers. +# +# In previous versions of Rails, Action Text always used `Rails::HTML4::Sanitizer` as its vendor. +#++ +# Rails.application.config.action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor + + +### +# Configure the log level used by the DebugExceptions middleware when logging +# uncaught exceptions during requests. +#++ +# Rails.application.config.action_dispatch.debug_exception_log_level = :error + + +### +# Configure the test helpers in Action View, Action Dispatch, and rails-dom-testing to use HTML5 +# parsers. +# +# Nokogiri::HTML5 isn't supported on JRuby, so JRuby applications must set this to :html4. +# +# In previous versions of Rails, these test helpers always used an HTML4 parser. +#++ +# Rails.application.config.dom_testing_default_html_version = :html5 diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb index 00f64d7..7db3b95 100644 --- a/config/initializers/permissions_policy.rb +++ b/config/initializers/permissions_policy.rb @@ -1,11 +1,13 @@ +# Be sure to restart your server when you modify this file. + # Define an application-wide HTTP permissions policy. For further -# information see https://developers.google.com/web/updates/2018/06/feature-policy -# -# Rails.application.config.permissions_policy do |f| -# f.camera :none -# f.gyroscope :none -# f.microphone :none -# f.usb :none -# f.fullscreen :self -# f.payment :self, "https://secure.example.com" +# information see: https://developers.google.com/web/updates/2018/06/feature-policy + +# Rails.application.config.permissions_policy do |policy| +# policy.camera :none +# policy.gyroscope :none +# policy.microphone :none +# policy.usb :none +# policy.fullscreen :self +# policy.payment :self, "https://secure.example.com" # end diff --git a/config/routes.rb b/config/routes.rb index 3636024..b17df8f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,8 @@ Rails.application.routes.draw do # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + get "up" => "rails/health#show", as: :rails_health_check get 'domains/request', to: 'domains#request_domain' @@ -46,4 +48,5 @@ # Defines the root path route ("/") root "domains#index" + end diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..28b280d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1416 @@ +{ + "name": "app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "app", + "dependencies": { + "autoprefixer": "latest", + "postcss": "latest", + "tailwindcss": "latest" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/autoprefixer": { + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001571", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz", + "integrity": "sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.616", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", + "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz", + "integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b0f51c5 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "app", + "private": "true", + "scripts": { + "build:css": "tailwindcss -c ./config/tailwind.config.js -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify" + }, + "dependencies": { + "@tailwindcss/aspect-ratio": "^0.4.2", + "@tailwindcss/forms": "^0.5.7", + "@tailwindcss/typography": "^0.5.10", + "autoprefixer": "latest", + "postcss": "latest", + "tailwindcss": "latest" + } +} diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..4bca89f --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,8 @@ +module.exports = { + content: [ + './app/views/**/*.html.erb', + './app/helpers/**/*.rb', + './app/assets/stylesheets/**/*.css', + './app/javascript/**/*.js' + ] +} From ce7343e11d755f0d3c9c772565cb408eddea9edf Mon Sep 17 00:00:00 2001 From: reesericci Date: Tue, 26 Dec 2023 17:54:26 +0000 Subject: [PATCH 3/7] Passkeys update (enable resident keys) --- app/controllers/auth_controller.rb | 12 +++++++++--- app/javascript/controllers/webauthn_controller.js | 5 ++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/controllers/auth_controller.rb b/app/controllers/auth_controller.rb index d51ff04..4de17f3 100644 --- a/app/controllers/auth_controller.rb +++ b/app/controllers/auth_controller.rb @@ -10,7 +10,7 @@ class AuthController < ApplicationController def login # allow: User::Credential.all.map { |c| c.webauthn_id } - options = WebAuthn::Credential.options_for_get( rp_id: WebAuthn.configuration.rp_id) + options = WebAuthn::Credential.options_for_get(rp_id: WebAuthn.configuration.rp_id) session[:authentication_challenge] = options.challenge @@ -70,8 +70,14 @@ def create_key @options = WebAuthn::Credential.options_for_create( - user: { id: user.webauthn_id, name: user.email } - ) + user: { id: user.webauthn_id, name: user.email, display_name: user.name }, + authenticator_selection: { + residentKey: "required", + userVerification: "preferred" + }, + extensions: { + "credProps": true + }) session[:creation_challenge] = @options.challenge end diff --git a/app/javascript/controllers/webauthn_controller.js b/app/javascript/controllers/webauthn_controller.js index 32c5f45..0112334 100644 --- a/app/javascript/controllers/webauthn_controller.js +++ b/app/javascript/controllers/webauthn_controller.js @@ -2,6 +2,7 @@ import { Controller } from "@hotwired/stimulus" import * as Auth from "@github/webauthn-json/browser-ponyfill"; import { encode } from 'url-safe-base64' + function utf8_to_b64(str) { return window.btoa(unescape(encodeURIComponent(str))); } @@ -16,11 +17,13 @@ export default class extends Controller { if (typeof(PublicKeyCredential) == "undefined") { window.location.pathname = "/auth/unsupported" } + + window.Auth = Auth } async createKey() { const options = Auth.parseCreationOptionsFromJSON({ publicKey: JSON.parse(this.optionsValue)}); - const response = await Auth.create(options); + const response = await Auth.create(options); return response; } From b0459760901c8446053812abc7e457c533eea33d Mon Sep 17 00:00:00 2001 From: reesericci Date: Tue, 26 Dec 2023 22:47:10 +0000 Subject: [PATCH 4/7] domain card aesthetic changes --- app/views/domains/_domain.html.erb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/domains/_domain.html.erb b/app/views/domains/_domain.html.erb index 4abc6f7..f614b9c 100644 --- a/app/views/domains/_domain.html.erb +++ b/app/views/domains/_domain.html.erb @@ -1,12 +1,12 @@ - -

- <%= domain.host + "." + Rails.application.config.domain %> + +

+ <%= domain.host %><%= "." + Rails.application.config.domain %>

-
+
<% if domain.top_records.length > 0 %> <% domain.top_records.each do |r| %>
- <%= r.type%> + <%= r.type%> <%= r.name %> → <%= r.content %>
<% end %> @@ -16,7 +16,7 @@
-
+
Live Manage →
From a3d281a1d8e0eeb42d5c1dc631e475b188aff1ff Mon Sep 17 00:00:00 2001 From: reesericci Date: Tue, 26 Dec 2023 23:05:46 +0000 Subject: [PATCH 5/7] fix registration -> login page bug --- app/views/auth/login.html.erb | 3 +++ app/views/layouts/application.html.erb | 1 + 2 files changed, 4 insertions(+) diff --git a/app/views/auth/login.html.erb b/app/views/auth/login.html.erb index ab141ce..ea040fa 100644 --- a/app/views/auth/login.html.erb +++ b/app/views/auth/login.html.erb @@ -1,3 +1,6 @@ +<% content_for :head do %> + +<% end %>
<%= image_tag "oval.svg", size: "200" %>

Login to continue to
Obl.ong

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 4037280..1770177 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,6 +8,7 @@ <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> <%= javascript_include_tag "application", "data-turbo-track": "reload" %> + <%= yield :head %> From 8de395df852e377d78be6e37e56296bd33452151 Mon Sep 17 00:00:00 2001 From: reesericci Date: Tue, 26 Dec 2023 23:32:38 +0000 Subject: [PATCH 6/7] fix registration email OTP --- app/controllers/users_controller.rb | 14 +++++++++----- app/views/domains/index.html.erb | 4 ++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 05daa21..f9f5538 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -35,16 +35,20 @@ def create end def email_verification - User::Mailer.with(user: self.current_user).verification_email.deliver_later + user = current_user + @user = user + if Time.now.to_i > (user.try(:otp_last_minted).nil? ? 0 : user.otp_last_minted) + 600 || params[:resend] == "true" then + User::Mailer.with(user: user).verification_email.deliver_later + if params[:resend] == "true" then flash[:notice] = "Sent email code" end + end end def verify_email - user = self.current_user - if user.use_otp(params[:otp].to_s) == true + u = current_user + if u.use_otp(params[:code]) == true then session[:email_verified] = true if params[:skip_passkey] == 'true' - user.verified = true - user.save + u.update(verified: true) session[:authenticated] = true redirect_to controller: 'domains', action: 'index' else diff --git a/app/views/domains/index.html.erb b/app/views/domains/index.html.erb index ed94dd2..dc773b0 100644 --- a/app/views/domains/index.html.erb +++ b/app/views/domains/index.html.erb @@ -1,3 +1,7 @@ +<% content_for :head do %> + +<% end %> +

Manage your domains

From 15b4a4b5985161f143ebf6fbc06f34f9fe087418 Mon Sep 17 00:00:00 2001 From: Reese Armstrong Date: Tue, 26 Dec 2023 17:40:12 -0600 Subject: [PATCH 7/7] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 85cd8f5..61eca61 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ This is the backbone for Obl.ong, a nonprofit service providing free, quality do - Install Ruby **3.1.2** - Install Ruby on Rails with Bundler +- Install Bun for compiling tailwind - Pull submodules - Run `rails credentials:edit` and add these keys: @@ -15,8 +16,10 @@ This is the backbone for Obl.ong, a nonprofit service providing free, quality do account_id: ACCOUNT_ID postmark_api_token: "POSTMARK_API_TOKEN" + sentry: SENTRY_URI ``` -- Run `rails tailwindcss:build` +- Run `rails assets:precompile` +- Copy `app/javascript/application.js` to `public/assets/application-{hash}.js` (must be done every time assets is recompiled) - Edit `config/application.rb` to reflect your environment - Start the server with `bin/rails server`