From 3be5b7e7b83c12b4de9ac9e4ea587f419c29eb0f Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Sun, 4 Jan 2026 23:04:40 +0100 Subject: [PATCH 01/12] Move to grover for PDF generation --- Dockerfile | 3 ++- Gemfile | 3 +-- Gemfile.lock | 9 +++------ app/assets/stylesheets/pdf.scss | 8 +------- app/controllers/invoices_controller.rb | 26 +++++++++++++++++++++----- app/mailers/invoice_mailer.rb | 8 ++++++-- app/policies/invoice_policy.rb | 4 ++++ app/views/invoices/index.html.erb | 8 ++++++++ config/initializers/grover.rb | 23 +++++++++++++++++++++++ config/initializers/wicked_pdf.rb | 21 --------------------- 10 files changed, 69 insertions(+), 44 deletions(-) create mode 100644 config/initializers/grover.rb delete mode 100644 config/initializers/wicked_pdf.rb diff --git a/Dockerfile b/Dockerfile index 9a7c160a6..cbd1116cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,8 @@ RUN apt-get update -qq && \ libpq-dev \ curl \ netcat-traditional \ - wkhtmltopdf \ + chromium \ + chromium-driver \ libyaml-dev # Add Node, required for asset pipeline. diff --git a/Gemfile b/Gemfile index 5c5494961..521486c87 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,7 @@ gem 'http', '~> 5.3.1' gem 'jbuilder', '~> 2.14.1' gem 'jquery-rails', '~> 4.6.1' gem 'jsbundling-rails', '~> 1.3', '>= 1.3.1' +gem 'grover', '~> 1.2.4' gem 'kaminari', '~> 1.2.2' gem 'mollie-api-ruby', '~> 4.18.0' gem 'net-imap', '~> 0.6.2' @@ -43,8 +44,6 @@ gem 'sprockets-rails', '~> 3.5', '>= 3.5.2' gem 'turbo-rails', '~> 2.0', '>= 2.0.20' gem 'uglifier', '~> 4.2.1' gem 'validates_timeliness', '~> 7.1.0' -gem 'wicked_pdf', '~> 2.8.2' -gem 'wkhtmltopdf-binary', '~> 0.12.6.10' group :development, :test do gem 'awesome_print', '~> 1.9.2' diff --git a/Gemfile.lock b/Gemfile.lock index 461a586d2..e5867c7cd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -183,6 +183,8 @@ GEM google-protobuf (4.33.0-x86_64-linux-gnu) bigdecimal rake (>= 13) + grover (1.2.4) + nokogiri (~> 1) guard (2.19.1) formatador (>= 0.2.4) listen (>= 2.7, < 4.0) @@ -596,10 +598,6 @@ GEM base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - wicked_pdf (2.8.2) - activesupport - ostruct - wkhtmltopdf-binary (0.12.6.10) zeitwerk (2.7.3) PLATFORMS @@ -625,6 +623,7 @@ DEPENDENCIES factory_bot_rails (~> 6.5.1) faker (~> 3.5.3) foreman (~> 0.90.0) + grover (~> 1.2.4) guard-livereload (~> 2.5.2) guard-rspec (~> 4.7.3) http (~> 5.3.1) @@ -682,8 +681,6 @@ DEPENDENCIES uglifier (~> 4.2.1) validates_timeliness (~> 7.1.0) web-console (~> 4.2.1) - wicked_pdf (~> 2.8.2) - wkhtmltopdf-binary (~> 0.12.6.10) BUNDLED WITH 2.6.9 diff --git a/app/assets/stylesheets/pdf.scss b/app/assets/stylesheets/pdf.scss index 040005003..575a5588d 100644 --- a/app/assets/stylesheets/pdf.scss +++ b/app/assets/stylesheets/pdf.scss @@ -1,7 +1 @@ -// There is a bug with Bootstrap tables in PDF, so we use td in a th, but it needs to be bold -thead, -tfoot { - td { - font-weight: bold; - } -} +// PDF-specific styles diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index b74ec4d28..d529bafaf 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -15,14 +15,11 @@ def index def show @invoice = invoice + token_based_access = !integer_id?(params[:id]) respond_to do |format| format.html - format.pdf do - render pdf: "Factuur #{@invoice.human_id}", - template: 'invoices/show.html.erb', - lowquality: true - end + format.pdf { render_invoice_pdf(token_based_access) } end end @@ -73,6 +70,13 @@ def send_invoice private + def integer_id?(id) + Integer(id) + true + rescue ArgumentError + false + end + def invoice @invoice = Invoice.find(Integer(params[:id])) authorize @invoice @@ -83,4 +87,16 @@ def invoice def permitted_attributes params.require(:invoice).permit(%i[user_id activity_id name_override email_override rows], rows_attributes: %i[name amount price]) end + + def render_invoice_pdf(token_based_access) + authorize @invoice, :download? unless token_based_access + + html = render_to_string( + template: 'invoices/show', + formats: [:html], + layout: 'pdf' + ) + pdf = Grover.new(html).to_pdf + send_data pdf, filename: "Factuur #{@invoice.human_id}.pdf", type: 'application/pdf', disposition: 'inline' + end end diff --git a/app/mailers/invoice_mailer.rb b/app/mailers/invoice_mailer.rb index b22410cf3..9ed62c98c 100644 --- a/app/mailers/invoice_mailer.rb +++ b/app/mailers/invoice_mailer.rb @@ -9,9 +9,13 @@ def invoice_mail(invoice) # rubocop:disable Metrics/AbcSize, Metrics/MethodLengt @cab_disabled = true end - attachments["#{invoice.human_id}.pdf"] = WickedPdf.new.pdf_from_string( - render_to_string(pdf: invoice.human_id.to_s, template: 'invoices/show', layout: 'pdf') + html = render_to_string( + template: 'invoices/show', + formats: [:html], + layout: 'pdf' ) + pdf = Grover.new(html).to_pdf + attachments["#{invoice.human_id}.pdf"] = pdf mail to: @invoice.email, subject: "Factuur #{invoice.human_id} #{Rails.application.config.x.company_name}" end diff --git a/app/policies/invoice_policy.rb b/app/policies/invoice_policy.rb index bbc1f1f13..f10316385 100644 --- a/app/policies/invoice_policy.rb +++ b/app/policies/invoice_policy.rb @@ -7,6 +7,10 @@ def send_invoice? user&.treasurer? end + def download? + user&.treasurer? + end + def pay? show? end diff --git a/app/views/invoices/index.html.erb b/app/views/invoices/index.html.erb index 24d47db7a..ffa778d96 100644 --- a/app/views/invoices/index.html.erb +++ b/app/views/invoices/index.html.erb @@ -35,6 +35,9 @@ <% if policy(Invoice).send_invoice? %> Verstuur <% end %> + <% if policy(Invoice).download? %> + Download + <% end %> @@ -77,6 +80,11 @@ <% end %> <% end %> + <% if policy(Invoice).download? %> + + <%= link_to 'Downloaden', invoice_path(invoice, format: :pdf), class: 'btn btn-primary', download: "Factuur-#{invoice.human_id}.pdf" %> + + <% end %> <% end %> diff --git a/config/initializers/grover.rb b/config/initializers/grover.rb new file mode 100644 index 000000000..62cb3d89d --- /dev/null +++ b/config/initializers/grover.rb @@ -0,0 +1,23 @@ +# Grover Global Configuration +# +# Use this to set up shared configuration options for your entire application. +# Any of the configuration options shown here can also be applied to single +# models by passing arguments to the Grover.new call. +# +# To learn more, check out the README: +# https://github.com/Studiosity/grover + +Grover.configure do |config| + # Location of the chromium/chrome executable + # config.options = { + # executable_path: ENV.fetch('GOOGLE_CHROME_SHIM', nil) + # } + + # Common PDF options + config.options = { + format: 'A4', + print_background: true, + prefer_css_page_size: false, + display_url: Rails.application.config.x.sofia_host || 'localhost' + } +end diff --git a/config/initializers/wicked_pdf.rb b/config/initializers/wicked_pdf.rb deleted file mode 100644 index ac482a9d7..000000000 --- a/config/initializers/wicked_pdf.rb +++ /dev/null @@ -1,21 +0,0 @@ -# WickedPDF Global Configuration -# -# Use this to set up shared configuration options for your entire application. -# Any of the configuration options shown here can also be applied to single -# models by passing arguments to the `render :pdf` call. -# -# To learn more, check out the README: -# -# https://github.com/mileszs/wicked_pdf/blob/master/README.md - -WickedPdf.configure do |config| - # Path to the wkhtmltopdf executable: This usually isn't needed if using - # one of the wkhtmltopdf-binary family of gems. - # config.exe_path = '/usr/local/bin/wkhtmltopdf' - # or - # config.exe_path = Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf') - - # Layout file to be used for all PDFs - # (but can be overridden in `render :pdf` calls) - config.layout = 'pdf.html.erb' -end From 7eddb255efbc8350d8bb2a283a6bfe3fc30fcb14 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Mon, 5 Jan 2026 00:53:17 +0100 Subject: [PATCH 02/12] incorporate the AI suggestions --- Dockerfile | 1 - Gemfile | 2 +- app/controllers/invoices_controller.rb | 13 +++++++++---- app/mailers/invoice_mailer.rb | 20 +++++++++++++------- config/initializers/grover.rb | 7 ++----- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index cbd1116cd..1c357bf02 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,6 @@ RUN apt-get update -qq && \ curl \ netcat-traditional \ chromium \ - chromium-driver \ libyaml-dev # Add Node, required for asset pipeline. diff --git a/Gemfile b/Gemfile index 521486c87..383126586 100644 --- a/Gemfile +++ b/Gemfile @@ -10,11 +10,11 @@ gem 'devise', '~>4.9.4' gem 'devise-i18n', '~>1.15.0' gem 'factory_bot_rails', '~> 6.5.1' gem 'faker', '~> 3.5.3' +gem 'grover', '~> 1.2.4' gem 'http', '~> 5.3.1' gem 'jbuilder', '~> 2.14.1' gem 'jquery-rails', '~> 4.6.1' gem 'jsbundling-rails', '~> 1.3', '>= 1.3.1' -gem 'grover', '~> 1.2.4' gem 'kaminari', '~> 1.2.2' gem 'mollie-api-ruby', '~> 4.18.0' gem 'net-imap', '~> 0.6.2' diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index d529bafaf..568513282 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -2,7 +2,7 @@ class InvoicesController < ApplicationController include ApplicationHelper before_action :authenticate_user!, except: %w[show pay] - after_action :verify_authorized, except: %w[show pay] + after_action :verify_authorized, except: %w[pay] def index authorize Invoice @@ -16,6 +16,9 @@ def index def show @invoice = invoice token_based_access = !integer_id?(params[:id]) + + # Authorize for authenticated access (integer ID), skip for token-based access + authorize @invoice, :show? unless token_based_access respond_to do |format| format.html @@ -89,14 +92,16 @@ def permitted_attributes end def render_invoice_pdf(token_based_access) - authorize @invoice, :download? unless token_based_access - html = render_to_string( template: 'invoices/show', formats: [:html], layout: 'pdf' ) pdf = Grover.new(html).to_pdf - send_data pdf, filename: "Factuur #{@invoice.human_id}.pdf", type: 'application/pdf', disposition: 'inline' + send_data pdf, filename: "Factuur-#{@invoice.human_id}.pdf", type: 'application/pdf', disposition: 'attachment' + rescue StandardError => e + Rails.logger.error "Failed to generate PDF for invoice #{@invoice.id}: #{e.message}" + flash[:error] = 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.' + redirect_to invoice_path(@invoice) end end diff --git a/app/mailers/invoice_mailer.rb b/app/mailers/invoice_mailer.rb index 9ed62c98c..e14a6846d 100644 --- a/app/mailers/invoice_mailer.rb +++ b/app/mailers/invoice_mailer.rb @@ -9,13 +9,19 @@ def invoice_mail(invoice) # rubocop:disable Metrics/AbcSize, Metrics/MethodLengt @cab_disabled = true end - html = render_to_string( - template: 'invoices/show', - formats: [:html], - layout: 'pdf' - ) - pdf = Grover.new(html).to_pdf - attachments["#{invoice.human_id}.pdf"] = pdf + begin + html = render_to_string( + template: 'invoices/show', + formats: [:html], + layout: 'pdf' + ) + pdf = Grover.new(html).to_pdf + attachments["#{invoice.human_id}.pdf"] = pdf + rescue StandardError => e + Rails.logger.error "Failed to generate PDF attachment for invoice #{invoice.id}: #{e.message}" + Rails.logger.error e.backtrace.join("\n") + # Continue sending email without PDF attachment + end mail to: @invoice.email, subject: "Factuur #{invoice.human_id} #{Rails.application.config.x.company_name}" end diff --git a/config/initializers/grover.rb b/config/initializers/grover.rb index 62cb3d89d..4793101ff 100644 --- a/config/initializers/grover.rb +++ b/config/initializers/grover.rb @@ -8,16 +8,13 @@ # https://github.com/Studiosity/grover Grover.configure do |config| - # Location of the chromium/chrome executable - # config.options = { - # executable_path: ENV.fetch('GOOGLE_CHROME_SHIM', nil) - # } # Common PDF options config.options = { format: 'A4', print_background: true, prefer_css_page_size: false, - display_url: Rails.application.config.x.sofia_host || 'localhost' + display_url: "https://#{Rails.application.config.x.sofia_host}" + } end From 5b9fe02b8a229a9a951f0b40dcf8b98e09ed4bf6 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Mon, 5 Jan 2026 01:11:46 +0100 Subject: [PATCH 03/12] fix lint --- app/controllers/invoices_controller.rb | 8 ++++---- config/initializers/grover.rb | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index 568513282..52261f415 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -2,7 +2,7 @@ class InvoicesController < ApplicationController include ApplicationHelper before_action :authenticate_user!, except: %w[show pay] - after_action :verify_authorized, except: %w[pay] + after_action :verify_authorized, except: %w[show pay] def index authorize Invoice @@ -16,13 +16,13 @@ def index def show @invoice = invoice token_based_access = !integer_id?(params[:id]) - + # Authorize for authenticated access (integer ID), skip for token-based access authorize @invoice, :show? unless token_based_access respond_to do |format| format.html - format.pdf { render_invoice_pdf(token_based_access) } + format.pdf { render_invoice_pdf } end end @@ -91,7 +91,7 @@ def permitted_attributes params.require(:invoice).permit(%i[user_id activity_id name_override email_override rows], rows_attributes: %i[name amount price]) end - def render_invoice_pdf(token_based_access) + def render_invoice_pdf # rubocop:disable Metrics/MethodLength html = render_to_string( template: 'invoices/show', formats: [:html], diff --git a/config/initializers/grover.rb b/config/initializers/grover.rb index 4793101ff..e5e9d0a33 100644 --- a/config/initializers/grover.rb +++ b/config/initializers/grover.rb @@ -8,7 +8,6 @@ # https://github.com/Studiosity/grover Grover.configure do |config| - # Common PDF options config.options = { format: 'A4', From 0cd8da2aaeb701ce291a1b849087db59aa85edad Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Mon, 5 Jan 2026 01:20:47 +0100 Subject: [PATCH 04/12] fix double auth --- app/controllers/invoices_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index 52261f415..d9900c8bd 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -82,7 +82,6 @@ def integer_id?(id) def invoice @invoice = Invoice.find(Integer(params[:id])) - authorize @invoice rescue ArgumentError @invoice = Invoice.find_by!(token: params[:id]) end From 647f44831eb4954b09af1b30e9d928690fcd75dc Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Wed, 7 Jan 2026 17:30:17 +0100 Subject: [PATCH 05/12] fix tests --- app/controllers/invoices_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index d9900c8bd..1a52a52b4 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -42,6 +42,9 @@ def create def pay # rubocop:disable Metrics/AbcSize, Metrics/MethodLength @invoice = invoice + token_based_access = !integer_id?(params[:id]) + + authorize @invoice, :pay? unless token_based_access if @invoice.paid? redirect_to invoice_path params[:id] From fa9b0d47138dd028c280cbef81147c7c5e4a4551 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Mon, 12 Jan 2026 00:58:37 +0100 Subject: [PATCH 06/12] fix last issues --- app/controllers/invoices_controller.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index 1a52a52b4..536e76762 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -94,6 +94,9 @@ def permitted_attributes end def render_invoice_pdf # rubocop:disable Metrics/MethodLength + token_based_access = !integer_id?(params[:id]) + authorize @invoice, :download? unless token_based_access + html = render_to_string( template: 'invoices/show', formats: [:html], @@ -101,8 +104,15 @@ def render_invoice_pdf # rubocop:disable Metrics/MethodLength ) pdf = Grover.new(html).to_pdf send_data pdf, filename: "Factuur-#{@invoice.human_id}.pdf", type: 'application/pdf', disposition: 'attachment' - rescue StandardError => e + rescue StandardError => e Rails.logger.error "Failed to generate PDF for invoice #{@invoice.id}: #{e.message}" + if request.format.pdf? + render plain: 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.', status: 500 + else + flash[:error] = 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.' + redirect_to invoice_path(@invoice) + end + end flash[:error] = 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.' redirect_to invoice_path(@invoice) end From 41ef2d8fc6420ba6744b48811edbe87be8e48353 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Wed, 14 Jan 2026 17:54:04 +0100 Subject: [PATCH 07/12] fix errorhandeling --- app/controllers/invoices_controller.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index 536e76762..9dfe35e1a 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -104,7 +104,7 @@ def render_invoice_pdf # rubocop:disable Metrics/MethodLength ) pdf = Grover.new(html).to_pdf send_data pdf, filename: "Factuur-#{@invoice.human_id}.pdf", type: 'application/pdf', disposition: 'attachment' - rescue StandardError => e + rescue StandardError => e Rails.logger.error "Failed to generate PDF for invoice #{@invoice.id}: #{e.message}" if request.format.pdf? render plain: 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.', status: 500 @@ -113,7 +113,4 @@ def render_invoice_pdf # rubocop:disable Metrics/MethodLength redirect_to invoice_path(@invoice) end end - flash[:error] = 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.' - redirect_to invoice_path(@invoice) - end end From d1fd410ce130fec0bcdc38136c8aa7dd97edf697 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Wed, 14 Jan 2026 18:01:59 +0100 Subject: [PATCH 08/12] fix lint --- app/controllers/invoices_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index 9dfe35e1a..ed4171101 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -93,7 +93,7 @@ def permitted_attributes params.require(:invoice).permit(%i[user_id activity_id name_override email_override rows], rows_attributes: %i[name amount price]) end - def render_invoice_pdf # rubocop:disable Metrics/MethodLength + def render_invoice_pdf # rubocop:disable Metrics/MethodLength, Metrics/AbcSize token_based_access = !integer_id?(params[:id]) authorize @invoice, :download? unless token_based_access @@ -107,7 +107,7 @@ def render_invoice_pdf # rubocop:disable Metrics/MethodLength rescue StandardError => e Rails.logger.error "Failed to generate PDF for invoice #{@invoice.id}: #{e.message}" if request.format.pdf? - render plain: 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.', status: 500 + render plain: 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.', status: :internal_server_error else flash[:error] = 'Er is een fout opgetreden bij het genereren van de PDF. Probeer het later opnieuw.' redirect_to invoice_path(@invoice) From 3461f8475e6c0fb996a13efda24380d2765f93f8 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Fri, 16 Jan 2026 11:42:00 +0100 Subject: [PATCH 09/12] add puppeteer --- package.json | 1 + yarn.lock | 593 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 586 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 50a990336..02208e7bc 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "jquery": "^3.7.1", "moment": "^2.30.1", "popper.js": "^1.16.1", + "puppeteer": "^24.35.0", "remove-accents": "^0.5.0", "vue": "^2.7.16", "vue-loader": "^15.11.1", diff --git a/yarn.lock b/yarn.lock index 95c2179e6..c58b4bac7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2278,6 +2278,23 @@ __metadata: languageName: node linkType: hard +"@puppeteer/browsers@npm:2.11.1": + version: 2.11.1 + resolution: "@puppeteer/browsers@npm:2.11.1" + dependencies: + debug: "npm:^4.4.3" + extract-zip: "npm:^2.0.1" + progress: "npm:^2.0.3" + proxy-agent: "npm:^6.5.0" + semver: "npm:^7.7.3" + tar-fs: "npm:^3.1.1" + yargs: "npm:^17.7.2" + bin: + browsers: lib/cjs/main-cli.js + checksum: 10c0/e8a92c5a600deda0aa1e3d437f1e35cb1cc0c24a218e01f33af6d5d106a3807e660fd09f67e31dd5c48a1efe9d207c405fc7f52d4172084dc99bb37adfb9341f + languageName: node + linkType: hard + "@rails/actioncable@npm:>=7.0": version: 8.1.100 resolution: "@rails/actioncable@npm:8.1.100" @@ -2292,6 +2309,13 @@ __metadata: languageName: node linkType: hard +"@tootallnate/quickjs-emscripten@npm:^0.23.0": + version: 0.23.0 + resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0" + checksum: 10c0/2a939b781826fb5fd3edd0f2ec3b321d259d760464cf20611c9877205aaca3ccc0b7304dea68416baa0d568e82cd86b17d29548d1e5139fa3155a4a86a2b4b49 + languageName: node + linkType: hard + "@types/eslint-scope@npm:^3.7.7": version: 3.7.7 resolution: "@types/eslint-scope@npm:3.7.7" @@ -2383,6 +2407,15 @@ __metadata: languageName: node linkType: hard +"@types/yauzl@npm:^2.9.1": + version: 2.10.3 + resolution: "@types/yauzl@npm:2.10.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/f1b7c1b99fef9f2fe7f1985ef7426d0cebe48cd031f1780fcdc7451eec7e31ac97028f16f50121a59bcf53086a1fc8c856fd5b7d3e00970e43d92ae27d6b43dc + languageName: node + linkType: hard + "@vue/compiler-sfc@npm:2.7.16": version: 2.7.16 resolution: "@vue/compiler-sfc@npm:2.7.16" @@ -2736,6 +2769,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.13.4": + version: 0.13.4 + resolution: "ast-types@npm:0.13.4" + dependencies: + tslib: "npm:^2.0.1" + checksum: 10c0/3a1a409764faa1471601a0ad01b3aa699292991aa9c8a30c7717002cabdf5d98008e7b53ae61f6e058f757fc6ba965e147967a93c13e62692c907d79cfb245f8 + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -2801,6 +2843,18 @@ __metadata: languageName: node linkType: hard +"b4a@npm:^1.6.4": + version: 1.7.3 + resolution: "b4a@npm:1.7.3" + peerDependencies: + react-native-b4a: "*" + peerDependenciesMeta: + react-native-b4a: + optional: true + checksum: 10c0/ac16d186e00fa0d16de1f1a4af413953bc762d50d5a0e382aaa744a13886600313b7293403ad77fc83f6b1489c3fc2610494d1026754a51d1b7cdac2115a7598 + languageName: node + linkType: hard + "babel-loader@npm:^10.0.0": version: 10.0.0 resolution: "babel-loader@npm:10.0.0" @@ -2874,6 +2928,78 @@ __metadata: languageName: node linkType: hard +"bare-events@npm:^2.5.4, bare-events@npm:^2.7.0": + version: 2.8.2 + resolution: "bare-events@npm:2.8.2" + peerDependencies: + bare-abort-controller: "*" + peerDependenciesMeta: + bare-abort-controller: + optional: true + checksum: 10c0/53fef240cf2cdcca62f78b6eead90ddb5a59b0929f414b13a63764c2b4f9de98ea8a578d033b04d64bb7b86dfbc402e937984e69950855cc3754c7b63da7db21 + languageName: node + linkType: hard + +"bare-fs@npm:^4.0.1": + version: 4.5.2 + resolution: "bare-fs@npm:4.5.2" + dependencies: + bare-events: "npm:^2.5.4" + bare-path: "npm:^3.0.0" + bare-stream: "npm:^2.6.4" + bare-url: "npm:^2.2.2" + fast-fifo: "npm:^1.3.2" + peerDependencies: + bare-buffer: "*" + peerDependenciesMeta: + bare-buffer: + optional: true + checksum: 10c0/b623c76d264017491667618055fdcebd5d3efe87768c06817bf29f912b77ce7f03f851eb7dc56810f5266f03927efafceded6b0911042d48dd3013b86c6bb79b + languageName: node + linkType: hard + +"bare-os@npm:^3.0.1": + version: 3.6.2 + resolution: "bare-os@npm:3.6.2" + checksum: 10c0/7d917bc202b7efbb6b78658403fac04ae4e91db98d38cbd24037f896a2b1b4f4571d8cd408d12bed6a4c406d6abaf8d03836eacbcc4c75a0b6974e268574fc5a + languageName: node + linkType: hard + +"bare-path@npm:^3.0.0": + version: 3.0.0 + resolution: "bare-path@npm:3.0.0" + dependencies: + bare-os: "npm:^3.0.1" + checksum: 10c0/56a3ca82a9f808f4976cb1188640ac206546ce0ddff582afafc7bd2a6a5b31c3bd16422653aec656eeada2830cfbaa433c6cbf6d6b4d9eba033d5e06d60d9a68 + languageName: node + linkType: hard + +"bare-stream@npm:^2.6.4": + version: 2.7.0 + resolution: "bare-stream@npm:2.7.0" + dependencies: + streamx: "npm:^2.21.0" + peerDependencies: + bare-buffer: "*" + bare-events: "*" + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true + checksum: 10c0/3acd840b7b288dc066226c36446ff605fba2ecce98f1a0ce6aa611b81aabbcd204046a3209bce172373d17eaeaa5b7d35a85649c18ffcb9f2c783242854e99bd + languageName: node + linkType: hard + +"bare-url@npm:^2.2.2": + version: 2.3.2 + resolution: "bare-url@npm:2.3.2" + dependencies: + bare-path: "npm:^3.0.0" + checksum: 10c0/4fd0046314390a54404519d9db20e130ab3a341ef638d040f9603ae3fa0a1d84f6970357d21c8fc64e6163d1f61fd212cb1cfa4cb537dfead99fb06e3c030b15 + languageName: node + linkType: hard + "baseline-browser-mapping@npm:^2.8.25": version: 2.8.31 resolution: "baseline-browser-mapping@npm:2.8.31" @@ -2892,6 +3018,13 @@ __metadata: languageName: node linkType: hard +"basic-ftp@npm:^5.0.2": + version: 5.1.0 + resolution: "basic-ftp@npm:5.1.0" + checksum: 10c0/397d5ed490f4d3b8b2dcd7afdf8e9fcf714a7d1c394a6c66b31704baf49c9fc250f1742f6189136a76b983675edf3d986b7ed93d253dc6477e65a567cf1e04c0 + languageName: node + linkType: hard + "big.js@npm:^5.2.2": version: 5.2.2 resolution: "big.js@npm:5.2.2" @@ -2971,6 +3104,13 @@ __metadata: languageName: node linkType: hard +"buffer-crc32@npm:~0.2.3": + version: 0.2.13 + resolution: "buffer-crc32@npm:0.2.13" + checksum: 10c0/cb0a8ddf5cf4f766466db63279e47761eb825693eeba6a5a95ee4ec8cb8f81ede70aa7f9d8aeec083e781d47154290eb5d4d26b3f7a465ec57fb9e7d59c47150 + languageName: node + linkType: hard + "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -3081,6 +3221,18 @@ __metadata: languageName: node linkType: hard +"chromium-bidi@npm:12.0.1": + version: 12.0.1 + resolution: "chromium-bidi@npm:12.0.1" + dependencies: + mitt: "npm:^3.0.1" + zod: "npm:^3.24.1" + peerDependencies: + devtools-protocol: "*" + checksum: 10c0/cc278125a6ad4d4010f4c093442c6da608d0b18be483efbfad67def029a73f0bd16a7deccd9bf848e26dbd47119e3415724abdd7da497a80f886127494fb40b9 + languageName: node + linkType: hard + "ci-info@npm:^3.2.0": version: 3.9.0 resolution: "ci-info@npm:3.9.0" @@ -3088,6 +3240,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 + languageName: node + linkType: hard + "clone-deep@npm:^4.0.1": version: 4.0.1 resolution: "clone-deep@npm:4.0.1" @@ -3329,6 +3492,13 @@ __metadata: languageName: node linkType: hard +"data-uri-to-buffer@npm:^6.0.2": + version: 6.0.2 + resolution: "data-uri-to-buffer@npm:6.0.2" + checksum: 10c0/f76922bf895b3d7d443059ff278c9cc5efc89d70b8b80cd9de0aa79b3adc6d7a17948eefb8692e30398c43635f70ece1673d6085cc9eba2878dbc6c6da5292ac + languageName: node + linkType: hard + "de-indent@npm:^1.0.2": version: 1.0.2 resolution: "de-indent@npm:1.0.2" @@ -3336,7 +3506,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0, debug@npm:^4.4.1, debug@npm:^4.4.3": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -3355,6 +3525,17 @@ __metadata: languageName: node linkType: hard +"degenerator@npm:^5.0.0": + version: 5.0.1 + resolution: "degenerator@npm:5.0.1" + dependencies: + ast-types: "npm:^0.13.4" + escodegen: "npm:^2.1.0" + esprima: "npm:^4.0.1" + checksum: 10c0/e48d8a651edeb512a648711a09afec269aac6de97d442a4bb9cf121a66877e0eec11b9727100a10252335c0666ae1c84a8bc1e3a3f47788742c975064d2c7b1c + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -3371,6 +3552,13 @@ __metadata: languageName: node linkType: hard +"devtools-protocol@npm:0.0.1534754": + version: 0.0.1534754 + resolution: "devtools-protocol@npm:0.0.1534754" + checksum: 10c0/2ee96f10c9833f7e6ad0f9f66e42242129547e96c8cfe816ce508c222f4ccf4431a4b787cd6ee8174c9b2c8cc9a3c7f3b3b0a1fff96dd3cc5a16eb314027c9f7 + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -3466,6 +3654,15 @@ __metadata: languageName: node linkType: hard +"end-of-stream@npm:^1.1.0": + version: 1.4.5 + resolution: "end-of-stream@npm:1.4.5" + dependencies: + once: "npm:^1.4.0" + checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 + languageName: node + linkType: hard + "enhanced-resolve@npm:^5.17.4": version: 5.18.4 resolution: "enhanced-resolve@npm:5.18.4" @@ -3557,7 +3754,7 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.2.0": +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 @@ -3571,6 +3768,24 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:^2.1.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" + dependencies: + esprima: "npm:^4.0.1" + estraverse: "npm:^5.2.0" + esutils: "npm:^2.0.2" + source-map: "npm:~0.6.1" + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 10c0/e1450a1f75f67d35c061bf0d60888b15f62ab63aef9df1901cffc81cffbbb9e8b3de237c5502cf8613a017c1df3a3003881307c78835a1ab54d8c8d2206e01d3 + languageName: node + linkType: hard + "eslint-plugin-vue@npm:^9.33.0": version: 9.33.0 resolution: "eslint-plugin-vue@npm:9.33.0" @@ -3721,6 +3936,16 @@ __metadata: languageName: node linkType: hard +"esprima@npm:^4.0.1": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3 + languageName: node + linkType: hard + "esquery@npm:^1.4.0, esquery@npm:^1.5.0, esquery@npm:^1.6.0": version: 1.6.0 resolution: "esquery@npm:1.6.0" @@ -3760,6 +3985,15 @@ __metadata: languageName: node linkType: hard +"events-universal@npm:^1.0.0": + version: 1.0.1 + resolution: "events-universal@npm:1.0.1" + dependencies: + bare-events: "npm:^2.7.0" + checksum: 10c0/a1d9a5e9f95843650f8ec240dd1221454c110189a9813f32cdf7185759b43f1f964367ac7dca4ebc69150b59043f2d77c7e122b0d03abf7c25477ea5494785a5 + languageName: node + linkType: hard + "events@npm:^3.2.0": version: 3.3.0 resolution: "events@npm:3.3.0" @@ -3774,6 +4008,23 @@ __metadata: languageName: node linkType: hard +"extract-zip@npm:^2.0.1": + version: 2.0.1 + resolution: "extract-zip@npm:2.0.1" + dependencies: + "@types/yauzl": "npm:^2.9.1" + debug: "npm:^4.1.1" + get-stream: "npm:^5.1.0" + yauzl: "npm:^2.10.0" + dependenciesMeta: + "@types/yauzl": + optional: true + bin: + extract-zip: cli.js + checksum: 10c0/9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -3781,6 +4032,13 @@ __metadata: languageName: node linkType: hard +"fast-fifo@npm:^1.2.0, fast-fifo@npm:^1.3.2": + version: 1.3.2 + resolution: "fast-fifo@npm:1.3.2" + checksum: 10c0/d53f6f786875e8b0529f784b59b4b05d4b5c31c651710496440006a398389a579c8dbcd2081311478b5bf77f4b0b21de69109c5a4eabea9d8e8783d1eb864e4c + languageName: node + linkType: hard + "fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.3": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" @@ -3831,6 +4089,15 @@ __metadata: languageName: node linkType: hard +"fd-slicer@npm:~1.1.0": + version: 1.1.0 + resolution: "fd-slicer@npm:1.1.0" + dependencies: + pend: "npm:~1.2.0" + checksum: 10c0/304dd70270298e3ffe3bcc05e6f7ade2511acc278bc52d025f8918b48b6aa3b77f10361bddfadfe2a28163f7af7adbdce96f4d22c31b2f648ba2901f0c5fc20e + languageName: node + linkType: hard + "fdir@npm:^6.5.0": version: 6.5.0 resolution: "fdir@npm:6.5.0" @@ -3987,6 +4254,13 @@ __metadata: languageName: node linkType: hard +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde + languageName: node + linkType: hard + "get-intrinsic@npm:^1.2.6": version: 1.3.1 resolution: "get-intrinsic@npm:1.3.1" @@ -4018,6 +4292,26 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 10c0/43797ffd815fbb26685bf188c8cfebecb8af87b3925091dd7b9a9c915993293d78e3c9e1bce125928ff92f2d0796f3889b92b5ec6d58d1041b574682132e0a80 + languageName: node + linkType: hard + +"get-uri@npm:^6.0.1": + version: 6.0.5 + resolution: "get-uri@npm:6.0.5" + dependencies: + basic-ftp: "npm:^5.0.2" + data-uri-to-buffer: "npm:^6.0.2" + debug: "npm:^4.3.4" + checksum: 10c0/c7ff5d5d55de53d23ecce7c5108cc3ed0db1174db43c9aa15506d640283d36ee0956fd8ba1fc50b06a718466cc85794ae9d8860193f91318afe846e3e7010f3a + languageName: node + linkType: hard + "glob-parent@npm:^5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -4222,7 +4516,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-agent@npm:^7.0.0": +"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.1": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" dependencies: @@ -4232,7 +4526,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1": +"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.6": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -4693,6 +4987,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^7.14.1": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: 10c0/b3a452b491433db885beed95041eb104c157ef7794b9c9b4d647be503be91769d11206bb573849a16b4cc0d03cbd15ffd22df7960997788b74c1d399ac7a4fed + languageName: node + linkType: hard + "make-fetch-happen@npm:^15.0.0": version: 15.0.3 resolution: "make-fetch-happen@npm:15.0.3" @@ -4897,6 +5198,13 @@ __metadata: languageName: node linkType: hard +"mitt@npm:^3.0.1": + version: 3.0.1 + resolution: "mitt@npm:3.0.1" + checksum: 10c0/3ab4fdecf3be8c5255536faa07064d05caa3dd332bd318ff02e04621f7b3069ca1de9106cfe8e7ced675abfc2bec2ce4c4ef321c4a1bb1fb29df8ae090741913 + languageName: node + linkType: hard + "moment@npm:^2.30.1": version: 2.30.1 resolution: "moment@npm:2.30.1" @@ -4941,6 +5249,13 @@ __metadata: languageName: node linkType: hard +"netmask@npm:^2.0.2": + version: 2.0.2 + resolution: "netmask@npm:2.0.2" + checksum: 10c0/cafd28388e698e1138ace947929f842944d0f1c0b87d3fa2601a61b38dc89397d33c0ce2c8e7b99e968584b91d15f6810b91bef3f3826adf71b1833b61d4bf4f + languageName: node + linkType: hard + "node-addon-api@npm:^7.0.0": version: 7.1.1 resolution: "node-addon-api@npm:7.1.1" @@ -5004,6 +5319,15 @@ __metadata: languageName: node linkType: hard +"once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + "optionator@npm:^0.9.3": version: 0.9.4 resolution: "optionator@npm:0.9.4" @@ -5068,6 +5392,32 @@ __metadata: languageName: node linkType: hard +"pac-proxy-agent@npm:^7.1.0": + version: 7.2.0 + resolution: "pac-proxy-agent@npm:7.2.0" + dependencies: + "@tootallnate/quickjs-emscripten": "npm:^0.23.0" + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + get-uri: "npm:^6.0.1" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.6" + pac-resolver: "npm:^7.0.1" + socks-proxy-agent: "npm:^8.0.5" + checksum: 10c0/0265c17c9401c2ea735697931a6553a0c6d8b20c4d7d4e3b3a0506080ba69a8d5ad656e2a6be875411212e2b6ed7a4d9526dd3997e08581fdfb1cbcad454c296 + languageName: node + linkType: hard + +"pac-resolver@npm:^7.0.1": + version: 7.0.1 + resolution: "pac-resolver@npm:7.0.1" + dependencies: + degenerator: "npm:^5.0.0" + netmask: "npm:^2.0.2" + checksum: 10c0/5f3edd1dd10fded31e7d1f95776442c3ee51aa098c28b74ede4927d9677ebe7cebb2636750c24e945f5b84445e41ae39093d3a1014a994e5ceb9f0b1b88ebff5 + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -5127,6 +5477,13 @@ __metadata: languageName: node linkType: hard +"pend@npm:~1.2.0": + version: 1.2.0 + resolution: "pend@npm:1.2.0" + checksum: 10c0/8a87e63f7a4afcfb0f9f77b39bb92374afc723418b9cb716ee4257689224171002e07768eeade4ecd0e86f1fa3d8f022994219fb45634f2dbd78c6803e452458 + languageName: node + linkType: hard + "picocolors@npm:^0.2.1": version: 0.2.1 resolution: "picocolors@npm:0.2.1" @@ -5748,6 +6105,13 @@ __metadata: languageName: node linkType: hard +"progress@npm:^2.0.3": + version: 2.0.3 + resolution: "progress@npm:2.0.3" + checksum: 10c0/1697e07cb1068055dbe9fe858d242368ff5d2073639e652b75a7eb1f2a1a8d4afd404d719de23c7b48481a6aa0040686310e2dac2f53d776daa2176d3f96369c + languageName: node + linkType: hard + "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -5758,6 +6122,22 @@ __metadata: languageName: node linkType: hard +"proxy-agent@npm:^6.5.0": + version: 6.5.0 + resolution: "proxy-agent@npm:6.5.0" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + http-proxy-agent: "npm:^7.0.1" + https-proxy-agent: "npm:^7.0.6" + lru-cache: "npm:^7.14.1" + pac-proxy-agent: "npm:^7.1.0" + proxy-from-env: "npm:^1.1.0" + socks-proxy-agent: "npm:^8.0.5" + checksum: 10c0/7fd4e6f36bf17098a686d4aee3b8394abfc0b0537c2174ce96b0a4223198b9fafb16576c90108a3fcfc2af0168bd7747152bfa1f58e8fee91d3780e79aab7fd8 + languageName: node + linkType: hard + "proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -5772,6 +6152,16 @@ __metadata: languageName: node linkType: hard +"pump@npm:^3.0.0": + version: 3.0.3 + resolution: "pump@npm:3.0.3" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 + languageName: node + linkType: hard + "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -5779,6 +6169,37 @@ __metadata: languageName: node linkType: hard +"puppeteer-core@npm:24.35.0": + version: 24.35.0 + resolution: "puppeteer-core@npm:24.35.0" + dependencies: + "@puppeteer/browsers": "npm:2.11.1" + chromium-bidi: "npm:12.0.1" + debug: "npm:^4.4.3" + devtools-protocol: "npm:0.0.1534754" + typed-query-selector: "npm:^2.12.0" + webdriver-bidi-protocol: "npm:0.3.10" + ws: "npm:^8.19.0" + checksum: 10c0/38a45a1e8bc1f688e0d6a98dd630d5e60485657510fc572077889e48dd82d22f354786dabfb8d7afde107602a7a7e35d046ac95dbfe93b880574d2e523b8a8d6 + languageName: node + linkType: hard + +"puppeteer@npm:^24.35.0": + version: 24.35.0 + resolution: "puppeteer@npm:24.35.0" + dependencies: + "@puppeteer/browsers": "npm:2.11.1" + chromium-bidi: "npm:12.0.1" + cosmiconfig: "npm:^9.0.0" + devtools-protocol: "npm:0.0.1534754" + puppeteer-core: "npm:24.35.0" + typed-query-selector: "npm:^2.12.0" + bin: + puppeteer: lib/cjs/puppeteer/node/cli.js + checksum: 10c0/2a7f3a5175bae9b52b4a071c99436bd3b8697faa6eb3fab8589950ab6b7a0d6b176c7573d256e2781a5f824cd03dd9561043f4371f1dfc8a7e6e8c9d280b5730 + languageName: node + linkType: hard + "qified@npm:^0.5.2": version: 0.5.2 resolution: "qified@npm:0.5.2" @@ -5891,6 +6312,13 @@ __metadata: languageName: node linkType: hard +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 + languageName: node + linkType: hard + "require-from-string@npm:^2.0.2": version: 2.0.2 resolution: "require-from-string@npm:2.0.2" @@ -6022,7 +6450,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5, semver@npm:^7.3.6, semver@npm:^7.5.4, semver@npm:^7.6.3": +"semver@npm:^7.3.5, semver@npm:^7.3.6, semver@npm:^7.5.4, semver@npm:^7.6.3, semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -6097,7 +6525,7 @@ __metadata: languageName: node linkType: hard -"socks-proxy-agent@npm:^8.0.3": +"socks-proxy-agent@npm:^8.0.3, socks-proxy-agent@npm:^8.0.5": version: 8.0.5 resolution: "socks-proxy-agent@npm:8.0.5" dependencies: @@ -6155,6 +6583,7 @@ __metadata: postcss-import: "npm:^16.1.1" postcss-preset-env: "npm:^10.6.0" postcss-scss: "npm:^4.0.9" + puppeteer: "npm:^24.35.0" remove-accents: "npm:^0.5.0" sass: "npm:^1.97.1" stylelint: "npm:^16.26.1" @@ -6205,7 +6634,18 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^4.2.3": +"streamx@npm:^2.15.0, streamx@npm:^2.21.0": + version: 2.23.0 + resolution: "streamx@npm:2.23.0" + dependencies: + events-universal: "npm:^1.0.0" + fast-fifo: "npm:^1.3.2" + text-decoder: "npm:^1.1.0" + checksum: 10c0/15708ce37818d588632fe1104e8febde573e33e8c0868bf583fce0703f3faf8d2a063c278e30df2270206811b69997f64eb78792099933a1fe757e786fbcbd44 + languageName: node + linkType: hard + +"string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -6216,7 +6656,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^6.0.1": +"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" dependencies: @@ -6436,6 +6876,34 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:^3.1.1": + version: 3.1.1 + resolution: "tar-fs@npm:3.1.1" + dependencies: + bare-fs: "npm:^4.0.1" + bare-path: "npm:^3.0.0" + pump: "npm:^3.0.0" + tar-stream: "npm:^3.1.5" + dependenciesMeta: + bare-fs: + optional: true + bare-path: + optional: true + checksum: 10c0/0c677d711c4aa41f94e1a712aa647022ba1910ff84430739e5d9e95a615e3ea1b7112dc93164fc8ce30dc715befcf9cfdc64da27d4e7958d73c59bda06aa0d8e + languageName: node + linkType: hard + +"tar-stream@npm:^3.1.5": + version: 3.1.7 + resolution: "tar-stream@npm:3.1.7" + dependencies: + b4a: "npm:^1.6.4" + fast-fifo: "npm:^1.2.0" + streamx: "npm:^2.15.0" + checksum: 10c0/a09199d21f8714bd729993ac49b6c8efcb808b544b89f23378ad6ffff6d1cb540878614ba9d4cfec11a64ef39e1a6f009a5398371491eb1fda606ffc7f70f718 + languageName: node + linkType: hard + "tar@npm:^7.5.2": version: 7.5.2 resolution: "tar@npm:7.5.2" @@ -6485,6 +6953,15 @@ __metadata: languageName: node linkType: hard +"text-decoder@npm:^1.1.0": + version: 1.2.3 + resolution: "text-decoder@npm:1.2.3" + dependencies: + b4a: "npm:^1.6.4" + checksum: 10c0/569d776b9250158681c83656ef2c3e0a5d5c660c27ca69f87eedef921749a4fbf02095e5f9a0f862a25cf35258379b06e31dee9c125c9f72e273b7ca1a6d1977 + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.12": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" @@ -6504,6 +6981,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.0.1": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -6520,6 +7004,13 @@ __metadata: languageName: node linkType: hard +"typed-query-selector@npm:^2.12.0": + version: 2.12.0 + resolution: "typed-query-selector@npm:2.12.0" + checksum: 10c0/069509887ecfff824a470f5f93d300cc9223cb059a36c47ac685f2812c4c9470340e07615893765e4264cef1678507532fa78f642fd52f276b589f7f5d791f79 + languageName: node + linkType: hard + "undici-types@npm:~7.16.0": version: 7.16.0 resolution: "undici-types@npm:7.16.0" @@ -6730,6 +7221,13 @@ __metadata: languageName: node linkType: hard +"webdriver-bidi-protocol@npm:0.3.10": + version: 0.3.10 + resolution: "webdriver-bidi-protocol@npm:0.3.10" + checksum: 10c0/fc66ba53b31c78a73ff7841303948894b77263051c146fed4331596b95f67a2e96dfaeb895483002bb152317d9cfbd215d9a66ef114f66dc17de2c32ac5ef33c + languageName: node + linkType: hard + "webfontloader@npm:^1.6.28": version: 1.6.28 resolution: "webfontloader@npm:1.6.28" @@ -6870,6 +7368,24 @@ __metadata: languageName: node linkType: hard +"wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + "write-file-atomic@npm:^5.0.1": version: 5.0.1 resolution: "write-file-atomic@npm:5.0.1" @@ -6880,6 +7396,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.19.0": + version: 8.19.0 + resolution: "ws@npm:8.19.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/4741d9b9bc3f9c791880882414f96e36b8b254e34d4b503279d6400d9a4b87a033834856dbdd94ee4b637944df17ea8afc4bce0ff4a1560d2166be8855da5b04 + languageName: node + linkType: hard + "xml-name-validator@npm:^4.0.0": version: 4.0.0 resolution: "xml-name-validator@npm:4.0.0" @@ -6887,6 +7418,13 @@ __metadata: languageName: node linkType: hard +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 + languageName: node + linkType: hard + "yallist@npm:^2.1.2": version: 2.1.2 resolution: "yallist@npm:2.1.2" @@ -6922,9 +7460,48 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 + languageName: node + linkType: hard + +"yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 + languageName: node + linkType: hard + +"yauzl@npm:^2.10.0": + version: 2.10.0 + resolution: "yauzl@npm:2.10.0" + dependencies: + buffer-crc32: "npm:~0.2.3" + fd-slicer: "npm:~1.1.0" + checksum: 10c0/f265002af7541b9ec3589a27f5fb8f11cf348b53cc15e2751272e3c062cd73f3e715bc72d43257de71bbaecae446c3f1b14af7559e8ab0261625375541816422 + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f languageName: node linkType: hard + +"zod@npm:^3.24.1": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: 10c0/5718ec35e3c40b600316c5b4c5e4976f7fee68151bc8f8d90ec18a469be9571f072e1bbaace10f1e85cf8892ea12d90821b200e980ab46916a6166a4260a983c + languageName: node + linkType: hard From 55e5a9195fb84f912f4765264c225f1bad69ccb3 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Fri, 16 Jan 2026 11:49:59 +0100 Subject: [PATCH 10/12] fix zatladder spending being zero --- app/controllers/zatladder_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/zatladder_controller.rb b/app/controllers/zatladder_controller.rb index b9c4e3c3d..01a3f7fa3 100644 --- a/app/controllers/zatladder_controller.rb +++ b/app/controllers/zatladder_controller.rb @@ -33,6 +33,7 @@ def zatladder_spendings(from, to) spendings: @users_spendings.fetch(user.id, 0) } end + zatladder.reject! { |user| user[:spendings].zero? } zatladder.sort_by { |id| id[:spendings] }.reverse! end end From bceba53005c72574e307e9cb9cd6a23c9d3ce7f7 Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Fri, 16 Jan 2026 12:04:56 +0100 Subject: [PATCH 11/12] make table header and footer bold --- app/views/invoices/show.html.erb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/views/invoices/show.html.erb b/app/views/invoices/show.html.erb index bfcd4daa1..ad7676617 100644 --- a/app/views/invoices/show.html.erb +++ b/app/views/invoices/show.html.erb @@ -94,9 +94,9 @@ - - - + + + @@ -110,9 +110,9 @@ - + +
ConsumptiesAantalTotaalbedragConsumptiesAantalTotaalbedrag
TotaalTotaal - <%= number_to_currency(@invoice.activity.revenue_by_user(@invoice.user), unit: '€') %><%= number_to_currency(@invoice.activity.revenue_by_user(@invoice.user), unit: '€') %>
@@ -124,9 +124,9 @@ - - - + + + @@ -140,9 +140,9 @@ - + +
<% if @invoice.activity.count_per_product(user: @invoice.user).any? %>Overige kosten<% else %>Kosten<% end %>AantalTotaalbedrag<% if @invoice.activity.count_per_product(user: @invoice.user).any? %>Overige kosten<% else %>Kosten<% end %>AantalTotaalbedrag
TotaalTotaal - <%= number_to_currency(@invoice.row_amount, unit: '€') %><%= number_to_currency(@invoice.row_amount, unit: '€') %>
From 436183f7b7a15bb490b56bb4839e6bfd69aa0e9d Mon Sep 17 00:00:00 2001 From: Lodewiges Date: Fri, 16 Jan 2026 12:07:27 +0100 Subject: [PATCH 12/12] fix lint --- app/controllers/zatladder_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/zatladder_controller.rb b/app/controllers/zatladder_controller.rb index 01a3f7fa3..afac435a3 100644 --- a/app/controllers/zatladder_controller.rb +++ b/app/controllers/zatladder_controller.rb @@ -23,6 +23,7 @@ def current_year end end + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def zatladder_spendings(from, to) users = User.in_amber.exists? ? User.in_amber : User.sofia_account @users_spendings = users.calculate_spendings(from:, to:) @@ -36,4 +37,5 @@ def zatladder_spendings(from, to) zatladder.reject! { |user| user[:spendings].zero? } zatladder.sort_by { |id| id[:spendings] }.reverse! end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength end