From fba838d61ad280e2a03dd937aa71637e7c0f166b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:45:19 +0100 Subject: [PATCH 01/15] Update dependency @material-symbols/svg-600 to ^0.14.0 (#27803) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 112 ++++++--------------------------------------------- 2 files changed, 14 insertions(+), 100 deletions(-) diff --git a/package.json b/package.json index e8f7f02e0e..96bfb1571c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@formatjs/intl-pluralrules": "^5.2.2", "@gamestdio/websocket": "^0.3.2", "@github/webauthn-json": "^2.1.1", - "@material-symbols/svg-600": "^0.13.1", + "@material-symbols/svg-600": "^0.14.0", "@rails/ujs": "^7.1.1", "@reduxjs/toolkit": "^1.9.5", "@svgr/webpack": "^5.5.0", diff --git a/yarn.lock b/yarn.lock index 1b2bfe0598..4c70859d08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -52,14 +52,7 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9": - version: 7.23.2 - resolution: "@babel/compat-data@npm:7.23.2" - checksum: 0397a08c3e491696cc1b12cf0879bf95fc550bfc6ef524d5a9452981aa0e192a958b2246debfb230fa22718fac473cc5a36616f89b1ad6e7e52055732cd374a1 - languageName: node - linkType: hard - -"@babel/compat-data@npm:^7.23.3": +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.3": version: 7.23.3 resolution: "@babel/compat-data@npm:7.23.3" checksum: c6af331753c34ee8a5678bc94404320826cb56b1dda3efc1311ec8fb0774e78225132f3c1acc988440ace667f14a838e297a822692b95758aa63da406e1f97a1 @@ -89,19 +82,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.7.2": - version: 7.23.0 - resolution: "@babel/generator@npm:7.23.0" - dependencies: - "@babel/types": "npm:^7.23.0" - "@jridgewell/gen-mapping": "npm:^0.3.2" - "@jridgewell/trace-mapping": "npm:^0.3.17" - jsesc: "npm:^2.5.1" - checksum: b7d8727c574119b5ef06e5d5d0d8d939527d51537db4b08273caebb18f3f2b1d4517b874776085e161fd47d28f26b22c08e7f270b64f43b2afd4a60c5936d6cd - languageName: node - linkType: hard - -"@babel/generator@npm:^7.23.3": +"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.7.2": version: 7.23.3 resolution: "@babel/generator@npm:7.23.3" dependencies: @@ -383,16 +364,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/parser@npm:7.23.0" - bin: - parser: ./bin/babel-parser.js - checksum: ab4ea9360ed4ba3c728c5a9bf33035103ebde20a7e943c4ae1d42becb02a313d731d12a93c795c5a19777031e4022e64b92a52262eda902522a1a18649826283 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.23.3": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3": version: 7.23.3 resolution: "@babel/parser@npm:7.23.3" bin: @@ -556,18 +528,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:7, @babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.7.2": - version: 7.22.5 - resolution: "@babel/plugin-syntax-jsx@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: b56ceaa9c6adc17fadfb48e1c801d07797195df2a581489e33c8034950e12e7778de6e1e70d6bcf7c5c7ada6222fe6bad5746187ab280df435f5a2799c8dd0d8 - languageName: node - linkType: hard - -"@babel/plugin-syntax-jsx@npm:^7.23.3": +"@babel/plugin-syntax-jsx@npm:7, @babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.7.2": version: 7.23.3 resolution: "@babel/plugin-syntax-jsx@npm:7.23.3" dependencies: @@ -666,7 +627,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.23.3": +"@babel/plugin-syntax-typescript@npm:^7.23.3, @babel/plugin-syntax-typescript@npm:^7.7.2": version: 7.23.3 resolution: "@babel/plugin-syntax-typescript@npm:7.23.3" dependencies: @@ -677,17 +638,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.22.5 - resolution: "@babel/plugin-syntax-typescript@npm:7.22.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 523a76627f17e67dc1999f4d7c7a71ed79e9f77f55a61cf05051101967ac23ec378ff0c93787b2cbd5d53720ad799658d796a649fa351682b2bf636f63b665a1 - languageName: node - linkType: hard - "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -1552,25 +1502,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.2": - version: 7.23.2 - resolution: "@babel/traverse@npm:7.23.2" - dependencies: - "@babel/code-frame": "npm:^7.22.13" - "@babel/generator": "npm:^7.23.0" - "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-function-name": "npm:^7.23.0" - "@babel/helper-hoist-variables": "npm:^7.22.5" - "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/parser": "npm:^7.23.0" - "@babel/types": "npm:^7.23.0" - debug: "npm:^4.1.0" - globals: "npm:^11.1.0" - checksum: d096c7c4bab9262a2f658298a3c630ae4a15a10755bb257ae91d5ab3e3b2877438934859c8d34018b7727379fe6b26c4fa2efc81cf4c462a7fe00caf79fa02ff - languageName: node - linkType: hard - -"@babel/traverse@npm:^7.23.3": +"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.23.3": version: 7.23.3 resolution: "@babel/traverse@npm:7.23.3" dependencies: @@ -1588,18 +1520,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.23.0 - resolution: "@babel/types@npm:7.23.0" - dependencies: - "@babel/helper-string-parser": "npm:^7.22.5" - "@babel/helper-validator-identifier": "npm:^7.22.20" - to-fast-properties: "npm:^2.0.0" - checksum: 70e4db41acb6793d0eb8d81a2fa88f19ee661219b84bd5f703dbdb54eb3a4d3c0dfc55e69034c945b479df9f43fd4b1376480aaccfc19797ce5af1c5d2576b36 - languageName: node - linkType: hard - -"@babel/types@npm:^7.22.10, @babel/types@npm:^7.23.3": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.10, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.23.3 resolution: "@babel/types@npm:7.23.3" dependencies: @@ -2438,7 +2359,7 @@ __metadata: "@formatjs/intl-pluralrules": "npm:^5.2.2" "@gamestdio/websocket": "npm:^0.3.2" "@github/webauthn-json": "npm:^2.1.1" - "@material-symbols/svg-600": "npm:^0.13.1" + "@material-symbols/svg-600": "npm:^0.14.0" "@rails/ujs": "npm:^7.1.1" "@reduxjs/toolkit": "npm:^1.9.5" "@svgr/webpack": "npm:^5.5.0" @@ -2621,10 +2542,10 @@ __metadata: languageName: unknown linkType: soft -"@material-symbols/svg-600@npm:^0.13.1": - version: 0.13.2 - resolution: "@material-symbols/svg-600@npm:0.13.2" - checksum: d467928fe07e640cef8767aaa144a5feda9f060596bf324bcbd0d4c19877073c8bb1b0dba126699b6830906d593bb63ea33ce3c58d102ce67efac674e5e5bfed +"@material-symbols/svg-600@npm:^0.14.0": + version: 0.14.0 + resolution: "@material-symbols/svg-600@npm:0.14.0" + checksum: e6547a9a0b2072f4109f2e4e0863367ea2507efce740c427a8544100db02ffff52f33608aac1a355f4977e2c0b2ce6cdd6bfee9177bb13cee0b28418f948b5a5 languageName: node linkType: hard @@ -11728,14 +11649,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0": - version: 7.0.3 - resolution: "minipass@npm:7.0.3" - checksum: c85426bce6310368218aad1f20b8f242180b6c2058209c78840959d6fff8a4738076a3224c3a6b651080f95684d559be1bdb084939bc40011c653ec4552cf06e - languageName: node - linkType: hard - -"minipass@npm:^7.0.2, minipass@npm:^7.0.3": +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": version: 7.0.4 resolution: "minipass@npm:7.0.4" checksum: 6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 From ac69f90098eba87d54f0bbfc0d76349d93c0792c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 10 Nov 2023 07:46:00 -0500 Subject: [PATCH 02/15] Add `Api::V1::Instances::BaseController` base controller class (#27797) --- app/controllers/api/v1/instances/activity_controller.rb | 6 +----- app/controllers/api/v1/instances/base_controller.rb | 8 ++++++++ .../api/v1/instances/domain_blocks_controller.rb | 4 +--- .../api/v1/instances/extended_descriptions_controller.rb | 5 +---- app/controllers/api/v1/instances/languages_controller.rb | 5 +---- app/controllers/api/v1/instances/peers_controller.rb | 5 +---- .../api/v1/instances/privacy_policies_controller.rb | 6 +----- app/controllers/api/v1/instances/rules_controller.rb | 5 +---- .../api/v1/instances/translation_languages_controller.rb | 6 +----- 9 files changed, 16 insertions(+), 34 deletions(-) create mode 100644 app/controllers/api/v1/instances/base_controller.rb diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb index 9da77f8dab..4c17bd79c2 100644 --- a/app/controllers/api/v1/instances/activity_controller.rb +++ b/app/controllers/api/v1/instances/activity_controller.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -class Api::V1::Instances::ActivityController < Api::BaseController +class Api::V1::Instances::ActivityController < Api::V1::Instances::BaseController before_action :require_enabled_api! - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? - - vary_by '' - def show cache_even_if_authenticated! render_with_cache json: :activity, expires_in: 1.day diff --git a/app/controllers/api/v1/instances/base_controller.rb b/app/controllers/api/v1/instances/base_controller.rb new file mode 100644 index 0000000000..ed0bebf0ff --- /dev/null +++ b/app/controllers/api/v1/instances/base_controller.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class Api::V1::Instances::BaseController < Api::BaseController + skip_before_action :require_authenticated_user!, + unless: :limited_federation_mode? + + vary_by '' +end diff --git a/app/controllers/api/v1/instances/domain_blocks_controller.rb b/app/controllers/api/v1/instances/domain_blocks_controller.rb index c91234e088..566764dbf0 100644 --- a/app/controllers/api/v1/instances/domain_blocks_controller.rb +++ b/app/controllers/api/v1/instances/domain_blocks_controller.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true -class Api::V1::Instances::DomainBlocksController < Api::BaseController - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? - +class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseController before_action :require_enabled_api! before_action :set_domain_blocks diff --git a/app/controllers/api/v1/instances/extended_descriptions_controller.rb b/app/controllers/api/v1/instances/extended_descriptions_controller.rb index 376fec9066..73d2248117 100644 --- a/app/controllers/api/v1/instances/extended_descriptions_controller.rb +++ b/app/controllers/api/v1/instances/extended_descriptions_controller.rb @@ -1,13 +1,10 @@ # frozen_string_literal: true -class Api::V1::Instances::ExtendedDescriptionsController < Api::BaseController - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? +class Api::V1::Instances::ExtendedDescriptionsController < Api::V1::Instances::BaseController skip_around_action :set_locale before_action :set_extended_description - vary_by '' - # Override `current_user` to avoid reading session cookies unless in whitelist mode def current_user super if limited_federation_mode? diff --git a/app/controllers/api/v1/instances/languages_controller.rb b/app/controllers/api/v1/instances/languages_controller.rb index 17509e748c..ea184d90da 100644 --- a/app/controllers/api/v1/instances/languages_controller.rb +++ b/app/controllers/api/v1/instances/languages_controller.rb @@ -1,13 +1,10 @@ # frozen_string_literal: true -class Api::V1::Instances::LanguagesController < Api::BaseController - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? +class Api::V1::Instances::LanguagesController < Api::V1::Instances::BaseController skip_around_action :set_locale before_action :set_languages - vary_by '' - def show cache_even_if_authenticated! render json: @languages, each_serializer: REST::LanguageSerializer diff --git a/app/controllers/api/v1/instances/peers_controller.rb b/app/controllers/api/v1/instances/peers_controller.rb index 08a982f227..83116472bb 100644 --- a/app/controllers/api/v1/instances/peers_controller.rb +++ b/app/controllers/api/v1/instances/peers_controller.rb @@ -1,13 +1,10 @@ # frozen_string_literal: true -class Api::V1::Instances::PeersController < Api::BaseController +class Api::V1::Instances::PeersController < Api::V1::Instances::BaseController before_action :require_enabled_api! - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? skip_around_action :set_locale - vary_by '' - # Override `current_user` to avoid reading session cookies unless in whitelist mode def current_user super if limited_federation_mode? diff --git a/app/controllers/api/v1/instances/privacy_policies_controller.rb b/app/controllers/api/v1/instances/privacy_policies_controller.rb index f5b1b4ec5f..9f87317d53 100644 --- a/app/controllers/api/v1/instances/privacy_policies_controller.rb +++ b/app/controllers/api/v1/instances/privacy_policies_controller.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -class Api::V1::Instances::PrivacyPoliciesController < Api::BaseController - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? - +class Api::V1::Instances::PrivacyPoliciesController < Api::V1::Instances::BaseController before_action :set_privacy_policy - vary_by '' - def show cache_even_if_authenticated! render json: @privacy_policy, serializer: REST::PrivacyPolicySerializer diff --git a/app/controllers/api/v1/instances/rules_controller.rb b/app/controllers/api/v1/instances/rules_controller.rb index 2f71984b05..d240d72464 100644 --- a/app/controllers/api/v1/instances/rules_controller.rb +++ b/app/controllers/api/v1/instances/rules_controller.rb @@ -1,13 +1,10 @@ # frozen_string_literal: true -class Api::V1::Instances::RulesController < Api::BaseController - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? +class Api::V1::Instances::RulesController < Api::V1::Instances::BaseController skip_around_action :set_locale before_action :set_rules - vary_by '' - # Override `current_user` to avoid reading session cookies unless in whitelist mode def current_user super if limited_federation_mode? diff --git a/app/controllers/api/v1/instances/translation_languages_controller.rb b/app/controllers/api/v1/instances/translation_languages_controller.rb index 78423e40e4..b8f7a16383 100644 --- a/app/controllers/api/v1/instances/translation_languages_controller.rb +++ b/app/controllers/api/v1/instances/translation_languages_controller.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -class Api::V1::Instances::TranslationLanguagesController < Api::BaseController - skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? - +class Api::V1::Instances::TranslationLanguagesController < Api::V1::Instances::BaseController before_action :set_languages - vary_by '' - def show cache_even_if_authenticated! render json: @languages From 43e2f763b2f43b5bbcb3b80890ebc89b73545b3b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 10 Nov 2023 07:47:38 -0500 Subject: [PATCH 03/15] Extract crutches_active_mentions from FeedManager (#27785) --- app/lib/feed_manager.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 2ed1457841..4e645a11f6 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -551,7 +551,7 @@ class FeedManager def build_crutches(receiver_id, statuses) crutches = {} - crutches[:active_mentions] = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact).pluck(:status_id, :account_id).each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) } + crutches[:active_mentions] = crutches_active_mentions(statuses) check_for_blocks = statuses.flat_map do |s| arr = crutches[:active_mentions][s.id] || [] @@ -578,4 +578,12 @@ class FeedManager crutches end + + def crutches_active_mentions(statuses) + Mention + .active + .where(status_id: statuses.flat_map { |status| [status.id, status.reblog_of_id] }.compact) + .pluck(:status_id, :account_id) + .each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) } + end end From ac62b995efdf6fc71f3a1adf60da99ed7ddde26b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 14:07:04 +0100 Subject: [PATCH 04/15] New Crowdin Translations (automated) (#27804) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/cy.json | 1 + app/javascript/mastodon/locales/da.json | 1 + app/javascript/mastodon/locales/de.json | 1 + app/javascript/mastodon/locales/es-AR.json | 1 + app/javascript/mastodon/locales/es-MX.json | 1 + app/javascript/mastodon/locales/es.json | 1 + app/javascript/mastodon/locales/eu.json | 1 + app/javascript/mastodon/locales/fr-QC.json | 1 + app/javascript/mastodon/locales/fr.json | 1 + app/javascript/mastodon/locales/gl.json | 1 + app/javascript/mastodon/locales/he.json | 1 + app/javascript/mastodon/locales/hu.json | 1 + app/javascript/mastodon/locales/is.json | 1 + app/javascript/mastodon/locales/it.json | 1 + app/javascript/mastodon/locales/ja.json | 1 + app/javascript/mastodon/locales/lt.json | 102 ++++++++++++++++++--- app/javascript/mastodon/locales/lv.json | 1 + app/javascript/mastodon/locales/nl.json | 1 + app/javascript/mastodon/locales/nn.json | 1 + app/javascript/mastodon/locales/pl.json | 1 + app/javascript/mastodon/locales/sq.json | 1 + app/javascript/mastodon/locales/sv.json | 1 + app/javascript/mastodon/locales/th.json | 1 + app/javascript/mastodon/locales/tr.json | 1 + app/javascript/mastodon/locales/uk.json | 1 + app/javascript/mastodon/locales/zh-CN.json | 1 + app/javascript/mastodon/locales/zh-HK.json | 1 + app/javascript/mastodon/locales/zh-TW.json | 1 + config/locales/doorkeeper.lt.yml | 68 ++++++++++++++ config/locales/fi.yml | 4 +- config/locales/ja.yml | 10 +- config/locales/lt.yml | 23 +++-- config/locales/lv.yml | 15 ++- config/locales/simple_form.ja.yml | 4 +- 34 files changed, 222 insertions(+), 31 deletions(-) diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 28c7ae1783..183ab6955b 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Canlyniadau chwilio", "emoji_button.symbols": "Symbolau", "emoji_button.travel": "Teithio a Llefydd", + "empty_column.account_hides_collections": "Mae'r defnyddiwr wedi dewis i beidio rhannu'r wybodaeth yma", "empty_column.account_suspended": "Cyfrif wedi'i atal", "empty_column.account_timeline": "Dim postiadau yma!", "empty_column.account_unavailable": "Nid yw'r proffil ar gael", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 0a8a4a1475..bb8b72bca4 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Søgeresultater", "emoji_button.symbols": "Symboler", "emoji_button.travel": "Rejser og steder", + "empty_column.account_hides_collections": "Brugeren har valgt ikke at gøre denne information tilgængelig", "empty_column.account_suspended": "Konto suspenderet", "empty_column.account_timeline": "Ingen indlæg hér!", "empty_column.account_unavailable": "Profil utilgængelig", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 0b93905816..e4f7fe6cec 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Suchergebnisse", "emoji_button.symbols": "Symbole", "emoji_button.travel": "Reisen & Orte", + "empty_column.account_hides_collections": "Das Konto hat sich dazu entschieden, diese Information nicht zu veröffentlichen", "empty_column.account_suspended": "Konto gesperrt", "empty_column.account_timeline": "Keine Beiträge vorhanden!", "empty_column.account_unavailable": "Profil nicht verfügbar", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 7aeb66b546..71d6e3119b 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Resultados de búsqueda", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viajes y lugares", + "empty_column.account_hides_collections": "Este usuario eligió no publicar esta información", "empty_column.account_suspended": "Cuenta suspendida", "empty_column.account_timeline": "¡No hay mensajes acá!", "empty_column.account_unavailable": "Perfil no disponible", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index f29a6fd0e5..aadc901f99 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Resultados de búsqueda", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viajes y lugares", + "empty_column.account_hides_collections": "Este usuario ha elegido no hacer disponible esta información", "empty_column.account_suspended": "Cuenta suspendida", "empty_column.account_timeline": "¡No hay toots aquí!", "empty_column.account_unavailable": "Perfil no disponible", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 5684ec4873..f3735d9685 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Resultados de búsqueda", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viajes y lugares", + "empty_column.account_hides_collections": "Este usuario ha decidido no mostrar esta información", "empty_column.account_suspended": "Cuenta suspendida", "empty_column.account_timeline": "¡No hay publicaciones aquí!", "empty_column.account_unavailable": "Perfil no disponible", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index 5b4fef59c0..7f109ea082 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Bilaketaren emaitzak", "emoji_button.symbols": "Sinboloak", "emoji_button.travel": "Bidaiak eta tokiak", + "empty_column.account_hides_collections": "Erabiltzaile honek informazio hau erabilgarri ez egotea aukeratu du.", "empty_column.account_suspended": "Kanporatutako kontua", "empty_column.account_timeline": "Ez dago bidalketarik hemen!", "empty_column.account_unavailable": "Profila ez dago eskuragarri", diff --git a/app/javascript/mastodon/locales/fr-QC.json b/app/javascript/mastodon/locales/fr-QC.json index 16a18048b4..a6dd91becf 100644 --- a/app/javascript/mastodon/locales/fr-QC.json +++ b/app/javascript/mastodon/locales/fr-QC.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Résultats", "emoji_button.symbols": "Symboles", "emoji_button.travel": "Voyage et lieux", + "empty_column.account_hides_collections": "Cet utilisateur·ice préfère ne pas rendre publiques ces informations", "empty_column.account_suspended": "Compte suspendu", "empty_column.account_timeline": "Aucune publication ici!", "empty_column.account_unavailable": "Profil non disponible", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 9471918543..0d2ba2bb9b 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Résultats de la recherche", "emoji_button.symbols": "Symboles", "emoji_button.travel": "Voyage et lieux", + "empty_column.account_hides_collections": "Cet utilisateur·ice préfère ne pas rendre publiques ces informations", "empty_column.account_suspended": "Compte suspendu", "empty_column.account_timeline": "Aucun message ici !", "empty_column.account_unavailable": "Profil non disponible", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 14ff22b287..e79e549264 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Resultados da procura", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viaxes e Lugares", + "empty_column.account_hides_collections": "A usuaria decideu non facer pública esta información", "empty_column.account_suspended": "Conta suspendida", "empty_column.account_timeline": "Non hai publicacións aquí!", "empty_column.account_unavailable": "Perfil non dispoñible", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 13d3239655..485e8313ad 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "תוצאות חיפוש", "emoji_button.symbols": "סמלים", "emoji_button.travel": "טיולים ואתרים", + "empty_column.account_hides_collections": "המשתמש.ת בחר.ה להסתיר מידע זה", "empty_column.account_suspended": "חשבון מושהה", "empty_column.account_timeline": "אין עדיין אף הודעה!", "empty_column.account_unavailable": "פרופיל לא זמין", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 482dc48be2..ca20271619 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Keresési találatok", "emoji_button.symbols": "Szimbólumok", "emoji_button.travel": "Utazás és Helyek", + "empty_column.account_hides_collections": "Ez a felhasználó úgy döntött, hogy nem teszi elérhetővé ezt az információt.", "empty_column.account_suspended": "Fiók felfüggesztve", "empty_column.account_timeline": "Itt nincs bejegyzés!", "empty_column.account_unavailable": "A profil nem érhető el", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index f2e6f1f449..0b6a8012ad 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Leitarniðurstöður", "emoji_button.symbols": "Tákn", "emoji_button.travel": "Ferðalög og staðir", + "empty_column.account_hides_collections": "Notandinn hefur valið að gera ekki tiltækar þessar upplýsingar", "empty_column.account_suspended": "Notandaaðgangur í frysti", "empty_column.account_timeline": "Engar færslur hér!", "empty_column.account_unavailable": "Notandasnið ekki tiltækt", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 473a123edf..4a2f41ce64 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Risultati della ricerca", "emoji_button.symbols": "Simboli", "emoji_button.travel": "Viaggi & Luoghi", + "empty_column.account_hides_collections": "Questo utente ha scelto di non rendere disponibili queste informazioni", "empty_column.account_suspended": "Profilo sospeso", "empty_column.account_timeline": "Nessun post qui!", "empty_column.account_unavailable": "Profilo non disponibile", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index a01354463f..72a57c8e3f 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "検索結果", "emoji_button.symbols": "記号", "emoji_button.travel": "旅行と場所", + "empty_column.account_hides_collections": "このユーザーはこの情報を開示しないことにしています。", "empty_column.account_suspended": "アカウントは停止されています", "empty_column.account_timeline": "投稿がありません!", "empty_column.account_unavailable": "プロフィールは利用できません", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 62aaa84758..a1ab531316 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -1,25 +1,37 @@ { - "about.blocks": "Moderatorių prižiūrimi serveriai", - "about.contact": "Kontaktai:", - "about.disclaimer": "Mastodon, tai nemokama, atviro kodo programa, kuriuos prekybinis ženklas priklauso Mastodon GmbH.", + "about.blocks": "Prižiūrimi serveriai", + "about.contact": "Kontaktuoti:", + "about.disclaimer": "Mastodon – nemokama atvirojo šaltinio programa ir Mastodon gGmbH prekės ženklas.", "about.domain_blocks.no_reason_available": "Priežastis nežinoma", - "about.domain_blocks.suspended.title": "Uždraustas", - "about.not_available": "Šiame serveryje informacijos nėra.", + "about.domain_blocks.preamble": "Mastodon paprastai leidžia peržiūrėti turinį ir bendrauti su naudotojais iš bet kurio kito fediverse esančio serverio. Šios yra išimtys, kurios buvo padarytos šiame konkrečiame serveryje.", + "about.domain_blocks.silenced.explanation": "Paprastai nematysi profilių ir turinio iš šio serverio, nebent jį aiškiai ieškosi arba pasirinksi jį sekdamas (-a).", + "about.domain_blocks.silenced.title": "Ribota", + "about.domain_blocks.suspended.explanation": "Jokie duomenys iš šio serverio nebus apdorojami, saugomi ar keičiami, todėl bet kokia sąveika ar bendravimas su šio serverio naudotojais bus neįmanomas.", + "about.domain_blocks.suspended.title": "Uždrausta", + "about.not_available": "Ši informacija nebuvo pateikta šiame serveryje.", + "about.powered_by": "Decentralizuota socialinė žiniasklaida, kurią valdo {mastodon}", "about.rules": "Serverio taisyklės", "account.account_note_header": "Pastaba", - "account.add_or_remove_from_list": "Pridėti arba ištrinti iš sąrašo", - "account.badges.bot": "Robotas", + "account.add_or_remove_from_list": "Pridėti arba ištrinti iš sąrašų", + "account.badges.bot": "Automatizuotas", "account.badges.group": "Grupė", "account.block": "Užblokuoti @{name}", - "account.block_domain": "Hide everything from {domain}", + "account.block_domain": "Blokuoti domeną {domain}", + "account.block_short": "Blokuoti", "account.blocked": "Užblokuota", - "account.cancel_follow_request": "Withdraw follow request", - "account.domain_blocked": "Domain hidden", + "account.browse_more_on_origin_server": "Naršyti daugiau originaliame profilyje", + "account.cancel_follow_request": "Atšaukti sekimą", + "account.direct": "Privačiai paminėti @{name}", + "account.disable_notifications": "Nustoti man pranešti, kai @{name} paskelbia", + "account.domain_blocked": "Užblokuotas domenas", + "account.edit_profile": "Redaguoti profilį", "account.follow": "Sekti", "account.follows_you": "Seka jus", "account.go_to_profile": "Eiti į profilį", + "account.in_memoriam": "Atminimui.", "account.joined_short": "Prisijungė", - "account.media": "Media", + "account.locked_info": "Šios paskyros privatumo būsena nustatyta kaip užrakinta. Savininkas (-ė) rankiniu būdu peržiūri, kas gali sekti.", + "account.media": "Medija", "account.mute": "Užtildyti @{name}", "account.muted": "Užtildytas", "account.posts": "Toots", @@ -33,6 +45,10 @@ "account.unmute_short": "Atitildyti", "account_note.placeholder": "Click to add a note", "alert.unexpected.title": "Oi!", + "announcement.announcement": "Skelbimas", + "audio.hide": "Slėpti garsą", + "autosuggest_hashtag.per_week": "{count} per savaitę", + "bundle_column_error.error.title": "O, ne!", "column.domain_blocks": "Hidden domains", "column.lists": "Sąrašai", "column.mutes": "Užtildyti vartotojai", @@ -43,24 +59,50 @@ "column_header.show_settings": "Rodyti nustatymus", "column_header.unpin": "Atsegti", "column_subheading.settings": "Nustatymai", - "community.column_settings.media_only": "Media only", + "community.column_settings.media_only": "Tik medija", + "compose.language.change": "Keisti kalbą", + "compose.language.search": "Ieškoti kalbų...", + "compose.published.body": "Įrašas paskelbtas.", "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.placeholder": "What is on your mind?", "compose_form.publish_form": "Publish", + "compose_form.sensitive.hide": "{count, plural, one {Žymėti mediją kaip jautrią} few {Žymėti medijas kaip jautrias} many {Žymėti medijos kaip jautrios} other {Žymėti medijų kaip jautrių}}", + "compose_form.sensitive.marked": "{count, plural, one {Medija pažymėta kaip jautri} few {Medijos pažymėtos kaip jautrios} many {Medijos pažymėta kaip jautrios} other {Medijų pažymėtos kaip jautrios}}", + "compose_form.sensitive.unmarked": "{count, plural, one {Medija nepažymėta kaip jautri} few {Medijos nepažymėtos kaip jautrios} many {Medijos nepažymėta kaip jautri} other {Medijų nepažymėta kaip jautrios}}", "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", + "confirmations.delete.confirm": "Ištrinti", "confirmations.delete.message": "Are you sure you want to delete this status?", + "confirmations.discard_edit_media.confirm": "Atmesti", + "confirmations.discard_edit_media.message": "Turi neišsaugotų medijos aprašymo ar peržiūros pakeitimų, vis tiek juos atmesti?", "confirmations.domain_block.confirm": "Hide entire domain", + "confirmations.reply.confirm": "Atsakyti", + "confirmations.reply.message": "Atsakydamas (-a) dabar perrašysi šiuo metu rašomą žinutę. Ar tikrai nori tęsti?", + "confirmations.unfollow.confirm": "Nebesekti", "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", "embed.instructions": "Embed this status on your website by copying the code below.", + "emoji_button.search": "Paieška...", + "empty_column.account_hides_collections": "Šis naudotojas (-a) pasirinko nepadaryti šią informaciją prieinamą", "empty_column.account_timeline": "No toots here!", "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.", "empty_column.domain_blocks": "There are no hidden domains yet.", + "empty_column.hashtag": "Nėra nieko šiame saitažodyje kol kas.", "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", + "firehose.local": "Šis serveris", + "follow_requests.unlocked_explanation": "Nors tavo paskyra neužrakinta, {domain} personalas mano, kad galbūt norėsi rankiniu būdu patikrinti šių paskyrų sekimo užklausas.", + "followed_tags": "Sekamos saitažodžiai", + "footer.about": "Apie", + "footer.invite": "Kviesti žmones", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", + "interaction_modal.no_account_yet": "Nesi Mastodon?", + "interaction_modal.on_another_server": "Kitame serveryje", + "interaction_modal.on_this_server": "Šiame serveryje", + "interaction_modal.sign_in": "Nesi prisijungęs (-usi) prie šio serverio. Kur yra laikoma tavo paskyra?", + "interaction_modal.sign_in_hint": "Patarimas: tai svetainė, kurioje užsiregistravai. Jei neprisimeni, ieškok sveikinimo el. laiško savo pašto dėžutėje. Taip pat gali įvesti visą savo naudotojo vardą (pvz., @Mastodon@mastodon.social).", + "interaction_modal.title.favourite": "Mėgstamiausias {name} įrašas", "keyboard_shortcuts.back": "to navigate back", "keyboard_shortcuts.blocked": "to open blocked users list", "keyboard_shortcuts.boost": "to boost", @@ -72,13 +114,14 @@ "keyboard_shortcuts.federated": "to open federated timeline", "keyboard_shortcuts.heading": "Keyboard Shortcuts", "keyboard_shortcuts.home": "to open home timeline", + "keyboard_shortcuts.hotkey": "Spartusis klavišas", "keyboard_shortcuts.legend": "to display this legend", "keyboard_shortcuts.local": "to open local timeline", "keyboard_shortcuts.mention": "to mention author", "keyboard_shortcuts.muted": "to open muted users list", "keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.notifications": "to open notifications column", - "keyboard_shortcuts.open_media": "to open media", + "keyboard_shortcuts.open_media": "Atidaryti mediją", "keyboard_shortcuts.pinned": "to open pinned toots list", "keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.reply": "to reply", @@ -87,21 +130,39 @@ "keyboard_shortcuts.spoilers": "to show/hide CW field", "keyboard_shortcuts.start": "to open \"get started\" column", "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", - "keyboard_shortcuts.toggle_sensitivity": "to show/hide media", + "keyboard_shortcuts.toggle_sensitivity": "Rodyti / slėpti mediją", "keyboard_shortcuts.toot": "to start a brand new toot", "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.up": "to move up in the list", + "lightbox.close": "Uždaryti", + "media_gallery.toggle_visible": "{number, plural, one {Slėpti vaizdą} few {Slėpti vaizdus} many {Slėpti vaizdo} other {Slėpti vaizdų}}", "navigation_bar.compose": "Compose new toot", "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.follows_and_followers": "Sekimai ir sekėjai", + "navigation_bar.lists": "Sąrašai", + "navigation_bar.logout": "Atsijungti", + "navigation_bar.mutes": "Užtildyti naudotojai", + "navigation_bar.opened_in_classic_interface": "Įrašai, paskyros ir kiti konkretūs puslapiai pagal numatytuosius nustatymus atidaromi klasikinėje žiniatinklio sąsajoje.", + "navigation_bar.personal": "Asmeninis", "navigation_bar.pins": "Pinned toots", + "navigation_bar.preferences": "Nuostatos", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", + "notification.own_poll": "Tavo apklausa baigėsi", + "notification.poll": "Apklausa, kurioje balsavai, pasibaigė", "notification.reblog": "{name} boosted your status", + "notification.status": "{name} ką tik paskelbė", + "notification.update": "{name} redagavo įrašą", + "notifications.clear": "Išvalyti pranešimus", + "notifications.clear_confirmation": "Ar tikrai nori visam laikui išvalyti visus pranešimus?", + "notifications.column_settings.admin.report": "Nauji ataskaitos:", "notifications.column_settings.status": "New toots:", + "notifications.filter.mentions": "Paminėjimai", "onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_home": "Go to your home feed", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", - "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", + "onboarding.share.message": "Aš {username} #Mastodon! Ateik sekti manęs adresu {url}", + "onboarding.start.lead": "Dabar esi Mastodon dalis – unikalios decentralizuotos socialinės žiniasklaidos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtį. Pradėkime tavo kelionę šioje naujoje socialinėje erdvėje:", "onboarding.start.skip": "Want to skip right ahead?", "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", @@ -110,11 +171,17 @@ "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.title": "Share your profile", + "poll.vote": "Balsuoti", + "poll.voted": "Tu balsavai už šį atsakymą", + "poll.votes": "{votes, plural, one {# balsas} few {# balsai} many {# balso} other {# balsų}}", "privacy.change": "Adjust status privacy", "privacy.direct.long": "Post to mentioned users only", "privacy.direct.short": "Direct", "privacy.private.long": "Post to followers only", "privacy.private.short": "Followers-only", + "privacy.unlisted.long": "Matomas visiems, bet atsisakyta atradimo funkcijų", + "privacy.unlisted.short": "Neįtrauktas į sąrašą", + "privacy_policy.last_updated": "Paskutinį kartą atnaujinta {date}", "report.placeholder": "Type or paste additional comments", "report.submit": "Submit report", "report.target": "Report {target}", @@ -124,14 +191,19 @@ "status.admin_status": "Open this status in the moderation interface", "status.copy": "Copy link to status", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", + "status.media.open": "Spausk, kad atidaryti", + "status.media.show": "Spausk, kad pamatyti", + "status.media_hidden": "Paslėpta medija", "status.open": "Expand this status", "status.pinned": "Pinned toot", "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}", + "status.uncached_media_warning": "Peržiūra nepasiekiama", "timeline_hint.resources.statuses": "Older toots", "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", "upload_form.audio_description": "Describe for people with hearing loss", "upload_form.description": "Describe for the visually impaired", "upload_form.video_description": "Describe for people with hearing loss or visual impairment", + "upload_modal.edit_media": "Redaguoti mediją", "upload_progress.label": "Uploading…" } diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 7f71d9318b..5d681b8291 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Meklēšanas rezultāti", "emoji_button.symbols": "Simboli", "emoji_button.travel": "Ceļošana un vietas", + "empty_column.account_hides_collections": "Šis lietotājs ir izvēlējies nedarīt šo informāciju pieejamu", "empty_column.account_suspended": "Konta darbība ir apturēta", "empty_column.account_timeline": "Šeit ziņojumu nav!", "empty_column.account_unavailable": "Profils nav pieejams", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 87a2af4f20..131d2e4aa0 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Zoekresultaten", "emoji_button.symbols": "Symbolen", "emoji_button.travel": "Reizen en locaties", + "empty_column.account_hides_collections": "Deze gebruiker heeft ervoor gekozen deze informatie niet beschikbaar te maken", "empty_column.account_suspended": "Account opgeschort", "empty_column.account_timeline": "Hier zijn geen berichten!", "empty_column.account_unavailable": "Profiel is niet beschikbaar", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 8ff390aabb..aa30aef7d2 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Søkeresultat", "emoji_button.symbols": "Symbol", "emoji_button.travel": "Reise & stader", + "empty_column.account_hides_collections": "Denne brukaren har valt å ikkje gjere denne informasjonen tilgjengeleg", "empty_column.account_suspended": "Kontoen er suspendert", "empty_column.account_timeline": "Ingen tut her!", "empty_column.account_unavailable": "Profil ikkje tilgjengeleg", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 84ea64bb98..643f78a884 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Wyniki wyszukiwania", "emoji_button.symbols": "Symbole", "emoji_button.travel": "Podróże i miejsca", + "empty_column.account_hides_collections": "Użytkownik postanowił nie udostępniać tych informacji", "empty_column.account_suspended": "Konto zawieszone", "empty_column.account_timeline": "Brak wpisów tutaj!", "empty_column.account_unavailable": "Profil niedostępny", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 2e908fdc5b..8d54ef41b1 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Përfundime kërkimi", "emoji_button.symbols": "Simbole", "emoji_button.travel": "Udhëtime & Vende", + "empty_column.account_hides_collections": "Ky përdorues ka zgjedhur të mos e japë këtë informacion", "empty_column.account_suspended": "Llogaria u pezullua", "empty_column.account_timeline": "S’ka mesazhe këtu!", "empty_column.account_unavailable": "Profil jashtë funksionimi", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index e0b6fc4722..edf981e112 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Sökresultat", "emoji_button.symbols": "Symboler", "emoji_button.travel": "Resor & platser", + "empty_column.account_hides_collections": "Användaren har valt att inte göra denna information tillgänglig", "empty_column.account_suspended": "Kontot är avstängt", "empty_column.account_timeline": "Inga inlägg här!", "empty_column.account_unavailable": "Profilen ej tillgänglig", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index ff6e5a52d5..80f862cbe0 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "ผลลัพธ์การค้นหา", "emoji_button.symbols": "สัญลักษณ์", "emoji_button.travel": "การเดินทางและสถานที่", + "empty_column.account_hides_collections": "ผู้ใช้นี้ได้เลือกที่จะไม่ทำให้ข้อมูลนี้พร้อมใช้งาน", "empty_column.account_suspended": "ระงับบัญชีอยู่", "empty_column.account_timeline": "ไม่มีโพสต์ที่นี่!", "empty_column.account_unavailable": "โปรไฟล์ไม่พร้อมใช้งาน", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index de92b9b56f..9ad2594930 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Arama sonuçları", "emoji_button.symbols": "Semboller", "emoji_button.travel": "Seyahat ve Yerler", + "empty_column.account_hides_collections": "Bu kullanıcı bu bilgiyi sağlamayı tercih etmemiştir", "empty_column.account_suspended": "Hesap askıya alındı", "empty_column.account_timeline": "Burada hiç gönderi yok!", "empty_column.account_unavailable": "Profil kullanılamıyor", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index aa17e12545..09fa58fbf9 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Результати пошуку", "emoji_button.symbols": "Символи", "emoji_button.travel": "Подорожі та місця", + "empty_column.account_hides_collections": "Цей користувач вирішив не робити цю інформацію доступною", "empty_column.account_suspended": "Обліковий запис заблоковано", "empty_column.account_timeline": "Тут немає дописів!", "empty_column.account_unavailable": "Профіль недоступний", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index c311b5ae33..f830aa2985 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "搜索结果", "emoji_button.symbols": "符号", "emoji_button.travel": "旅行和地点", + "empty_column.account_hides_collections": "该用户选择不提供此信息", "empty_column.account_suspended": "账户已被停用", "empty_column.account_timeline": "这里没有嘟文!", "empty_column.account_unavailable": "个人资料不可用", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index 47880f7112..7121a7d03e 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "搜尋結果", "emoji_button.symbols": "符號", "emoji_button.travel": "旅遊景物", + "empty_column.account_hides_collections": "這位使用者選擇不公開此資訊", "empty_column.account_suspended": "帳號已停權", "empty_column.account_timeline": "這裡還沒有嘟文!", "empty_column.account_unavailable": "無法取得個人資料", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 5d3d74ea68..db4fe4eab2 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "搜尋結果", "emoji_button.symbols": "符號", "emoji_button.travel": "旅遊與地點", + "empty_column.account_hides_collections": "這位使用者選擇不提供此資訊", "empty_column.account_suspended": "帳號已被停權", "empty_column.account_timeline": "這裡還沒有嘟文!", "empty_column.account_unavailable": "無法取得個人檔案", diff --git a/config/locales/doorkeeper.lt.yml b/config/locales/doorkeeper.lt.yml index 6c5cb837ac..36f31e39ea 100644 --- a/config/locales/doorkeeper.lt.yml +++ b/config/locales/doorkeeper.lt.yml @@ -1 +1,69 @@ +--- lt: + doorkeeper: + authorizations: + error: + title: Įvyko klaida. + new: + prompt_html: "%{client_name} norėtų gauti leidimą prieigos prie tavo paskyros. Tai trečiosios šalies programėlė. Jei ja nepasitiki, neturėtum jai leisti." + authorized_applications: + index: + title: Tavo leidžiamos programėlės + grouped_scopes: + title: + blocks: Blokavimai + follow: Sekimai, nutildymai ir blokavimai + statuses: Įrašai + layouts: + admin: + nav: + applications: Programėlės + oauth2_provider: OAuth2 teikėjas + application: + title: Reikalingas OAuth įgaliojimas + scopes: + admin:read: skaityti visus serveryje esančius duomenis + admin:read:accounts: skaityti neskelbtiną visų paskyrų informaciją + admin:read:canonical_email_blocks: skaityti neskelbtiną visų kanoninių el. laiško blokavimų informaciją + admin:read:domain_allows: skaityti neskelbtiną visų domeno leidimus informaciją + admin:read:domain_blocks: skaityti neskelbtiną visų domeno blokavimų informaciją + admin:read:email_domain_blocks: skaityti neskelbtiną visų el. laiško domeno blokavimų informaciją + admin:read:ip_blocks: skaityti neskelbtiną visų IP blokavimų informaciją + admin:read:reports: skaityti neskelbtiną visų ataskaitų ir praneštų paskyrų informaciją + admin:write: modifikuoti visus serveryje esančius duomenis + admin:write:accounts: atlikti paskyrų prižiūrėjimo veiksmus + admin:write:canonical_email_blocks: atlikti kanoninių el. laiško blokavimų prižiūrėjimo veiksmus + admin:write:domain_allows: atlikti prižiūrėjimo veiksmus su domeno leidimais + admin:write:domain_blocks: atlikti prižiūrėjimo veiksmus su domenų blokavimais + admin:write:email_domain_blocks: atlikti prižiūrėjimo veiksmus su el. laiško domenų blokavimais + admin:write:ip_blocks: atlikti prižiūrėjimo veiksmus su IP blokavimais + crypto: naudoti galo iki galo šifravimą + follow: modifikuoti paskyros santykius + push: gauti tavo stumiamuosius pranešimus + read: skaityti tavo visus paskyros duomenis + read:accounts: matyti paskyrų informaciją + read:blocks: matyti tavo blokavimus + read:bookmarks: matyti tavo žymes + read:favourites: matyti tavo mėgstamiausius + read:filters: matyti tavo filtrus + read:follows: matyti tavo sekimus + read:lists: matyti tavo sąrašus + read:mutes: matyti tavo nutildymus + read:notifications: matyti tavo pranešimus + read:reports: matyti tavo ataskaitas + read:search: ieškoti tavo vardu + read:statuses: matyti visus įrašus + write: modifikuoti visus tavo paskyros duomenis + write:accounts: modifikuoti tavo profilį + write:blocks: blokuoti paskyras ir domenus + write:bookmarks: įrašyti įrašus + write:conversations: nutildyti ir ištrinti pokalbius + write:favourites: mėgti įrašai + write:filters: sukurti filtrus + write:follows: sekti žmones + write:lists: sukurti sąrašus + write:media: įkelti medijos failus + write:mutes: nutildyti žmones ir pokalbius + write:notifications: išvalyti tavo pranešimus + write:reports: pranešti kitus asmenus + write:statuses: skelbti įrašus diff --git a/config/locales/fi.yml b/config/locales/fi.yml index d6f327c327..4fe0179dfe 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1041,13 +1041,13 @@ fi: hint_html: Vielä yksi juttu! Meidän on vahvistettava, että olet ihminen (tämän avulla pidämme roskapostin poissa!). Ratkaise alla oleva CAPTCHA-vahvistus ja paina "Jatka". title: Turvatarkastus confirmations: - awaiting_review: Sähköpostiosoitteesi on vahvistettu! Seuraavaksi palvelimen %{domain} ylläpito tarkistaa rekisteröitymisesi ja saat lopuksi ilmoituksen sähköpostitse, jos tilisi hyväksytään! + awaiting_review: Sähköpostiosoitteesi on vahvistettu! Seuraavaksi palvelimen %{domain} ylläpito tarkistaa rekisteröitymisesi, ja saat lopuksi ilmoituksen sähköpostitse, jos tilisi hyväksytään! awaiting_review_title: Rekisteröitymisesi on tarkistettavana clicking_this_link: tästä linkistä login_link: kirjautumalla sisään proceed_to_login_html: Voit nyt jatkaa %{login_link}. redirect_to_app_html: Sinun olisi pitänyt ohjautua sovellukseen %{app_name}. Jos näin ei tapahtunut, yritä avata se %{clicking_this_link} tai palaa sovellukseen manuaalisesti. - registration_complete: Rekisteröitymisesi palvelimelle %{domain} on suoritettu! + registration_complete: Rekisteröitymisesi palvelimelle %{domain} on nyt valmis! welcome_title: Tervetuloa, %{name}! wrong_email_hint: Jos sähköpostiosoite ei ole oikein, voit muuttaa sen tilin asetuksista. delete_account: Poista tili diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 0c805b9e56..ca438f53d2 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1025,12 +1025,12 @@ ja: confirmations: awaiting_review: メールアドレスは確認済みです。%{domain} のモデレーターによりアカウント登録の審査が完了すると、メールでお知らせします。 awaiting_review_title: 登録の審査待ちです - clicking_this_link: こちらのリンク - login_link: こちらのリンク - proceed_to_login_html: "%{login_link}から早速ログインしてみましょう。" - redirect_to_app_html: "%{app_name}に戻ります。自動で移動しない場合は%{clicking_this_link}を押すか、手動でアプリを切り替えてください。" + clicking_this_link: このリンクを押す + login_link: ログイン + proceed_to_login_html: それでは%{login_link}しましょう。 + redirect_to_app_html: 自動的に%{app_name}に戻らなかった場合、%{clicking_this_link}か、手動でアプリを切り替えてください。 registration_complete: "%{domain} へのアカウント登録が完了しました。" - welcome_title: Mastodonへようこそ、%{name}さん + welcome_title: ようこそ、%{name}さん! wrong_email_hint: メールアドレスが正しくない場合は、アカウント設定で変更できます。 delete_account: アカウントの削除 delete_account_html: アカウントを削除したい場合、こちらから手続きが行えます。削除する前に、確認画面があります。 diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 7ad63c5e39..2f4d813c9e 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -58,6 +58,7 @@ lt: follows: Seka header: Antraštė inbox_url: Gautųjų URL + invite_request_text: Priežastys prisijungiant invited_by: Pakvietė ip: IP joined: Prisijungė @@ -183,10 +184,10 @@ lt: deactivate_all: Deaktyvuoti visus filter: all: Visi - available: Prieinamas + available: Pasiekiamas expired: Pasibaigęs title: Filtras - title: Pakvietimai + title: Kvietimai relays: add_new: Pridėti naują pamainą delete: Ištrinti @@ -236,6 +237,8 @@ lt: everyone: Numatytieji leidimai everyone_full_description_html: Tai – bazinis vaidmuo, turintis įtakos visiems naudotojams, net ir tiems, kurie neturi priskirto vaidmens. Visi kiti vaidmenys iš jo paveldi teises. settings: + captcha_enabled: + desc_html: Tai priklauso nuo hCaptcha išorinių skriptų, kurie gali kelti susirūpinimą dėl saugumo ir privatumo. Be to, dėl to registracijos procesas kai kuriems žmonėms (ypač neįgaliesiems) gali būti gerokai sunkiau prieinami. Dėl šių priežasčių apsvarstyk alternatyvias priemones, pavyzdžiui, patvirtinimu arba kvietimu grindžiamą registraciją. domain_blocks: all: Visiems statuses: @@ -285,6 +288,9 @@ lt: or_log_in_with: Arba prisijungti su register: Užsiregistruoti reset_password: Atstatyti slaptažodį + rules: + invited_by: 'Gali prisijungti prie %{domain} pagal kvietimą, kurį gavai iš:' + preamble_invited: Prieš tęsiant, atsižvelk į pagrindines taisykles, kurias nustatė %{domain} prižiūrėtojai. security: Apsauga set_new_password: Nustatyti naują slaptažodį datetime: @@ -367,7 +373,7 @@ lt: upload: Įkelti invites: delete: Deaktyvuoti - expired: Pasibaigęs + expired: Pasibaigė expires_in: '1800': 30 minučių '21600': 6 valandų @@ -378,10 +384,15 @@ lt: expires_in_prompt: Niekada generate: Generuoti invited_by: 'Jus pakvietė:' - max_uses_prompt: Be limito - prompt: Generuoti ir dalintis įrašais su kitais, kad sukurti prieigą prie serverio + max_uses: + few: "%{count} panaudojimai" + many: "%{count} panaudojimo" + one: 1 panaudojimas + other: "%{count} panaudojimų" + max_uses_prompt: Nėra limito + prompt: Generuok ir bendrink nuorodas su kitais, kad suteiktum prieigą prie šio serverio table: - expires_at: Pasibaigia + expires_at: Baigsis uses: Naudojimai title: Pakviesti žmones media_attachments: diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 28a1a33dcb..4bcf23de4d 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -343,7 +343,7 @@ lv: title: Pielāgotās emocijzīmes uncategorized: Nekategorizētās unlist: Izslēgt - unlisted: Nerindota + unlisted: Neminētie update_failed_msg: Nevarēja atjaunināt šo emocijzīmi updated_msg: Emocijzīme veiksmīgi atjaunināta! upload: Augšupielādēt @@ -545,6 +545,7 @@ lv: total_reported: Ziņojumi par viņiem total_storage: Multividesu pielikumi totals_time_period_hint_html: Tālāk redzamajās summās ir iekļauti dati par visu laiku. + unknown_instance: Pašlaik šajā serverī nav ierakstu par šo domēnu. invites: deactivate_all: Deaktivēt visu filter: @@ -1058,6 +1059,14 @@ lv: hint_html: Vēl tikai viena lieta! Mums ir jāapstiprina, ka tu esi cilvēks (tas ir tāpēc, lai mēs varētu nepieļaut surogātpasta izsūtīšanu!). Atrisini tālāk norādīto CAPTCHA un noklikšķini uz "Turpināt". title: Drošības pārbaude confirmations: + awaiting_review: Tava e-pasta adrese ir apstiprināta! %{domain} darbinieki tagad pārskata tavu reģistrāciju. Tu saņemsi e-pastu, ja viņi apstiprinās tavu kontu! + awaiting_review_title: Tava reģistrācija tiek izskatīta + clicking_this_link: klikšķinot šo saiti + login_link: pieteikties + proceed_to_login_html: Tagad vari doties uz %{login_link}. + redirect_to_app_html: Tev vajadzētu būt novirzītam uz lietotni %{app_name}. Ja tas nenotika, mēģini %{clicking_this_link} vai manuāli atgriezieties lietotnē. + registration_complete: Tava reģistrācija domēnā %{domain} tagad ir pabeigta! + welcome_title: Laipni lūdzam, %{name}! wrong_email_hint: Ja šī e-pasta adrese nav pareiza, varat to mainīt konta iestatījumos. delete_account: Dzēst kontu delete_account_html: Ja vēlies dzēst savu kontu, tu vari turpināt šeit. Tev tiks lūgts apstiprinājums. @@ -1119,6 +1128,7 @@ lv: functional: Tavs konts ir pilnībā darboties spējīgs. pending: Tavu pieteikumu gaida mūsu darbinieku izskatīšana. Tas var aizņemt kādu laiku. Ja tavs pieteikums tiks apstiprināts, tu saņemsi e-pastu. redirecting_to: Tavs konts ir neaktīvs, jo pašlaik tas tiek novirzīts uz %{acct}. + self_destruct: Tā kā %{domain} tiek slēgts, tu iegūsi tikai ierobežotu piekļuvi savam kontam. view_strikes: Skati iepriekšējos brīdinājumus par savu kontu too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz. use_security_key: Lietot drošības atslēgu @@ -1596,6 +1606,9 @@ lv: over_daily_limit: Tu esi pārsniedzis šodien ieplānoto %{limit} ziņu ierobežojumu over_total_limit: Tu esi pārsniedzis ieplānoto %{limit} ziņu ierobežojumu too_soon: Ieplānotajam datumam ir jābūt nākotnē + self_destruct: + lead_html: Diemžēl domēns %{domain} tiek neatgriezeniski slēgts. Ja tev tur bija konts, tu nevarēsi turpināt to lietot, taču joprojām vari pieprasīt savu datu kopiju. + title: Šis serveris tiek slēgts sessions: activity: Pēdējā aktivitāte browser: Pārlūks diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 41ae838b2e..08e866b55e 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -247,7 +247,7 @@ ja: mascot: カスタムマスコット(レガシー) media_cache_retention_period: メディアキャッシュの保持期間 peers_api_enabled: 発見したサーバーのリストをAPIで公開する - profile_directory: ディレクトリを有効にする + profile_directory: プロフィール一覧を有効にする registrations_mode: 新規登録が可能な人 require_invite_text: 申請事由の入力を必須にする show_domain_blocks: ドメインブロックを表示 @@ -258,7 +258,7 @@ ja: site_short_description: サーバーの説明 site_terms: プライバシーポリシー site_title: サーバーの名前 - status_page_url: ステータスページのURL + status_page_url: サーバーの状態ページのURL theme: デフォルトテーマ thumbnail: サーバーのサムネイル timeline_preview: 公開タイムラインへの未認証のアクセスを許可する From 9dc3ce878b51ab80b19365b2a74101cb3e5a8903 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 10 Nov 2023 10:13:42 -0500 Subject: [PATCH 05/15] Speed-up in `Settings::` controllers specs (#27808) --- .../settings/aliases_controller_spec.rb | 5 +- .../settings/applications_controller_spec.rb | 66 ++++++------------ .../settings/deletes_controller_spec.rb | 21 +----- .../settings/exports_controller_spec.rb | 5 +- .../settings/imports_controller_spec.rb | 69 ++++--------------- .../login_activities_controller_spec.rb | 5 +- .../migration/redirects_controller_spec.rb | 5 +- .../settings/migrations_controller_spec.rb | 21 +++--- .../preferences/appearance_controller_spec.rb | 5 +- .../notifications_controller_spec.rb | 5 +- .../preferences/other_controller_spec.rb | 5 +- .../settings/profiles_controller_spec.rb | 5 +- .../webauthn_credentials_controller_spec.rb | 59 +++------------- ..._authentication_methods_controller_spec.rb | 5 +- 14 files changed, 65 insertions(+), 216 deletions(-) diff --git a/spec/controllers/settings/aliases_controller_spec.rb b/spec/controllers/settings/aliases_controller_spec.rb index 9636c1ac55..18e568be0b 100644 --- a/spec/controllers/settings/aliases_controller_spec.rb +++ b/spec/controllers/settings/aliases_controller_spec.rb @@ -17,11 +17,8 @@ describe Settings::AliasesController do get :index end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/applications_controller_spec.rb b/spec/controllers/settings/applications_controller_spec.rb index 169304b3ed..ccbb634911 100644 --- a/spec/controllers/settings/applications_controller_spec.rb +++ b/spec/controllers/settings/applications_controller_spec.rb @@ -18,11 +18,8 @@ describe Settings::ApplicationsController do get :index end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end @@ -51,7 +48,7 @@ describe Settings::ApplicationsController do describe 'POST #create' do context 'when success (passed scopes as a String)' do - def call_create + subject do post :create, params: { doorkeeper_application: { name: 'My New App', @@ -60,20 +57,16 @@ describe Settings::ApplicationsController do scopes: 'read write follow', }, } - response end - it 'creates an entry in the database' do - expect { call_create }.to change(Doorkeeper::Application, :count) - end - - it 'redirects back to applications page' do - expect(call_create).to redirect_to(settings_applications_path) + it 'creates an entry in the database', :aggregate_failures do + expect { subject }.to change(Doorkeeper::Application, :count) + expect(response).to redirect_to(settings_applications_path) end end context 'when success (passed scopes as an Array)' do - def call_create + subject do post :create, params: { doorkeeper_application: { name: 'My New App', @@ -82,15 +75,11 @@ describe Settings::ApplicationsController do scopes: %w(read write follow), }, } - response end - it 'creates an entry in the database' do - expect { call_create }.to change(Doorkeeper::Application, :count) - end - - it 'redirects back to applications page' do - expect(call_create).to redirect_to(settings_applications_path) + it 'creates an entry in the database', :aggregate_failures do + expect { subject }.to change(Doorkeeper::Application, :count) + expect(response).to redirect_to(settings_applications_path) end end @@ -106,11 +95,8 @@ describe Settings::ApplicationsController do } end - it 'returns http success' do + it 'returns http success and renders form', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'renders form again' do expect(response).to render_template(:new) end end @@ -118,13 +104,7 @@ describe Settings::ApplicationsController do describe 'PATCH #update' do context 'when success' do - let(:opts) do - { - website: 'https://foo.bar/', - } - end - - def call_update + subject do patch :update, params: { id: app.id, doorkeeper_application: opts, @@ -132,13 +112,17 @@ describe Settings::ApplicationsController do response end - it 'updates existing application' do - call_update - expect(app.reload.website).to eql(opts[:website]) + let(:opts) do + { + website: 'https://foo.bar/', + } end - it 'redirects back to applications page' do - expect(call_update).to redirect_to(settings_application_path(app)) + it 'updates existing application' do + subject + + expect(app.reload.website).to eql(opts[:website]) + expect(response).to redirect_to(settings_application_path(app)) end end @@ -155,11 +139,8 @@ describe Settings::ApplicationsController do } end - it 'returns http success' do + it 'returns http success and renders form', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'renders form again' do expect(response).to render_template(:show) end end @@ -170,11 +151,8 @@ describe Settings::ApplicationsController do post :destroy, params: { id: app.id } end - it 'redirects back to applications page' do + it 'redirects back to applications page and removes the app' do expect(response).to redirect_to(settings_applications_path) - end - - it 'removes the app' do expect(Doorkeeper::Application.find_by(id: app.id)).to be_nil end end diff --git a/spec/controllers/settings/deletes_controller_spec.rb b/spec/controllers/settings/deletes_controller_spec.rb index 7ee18f9fb1..2c1532ecd8 100644 --- a/spec/controllers/settings/deletes_controller_spec.rb +++ b/spec/controllers/settings/deletes_controller_spec.rb @@ -14,22 +14,16 @@ describe Settings::DeletesController do get :show end - it 'renders confirmation page' do + it 'renders confirmation page with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end context 'when suspended' do let(:user) { Fabricate(:user, account_attributes: { suspended_at: Time.now.utc }) } - it 'returns http forbidden' do + it 'returns http forbidden with private cache control headers', :aggregate_failures do expect(response).to have_http_status(403) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end @@ -56,19 +50,10 @@ describe Settings::DeletesController do delete :destroy, params: { form_delete_confirmation: { password: 'petsmoldoggos' } } end - it 'redirects to sign in page' do + it 'removes user record and redirects', :aggregate_failures do expect(response).to redirect_to '/auth/sign_in' - end - - it 'removes user record' do expect(User.find_by(id: user.id)).to be_nil - end - - it 'marks account as suspended' do expect(user.account.reload).to be_suspended - end - - it 'does not create an email block' do expect(CanonicalEmailBlock.block?(user.email)).to be false end diff --git a/spec/controllers/settings/exports_controller_spec.rb b/spec/controllers/settings/exports_controller_spec.rb index 6a42021318..c8c11c3be3 100644 --- a/spec/controllers/settings/exports_controller_spec.rb +++ b/spec/controllers/settings/exports_controller_spec.rb @@ -14,11 +14,8 @@ describe Settings::ExportsController do get :show end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/imports_controller_spec.rb b/spec/controllers/settings/imports_controller_spec.rb index 900d0eb90d..1e7b758931 100644 --- a/spec/controllers/settings/imports_controller_spec.rb +++ b/spec/controllers/settings/imports_controller_spec.rb @@ -19,15 +19,9 @@ RSpec.describe Settings::ImportsController do get :index end - it 'assigns the expected imports' do - expect(assigns(:recent_imports)).to eq [import] - end - - it 'returns http success' do + it 'assigns the expected imports', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do + expect(assigns(:recent_imports)).to eq [import] expect(response.headers['Cache-Control']).to include('private, no-store') end end @@ -72,17 +66,10 @@ RSpec.describe Settings::ImportsController do context 'with someone else\'s import' do let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) } - it 'does not change the import\'s state' do + it 'does not change the import\'s state and returns missing', :aggregate_failures do expect { subject }.to_not(change { bulk_import.reload.state }) - end - it 'does not fire the import worker' do - subject expect(BulkImportWorker).to_not have_received(:perform_async) - end - - it 'returns http not found' do - subject expect(response).to have_http_status(404) end end @@ -90,17 +77,10 @@ RSpec.describe Settings::ImportsController do context 'with an already-confirmed import' do let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) } - it 'does not change the import\'s state' do + it 'does not change the import\'s state and returns missing', :aggregate_failures do expect { subject }.to_not(change { bulk_import.reload.state }) - end - it 'does not fire the import worker' do - subject expect(BulkImportWorker).to_not have_received(:perform_async) - end - - it 'returns http not found' do - subject expect(response).to have_http_status(404) end end @@ -108,17 +88,10 @@ RSpec.describe Settings::ImportsController do context 'with an unconfirmed import' do let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) } - it 'changes the import\'s state to scheduled' do + it 'changes the import\'s state to scheduled and redirects', :aggregate_failures do expect { subject }.to change { bulk_import.reload.state.to_sym }.from(:unconfirmed).to(:scheduled) - end - it 'fires the import worker on the expected import' do - subject expect(BulkImportWorker).to have_received(:perform_async).with(bulk_import.id) - end - - it 'redirects to imports path' do - subject expect(response).to redirect_to(settings_imports_path) end end @@ -130,12 +103,9 @@ RSpec.describe Settings::ImportsController do context 'with someone else\'s import' do let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) } - it 'does not delete the import' do + it 'does not delete the import and returns missing', :aggregate_failures do expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) }) - end - it 'returns http not found' do - subject expect(response).to have_http_status(404) end end @@ -143,12 +113,9 @@ RSpec.describe Settings::ImportsController do context 'with an already-confirmed import' do let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) } - it 'does not delete the import' do + it 'does not delete the import and returns missing', :aggregate_failures do expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) }) - end - it 'returns http not found' do - subject expect(response).to have_http_status(404) end end @@ -156,12 +123,9 @@ RSpec.describe Settings::ImportsController do context 'with an unconfirmed import' do let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) } - it 'deletes the import' do + it 'deletes the import and redirects', :aggregate_failures do expect { subject }.to change { BulkImport.exists?(bulk_import.id) }.from(true).to(false) - end - it 'redirects to imports path' do - subject expect(response).to redirect_to(settings_imports_path) end end @@ -177,13 +141,10 @@ RSpec.describe Settings::ImportsController do bulk_import.update(total_items: bulk_import.rows.count, processed_items: bulk_import.rows.count, imported_items: 0) end - it 'returns http success' do + it 'returns expected contents', :aggregate_failures do subject - expect(response).to have_http_status(200) - end - it 'returns expected contents' do - subject + expect(response).to have_http_status(200) expect(response.body).to eq expected_contents end end @@ -283,12 +244,9 @@ RSpec.describe Settings::ImportsController do let(:import_file) { file } let(:import_mode) { mode } - it 'creates an unconfirmed bulk_import with expected type' do + it 'creates an unconfirmed bulk_import with expected type and redirects', :aggregate_failures do expect { subject }.to change { user.account.bulk_imports.pluck(:state, :type) }.from([]).to([['unconfirmed', import_type]]) - end - it 'redirects to confirmation page for the import' do - subject expect(response).to redirect_to(settings_import_path(user.account.bulk_imports.first)) end end @@ -298,12 +256,9 @@ RSpec.describe Settings::ImportsController do let(:import_file) { file } let(:import_mode) { mode } - it 'does not creates an unconfirmed bulk_import' do + it 'does not creates an unconfirmed bulk_import', :aggregate_failures do expect { subject }.to_not(change { user.account.bulk_imports.count }) - end - it 'sets error to the import' do - subject expect(assigns(:import).errors).to_not be_empty end end diff --git a/spec/controllers/settings/login_activities_controller_spec.rb b/spec/controllers/settings/login_activities_controller_spec.rb index 80c8f484cc..4f266e03dd 100644 --- a/spec/controllers/settings/login_activities_controller_spec.rb +++ b/spec/controllers/settings/login_activities_controller_spec.rb @@ -16,11 +16,8 @@ describe Settings::LoginActivitiesController do get :index end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/migration/redirects_controller_spec.rb b/spec/controllers/settings/migration/redirects_controller_spec.rb index aa6df64cff..b909a02668 100644 --- a/spec/controllers/settings/migration/redirects_controller_spec.rb +++ b/spec/controllers/settings/migration/redirects_controller_spec.rb @@ -16,11 +16,8 @@ describe Settings::Migration::RedirectsController do get :new end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/migrations_controller_spec.rb b/spec/controllers/settings/migrations_controller_spec.rb index 9b12bc40f1..f3340574d0 100644 --- a/spec/controllers/settings/migrations_controller_spec.rb +++ b/spec/controllers/settings/migrations_controller_spec.rb @@ -71,24 +71,22 @@ describe Settings::MigrationsController do context 'when acct is the current account' do let(:acct) { user.account } - it 'renders show' do - expect(subject).to render_template :show - end + it 'does not update the moved account', :aggregate_failures do + subject - it 'does not update the moved account' do expect(user.account.reload.moved_to_account_id).to be_nil + expect(response).to render_template :show end end context 'when target account does not reference the account being moved from' do let(:acct) { Fabricate(:account, also_known_as: []) } - it 'renders show' do - expect(subject).to render_template :show - end + it 'does not update the moved account', :aggregate_failures do + subject - it 'does not update the moved account' do expect(user.account.reload.moved_to_account_id).to be_nil + expect(response).to render_template :show end end @@ -100,12 +98,11 @@ describe Settings::MigrationsController do user.account.migrations.create!(acct: moved_to.acct) end - it 'renders show' do - expect(subject).to render_template :show - end + it 'does not update the moved account', :aggregate_failures do + subject - it 'does not update the moved account' do expect(user.account.reload.moved_to_account_id).to be_nil + expect(response).to render_template :show end end end diff --git a/spec/controllers/settings/preferences/appearance_controller_spec.rb b/spec/controllers/settings/preferences/appearance_controller_spec.rb index 9a98a41886..ee0ded1b91 100644 --- a/spec/controllers/settings/preferences/appearance_controller_spec.rb +++ b/spec/controllers/settings/preferences/appearance_controller_spec.rb @@ -16,11 +16,8 @@ describe Settings::Preferences::AppearanceController do get :show end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/preferences/notifications_controller_spec.rb b/spec/controllers/settings/preferences/notifications_controller_spec.rb index 6a04df9edb..b61d7461ce 100644 --- a/spec/controllers/settings/preferences/notifications_controller_spec.rb +++ b/spec/controllers/settings/preferences/notifications_controller_spec.rb @@ -16,11 +16,8 @@ describe Settings::Preferences::NotificationsController do get :show end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/preferences/other_controller_spec.rb b/spec/controllers/settings/preferences/other_controller_spec.rb index 750510b04b..61a94a4142 100644 --- a/spec/controllers/settings/preferences/other_controller_spec.rb +++ b/spec/controllers/settings/preferences/other_controller_spec.rb @@ -16,11 +16,8 @@ describe Settings::Preferences::OtherController do get :show end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/profiles_controller_spec.rb b/spec/controllers/settings/profiles_controller_spec.rb index 806fad19a8..e3197f0a6d 100644 --- a/spec/controllers/settings/profiles_controller_spec.rb +++ b/spec/controllers/settings/profiles_controller_spec.rb @@ -17,11 +17,8 @@ RSpec.describe Settings::ProfilesController do get :show end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end diff --git a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb index 2ffad13c61..719ed2f886 100644 --- a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb @@ -121,24 +121,12 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do add_webauthn_credential(user) end - it 'returns http success' do - get :options + it 'includes existing credentials in list of excluded credentials', :aggregate_failures do + expect { get :options }.to_not change(user, :webauthn_id) expect(response).to have_http_status(200) - end - - it 'stores the challenge on the session' do - get :options expect(controller.session[:webauthn_challenge]).to be_present - end - - it 'does not change webauthn_id' do - expect { get :options }.to_not change(user, :webauthn_id) - end - - it 'includes existing credentials in list of excluded credentials' do - get :options excluded_credentials_ids = response.parsed_body['excludeCredentials'].pluck('id') expect(excluded_credentials_ids).to match_array(user.webauthn_credentials.pluck(:external_id)) @@ -146,21 +134,11 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do end context 'when user does not have webauthn enabled' do - it 'returns http success' do + it 'stores the challenge on the session and sets user webauthn_id', :aggregate_failures do get :options expect(response).to have_http_status(200) - end - - it 'stores the challenge on the session' do - get :options - expect(controller.session[:webauthn_challenge]).to be_present - end - - it 'sets user webauthn_id' do - get :options - expect(user.reload.webauthn_id).to be_present end end @@ -217,28 +195,15 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do end context 'when creation succeeds' do - it 'returns http success' do - controller.session[:webauthn_challenge] = challenge - - post :create, params: { credential: new_webauthn_credential, nickname: nickname } - - expect(response).to have_http_status(200) - end - - it 'adds a new credential to user credentials' do + it 'adds a new credential to user credentials and does not change webauthn_id', :aggregate_failures do controller.session[:webauthn_challenge] = challenge expect do post :create, params: { credential: new_webauthn_credential, nickname: nickname } end.to change { user.webauthn_credentials.count }.by(1) - end + .and not_change(user, :webauthn_id) - it 'does not change webauthn_id' do - controller.session[:webauthn_challenge] = challenge - - expect do - post :create, params: { credential: new_webauthn_credential, nickname: nickname } - end.to_not change(user, :webauthn_id) + expect(response).to have_http_status(200) end end @@ -328,17 +293,13 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do end context 'when deletion succeeds' do - it 'redirects to 2FA methods list and shows flash success' do - delete :destroy, params: { id: user.webauthn_credentials.take.id } - - expect(response).to redirect_to settings_two_factor_authentication_methods_path - expect(flash[:success]).to be_present - end - - it 'deletes the credential' do + it 'redirects to 2FA methods list and shows flash success and deletes the credential', :aggregate_failures do expect do delete :destroy, params: { id: user.webauthn_credentials.take.id } end.to change { user.webauthn_credentials.count }.by(-1) + + expect(response).to redirect_to settings_two_factor_authentication_methods_path + expect(flash[:success]).to be_present end end end diff --git a/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb b/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb index 3e61912ad4..de0d28463b 100644 --- a/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb @@ -29,11 +29,8 @@ describe Settings::TwoFactorAuthenticationMethodsController do get :index end - it 'returns http success' do + it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns private cache control headers' do expect(response.headers['Cache-Control']).to include('private, no-store') end end From 0d14fcebae0b9a0e5da73049c960064338dfee8e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 13 Nov 2023 10:58:28 +0100 Subject: [PATCH 06/15] Change link previews to keep original URL from the status (#27312) --- app/chewy/public_statuses_index.rb | 2 +- app/chewy/statuses_index.rb | 2 +- .../api/v1/conversations_controller.rb | 2 +- app/models/admin/status_batch_action.rb | 2 +- app/models/concerns/status_search_concern.rb | 2 +- app/models/preview_card.rb | 7 ++++++- app/models/preview_cards_status.rb | 18 ++++++++++++++++++ app/models/status.rb | 15 ++++++++++----- app/models/trends/links.rb | 4 +--- .../rest/preview_card_serializer.rb | 4 ++++ .../process_status_update_service.rb | 2 +- app/services/fetch_link_card_service.rb | 6 +++--- app/services/update_status_service.rb | 2 +- ...183200_add_url_to_preview_cards_statuses.rb | 7 +++++++ db/schema.rb | 3 ++- lib/tasks/tests.rake | 2 +- spec/helpers/media_component_helper_spec.rb | 4 +++- spec/services/fetch_link_card_service_spec.rb | 8 ++++---- spec/services/update_status_service_spec.rb | 8 ++++---- 19 files changed, 70 insertions(+), 30 deletions(-) create mode 100644 app/models/preview_cards_status.rb create mode 100644 db/migrate/20231006183200_add_url_to_preview_cards_statuses.rb diff --git a/app/chewy/public_statuses_index.rb b/app/chewy/public_statuses_index.rb index 4be204d4a9..b5f0be5e5c 100644 --- a/app/chewy/public_statuses_index.rb +++ b/app/chewy/public_statuses_index.rb @@ -53,7 +53,7 @@ class PublicStatusesIndex < Chewy::Index index_scope ::Status.unscoped .kept .indexable - .includes(:media_attachments, :preloadable_poll, :preview_cards, :tags) + .includes(:media_attachments, :preloadable_poll, :tags, preview_cards_status: :preview_card) root date_detection: false do field(:id, type: 'long') diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index 6b25dc9dff..e315a2030f 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -50,7 +50,7 @@ class StatusesIndex < Chewy::Index }, } - index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preview_cards, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? } + index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preview_cards_status: :preview_card, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? } root date_detection: false do field(:id, type: 'long') diff --git a/app/controllers/api/v1/conversations_controller.rb b/app/controllers/api/v1/conversations_controller.rb index b3ca2f7903..6a3567e624 100644 --- a/app/controllers/api/v1/conversations_controller.rb +++ b/app/controllers/api/v1/conversations_controller.rb @@ -41,10 +41,10 @@ class Api::V1::ConversationsController < Api::BaseController account: :account_stat, last_status: [ :media_attachments, - :preview_cards, :status_stat, :tags, { + preview_cards_status: :preview_card, active_mentions: [account: :account_stat], account: :account_stat, }, diff --git a/app/models/admin/status_batch_action.rb b/app/models/admin/status_batch_action.rb index 24c3979aa2..8a8e2fa378 100644 --- a/app/models/admin/status_batch_action.rb +++ b/app/models/admin/status_batch_action.rb @@ -74,7 +74,7 @@ class Admin::StatusBatchAction # Can't use a transaction here because UpdateStatusService queues # Sidekiq jobs - statuses.includes(:media_attachments, :preview_cards).find_each do |status| + statuses.includes(:media_attachments, preview_cards_status: :preview_card).find_each do |status| next if status.discarded? || !(status.with_media? || status.with_preview_card?) authorize([:admin, status], :update?) diff --git a/app/models/concerns/status_search_concern.rb b/app/models/concerns/status_search_concern.rb index 3ef45754ab..7252fde737 100644 --- a/app/models/concerns/status_search_concern.rb +++ b/app/models/concerns/status_search_concern.rb @@ -40,7 +40,7 @@ module StatusSearchConcern properties << 'media' if with_media? properties << 'poll' if with_poll? properties << 'link' if with_preview_card? - properties << 'embed' if preview_cards.any?(&:video?) + properties << 'embed' if preview_card&.video? properties << 'sensitive' if sensitive? properties << 'reply' if reply? end diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb index a1751c426d..8375927430 100644 --- a/app/models/preview_card.rb +++ b/app/models/preview_card.rb @@ -50,7 +50,9 @@ class PreviewCard < ApplicationRecord enum type: { link: 0, photo: 1, video: 2, rich: 3 } enum link_type: { unknown: 0, article: 1 } - has_and_belongs_to_many :statuses + has_many :preview_cards_statuses, dependent: :delete_all, inverse_of: :preview_card + has_many :statuses, through: :preview_cards_statuses + has_one :trend, class_name: 'PreviewCardTrend', inverse_of: :preview_card, dependent: :destroy has_attached_file :image, processors: [:thumbnail, :blurhash_transcoder], styles: ->(f) { image_styles(f) }, convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' }, validate_media_type: false @@ -64,6 +66,9 @@ class PreviewCard < ApplicationRecord before_save :extract_dimensions, if: :link? + # This can be set by the status when retrieving the preview card using the join model + attr_accessor :original_url + def appropriate_for_trends? link? && article? && title.present? && description.present? && image.present? && provider_name.present? end diff --git a/app/models/preview_cards_status.rb b/app/models/preview_cards_status.rb new file mode 100644 index 0000000000..341771e4d3 --- /dev/null +++ b/app/models/preview_cards_status.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: preview_cards_statuses +# +# preview_card_id :bigint(8) not null +# status_id :bigint(8) not null +# url :string +# +class PreviewCardsStatus < ApplicationRecord + # Composite primary keys are not properly supported in Rails. However, + # we shouldn't need this anyway... + self.primary_key = nil + + belongs_to :preview_card + belongs_to :status +end diff --git a/app/models/status.rb b/app/models/status.rb index 1c41ef1d52..41c8950296 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -79,8 +79,8 @@ class Status < ApplicationRecord has_many :local_bookmarked, -> { merge(Account.local) }, through: :bookmarks, source: :account has_and_belongs_to_many :tags - has_and_belongs_to_many :preview_cards + has_one :preview_cards_status, inverse_of: :status # Because of a composite primary key, the dependent option cannot be used has_one :notification, as: :activity, dependent: :destroy has_one :status_stat, inverse_of: :status has_one :poll, inverse_of: :status, dependent: :destroy @@ -142,24 +142,25 @@ class Status < ApplicationRecord # The `prepend: true` option below ensures this runs before # the `dependent: destroy` callbacks remove relevant records before_destroy :unlink_from_conversations!, prepend: true + before_destroy :reset_preview_card! cache_associated :application, :media_attachments, :conversation, :status_stat, :tags, - :preview_cards, :preloadable_poll, + preview_cards_status: [:preview_card], account: [:account_stat, user: :role], active_mentions: { account: :account_stat }, reblog: [ :application, :tags, - :preview_cards, :media_attachments, :conversation, :status_stat, :preloadable_poll, + preview_cards_status: [:preview_card], account: [:account_stat, user: :role], active_mentions: { account: :account_stat }, ], @@ -226,7 +227,11 @@ class Status < ApplicationRecord end def preview_card - preview_cards.first + preview_cards_status&.preview_card&.tap { |x| x.original_url = preview_cards_status.url } + end + + def reset_preview_card! + PreviewCardsStatus.where(status_id: id).delete_all end def hidden? @@ -244,7 +249,7 @@ class Status < ApplicationRecord end def with_preview_card? - preview_cards.any? + preview_cards_status.present? end def with_poll? diff --git a/app/models/trends/links.rb b/app/models/trends/links.rb index fcbdb1a5f5..b4eae9f702 100644 --- a/app/models/trends/links.rb +++ b/app/models/trends/links.rb @@ -54,9 +54,7 @@ class Trends::Links < Trends::Base !(original_status.account.silenced? || status.account.silenced?) && !(original_status.spoiler_text? || original_status.sensitive?) - original_status.preview_cards.each do |preview_card| - add(preview_card, status.account_id, at_time) if preview_card.appropriate_for_trends? - end + add(original_status.preview_card, status.account_id, at_time) if original_status.preview_card&.appropriate_for_trends? end def add(preview_card, account_id, at_time = Time.now.utc) diff --git a/app/serializers/rest/preview_card_serializer.rb b/app/serializers/rest/preview_card_serializer.rb index 3e1c4bde3c..039262cd5f 100644 --- a/app/serializers/rest/preview_card_serializer.rb +++ b/app/serializers/rest/preview_card_serializer.rb @@ -8,6 +8,10 @@ class REST::PreviewCardSerializer < ActiveModel::Serializer :provider_url, :html, :width, :height, :image, :image_description, :embed_url, :blurhash, :published_at + def url + object.original_url.presence || object.url + end + def image object.image? ? full_asset_url(object.image.url(:original)) : nil end diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 4ff92da01f..2db0e80e7c 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -280,7 +280,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService end def reset_preview_card! - @status.preview_cards.clear + @status.reset_preview_card! LinkCrawlWorker.perform_in(rand(1..59).seconds, @status.id) end diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index 13775e63c1..c6b600dd7c 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -19,7 +19,7 @@ class FetchLinkCardService < BaseService @status = status @original_url = parse_urls - return if @original_url.nil? || @status.preview_cards.any? + return if @original_url.nil? || @status.with_preview_card? @url = @original_url.to_s @@ -62,9 +62,9 @@ class FetchLinkCardService < BaseService def attach_card with_redis_lock("attach_card:#{@status.id}") do - return if @status.preview_cards.any? + return if @status.with_preview_card? - @status.preview_cards << @card + PreviewCardsStatus.create(status: @status, preview_card: @card, url: @original_url) Rails.cache.delete(@status) Trends.links.register(@status) end diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb index d1c2b990f6..cdfe283659 100644 --- a/app/services/update_status_service.rb +++ b/app/services/update_status_service.rb @@ -123,7 +123,7 @@ class UpdateStatusService < BaseService def reset_preview_card! return unless @status.text_previously_changed? - @status.preview_cards.clear + @status.reset_preview_card! LinkCrawlWorker.perform_async(@status.id) end diff --git a/db/migrate/20231006183200_add_url_to_preview_cards_statuses.rb b/db/migrate/20231006183200_add_url_to_preview_cards_statuses.rb new file mode 100644 index 0000000000..f7c6de462e --- /dev/null +++ b/db/migrate/20231006183200_add_url_to_preview_cards_statuses.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddURLToPreviewCardsStatuses < ActiveRecord::Migration[7.0] + def change + add_column :preview_cards_statuses, :url, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 37020c2d72..a0062c8cea 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_09_07_150100) do +ActiveRecord::Schema[7.0].define(version: 2023_10_06_183200) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -811,6 +811,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do create_table "preview_cards_statuses", primary_key: ["status_id", "preview_card_id"], force: :cascade do |t| t.bigint "preview_card_id", null: false t.bigint "status_id", null: false + t.string "url" end create_table "relays", force: :cascade do |t| diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake index 7f8e72dd8f..209a73efa5 100644 --- a/lib/tasks/tests.rake +++ b/lib/tasks/tests.rake @@ -69,7 +69,7 @@ namespace :tests do exit(1) end - unless Status.find(12).preview_cards.pluck(:url) == ['https://joinmastodon.org/'] + unless PreviewCard.where(id: PreviewCardsStatus.where(status_id: 12).select(:preview_card_id)).pluck(:url) == ['https://joinmastodon.org/'] puts 'Preview cards not deduplicated as expected' exit(1) end diff --git a/spec/helpers/media_component_helper_spec.rb b/spec/helpers/media_component_helper_spec.rb index 71a9af6f3b..149f6a83ad 100644 --- a/spec/helpers/media_component_helper_spec.rb +++ b/spec/helpers/media_component_helper_spec.rb @@ -49,10 +49,12 @@ describe MediaComponentHelper do end describe 'render_card_component' do - let(:status) { Fabricate(:status, preview_cards: [Fabricate(:preview_card)]) } + let(:status) { Fabricate(:status) } let(:result) { helper.render_card_component(status) } before do + PreviewCardsStatus.create(status: status, preview_card: Fabricate(:preview_card)) + without_partial_double_verification do allow(helper).to receive(:current_account).and_return(status.account) end diff --git a/spec/services/fetch_link_card_service_spec.rb b/spec/services/fetch_link_card_service_spec.rb index f44cbb750c..d8ca310b28 100644 --- a/spec/services/fetch_link_card_service_spec.rb +++ b/spec/services/fetch_link_card_service_spec.rb @@ -120,7 +120,7 @@ RSpec.describe FetchLinkCardService, type: :service do let(:status) { Fabricate(:status, text: 'Check out http://example.com/sjis') } it 'decodes the HTML' do - expect(status.preview_cards.first.title).to eq('SJISのページ') + expect(status.preview_card.title).to eq('SJISのページ') end end @@ -128,7 +128,7 @@ RSpec.describe FetchLinkCardService, type: :service do let(:status) { Fabricate(:status, text: 'Check out http://example.com/sjis_with_wrong_charset') } it 'decodes the HTML despite the wrong charset header' do - expect(status.preview_cards.first.title).to eq('SJISのページ') + expect(status.preview_card.title).to eq('SJISのページ') end end @@ -136,7 +136,7 @@ RSpec.describe FetchLinkCardService, type: :service do let(:status) { Fabricate(:status, text: 'Check out http://example.com/koi8-r') } it 'decodes the HTML' do - expect(status.preview_cards.first.title).to eq('Московя начинаетъ только въ XVI ст. привлекать внимане иностранцевъ.') + expect(status.preview_card.title).to eq('Московя начинаетъ только въ XVI ст. привлекать внимане иностранцевъ.') end end @@ -144,7 +144,7 @@ RSpec.describe FetchLinkCardService, type: :service do let(:status) { Fabricate(:status, text: 'Check out http://example.com/windows-1251') } it 'decodes the HTML' do - expect(status.preview_cards.first.title).to eq('сэмпл текст') + expect(status.preview_card.title).to eq('сэмпл текст') end end diff --git a/spec/services/update_status_service_spec.rb b/spec/services/update_status_service_spec.rb index 9c53ebb2fd..eb38230b0a 100644 --- a/spec/services/update_status_service_spec.rb +++ b/spec/services/update_status_service_spec.rb @@ -23,11 +23,11 @@ RSpec.describe UpdateStatusService, type: :service do end context 'when text changes' do - let!(:status) { Fabricate(:status, text: 'Foo') } + let(:status) { Fabricate(:status, text: 'Foo') } let(:preview_card) { Fabricate(:preview_card) } before do - status.preview_cards << preview_card + PreviewCardsStatus.create(status: status, preview_card: preview_card) subject.call(status, status.account_id, text: 'Bar') end @@ -45,11 +45,11 @@ RSpec.describe UpdateStatusService, type: :service do end context 'when content warning changes' do - let!(:status) { Fabricate(:status, text: 'Foo', spoiler_text: '') } + let(:status) { Fabricate(:status, text: 'Foo', spoiler_text: '') } let(:preview_card) { Fabricate(:preview_card) } before do - status.preview_cards << preview_card + PreviewCardsStatus.create(status: status, preview_card: preview_card) subject.call(status, status.account_id, text: 'Foo', spoiler_text: 'Bar') end From da4f37020b6ef15235fd5bcaf3ed7cd2fd15437f Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Mon, 13 Nov 2023 13:19:41 +0100 Subject: [PATCH 07/15] Fix Jest config (#27834) --- .watchmanconfig | 3 +++ jest.config.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .watchmanconfig diff --git a/.watchmanconfig b/.watchmanconfig new file mode 100644 index 0000000000..29e4f231e9 --- /dev/null +++ b/.watchmanconfig @@ -0,0 +1,3 @@ +{ + "ignore_dirs": ["node_modules/", "public/"] +} diff --git a/jest.config.js b/jest.config.js index 83eae46cb9..b4a34a5abd 100644 --- a/jest.config.js +++ b/jest.config.js @@ -19,7 +19,7 @@ const config = { // Those packages are ESM, so we need them to be processed by Babel transformIgnorePatterns: ['/node_modules/(?!(redent|strip-indent)/)'], coverageDirectory: '/coverage', - moduleDirectories: ['/node_modules', '/app/javascript'], + moduleDirectories: ['node_modules', '/app/javascript'], moduleNameMapper: { '\\.svg$': '/app/javascript/__mocks__/svg.js', }, From 3b989e4d644d2c5e1b191e2740cd700cf9dc291d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:13:53 +0100 Subject: [PATCH 08/15] Update dependency rails to v7.1.2 (#27812) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 121 ++++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 60 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 83693812fa..84ad19b805 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,50 +39,51 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.1) - actionpack (= 7.1.1) - activesupport (= 7.1.1) + actioncable (7.1.2) + actionpack (= 7.1.2) + activesupport (= 7.1.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.1) - actionpack (= 7.1.1) - activejob (= 7.1.1) - activerecord (= 7.1.1) - activestorage (= 7.1.1) - activesupport (= 7.1.1) + 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.1.1) - actionpack (= 7.1.1) - actionview (= 7.1.1) - activejob (= 7.1.1) - activesupport (= 7.1.1) + 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.2) - actionpack (7.1.1) - actionview (= 7.1.1) - activesupport (= 7.1.1) + 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.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.1) - actionpack (= 7.1.1) - activerecord (= 7.1.1) - activestorage (= 7.1.1) - activesupport (= 7.1.1) + 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.1.1) - activesupport (= 7.1.1) + actionview (7.1.2) + activesupport (= 7.1.2) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -92,22 +93,22 @@ GEM activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (7.1.1) - activesupport (= 7.1.1) + activejob (7.1.2) + activesupport (= 7.1.2) globalid (>= 0.3.6) - activemodel (7.1.1) - activesupport (= 7.1.1) - activerecord (7.1.1) - activemodel (= 7.1.1) - activesupport (= 7.1.1) + 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.1) - actionpack (= 7.1.1) - activejob (= 7.1.1) - activerecord (= 7.1.1) - activesupport (= 7.1.1) + activestorage (7.1.2) + actionpack (= 7.1.2) + activejob (= 7.1.2) + activerecord (= 7.1.2) + activesupport (= 7.1.2) marcel (~> 1.0) - activesupport (7.1.1) + activesupport (7.1.2) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -218,7 +219,7 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - date (3.3.3) + date (3.3.4) debug_inspector (1.1.0) devise (4.9.3) bcrypt (~> 3.0) @@ -369,7 +370,7 @@ GEM terminal-table (>= 1.5.1) idn-ruby (0.1.5) io-console (0.6.0) - irb (1.8.1) + irb (1.8.3) rdoc reline (>= 0.3.8) jmespath (1.6.2) @@ -462,13 +463,13 @@ GEM uri net-http-persistent (4.0.2) connection_pool (~> 2.2) - net-imap (0.4.1) + net-imap (0.4.4) date net-protocol net-ldap (0.18.0) net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout net-smtp (0.4.0) net-protocol @@ -526,7 +527,7 @@ GEM net-smtp premailer (~> 1.7, >= 1.7.9) private_address_check (0.5.0) - psych (5.1.1) + psych (5.1.1.1) stringio public_suffix (5.0.3) puma (6.4.0) @@ -557,20 +558,20 @@ GEM rackup (1.0.0) rack (< 3) webrick - rails (7.1.1) - actioncable (= 7.1.1) - actionmailbox (= 7.1.1) - actionmailer (= 7.1.1) - actionpack (= 7.1.1) - actiontext (= 7.1.1) - actionview (= 7.1.1) - activejob (= 7.1.1) - activemodel (= 7.1.1) - activerecord (= 7.1.1) - activestorage (= 7.1.1) - activesupport (= 7.1.1) + 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.1.1) + railties (= 7.1.2) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -585,9 +586,9 @@ GEM rails-i18n (7.0.8) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.1) - actionpack (= 7.1.1) - activesupport (= 7.1.1) + railties (7.1.2) + actionpack (= 7.1.2) + activesupport (= 7.1.2) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -737,7 +738,7 @@ GEM statsd-ruby (1.5.0) stoplight (3.0.2) redlock (~> 1.0) - stringio (3.0.8) + stringio (3.0.9) strong_migrations (1.6.4) activerecord (>= 5.2) swd (1.3.0) @@ -753,7 +754,7 @@ GEM test-prof (1.2.3) thor (1.3.0) tilt (2.3.0) - timeout (0.4.0) + timeout (0.4.1) tpm-key_attestation (0.12.0) bindata (~> 2.4) openssl (> 2.0) From a7117bbef635735d4f01fc2fb6eaa085568862fa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:13:57 +0100 Subject: [PATCH 09/15] Update dependency @rails/ujs to v7.1.2 (#27811) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4c70859d08..0058a6837a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2661,9 +2661,9 @@ __metadata: linkType: hard "@rails/ujs@npm:^7.1.1": - version: 7.1.1 - resolution: "@rails/ujs@npm:7.1.1" - checksum: 79aa50400097d9254e194979cc011aaa92b456631fd0087a7bfc6b74ff47821c005b34a0fbb421361741c68133ac9bb35f1bb8f97de1c501144dad4e2c7440f3 + version: 7.1.2 + resolution: "@rails/ujs@npm:7.1.2" + checksum: 072962733c371fa0fff5e88a0aecd8e91c892f9dc2d31723b7586b45c723206d6b82ac71b0d7db26ea0a5ce60e0832430b061e4669b8f2aa813c3ea975aac98a languageName: node linkType: hard From e5a7b73ef4ca8934bb967d15d17c8ee1bd1c2cf0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:21:02 +0100 Subject: [PATCH 10/15] New Crowdin Translations (automated) (#27815) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/be.json | 1 + app/javascript/mastodon/locales/et.json | 1 + app/javascript/mastodon/locales/fa.json | 5 +- app/javascript/mastodon/locales/fi.json | 1 + app/javascript/mastodon/locales/fo.json | 1 + app/javascript/mastodon/locales/ig.json | 18 +++ app/javascript/mastodon/locales/ja.json | 4 +- app/javascript/mastodon/locales/ko.json | 1 + app/javascript/mastodon/locales/lt.json | 13 ++- app/javascript/mastodon/locales/no.json | 1 + app/javascript/mastodon/locales/pt-BR.json | 1 + app/javascript/mastodon/locales/pt-PT.json | 1 + app/javascript/mastodon/locales/vi.json | 1 + config/locales/doorkeeper.lt.yml | 128 ++++++++++++++++++++- config/locales/fa.yml | 8 +- config/locales/ig.yml | 4 + config/locales/ja.yml | 2 +- config/locales/ko.yml | 4 +- config/locales/nn.yml | 8 ++ config/locales/no.yml | 17 +++ config/locales/simple_form.he.yml | 2 +- config/locales/simple_form.no.yml | 1 + 22 files changed, 210 insertions(+), 13 deletions(-) diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index 6262d24e2c..7c2d652b61 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Вынікі пошуку", "emoji_button.symbols": "Сімвалы", "emoji_button.travel": "Падарожжы і месцы", + "empty_column.account_hides_collections": "Гэты карыстальнік вырашыў схаваць гэтую інфармацыю", "empty_column.account_suspended": "Уліковы запіс прыпынены", "empty_column.account_timeline": "Тут няма допісаў!", "empty_column.account_unavailable": "Профіль недаступны", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 0b0a8110d6..c4182a073d 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Otsitulemused", "emoji_button.symbols": "Sümbolid", "emoji_button.travel": "Reisimine & kohad", + "empty_column.account_hides_collections": "See kasutaja otsustas mitte teha seda infot saadavaks", "empty_column.account_suspended": "Konto kustutatud", "empty_column.account_timeline": "Siin postitusi ei ole!", "empty_column.account_unavailable": "Profiil pole saadaval", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index f4a2e09e73..246f218998 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "نتایج جست‌وجو", "emoji_button.symbols": "نمادها", "emoji_button.travel": "سفر و مکان", + "empty_column.account_hides_collections": "کاربر خواسته که این اطّلاعات در دسترس نباشند", "empty_column.account_suspended": "حساب معلق شد", "empty_column.account_timeline": "هیچ فرسته‌ای این‌جا نیست!", "empty_column.account_unavailable": "نمایهٔ موجود نیست", @@ -358,13 +359,13 @@ "keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده", "keyboard_shortcuts.reply": "پاسخ به فرسته", "keyboard_shortcuts.requests": "گشودن سیاههٔ درخواست‌های پی‌گیری", - "keyboard_shortcuts.search": "تمرکز روی جست‌وجو", + "keyboard_shortcuts.search": "تمرکز روی نوار جست‌وجو", "keyboard_shortcuts.spoilers": "نمایش/نهفتن زمینهٔ هشدار محتوا", "keyboard_shortcuts.start": "گشودن ستون «آغاز کنید»", "keyboard_shortcuts.toggle_hidden": "نمایش/نهفتن نوشتهٔ پشت هشدار محتوا", "keyboard_shortcuts.toggle_sensitivity": "نمایش/نهفتن رسانه", "keyboard_shortcuts.toot": "شروع یک فرستهٔ جدید", - "keyboard_shortcuts.unfocus": "برداشتن تمرکز از نوشتن/جست‌وجو", + "keyboard_shortcuts.unfocus": "برداشتن تمرکز از ناحیهٔ نوشتن یا جست‌وجو", "keyboard_shortcuts.up": "بالا بردن در سیاهه", "lightbox.close": "بستن", "lightbox.compress": "فشرده‌سازی جعبهٔ نمایش تصویر", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index cc4a9391a3..9aa2e7355f 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Hakutulokset", "emoji_button.symbols": "Symbolit", "emoji_button.travel": "Matkailu ja paikat", + "empty_column.account_hides_collections": "Käyttäjä on päättänyt olla julkaisematta näitä tietoja", "empty_column.account_suspended": "Tili jäädytetty", "empty_column.account_timeline": "Ei viestejä täällä.", "empty_column.account_unavailable": "Profiilia ei löydy", diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index d6130deb0c..42a1317db7 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Leitiúrslit", "emoji_button.symbols": "Ímyndir", "emoji_button.travel": "Ferðing og støð", + "empty_column.account_hides_collections": "Hesin brúkarin hevur valt, at hesar upplýsingarnar ikki skulu vera tøkar", "empty_column.account_suspended": "Kontan gjørd óvirkin", "empty_column.account_timeline": "Einki uppslag her!", "empty_column.account_unavailable": "Vangin er ikki tøkur", diff --git a/app/javascript/mastodon/locales/ig.json b/app/javascript/mastodon/locales/ig.json index 3eec2158b9..201bebc05f 100644 --- a/app/javascript/mastodon/locales/ig.json +++ b/app/javascript/mastodon/locales/ig.json @@ -1,8 +1,11 @@ { "account.add_or_remove_from_list": "Tinye ma ọ bụ Wepu na ndepụta", "account.badges.bot": "Bot", + "account.badges.group": "Otù", "account.cancel_follow_request": "Withdraw follow request", "account.follow": "Soro", + "account.followers": "Ndị na-eso", + "account.following": "Na-eso", "account.follows_you": "Na-eso gị", "account.mute": "Mee ogbi @{name}", "account.unfollow": "Kwụsị iso", @@ -11,16 +14,20 @@ "audio.hide": "Zoo ụda", "bundle_column_error.retry": "Nwaa ọzọ", "bundle_column_error.routing.title": "404", + "bundle_modal_error.close": "Mechie", "bundle_modal_error.retry": "Nwaa ọzọ", "column.about": "Maka", "column.blocks": "Ojiarụ egbochiri", "column.bookmarks": "Ebenrụtụakā", "column.home": "Be", + "column.lists": "Ndepụta", "column.pins": "Pinned post", + "column_header.pin": "Gbado na profaịlụ gị", "column_subheading.settings": "Mwube", "community.column_settings.media_only": "Media only", "compose.language.change": "Gbanwee asụsụ", "compose.language.search": "Chọọ asụsụ...", + "compose.published.open": "Mepe", "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.placeholder": "What is on your mind?", @@ -32,7 +39,10 @@ "confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete_list.confirm": "Hichapụ", "confirmations.domain_block.confirm": "Hide entire domain", + "confirmations.edit.confirm": "Dezie", + "confirmations.mute.confirm": "Mee ogbi", "confirmations.reply.confirm": "Zaa", + "confirmations.unfollow.confirm": "Kwụsị iso", "conversation.delete": "Hichapụ nkata", "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", @@ -76,6 +86,7 @@ "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.up": "to move up in the list", "lists.delete": "Hichapụ ndepụta", + "lists.edit": "Dezie ndepụta", "lists.subheading": "Ndepụta gị", "loading_indicator.label": "Na-adọnye...", "navigation_bar.about": "Maka", @@ -100,20 +111,27 @@ "privacy.change": "Adjust status privacy", "privacy.direct.short": "Direct", "privacy.private.short": "Followers-only", + "relative_time.full.just_now": "kịta", "relative_time.just_now": "kịta", "relative_time.today": "taa", "reply_indicator.cancel": "Kagbuo", "report.categories.other": "Ọzọ", + "report.categories.spam": "Nzipụ Ozièlètrọniìk Nkeāchọghị", + "report.mute": "Mee ogbi", "report.placeholder": "Type or paste additional comments", "report.submit": "Submit report", "report.target": "Report {target}", "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", + "report_notification.categories.other": "Ọzọ", + "search.placeholder": "Chọọ", "server_banner.active_users": "ojiarụ dị ìrè", + "server_banner.learn_more": "Mụtakwuo", "sign_in_banner.sign_in": "Sign in", "status.admin_status": "Open this status in the moderation interface", "status.bookmark": "Kee ebenrụtụakā", "status.copy": "Copy link to status", "status.delete": "Hichapụ", + "status.edit": "Dezie", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.open": "Expand this status", "status.remove_bookmark": "Wepu ebenrụtụakā", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 72a57c8e3f..4cd7228c8c 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -586,8 +586,8 @@ "search.no_recent_searches": "検索履歴はありません", "search.placeholder": "検索", "search.quick_action.account_search": "{x}に該当するプロフィール", - "search.quick_action.go_to_account": "{x}のプロフィールを見る", - "search.quick_action.go_to_hashtag": "{x}に該当するハッシュタグ", + "search.quick_action.go_to_account": "プロフィール {x} を見る", + "search.quick_action.go_to_hashtag": "ハッシュタグ {x} を見る", "search.quick_action.open_url": "MastodonでURLを開く", "search.quick_action.status_search": "{x}に該当する投稿", "search.search_or_paste": "検索またはURLを入力", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 269063b7cb..574d8e211b 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "검색 결과", "emoji_button.symbols": "기호", "emoji_button.travel": "여행과 장소", + "empty_column.account_hides_collections": "이 사용자는 이 정보를 사용할 수 없도록 설정했습니다", "empty_column.account_suspended": "계정 정지됨", "empty_column.account_timeline": "이곳에는 게시물이 없습니다!", "empty_column.account_unavailable": "프로필 사용 불가", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index a1ab531316..75f4a239e7 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -15,7 +15,7 @@ "account.add_or_remove_from_list": "Pridėti arba ištrinti iš sąrašų", "account.badges.bot": "Automatizuotas", "account.badges.group": "Grupė", - "account.block": "Užblokuoti @{name}", + "account.block": "Blokuoti @{name}", "account.block_domain": "Blokuoti domeną {domain}", "account.block_short": "Blokuoti", "account.blocked": "Užblokuota", @@ -25,11 +25,20 @@ "account.disable_notifications": "Nustoti man pranešti, kai @{name} paskelbia", "account.domain_blocked": "Užblokuotas domenas", "account.edit_profile": "Redaguoti profilį", + "account.enable_notifications": "Pranešti man, kai @{name} paskelbia", + "account.featured_tags.last_status_at": "Paskutinį kartą paskelbta {date}", + "account.featured_tags.last_status_never": "Nėra įrašų", "account.follow": "Sekti", - "account.follows_you": "Seka jus", + "account.followers": "Sekėjai", + "account.followers.empty": "Šio naudotojo dar niekas neseka.", + "account.followers_counter": "{count, plural, one {{counter} sekėjas (-a)} few {{counter} sekėjai} many {{counter} sekėjo} other {{counter} sekėjų}}", + "account.following": "Seka", + "account.follows.empty": "Šis naudotojas (-a) dar nieko neseka.", + "account.follows_you": "Seka tave", "account.go_to_profile": "Eiti į profilį", "account.in_memoriam": "Atminimui.", "account.joined_short": "Prisijungė", + "account.languages": "Keisti prenumeruojamas kalbas", "account.locked_info": "Šios paskyros privatumo būsena nustatyta kaip užrakinta. Savininkas (-ė) rankiniu būdu peržiūri, kas gali sekti.", "account.media": "Medija", "account.mute": "Užtildyti @{name}", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 449fdfb1a1..7421c780f5 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Søkeresultat", "emoji_button.symbols": "Symboler", "emoji_button.travel": "Reise & steder", + "empty_column.account_hides_collections": "Denne brukeren har valgt å ikke gjøre denne informasjonen tilgjengelig", "empty_column.account_suspended": "Kontoen er suspendert", "empty_column.account_timeline": "Ingen innlegg her!", "empty_column.account_unavailable": "Profilen er utilgjengelig", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index dfb464dbb5..9c09e2d719 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Resultado da pesquisa", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viagem e Lugares", + "empty_column.account_hides_collections": "A pessoa optou por não disponibilizar esta informação", "empty_column.account_suspended": "Conta suspensa", "empty_column.account_timeline": "Nada aqui.", "empty_column.account_unavailable": "Perfil indisponível", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index f33dd2fb80..988bec9b03 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Resultados da pesquisa", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viagens & Lugares", + "empty_column.account_hides_collections": "Este utilizador escolheu não disponibilizar esta informação", "empty_column.account_suspended": "Conta suspensa", "empty_column.account_timeline": "Sem publicações por aqui!", "empty_column.account_unavailable": "Perfil indisponível", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 3a7e75b912..aa229eceb8 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -222,6 +222,7 @@ "emoji_button.search_results": "Kết quả tìm kiếm", "emoji_button.symbols": "Biểu tượng", "emoji_button.travel": "Du lịch", + "empty_column.account_hides_collections": "Người này đã chọn ẩn thông tin", "empty_column.account_suspended": "Tài khoản vô hiệu hóa", "empty_column.account_timeline": "Chưa có tút nào!", "empty_column.account_unavailable": "Tài khoản bị đình chỉ", diff --git a/config/locales/doorkeeper.lt.yml b/config/locales/doorkeeper.lt.yml index 36f31e39ea..1012160f62 100644 --- a/config/locales/doorkeeper.lt.yml +++ b/config/locales/doorkeeper.lt.yml @@ -1,18 +1,143 @@ --- lt: + activerecord: + attributes: + doorkeeper/application: + name: Programėlės pavadinimas + redirect_uri: Peradresavimo URI + scopes: Aprėptys + website: Programėlės svetainė + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: negali turėti fragmento. + invalid_uri: turi būti tinkamas URI. + relative_uri: turi būti absoliutus URI. + secured_uri: turi būti HTTPS/SSL URI. doorkeeper: + applications: + buttons: + authorize: Įgalinti + cancel: Atšaukti + destroy: Sunaikinti + edit: Redaguoti + submit: Pateikti + confirmations: + destroy: Ar esi įsitikinęs (-usi)? + edit: + title: Redaguoti programėlę + form: + error: Ups! Patikrink, ar formoje nėra galimų klaidų. + help: + native_redirect_uri: Naudoti %{native_redirect_uri} vietiniams bandymams + redirect_uri: Naudoti po vieną eilutę kiekvienam URI + scopes: Atskirk aprėptis tarpais. Palik tuščią, jei nori naudoti numatytąsias aprėtis. + index: + application: Programėlė + callback_url: Atgalinis URL + delete: Ištrinti + empty: Neturi jokių programėlių. + name: Pavadinimas + new: Nauja programėlė + scopes: Aprėptys + show: Rodyti + title: Tavo programėlės + new: + title: Nauja programėlė + show: + actions: Veiksmai + application_id: Kliento raktas + callback_urls: Atgalinių URL adresų + scopes: Aprėptys + secret: Kliento paslaptis + title: 'Programėlė: %{name}' authorizations: + buttons: + authorize: Įgalinti + deny: Atmesti error: title: Įvyko klaida. new: prompt_html: "%{client_name} norėtų gauti leidimą prieigos prie tavo paskyros. Tai trečiosios šalies programėlė. Jei ja nepasitiki, neturėtum jai leisti." + review_permissions: Peržiūrėti leidimus + title: Reikalingas įgaliojimas + show: + title: Nukopijuok šį įgaliojimo kodą ir įklijuok jį į programėlę. authorized_applications: + buttons: + revoke: Naikinti + confirmations: + revoke: Ar esi įsitikinęs (-usi)? index: - title: Tavo leidžiamos programėlės + authorized_at: Įgaliota %{date} + description_html: Tai programėlės, kurios gali pasiekti tavo paskyrą naudojant API. Jei čia yra programėlių, kurių neatpažįsti, arba jei programėlė elgiasi netinkamai, gali panaikinti jos prieigą. + last_used_at: Paskutinį kartą naudota %{date} + never_used: Niekada nenaudotas + scopes: Leidimai + superapp: Vidinis + title: Tavo įgaliotos programėlės + errors: + messages: + access_denied: Išteklių savininkas (-ė) arba įgaliojimų serveris atmetė užklausą. + credential_flow_not_configured: Išteklių savininko slaptažodžio kredencialų srautas nepavyko, nes Doorkeeper.configure.resource_owner_from_credentials nėra nesukonfigūruotas. + invalid_client: Kliento tapatybės nustatymas nepavyko dėl nežinomo kliento, neįtraukto kliento tapatybės nustatymo arba nepalaikomo tapatybės nustatymo metodo. + invalid_grant: Pateiktas įgaliojimas yra netinkamas, pasibaigęs, panaikintas, neatitinka įgaliojimo užklausoje naudoto nukreipimo URI arba buvo išduotas kitam klientui. + invalid_redirect_uri: Nukreipimo uri įtrauktas yra netinkamas. + invalid_request: + missing_param: 'Trūksta privalomo parametro: %{value}.' + request_not_authorized: Užklausą reikia įgalioti. Reikalingo parametro užklausai įgalioti trūksta arba jis netinkamas. + unknown: Užklausoje trūksta privalomo parametro, turi nepalaikomą parametro reikšmę arba yra kitaip netinkamai suformuota. + invalid_resource_owner: Pateikti išteklių savininko įgaliojimai yra netinkami arba išteklių savininko negalima surasti. + invalid_scope: Užklausos aprėptis yra netinkama, nežinoma arba netinkamai suformuota. + invalid_token: + expired: Baigėsi prieigos rakto galiojimas. + revoked: Prieigos raktas buvo panaikintas. + unknown: Prieigos raktas yra netinkamas. + resource_owner_authenticator_not_configured: Išteklių savininko suradimas nepavyko dėl to, kad Doorkeeper.configure.resource_owner_authenticator nėra sukonfigūruotas. + server_error: Įgaliojimų serveris susidūrė su netikėta sąlyga, dėl kurios negalėjo užpildyti užklausos. + temporarily_unavailable: Įgaliojimų serveris šiuo metu negali apdoroti užklausos dėl laikinos serverio perkrovos arba techninės priežiūros. + unauthorized_client: Klientas nėra įgaliotas atlikti šią užklausą šiuo metodu. + unsupported_grant_type: Įgaliojimų suteikimo tipas nepalaikomas įgaliojimų serveryje. + unsupported_response_type: Įgaliojimų serveris nepalaiko šio atsako tipo. + flash: + applications: + create: + notice: Programėlė sukurta. + destroy: + notice: Programėlė ištrinta. + update: + notice: Programėlė atnaujinta. + authorized_applications: + destroy: + notice: Programėlė panaikinta. grouped_scopes: + access: + read: Tik skaitymo prieiga + read/write: Skaitymo ir rašymo prieiga + write: Tik rašymo prieiga title: + accounts: Paskyros + admin/accounts: Paskyrų administravimas + admin/all: Visi administraciniai funkcijos + admin/reports: Ataskaitų administravimas + all: Pilna prieiga prie tavo Mastodon paskyros blocks: Blokavimai + bookmarks: Žymės + conversations: Pokalbiai + crypto: Galo iki galo užšifravimas + favourites: Mėgstami + filters: Filtrai follow: Sekimai, nutildymai ir blokavimai + follows: Sekimai + lists: Sąrašai + media: Medijos priedai + mutes: Užtildymai + notifications: Pranešimai + push: Stumdomieji pranešimai + reports: Ataskaitos + search: Paieška statuses: Įrašai layouts: admin: @@ -37,6 +162,7 @@ lt: admin:write:domain_blocks: atlikti prižiūrėjimo veiksmus su domenų blokavimais admin:write:email_domain_blocks: atlikti prižiūrėjimo veiksmus su el. laiško domenų blokavimais admin:write:ip_blocks: atlikti prižiūrėjimo veiksmus su IP blokavimais + admin:write:reports: atlikti paskyrų prižiūrėjimo veiksmus atsakaitams crypto: naudoti galo iki galo šifravimą follow: modifikuoti paskyros santykius push: gauti tavo stumiamuosius pranešimus diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 8e076878a0..8569d2e371 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -131,7 +131,7 @@ fa: reset_password: بازنشانی گذرواژه resubscribe: اشتراک دوباره role: نقش - search: جستجو + search: جست‌وجو search_same_email_domain: دیگر کاربران با دامنهٔ رایانامهٔ یکسان search_same_ip: دیگر کاربران با IP یکسان security: امنیت @@ -386,6 +386,10 @@ fa: confirm_suspension: cancel: لغو confirm: تعلیق + permanent_action: برگرداندن تعلیق هیچ داده یا ارتباطی را برنخواهد گرداند. + preamble_html: در حال تعلیق %{domain} و همهٔ زیردامنه‌هایش هستید. + remove_all_data: این کار همهٔ داده‌های نمایه، محتوا و رسانه‌های حساب‌های این دامنه را از کارسازتان برمی‌دارد. + stop_communication: کارسازتان دیگر با این کارسازها ارتباط برقرار نخواهد کرد. title: تأیید انسداد دامنه برای %{domain} created_msg: مسدودسازی دامنه در حال پردازش است destroyed_msg: انسداد دامنه واگردانده شد @@ -1219,7 +1223,7 @@ fa: followers: این کار همهٔ پیگیران شما را از حساب فعلی به حساب تازه منتقل خواهد کرد only_redirect_html: شما همچنین می‌توانید حساب خود را به یک حساب دیگر اشاره دهید. other_data: هیچ دادهٔ دیگری خودبه‌خود منتقل نخواهد شد - redirect: نمایهٔ حساب فعلی شما به حساب تازه اشاره خواهد کرد و خودش در نتیجهٔ جستجوها ظاهر نخواهد شد + redirect: نمایهٔ حساب کنونیتان به حساب تازه اشاره خواهد کرد و از جست‌وجوها حذف خواهد شد moderation: title: مدیریت کاربران move_handler: diff --git a/config/locales/ig.yml b/config/locales/ig.yml index 7c264f0d73..9db771fdcf 100644 --- a/config/locales/ig.yml +++ b/config/locales/ig.yml @@ -1 +1,5 @@ +--- ig: + filters: + contexts: + home: Ụlọ na ndepụta diff --git a/config/locales/ja.yml b/config/locales/ja.yml index ca438f53d2..3318b690a0 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1023,7 +1023,7 @@ ja: hint_html: もう一つだけ!あなたが人間であることを確認する必要があります(スパムを防ぐためです!)。 以下のCAPTCHAを解き、「続ける」をクリックします。 title: セキュリティチェック confirmations: - awaiting_review: メールアドレスは確認済みです。%{domain} のモデレーターによりアカウント登録の審査が完了すると、メールでお知らせします。 + awaiting_review: メールアドレスが確認できました。%{domain} のスタッフが登録審査を行います。承認されたらメールでお知らせします! awaiting_review_title: 登録の審査待ちです clicking_this_link: このリンクを押す login_link: ログイン diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 530cf6a447..72eafc8fb8 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1689,8 +1689,8 @@ ko: keep_polls_hint: 설문을 삭제하지 않았음 keep_self_bookmark: 북마크한 게시물 유지 keep_self_bookmark_hint: 북마크한 본인의 게시물을 삭제하지 않습니다 - keep_self_fav: 마음에 들어한 게시물 유지 - keep_self_fav_hint: 내 스스로 마음에 들어한 본인의 게시물을 삭제하지 않습니다 + keep_self_fav: 내가 좋아요한 게시물 유지 + keep_self_fav_hint: 스스로 좋아요를 누른 본인의 게시물을 삭제하지 않습니다 min_age: '1209600': 2 주 '15778476': 6 개월 diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 551824e800..acd6b206e7 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -1041,6 +1041,14 @@ nn: hint_html: Berre ein ting til! Vi må bekrefte at du er et menneske (så vi kan halde spam ute!). Løys CAPTCHA-en nedanfor og klikk "Fortsett". title: Sikkerheitssjekk confirmations: + awaiting_review: Din e-post adresse er bekreftet! %{domain} ansatte gjennomgår nå registreringen din. Du vil motta en e-post hvis de godkjenner din konto! + awaiting_review_title: Din registrering blir vurdert + clicking_this_link: klikke på denne lenken + login_link: logg inn + proceed_to_login_html: Du kan nå fortsette til %{login_link}. + redirect_to_app_html: Du burde bli omdirigert til %{app_name} -appen. Hvis det ikke skjedde, kan du prøve %{clicking_this_link} eller manuelt gå tilbake til appen. + registration_complete: Registreringen på %{domain} er nå fullført! + welcome_title: Velkommen, %{name}! wrong_email_hint: Viss epostadressa er feil, kan du endra ho i kontoinnstillingane. delete_account: Slett konto delete_account_html: Om du vil sletta kontoen din, kan du gå hit. Du vert spurd etter stadfesting. diff --git a/config/locales/no.yml b/config/locales/no.yml index 1abfbdb97d..75085fa5ab 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -772,6 +772,11 @@ approved: Godkjenning kreves for påmelding none: Ingen kan melde seg inn open: Hvem som helst kan melde seg inn + security: + authorized_fetch: Krev autentisering fra fødererte servere + authorized_fetch_hint: Krav om godkjenning fra fødererte servere muliggjør strengere håndhevelse av blokker på både brukernivå og servernivå. Dette går imidlertid på bekostning av en ytelsesstraff, reduserer rekkevidden til svarene dine og kan introdusere kompatibilitetsproblemer med enkelte fødererte tjenester. I tillegg vil dette ikke hindre dedikerte aktører i å hente dine offentlige innlegg og kontoer. + authorized_fetch_overridden_hint: Du kan for øyeblikket ikke endre denne innstillingen fordi den overstyres av en miljøvariabel. + federation_authentication: Håndheving av føderasjonsautentisering title: Serverinnstillinger site_uploads: delete: Slett den opplastede filen @@ -1036,6 +1041,14 @@ hint_html: Bare en ting til! Vi må bekrefte at du er et menneske (dette er slik at vi kan holde spam ute!). Løs CAPTCHA nedenfor og klikk "Fortsett". title: Sikkerhetskontroll confirmations: + awaiting_review: Din e-post adresse er bekreftet! %{domain} ansatte gjennomgår nå registreringen din. Du vil motta en e-post hvis de godkjenner din konto! + awaiting_review_title: Din registrering blir vurdert + clicking_this_link: klikke på denne lenken + login_link: logg inn + proceed_to_login_html: Du kan nå fortsette til %{login_link}. + redirect_to_app_html: Du burde bli omdirigert til %{app_name} -appen. Hvis det ikke skjedde, kan du prøve %{clicking_this_link} eller manuelt gå tilbake til appen. + registration_complete: Registreringen på %{domain} er nå fullført! + welcome_title: Velkommen, %{name}! wrong_email_hint: Hvis e-postadressen ikke er riktig, kan du endre den i kontoinnstillingene. delete_account: Slett konto delete_account_html: Hvis du ønsker å slette kontoen din, kan du gå hit. Du vil bli spurt om bekreftelse. @@ -1739,6 +1752,10 @@ month: "%b %Y" time: "%H:%M" with_time_zone: "%-d. %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Den serveromfattende brukskvoten for oversettelsestjenesten er overskredet. + too_many_requests: Det har nylig vært for mange forespørsler til oversettelsestjenesten. two_factor_authentication: add: Legg til disable: Skru av diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index 581a66807f..13ea8a0c4f 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -5,7 +5,7 @@ he: account: discoverable: הפוסטים והפרופיל שלך עשויים להיות מוצגים או מומלצים באזורים שונים באתר וייתכן שהפרופיל שלך יוצע למשתמשים אחרים. display_name: שמך המלא או שם הכיף שלך. - fields: עמוד הבית שלך, כינויי גוף, גיל, וכל מידע אחר לפי העדפתך האישית. + fields: עמוד הבית שלך, לשון הפנייה, גיל, וכל מידע אחר לפי העדפתך האישית. indexable: ההודעות הפומביות שלך עשויות להופיע בתוצאות חיפוש במסטודון. אחרים שהדהדו, חיבבו או ענו להודעות האלו יוכלו למצוא אותן בחיפוש בכל מקרה. note: 'ניתן לאזכר @אחרים או #תגיות.' show_collections: אנשים יוכלו לדפדף בין העוקבים והנעקבים שלך. אנשים שאת.ה עוקב.ת אחריהם יראו את המעקב אחריהם כרגיל. diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml index a9d5465f36..ca2020e21e 100644 --- a/config/locales/simple_form.no.yml +++ b/config/locales/simple_form.no.yml @@ -323,6 +323,7 @@ url: Endepunkt lenke 'no': Nei not_recommended: Ikke anbefalt + overridden: Overstyrt recommended: Anbefalt required: mark: "*" From 5bca5c4c5b036c922144e713e776727cd06615bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:24:14 +0100 Subject: [PATCH 11/15] Update formatjs monorepo (#27823) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 142 +++++++++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0058a6837a..c1e9ec9a46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1800,13 +1800,13 @@ __metadata: languageName: node linkType: hard -"@formatjs/ecma402-abstract@npm:1.17.3": - version: 1.17.3 - resolution: "@formatjs/ecma402-abstract@npm:1.17.3" +"@formatjs/ecma402-abstract@npm:1.17.4": + version: 1.17.4 + resolution: "@formatjs/ecma402-abstract@npm:1.17.4" dependencies: - "@formatjs/intl-localematcher": "npm:0.5.0" + "@formatjs/intl-localematcher": "npm:0.5.1" tslib: "npm:^2.4.0" - checksum: 00eb87301272d22dcdb0f2de74df22fa96c0062a9c1b1d718da5b8d8a4d9841aa59f909da624bd7f99db97d19c8a0338e511ad57a01d6fcfc02e67c6627035ce + checksum: c24bf58cd3152ad64a29dfab185d1fde91e44423aabb041f332216b37a23256618efee1e252c0015e735bc688708ee279348e2a4a67a77f6cf918028848ef071 languageName: node linkType: hard @@ -1830,14 +1830,14 @@ __metadata: languageName: node linkType: hard -"@formatjs/icu-messageformat-parser@npm:2.7.1": - version: 2.7.1 - resolution: "@formatjs/icu-messageformat-parser@npm:2.7.1" +"@formatjs/icu-messageformat-parser@npm:2.7.2": + version: 2.7.2 + resolution: "@formatjs/icu-messageformat-parser@npm:2.7.2" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" - "@formatjs/icu-skeleton-parser": "npm:1.6.3" + "@formatjs/ecma402-abstract": "npm:1.17.4" + "@formatjs/icu-skeleton-parser": "npm:1.6.4" tslib: "npm:^2.4.0" - checksum: 4bfc01538ef385e8bcc7c86f08b20ab87ce22c355cf3ea322c8f8d941260e00484f10aa43266f5eea096879f782fa6cdb8fe649dcb13d2745868beea36316ecb + checksum: c7a2f7daecec9ba36acda2c5b7ef21f515883b886d4d9965d83c93bc55fc604f56c1097d4641608633c32917aaa0b9b0c65c0d162723428249dc29271270a064 languageName: node linkType: hard @@ -1851,35 +1851,35 @@ __metadata: languageName: node linkType: hard -"@formatjs/icu-skeleton-parser@npm:1.6.3": - version: 1.6.3 - resolution: "@formatjs/icu-skeleton-parser@npm:1.6.3" +"@formatjs/icu-skeleton-parser@npm:1.6.4": + version: 1.6.4 + resolution: "@formatjs/icu-skeleton-parser@npm:1.6.4" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" + "@formatjs/ecma402-abstract": "npm:1.17.4" tslib: "npm:^2.4.0" - checksum: 97a05fef16c93d9d663c5d7dadf9dcc72217d7a8afedda3a441ceedf085d45e500022dd67d3c578a1a508dd334538e4eca07129a9994c39c0c36e205e567c04b + checksum: 3688aad6d12fe677ef0ce3d6a3424c5bde9ed223dc49841de8dd33c547bdd2858f8bce4437fcc135048b4f92385374776ab48e39b3cc5063a45bdb1ce85ad2d4 languageName: node linkType: hard -"@formatjs/intl-displaynames@npm:6.6.2": - version: 6.6.2 - resolution: "@formatjs/intl-displaynames@npm:6.6.2" +"@formatjs/intl-displaynames@npm:6.6.3": + version: 6.6.3 + resolution: "@formatjs/intl-displaynames@npm:6.6.3" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" - "@formatjs/intl-localematcher": "npm:0.5.0" + "@formatjs/ecma402-abstract": "npm:1.17.4" + "@formatjs/intl-localematcher": "npm:0.5.1" tslib: "npm:^2.4.0" - checksum: e0dbf749b19b93e009d487e70f4926bac4f94b0a4e60b435d4f925f686a54a869fd871902f6af322843437b8f80725981136be20cfb145c7d7c3b9826bfc43e3 + checksum: b0520cb744a51290fbcde80860f39ed9c9df9b81beae98986e1fc089ef635f7699c750631fa42a559f3678d1dd02b14904614e70360477d18e68d3eba6592390 languageName: node linkType: hard -"@formatjs/intl-listformat@npm:7.5.1": - version: 7.5.1 - resolution: "@formatjs/intl-listformat@npm:7.5.1" +"@formatjs/intl-listformat@npm:7.5.2": + version: 7.5.2 + resolution: "@formatjs/intl-listformat@npm:7.5.2" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" - "@formatjs/intl-localematcher": "npm:0.5.0" + "@formatjs/ecma402-abstract": "npm:1.17.4" + "@formatjs/intl-localematcher": "npm:0.5.1" tslib: "npm:^2.4.0" - checksum: bb972ad9078db197699452a2958dea74cfd62fcea84015a8786ac8e399738c9fe08c3c71dd1ea34ff46f24783daa20d26d5af4b5d1df5ee0ca9af7530788d2a5 + checksum: 54fa03da4ea45504681d6d87d72d1cac574809ce43f965fa4b845e83be3072d92324c58cec57ad386827087fb1d6ecae438d29576f30176bf52eb212e454bce2 languageName: node linkType: hard @@ -1892,43 +1892,43 @@ __metadata: languageName: node linkType: hard -"@formatjs/intl-localematcher@npm:0.5.0": - version: 0.5.0 - resolution: "@formatjs/intl-localematcher@npm:0.5.0" +"@formatjs/intl-localematcher@npm:0.5.1": + version: 0.5.1 + resolution: "@formatjs/intl-localematcher@npm:0.5.1" dependencies: tslib: "npm:^2.4.0" - checksum: adc82cad4c37dfff2ba1d00216e2056ce4c91b85fd39c60474849ccd74ec1262a8203d460d0ee863b71eb399297c3e087f5ccbbf3a874d682b021e6e3fd2c943 + checksum: 2282db3e623d3f65681b6a2a2dbffc4f948b8411789f51af1b221610105f809ebec7f58f9afd5008e72c62ed5524c8c321f85c78cab0cffb632e20c0064b701b languageName: node linkType: hard "@formatjs/intl-pluralrules@npm:^5.2.2": - version: 5.2.8 - resolution: "@formatjs/intl-pluralrules@npm:5.2.8" + version: 5.2.9 + resolution: "@formatjs/intl-pluralrules@npm:5.2.9" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" - "@formatjs/intl-localematcher": "npm:0.5.0" + "@formatjs/ecma402-abstract": "npm:1.17.4" + "@formatjs/intl-localematcher": "npm:0.5.1" tslib: "npm:^2.4.0" - checksum: cc5826774829a9c424b05010c398192aef93d89cca0144ebdc91df29032b808b235e7dde8def27887c5cddb695affd518993d728a908911897599d67d10e1954 + checksum: a6ca5c498ce542facacf8ce8640d4ba068f9119b758547a23614b50611eb385a46abd386ff88fa423211355ec463cf102c2c908b74f6e23a5bc9e2a23873dc29 languageName: node linkType: hard -"@formatjs/intl@npm:2.9.6": - version: 2.9.6 - resolution: "@formatjs/intl@npm:2.9.6" +"@formatjs/intl@npm:2.9.8": + version: 2.9.8 + resolution: "@formatjs/intl@npm:2.9.8" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" + "@formatjs/ecma402-abstract": "npm:1.17.4" "@formatjs/fast-memoize": "npm:2.2.0" - "@formatjs/icu-messageformat-parser": "npm:2.7.1" - "@formatjs/intl-displaynames": "npm:6.6.2" - "@formatjs/intl-listformat": "npm:7.5.1" - intl-messageformat: "npm:10.5.5" + "@formatjs/icu-messageformat-parser": "npm:2.7.2" + "@formatjs/intl-displaynames": "npm:6.6.3" + "@formatjs/intl-listformat": "npm:7.5.2" + intl-messageformat: "npm:10.5.7" tslib: "npm:^2.4.0" peerDependencies: typescript: 5 peerDependenciesMeta: typescript: optional: true - checksum: 6dadbf3dfcd1534735899fb5eed3e340a547d92ca4b0c33857e7ec3a19bddbf7787d0ab2aa014f3c2d7288e81d0ed1cb3308b0ede8299fda6d12b0bd6b1ad89d + checksum: 6341f4bfb56a0e14373395b1232e1eeb8e64588a8c3d4614cd2b06f71d4e65dbd4a79e3a1c07e1b6c20c48e399ac2385977b01a559e1d2bd1a1d226e0eae3058 languageName: node linkType: hard @@ -1952,11 +1952,11 @@ __metadata: languageName: node linkType: hard -"@formatjs/ts-transformer@npm:3.13.7": - version: 3.13.7 - resolution: "@formatjs/ts-transformer@npm:3.13.7" +"@formatjs/ts-transformer@npm:3.13.8": + version: 3.13.8 + resolution: "@formatjs/ts-transformer@npm:3.13.8" dependencies: - "@formatjs/icu-messageformat-parser": "npm:2.7.1" + "@formatjs/icu-messageformat-parser": "npm:2.7.2" "@types/json-stable-stringify": "npm:^1.0.32" "@types/node": "npm:14 || 16 || 17" chalk: "npm:^4.0.0" @@ -1968,7 +1968,7 @@ __metadata: peerDependenciesMeta: ts-jest: optional: true - checksum: 1ce528a01fa831a4a07890ae6c447c1b1cb63870c98b5f5dfbbd9f69c7e42dcd3cfd58d2717cc7214b41ddb4c3949f69525e52b6f6001d1b494573036d1478c8 + checksum: 32b13b75732739ca016d9d654e5f40077cafa3ff2f924fbb5fd91155cd6af3292c5fee9be022bb224fb69d2ab60ed9cdda49ee83fbf9e1e8de470ee33ceae4f3 languageName: node linkType: hard @@ -4735,21 +4735,21 @@ __metadata: linkType: hard "babel-plugin-formatjs@npm:^10.5.1": - version: 10.5.8 - resolution: "babel-plugin-formatjs@npm:10.5.8" + version: 10.5.9 + resolution: "babel-plugin-formatjs@npm:10.5.9" dependencies: "@babel/core": "npm:^7.10.4" "@babel/helper-plugin-utils": "npm:^7.10.4" "@babel/plugin-syntax-jsx": "npm:7" "@babel/traverse": "npm:7" "@babel/types": "npm:^7.12.11" - "@formatjs/icu-messageformat-parser": "npm:2.7.1" - "@formatjs/ts-transformer": "npm:3.13.7" + "@formatjs/icu-messageformat-parser": "npm:2.7.2" + "@formatjs/ts-transformer": "npm:3.13.8" "@types/babel__core": "npm:^7.1.7" "@types/babel__helper-plugin-utils": "npm:^7.10.0" "@types/babel__traverse": "npm:^7.1.7" tslib: "npm:^2.4.0" - checksum: 837f031e46a771ac6874b7dbe852ebb0919da81af97d2a6d38e47cc798502ee0e02ce247c6f0d0665108aa336ef3b15b321070d444b6d6994499b931ab178537 + checksum: 5e4127cf7b4b9b3306a9d0ab5b029831712d22db5e2117225ce706b55d222d09a7eba1f3720fdad7a99f61843b5cba107296fc11ae00a6f0941217d9322aa02e languageName: node linkType: hard @@ -9276,15 +9276,15 @@ __metadata: languageName: node linkType: hard -"intl-messageformat@npm:10.5.5, intl-messageformat@npm:^10.3.5": - version: 10.5.5 - resolution: "intl-messageformat@npm:10.5.5" +"intl-messageformat@npm:10.5.7, intl-messageformat@npm:^10.3.5": + version: 10.5.7 + resolution: "intl-messageformat@npm:10.5.7" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" + "@formatjs/ecma402-abstract": "npm:1.17.4" "@formatjs/fast-memoize": "npm:2.2.0" - "@formatjs/icu-messageformat-parser": "npm:2.7.1" + "@formatjs/icu-messageformat-parser": "npm:2.7.2" tslib: "npm:^2.4.0" - checksum: 223f48d719585b572f07012e2432c742e0acc371950c01a6fc9d7cb3e022d8486593ab8b7ed50849444035cdce119484e49f7c32b3646a8601a4d8f312395cf2 + checksum: 7f341b3eb5b3d402167c99ca7fb98720c7ad553bed8a490b2210bd90ea9009a09f9030939307fecb111fce1454f31b4298b4f0a346999af627c86f8164a5c547 languageName: node linkType: hard @@ -13663,18 +13663,18 @@ __metadata: linkType: hard "react-intl@npm:^6.4.2": - version: 6.5.2 - resolution: "react-intl@npm:6.5.2" + version: 6.5.4 + resolution: "react-intl@npm:6.5.4" dependencies: - "@formatjs/ecma402-abstract": "npm:1.17.3" - "@formatjs/icu-messageformat-parser": "npm:2.7.1" - "@formatjs/intl": "npm:2.9.6" - "@formatjs/intl-displaynames": "npm:6.6.2" - "@formatjs/intl-listformat": "npm:7.5.1" + "@formatjs/ecma402-abstract": "npm:1.17.4" + "@formatjs/icu-messageformat-parser": "npm:2.7.2" + "@formatjs/intl": "npm:2.9.8" + "@formatjs/intl-displaynames": "npm:6.6.3" + "@formatjs/intl-listformat": "npm:7.5.2" "@types/hoist-non-react-statics": "npm:^3.3.1" "@types/react": "npm:16 || 17 || 18" hoist-non-react-statics: "npm:^3.3.2" - intl-messageformat: "npm:10.5.5" + intl-messageformat: "npm:10.5.7" tslib: "npm:^2.4.0" peerDependencies: react: ^16.6.0 || 17 || 18 @@ -13682,7 +13682,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 8c2cbad85c4fc3647f9498a5dab13c11490a77936dcf14cb769b5659b361e7070c7528bf0d8708eec06a6dbca93b34cccf5cc919005d33c645739865cfccb878 + checksum: 1117a7f866b103abf88a4087f5fe8b854d9c069c69444c592f8431e7d28c9b90423f7b50e550be0f2f173b7563e943bcc9238e80f6747181f81861275f6e2ce7 languageName: node linkType: hard From 07a4059901e8723cd3d986a0aefb216faa42b5fe Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Nov 2023 14:27:00 +0100 Subject: [PATCH 12/15] Add support for invite codes in the registration API (#27805) --- app/controllers/api/v1/accounts_controller.rb | 18 ++-- app/controllers/api/v1/invites_controller.rb | 30 ++++++ .../auth/registrations_controller.rb | 15 +-- app/helpers/registration_helper.rb | 21 +++++ app/services/app_sign_up_service.rb | 30 ++---- config/locales/en.yml | 1 + config/routes.rb | 2 + spec/requests/invite_spec.rb | 27 ++++++ spec/services/app_sign_up_service_spec.rb | 92 ++++++++++++------- 9 files changed, 158 insertions(+), 78 deletions(-) create mode 100644 app/controllers/api/v1/invites_controller.rb create mode 100644 app/helpers/registration_helper.rb create mode 100644 spec/requests/invite_spec.rb diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index ddb94d5ca4..653529316f 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Api::V1::AccountsController < Api::BaseController + include RegistrationHelper + before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :remove_from_followers, :block, :unblock, :mute, :unmute] before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, only: [:follow, :unfollow, :remove_from_followers] before_action -> { doorkeeper_authorize! :follow, :write, :'write:mutes' }, only: [:mute, :unmute] @@ -90,18 +92,14 @@ class Api::V1::AccountsController < Api::BaseController end def account_params - params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone) + params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code) + end + + def invite + Invite.find_by(code: params[:invite_code]) if params[:invite_code].present? end def check_enabled_registrations - forbidden if single_user_mode? || omniauth_only? || !allowed_registrations? - end - - def allowed_registrations? - Setting.registrations_mode != 'none' - end - - def omniauth_only? - ENV['OMNIAUTH_ONLY'] == 'true' + forbidden unless allowed_registration?(request.remote_ip, invite) end end diff --git a/app/controllers/api/v1/invites_controller.rb b/app/controllers/api/v1/invites_controller.rb new file mode 100644 index 0000000000..ea17ba7403 --- /dev/null +++ b/app/controllers/api/v1/invites_controller.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class Api::V1::InvitesController < Api::BaseController + include RegistrationHelper + + skip_before_action :require_authenticated_user! + skip_around_action :set_locale + + before_action :set_invite + before_action :check_enabled_registrations! + + # Override `current_user` to avoid reading session cookies + def current_user; end + + def show + render json: { invite_code: params[:invite_code], instance_api_url: api_v2_instance_url }, status: 200 + end + + private + + def set_invite + @invite = Invite.find_by!(code: params[:invite_code]) + end + + def check_enabled_registrations! + return render json: { error: I18n.t('invites.invalid') }, status: 401 unless @invite.valid_for_use? + + raise Mastodon::NotPermittedError unless allowed_registration?(request.remote_ip, @invite) + end +end diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 331484f36d..8be7c5f192 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class Auth::RegistrationsController < Devise::RegistrationsController + include RegistrationHelper include RegistrationSpamConcern layout :determine_layout @@ -82,19 +83,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def check_enabled_registrations - redirect_to root_path if single_user_mode? || omniauth_only? || !allowed_registrations? || ip_blocked? - end - - def allowed_registrations? - Setting.registrations_mode != 'none' || @invite&.valid_for_use? - end - - def omniauth_only? - ENV['OMNIAUTH_ONLY'] == 'true' - end - - def ip_blocked? - IpBlock.where(severity: :sign_up_block).where('ip >>= ?', request.remote_ip.to_s).exists? + redirect_to root_path unless allowed_registration?(request.remote_ip, @invite) end def invite_code diff --git a/app/helpers/registration_helper.rb b/app/helpers/registration_helper.rb new file mode 100644 index 0000000000..ef5462ac88 --- /dev/null +++ b/app/helpers/registration_helper.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module RegistrationHelper + extend ActiveSupport::Concern + + def allowed_registration?(remote_ip, invite) + !Rails.configuration.x.single_user_mode && !omniauth_only? && (registrations_open? || invite&.valid_for_use?) && !ip_blocked?(remote_ip) + end + + def registrations_open? + Setting.registrations_mode != 'none' + end + + def omniauth_only? + ENV['OMNIAUTH_ONLY'] == 'true' + end + + def ip_blocked?(remote_ip) + IpBlock.where(severity: :sign_up_block).exists?(['ip >>= ?', remote_ip.to_s]) + end +end diff --git a/app/services/app_sign_up_service.rb b/app/services/app_sign_up_service.rb index 94547b61b2..7665880115 100644 --- a/app/services/app_sign_up_service.rb +++ b/app/services/app_sign_up_service.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true class AppSignUpService < BaseService + include RegistrationHelper + def call(app, remote_ip, params) @app = app @remote_ip = remote_ip @params = params - raise Mastodon::NotPermittedError unless allowed_registrations? + raise Mastodon::NotPermittedError unless allowed_registration?(remote_ip, invite) ApplicationRecord.transaction do create_user! @@ -34,8 +36,12 @@ class AppSignUpService < BaseService ) end + def invite + Invite.find_by(code: @params[:invite_code]) if @params[:invite_code].present? + end + def user_params - @params.slice(:email, :password, :agreement, :locale, :time_zone) + @params.slice(:email, :password, :agreement, :locale, :time_zone, :invite_code) end def account_params @@ -45,24 +51,4 @@ class AppSignUpService < BaseService def invite_request_params { text: @params[:reason] } end - - def allowed_registrations? - registrations_open? && !single_user_mode? && !omniauth_only? && !ip_blocked? - end - - def registrations_open? - Setting.registrations_mode != 'none' - end - - def single_user_mode? - Rails.configuration.x.single_user_mode - end - - def omniauth_only? - ENV['OMNIAUTH_ONLY'] == 'true' - end - - def ip_blocked? - IpBlock.where(severity: :sign_up_block).where('ip >>= ?', @remote_ip.to_s).exists? - end end diff --git a/config/locales/en.yml b/config/locales/en.yml index c298c47d35..7319de53db 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1368,6 +1368,7 @@ en: '86400': 1 day expires_in_prompt: Never generate: Generate invite link + invalid: This invite is not valid invited_by: 'You were invited by:' max_uses: one: 1 use diff --git a/config/routes.rb b/config/routes.rb index 3adda3b822..82431f6ec3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -81,6 +81,8 @@ Rails.application.routes.draw do resource :outbox, only: [:show], module: :activitypub end + get '/invite/:invite_code', constraints: ->(req) { req.format == :json }, to: 'api/v1/invites#show' + devise_scope :user do get '/invite/:invite_code', to: 'auth/registrations#new', as: :public_invite diff --git a/spec/requests/invite_spec.rb b/spec/requests/invite_spec.rb new file mode 100644 index 0000000000..c44ef2419c --- /dev/null +++ b/spec/requests/invite_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'invites' do + let(:invite) { Fabricate(:invite) } + + context 'when requesting a JSON document' do + it 'returns a JSON document with expected attributes' do + get "/invite/#{invite.code}", headers: { 'Accept' => 'application/activity+json' } + + expect(response).to have_http_status(200) + expect(response.media_type).to eq 'application/json' + + expect(body_as_json[:invite_code]).to eq invite.code + end + end + + context 'when not requesting a JSON document' do + it 'returns an HTML page' do + get "/invite/#{invite.code}" + + expect(response).to have_http_status(200) + expect(response.media_type).to eq 'text/html' + end + end +end diff --git a/spec/services/app_sign_up_service_spec.rb b/spec/services/app_sign_up_service_spec.rb index 2532304964..d5946cf9b0 100644 --- a/spec/services/app_sign_up_service_spec.rb +++ b/spec/services/app_sign_up_service_spec.rb @@ -10,46 +10,72 @@ RSpec.describe AppSignUpService, type: :service do let(:remote_ip) { IPAddr.new('198.0.2.1') } describe '#call' do - it 'returns nil when registrations are closed' do - tmp = Setting.registrations_mode - Setting.registrations_mode = 'none' - expect { subject.call(app, remote_ip, good_params) }.to raise_error Mastodon::NotPermittedError - Setting.registrations_mode = tmp + let(:params) { good_params } + + shared_examples 'successful registration' do + it 'creates an unconfirmed user with access token and the app\'s scope', :aggregate_failures do + access_token = subject.call(app, remote_ip, params) + expect(access_token).to_not be_nil + expect(access_token.scopes.to_s).to eq 'read write' + + user = User.find_by(id: access_token.resource_owner_id) + expect(user).to_not be_nil + expect(user.confirmed?).to be false + + expect(user.account).to_not be_nil + expect(user.invite_request).to be_nil + end + end + + context 'when registrations are closed' do + around do |example| + tmp = Setting.registrations_mode + Setting.registrations_mode = 'none' + + example.run + + Setting.registrations_mode = tmp + end + + it 'raises an error', :aggregate_failures do + expect { subject.call(app, remote_ip, good_params) }.to raise_error Mastodon::NotPermittedError + end + + context 'when using a valid invite' do + let(:params) { good_params.merge({ invite_code: invite.code }) } + let(:invite) { Fabricate(:invite) } + + before do + invite.user.approve! + end + + it_behaves_like 'successful registration' + end + + context 'when using an invalid invite' do + let(:params) { good_params.merge({ invite_code: invite.code }) } + let(:invite) { Fabricate(:invite, uses: 1, max_uses: 1) } + + it 'raises an error', :aggregate_failures do + expect { subject.call(app, remote_ip, params) }.to raise_error Mastodon::NotPermittedError + end + end end it 'raises an error when params are missing' do expect { subject.call(app, remote_ip, {}) }.to raise_error ActiveRecord::RecordInvalid end - it 'creates an unconfirmed user with access token' do - access_token = subject.call(app, remote_ip, good_params) - expect(access_token).to_not be_nil - user = User.find_by(id: access_token.resource_owner_id) - expect(user).to_not be_nil - expect(user.confirmed?).to be false - end + it_behaves_like 'successful registration' - it 'creates access token with the app\'s scopes' do - access_token = subject.call(app, remote_ip, good_params) - expect(access_token).to_not be_nil - expect(access_token.scopes.to_s).to eq 'read write' - end - - it 'creates an account' do - access_token = subject.call(app, remote_ip, good_params) - expect(access_token).to_not be_nil - user = User.find_by(id: access_token.resource_owner_id) - expect(user).to_not be_nil - expect(user.account).to_not be_nil - expect(user.invite_request).to be_nil - end - - it 'creates an account with invite request text' do - access_token = subject.call(app, remote_ip, good_params.merge(reason: 'Foo bar')) - expect(access_token).to_not be_nil - user = User.find_by(id: access_token.resource_owner_id) - expect(user).to_not be_nil - expect(user.invite_request&.text).to eq 'Foo bar' + context 'when given an invite request text' do + it 'creates an account with invite request text' do + access_token = subject.call(app, remote_ip, good_params.merge(reason: 'Foo bar')) + expect(access_token).to_not be_nil + user = User.find_by(id: access_token.resource_owner_id) + expect(user).to_not be_nil + expect(user.invite_request&.text).to eq 'Foo bar' + end end end end From ed79713f3ad20a78640f113d44454bab387a2d8c Mon Sep 17 00:00:00 2001 From: pajowu Date: Mon, 13 Nov 2023 14:27:50 +0100 Subject: [PATCH 13/15] Fix modal content not being selectable (#27813) --- app/javascript/styles/mastodon/components.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index ae8e23f53c..c8cfe46a8c 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -5226,6 +5226,7 @@ a.status-card { .modal-root__modal { pointer-events: auto; + user-select: text; display: flex; } From 0c98a9d9becec126ea9a53619045dbb1b88f555a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 15:01:07 +0100 Subject: [PATCH 14/15] Update devDependencies (non-major) (#25612) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 828 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 434 insertions(+), 394 deletions(-) diff --git a/yarn.lock b/yarn.lock index c1e9ec9a46..891eb59fef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,10 +12,10 @@ __metadata: languageName: node linkType: hard -"@adobe/css-tools@npm:^4.0.1": - version: 4.3.0 - resolution: "@adobe/css-tools@npm:4.3.0" - checksum: 70401c49ab6b7d715147c3637fc6467608276253150c1a5fa933ee45d7c1472b5188e31c1760d06c8a19c5bc2b2914583daa33486d7eac1e8fc7c6dc76a57b3c +"@adobe/css-tools@npm:^4.3.1": + version: 4.3.1 + resolution: "@adobe/css-tools@npm:4.3.1" + checksum: 05672719b544cc0c21ae3ed0eb6349bf458e9d09457578eeeb07cf0f696469ac6417e9c9be1b129e5d6a18098a061c1db55b2275591760ef30a79822436fcbfa languageName: node linkType: hard @@ -1538,29 +1538,29 @@ __metadata: languageName: node linkType: hard -"@csstools/css-parser-algorithms@npm:^2.3.0": - version: 2.3.1 - resolution: "@csstools/css-parser-algorithms@npm:2.3.1" +"@csstools/css-parser-algorithms@npm:^2.3.1": + version: 2.3.2 + resolution: "@csstools/css-parser-algorithms@npm:2.3.2" peerDependencies: - "@csstools/css-tokenizer": ^2.2.0 - checksum: 0f1688cc5de75f41af4581a0b4df994e9af90f6df2b3f962e0680c4ed8e2aa32b23fbf3ba4fdaffc09a9afcf93fcf13a9743204f179bab57a7603ce88cb635e8 + "@csstools/css-tokenizer": ^2.2.1 + checksum: ccae373a3ab5c10716418b69ce1f6db10a26d3a2d60b65df5fe69099afe4fb1d3192925f3c0f93c3b17c3ab1964b0f39ad2b0e97312ec4a51caa55d6b6a31672 languageName: node linkType: hard -"@csstools/css-tokenizer@npm:^2.1.1": - version: 2.2.0 - resolution: "@csstools/css-tokenizer@npm:2.2.0" - checksum: 7a6178d5a148e426ea79d4b2761857daacd7cde00512b45697146228d59183b0043f9803b48be55299f5a331f07ff14477612c608f18df7550ee642467d74564 +"@csstools/css-tokenizer@npm:^2.2.0": + version: 2.2.1 + resolution: "@csstools/css-tokenizer@npm:2.2.1" + checksum: 0c6901d291e99c567893846a47068057c2a28b3edc4219b6da589a530f55f51ddd4675f906f707b393bfe7a508ab2604bf3f75708f064db857bb277636bd5a44 languageName: node linkType: hard -"@csstools/media-query-list-parser@npm:^2.1.2": - version: 2.1.4 - resolution: "@csstools/media-query-list-parser@npm:2.1.4" +"@csstools/media-query-list-parser@npm:^2.1.4": + version: 2.1.5 + resolution: "@csstools/media-query-list-parser@npm:2.1.5" peerDependencies: - "@csstools/css-parser-algorithms": ^2.3.1 - "@csstools/css-tokenizer": ^2.2.0 - checksum: a796ebc8df7d1c8bc2bb71f152b6bedd540bd6679a33a50c1d99f8c383a24d79e9cb8fa59b2ad8f39da12c9d4501fd799caa16da542c23b8dff8257b0b5a0ea7 + "@csstools/css-parser-algorithms": ^2.3.2 + "@csstools/css-tokenizer": ^2.2.1 + checksum: ae0692c6f92cdc82053291c7a50028b692094dfed795f0259571c5eb40f4b3fa580182ac3701e56c2834e40a62a122ea6639299e43ae88b3a835ae4c869a1a12 languageName: node linkType: hard @@ -1777,16 +1777,16 @@ __metadata: linkType: hard "@formatjs/cli@npm:^6.1.1": - version: 6.1.3 - resolution: "@formatjs/cli@npm:6.1.3" + version: 6.2.3 + resolution: "@formatjs/cli@npm:6.2.3" peerDependencies: - "@vue/compiler-sfc": ^3.2.34 + vue: ^3.3.4 peerDependenciesMeta: - "@vue/compiler-sfc": + vue: optional: true bin: formatjs: bin/formatjs - checksum: d7f069b4813c7c1a4fd7e16906da6bc024553c5df3d3ebb0b3da12ec23bb763d184c0424c562bc7ef89d62a963dadd114dd5acb5acec8f0c9160a36bb79f05c2 + checksum: 91eada7676333e2e647cbfbf9c0da88e4ca52e7b486dca73a7299594b0b0dea99de00e1b4110fac993633feb4bf5f26c97885b1a870dfd0ef95688d7f3234a03 languageName: node linkType: hard @@ -2061,50 +2061,50 @@ __metadata: languageName: node linkType: hard -"@jest/console@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/console@npm:29.6.2" +"@jest/console@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/console@npm:29.7.0" dependencies: - "@jest/types": "npm:^29.6.1" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" chalk: "npm:^4.0.0" - jest-message-util: "npm:^29.6.2" - jest-util: "npm:^29.6.2" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" slash: "npm:^3.0.0" - checksum: cdd97d89df5e3e84ba7927ba58a297eb0eae25190575299fede876f7d09a08dc120094be08e49bf01859c54053470215194c0d9a64fc56beb735c5de4de8c5a8 + checksum: 7be408781d0a6f657e969cbec13b540c329671819c2f57acfad0dae9dbfe2c9be859f38fe99b35dba9ff1536937dc6ddc69fdcd2794812fa3c647a1619797f6c languageName: node linkType: hard -"@jest/core@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/core@npm:29.6.2" +"@jest/core@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/core@npm:29.7.0" dependencies: - "@jest/console": "npm:^29.6.2" - "@jest/reporters": "npm:^29.6.2" - "@jest/test-result": "npm:^29.6.2" - "@jest/transform": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/console": "npm:^29.7.0" + "@jest/reporters": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" ansi-escapes: "npm:^4.2.1" chalk: "npm:^4.0.0" ci-info: "npm:^3.2.0" exit: "npm:^0.1.2" graceful-fs: "npm:^4.2.9" - jest-changed-files: "npm:^29.5.0" - jest-config: "npm:^29.6.2" - jest-haste-map: "npm:^29.6.2" - jest-message-util: "npm:^29.6.2" - jest-regex-util: "npm:^29.4.3" - jest-resolve: "npm:^29.6.2" - jest-resolve-dependencies: "npm:^29.6.2" - jest-runner: "npm:^29.6.2" - jest-runtime: "npm:^29.6.2" - jest-snapshot: "npm:^29.6.2" - jest-util: "npm:^29.6.2" - jest-validate: "npm:^29.6.2" - jest-watcher: "npm:^29.6.2" + jest-changed-files: "npm:^29.7.0" + jest-config: "npm:^29.7.0" + jest-haste-map: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-regex-util: "npm:^29.6.3" + jest-resolve: "npm:^29.7.0" + jest-resolve-dependencies: "npm:^29.7.0" + jest-runner: "npm:^29.7.0" + jest-runtime: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" + jest-watcher: "npm:^29.7.0" micromatch: "npm:^4.0.4" - pretty-format: "npm:^29.6.2" + pretty-format: "npm:^29.7.0" slash: "npm:^3.0.0" strip-ansi: "npm:^6.0.0" peerDependencies: @@ -2112,23 +2112,23 @@ __metadata: peerDependenciesMeta: node-notifier: optional: true - checksum: 066fc9dc66bb3785c2670280f05cb4f01a776a2d88bc6106ad4224e4a1064b1dbe3752545b4d744d6e0e3203fb0a2a102e9864104f160f2266fd30e756d9d693 + checksum: 934f7bf73190f029ac0f96662c85cd276ec460d407baf6b0dbaec2872e157db4d55a7ee0b1c43b18874602f662b37cb973dda469a4e6d88b4e4845b521adeeb2 languageName: node linkType: hard -"@jest/environment@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/environment@npm:29.6.2" +"@jest/environment@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/environment@npm:29.7.0" dependencies: - "@jest/fake-timers": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/fake-timers": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" - jest-mock: "npm:^29.6.2" - checksum: 82f040b4f729e1a3ab9e61b33e009a7b4ccf572ff94fc157e6fe8ecd267c8af53c8c02853bfe7f023d0f6bf35edf06b6bc7873efc433f335a3774b6c2445662d + jest-mock: "npm:^29.7.0" + checksum: c7b1b40c618f8baf4d00609022d2afa086d9c6acc706f303a70bb4b67275868f620ad2e1a9efc5edd418906157337cce50589a627a6400bbdf117d351b91ef86 languageName: node linkType: hard -"@jest/expect-utils@npm:^29.6.2, @jest/expect-utils@npm:^29.7.0": +"@jest/expect-utils@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect-utils@npm:29.7.0" dependencies: @@ -2137,51 +2137,51 @@ __metadata: languageName: node linkType: hard -"@jest/expect@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/expect@npm:29.6.2" +"@jest/expect@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect@npm:29.7.0" dependencies: - expect: "npm:^29.6.2" - jest-snapshot: "npm:^29.6.2" - checksum: 2cd9a5613b1bae5300dd16d76c7790d1d3b43cb55654dc2b64b202d1522bb03844f88c7bc60b72e3095c8479873ade91009ab0cb8a851842dab00d4d9fc1e3cb + expect: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + checksum: b41f193fb697d3ced134349250aed6ccea075e48c4f803159db102b826a4e473397c68c31118259868fd69a5cba70e97e1c26d2c2ff716ca39dc73a2ccec037e languageName: node linkType: hard -"@jest/fake-timers@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/fake-timers@npm:29.6.2" +"@jest/fake-timers@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/fake-timers@npm:29.7.0" dependencies: - "@jest/types": "npm:^29.6.1" + "@jest/types": "npm:^29.6.3" "@sinonjs/fake-timers": "npm:^10.0.2" "@types/node": "npm:*" - jest-message-util: "npm:^29.6.2" - jest-mock: "npm:^29.6.2" - jest-util: "npm:^29.6.2" - checksum: 4f333b7f8f6bc8e0549e3838e68c3859de1faa3e0639f8ede2786602ec1c237f4691e7bd13649b308ddfaf3fd5aa6b75067fe34f6b6dfa9c0b570773611e0e73 + jest-message-util: "npm:^29.7.0" + jest-mock: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + checksum: cf0a8bcda801b28dc2e2b2ba36302200ee8104a45ad7a21e6c234148932f826cb3bc57c8df3b7b815aeea0861d7b6ca6f0d4778f93b9219398ef28749e03595c languageName: node linkType: hard -"@jest/globals@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/globals@npm:29.6.2" +"@jest/globals@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/globals@npm:29.7.0" dependencies: - "@jest/environment": "npm:^29.6.2" - "@jest/expect": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" - jest-mock: "npm:^29.6.2" - checksum: 3ee73f13d51a08b9fe3bc39305a3b9c0259a7610d89f17b9579684b80bdff3e079adc81d6aec298f5ebe07b43ba0dfdb305be2747b9dc87aa7f337bddc83fedc + "@jest/environment": "npm:^29.7.0" + "@jest/expect": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + jest-mock: "npm:^29.7.0" + checksum: a385c99396878fe6e4460c43bd7bb0a5cc52befb462cc6e7f2a3810f9e7bcce7cdeb51908fd530391ee452dc856c98baa2c5f5fa8a5b30b071d31ef7f6955cea languageName: node linkType: hard -"@jest/reporters@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/reporters@npm:29.6.2" +"@jest/reporters@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/reporters@npm:29.7.0" dependencies: "@bcoe/v8-coverage": "npm:^0.2.3" - "@jest/console": "npm:^29.6.2" - "@jest/test-result": "npm:^29.6.2" - "@jest/transform": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/console": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@jridgewell/trace-mapping": "npm:^0.3.18" "@types/node": "npm:*" chalk: "npm:^4.0.0" @@ -2190,13 +2190,13 @@ __metadata: glob: "npm:^7.1.3" graceful-fs: "npm:^4.2.9" istanbul-lib-coverage: "npm:^3.0.0" - istanbul-lib-instrument: "npm:^5.1.0" + istanbul-lib-instrument: "npm:^6.0.0" istanbul-lib-report: "npm:^3.0.0" istanbul-lib-source-maps: "npm:^4.0.0" istanbul-reports: "npm:^3.1.3" - jest-message-util: "npm:^29.6.2" - jest-util: "npm:^29.6.2" - jest-worker: "npm:^29.6.2" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-worker: "npm:^29.7.0" slash: "npm:^3.0.0" string-length: "npm:^4.0.1" strip-ansi: "npm:^6.0.0" @@ -2206,7 +2206,7 @@ __metadata: peerDependenciesMeta: node-notifier: optional: true - checksum: d4321978208fa8c64ff4e14694508ec8fa5712801b66db62a6c58456798ffc2fab5761db24b1c3596664f2ad0862fcabc69927f0ed54cc9f219689a77cc7db4a + checksum: a754402a799541c6e5aff2c8160562525e2a47e7d568f01ebfc4da66522de39cbb809bbb0a841c7052e4270d79214e70aec3c169e4eae42a03bc1a8a20cb9fa2 languageName: node linkType: hard @@ -2219,65 +2219,65 @@ __metadata: languageName: node linkType: hard -"@jest/source-map@npm:^29.6.0": - version: 29.6.0 - resolution: "@jest/source-map@npm:29.6.0" +"@jest/source-map@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/source-map@npm:29.6.3" dependencies: "@jridgewell/trace-mapping": "npm:^0.3.18" callsites: "npm:^3.0.0" graceful-fs: "npm:^4.2.9" - checksum: afa654e3634ad74d5f8388ccffd7ecbd745bdce7f6f0860b69c07827c3ee5bb408f52b6c3136b43157ef5874c099059484e43bd3aa391232ab27d8c330399789 + checksum: a2f177081830a2e8ad3f2e29e20b63bd40bade294880b595acf2fc09ec74b6a9dd98f126a2baa2bf4941acd89b13a4ade5351b3885c224107083a0059b60a219 languageName: node linkType: hard -"@jest/test-result@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/test-result@npm:29.6.2" +"@jest/test-result@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-result@npm:29.7.0" dependencies: - "@jest/console": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/console": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/istanbul-lib-coverage": "npm:^2.0.0" collect-v8-coverage: "npm:^1.0.0" - checksum: 9c373db297d6cc4b23b143592b3121da047890ba3609115e4db7b94220095d5e32a11f7179ca3dfa1ab29fa30a5e51cbdbbdf58dcd8ef3216e92e86d2aa3251c + checksum: 7de54090e54a674ca173470b55dc1afdee994f2d70d185c80236003efd3fa2b753fff51ffcdda8e2890244c411fd2267529d42c4a50a8303755041ee493e6a04 languageName: node linkType: hard -"@jest/test-sequencer@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/test-sequencer@npm:29.6.2" +"@jest/test-sequencer@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-sequencer@npm:29.7.0" dependencies: - "@jest/test-result": "npm:^29.6.2" + "@jest/test-result": "npm:^29.7.0" graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.2" + jest-haste-map: "npm:^29.7.0" slash: "npm:^3.0.0" - checksum: dc6a37f0eb93a72ce76a5100f8adb97e40bb0ab9b6f49b07476e0b83b07d1366803185b3d64da2219448312fa78a687f473f54e0c1da08efc4d2e1cb2d3c1dfb + checksum: 593a8c4272797bb5628984486080cbf57aed09c7cfdc0a634e8c06c38c6bef329c46c0016e84555ee55d1cd1f381518cf1890990ff845524c1123720c8c1481b languageName: node linkType: hard -"@jest/transform@npm:^29.6.2": - version: 29.6.2 - resolution: "@jest/transform@npm:29.6.2" +"@jest/transform@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/transform@npm:29.7.0" dependencies: "@babel/core": "npm:^7.11.6" - "@jest/types": "npm:^29.6.1" + "@jest/types": "npm:^29.6.3" "@jridgewell/trace-mapping": "npm:^0.3.18" babel-plugin-istanbul: "npm:^6.1.1" chalk: "npm:^4.0.0" convert-source-map: "npm:^2.0.0" fast-json-stable-stringify: "npm:^2.1.0" graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.2" - jest-regex-util: "npm:^29.4.3" - jest-util: "npm:^29.6.2" + jest-haste-map: "npm:^29.7.0" + jest-regex-util: "npm:^29.6.3" + jest-util: "npm:^29.7.0" micromatch: "npm:^4.0.4" pirates: "npm:^4.0.4" slash: "npm:^3.0.0" write-file-atomic: "npm:^4.0.2" - checksum: dce3a28ca01ce78923bb0faf7ff4fa6e64f1ec77a729a89f874b05a98c8f4408df52fc41a9e39755e9490660163ecebb58d2364530391a443fc2e4bd0e4195d6 + checksum: 7f4a7f73dcf45dfdf280c7aa283cbac7b6e5a904813c3a93ead7e55873761fc20d5c4f0191d2019004fac6f55f061c82eb3249c2901164ad80e362e7a7ede5a6 languageName: node linkType: hard -"@jest/types@npm:^29.6.1, @jest/types@npm:^29.6.3": +"@jest/types@npm:^29.6.3": version: 29.6.3 resolution: "@jest/types@npm:29.6.3" dependencies: @@ -2941,10 +2941,10 @@ __metadata: linkType: hard "@testing-library/jest-dom@npm:^6.0.0": - version: 6.0.0 - resolution: "@testing-library/jest-dom@npm:6.0.0" + version: 6.1.4 + resolution: "@testing-library/jest-dom@npm:6.1.4" dependencies: - "@adobe/css-tools": "npm:^4.0.1" + "@adobe/css-tools": "npm:^4.3.1" "@babel/runtime": "npm:^7.9.2" aria-query: "npm:^5.0.0" chalk: "npm:^3.0.0" @@ -2966,13 +2966,13 @@ __metadata: optional: true vitest: optional: true - checksum: dd5a7ff79dad99b08195cab8d7b818b3de0d02f6c84b5d28d5dbca265ceb867931a0ff79da2279a2d476db1cdafb81c14255d898f0bd1ace9d0b36896368cf96 + checksum: 2e23f120613fd8ae6d5169bbc94f1a2e4c82b07182057dc94db8ec54ebf32555833442e6c43a187e59715d83704ffb5df49ba88a71f6f32d2683f3d95ba721c7 languageName: node linkType: hard "@testing-library/react@npm:^14.0.0": - version: 14.0.0 - resolution: "@testing-library/react@npm:14.0.0" + version: 14.1.0 + resolution: "@testing-library/react@npm:14.1.0" dependencies: "@babel/runtime": "npm:^7.12.5" "@testing-library/dom": "npm:^9.0.0" @@ -2980,7 +2980,7 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 81035913024faf18ba7e163418af517b2c3b85aef496fbd6334bda38f6f6dd4072678c6b76c41148b46b7fc846764f875e1156cbfc7643ffa1b62ee069d78951 + checksum: 357ad80b11bdd4b6d10d2fb1bf86d5b39fb457cf09293033cf42bcc7a95738a86a2b12b760ae15bad326da0b9c074ca015d2bbf0baae7da38fdbc7c808925820 languageName: node linkType: hard @@ -4702,20 +4702,20 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^29.5.0, babel-jest@npm:^29.6.2": - version: 29.6.2 - resolution: "babel-jest@npm:29.6.2" +"babel-jest@npm:^29.5.0, babel-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "babel-jest@npm:29.7.0" dependencies: - "@jest/transform": "npm:^29.6.2" + "@jest/transform": "npm:^29.7.0" "@types/babel__core": "npm:^7.1.14" babel-plugin-istanbul: "npm:^6.1.1" - babel-preset-jest: "npm:^29.5.0" + babel-preset-jest: "npm:^29.6.3" chalk: "npm:^4.0.0" graceful-fs: "npm:^4.2.9" slash: "npm:^3.0.0" peerDependencies: "@babel/core": ^7.8.0 - checksum: c1ebaecd1323852867765a6920ab8b5e1e4236254415090a682e0ebf6a3339a9861f65791b23acad2e3a4c4bf5bca31c9abc154306ba7cf9725c2f6e78c92444 + checksum: 2eda9c1391e51936ca573dd1aedfee07b14c59b33dbe16ef347873ddd777bcf6e2fc739681e9e9661ab54ef84a3109a03725be2ac32cd2124c07ea4401cbe8c1 languageName: node linkType: hard @@ -4766,15 +4766,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^29.5.0": - version: 29.5.0 - resolution: "babel-plugin-jest-hoist@npm:29.5.0" +"babel-plugin-jest-hoist@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-plugin-jest-hoist@npm:29.6.3" dependencies: "@babel/template": "npm:^7.3.3" "@babel/types": "npm:^7.3.3" "@types/babel__core": "npm:^7.1.14" "@types/babel__traverse": "npm:^7.0.6" - checksum: 385547c4d81647848dc3e86fecf4381032be99ed97d87aee78d422631f651042600371ee31e37ec9bb6f4a0a4f296b3b5798d69c410626ea94eae76d9c64da63 + checksum: 7e6451caaf7dce33d010b8aafb970e62f1b0c0b57f4978c37b0d457bbcf0874d75a395a102daf0bae0bd14eafb9f6e9a165ee5e899c0a4f1f3bb2e07b304ed2e languageName: node linkType: hard @@ -4892,15 +4892,15 @@ __metadata: languageName: node linkType: hard -"babel-preset-jest@npm:^29.5.0": - version: 29.5.0 - resolution: "babel-preset-jest@npm:29.5.0" +"babel-preset-jest@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-preset-jest@npm:29.6.3" dependencies: - babel-plugin-jest-hoist: "npm:^29.5.0" + babel-plugin-jest-hoist: "npm:^29.6.3" babel-preset-current-node-syntax: "npm:^1.0.0" peerDependencies: "@babel/core": ^7.0.0 - checksum: 752b8682c8cf55bca46d870003f4ce43a4ba0fcaa1138ff7f0e02340628e221810b0c2c3e77a7d5070168dc163eb11907f6c9256f187242abe0f14219d1f6b12 + checksum: ec5fd0276b5630b05f0c14bb97cc3815c6b31600c683ebb51372e54dcb776cff790bdeeabd5b8d01ede375a040337ccbf6a3ccd68d3a34219125945e167ad943 languageName: node linkType: hard @@ -6067,6 +6067,23 @@ __metadata: languageName: node linkType: hard +"create-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "create-jest@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + chalk: "npm:^4.0.0" + exit: "npm:^0.1.2" + graceful-fs: "npm:^4.2.9" + jest-config: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + prompts: "npm:^2.0.1" + bin: + create-jest: bin/create-jest.js + checksum: e7e54c280692470d3398f62a6238fd396327e01c6a0757002833f06d00afc62dd7bfe04ff2b9cd145264460e6b4d1eb8386f2925b7e567f97939843b7b0e812f + languageName: node + linkType: hard + "cross-env@npm:^7.0.3": version: 7.0.3 resolution: "cross-env@npm:7.0.3" @@ -6138,10 +6155,10 @@ __metadata: languageName: node linkType: hard -"css-functions-list@npm:^3.2.0": - version: 3.2.0 - resolution: "css-functions-list@npm:3.2.0" - checksum: 640a1760c6d63536def671b7ccd89c2525a7197fc845a5ae1ec9f380fedd1aa9634f547db81f02f1a3736492867e9333ee8d6bf9aa498d211e36feae0e71a672 +"css-functions-list@npm:^3.2.1": + version: 3.2.1 + resolution: "css-functions-list@npm:3.2.1" + checksum: e6e2d9580437ad6df9f2cf18cff3f941691ec5cbbaebd4cb17a5da40d8d5dac50004807ddd05c00a121d2f21a224e2c5d339fe8e13614af21c00181d7d1c22b9 languageName: node linkType: hard @@ -7820,7 +7837,7 @@ __metadata: languageName: node linkType: hard -"expect@npm:^29.0.0, expect@npm:^29.6.2": +"expect@npm:^29.0.0, expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" dependencies: @@ -7998,6 +8015,15 @@ __metadata: languageName: node linkType: hard +"file-entry-cache@npm:^7.0.0": + version: 7.0.1 + resolution: "file-entry-cache@npm:7.0.1" + dependencies: + flat-cache: "npm:^3.1.1" + checksum: fc0e4f830777e07087f97da9a6734820fdffa2945583355433f40d9819dd97b89f16ac87c07118737a6bc3eb9cf4bd896e7b38b07f0768aefcf44da33e797363 + languageName: node + linkType: hard + "file-loader@npm:^6.2.0": version: 6.2.0 resolution: "file-loader@npm:6.2.0" @@ -8128,14 +8154,14 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.1.1 - resolution: "flat-cache@npm:3.1.1" +"flat-cache@npm:^3.0.4, flat-cache@npm:^3.1.1": + version: 3.2.0 + resolution: "flat-cache@npm:3.2.0" dependencies: flatted: "npm:^3.2.9" keyv: "npm:^4.5.3" rimraf: "npm:^3.0.2" - checksum: 15f7f854830089a903ea660809b67ee25632b8b1965da6a328d3dc59d451abe2e9f16ad0b7523571ece2b5424d1e1979469ba25870f76f49ce3bbffc836072ef + checksum: b76f611bd5f5d68f7ae632e3ae503e678d205cf97a17c6ab5b12f6ca61188b5f1f7464503efae6dc18683ed8f0b41460beb48ac4b9ac63fe6201296a91ba2f75 languageName: node linkType: hard @@ -9955,7 +9981,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:^5.0.4, istanbul-lib-instrument@npm:^5.1.0": +"istanbul-lib-instrument@npm:^5.0.4": version: 5.2.1 resolution: "istanbul-lib-instrument@npm:5.2.1" dependencies: @@ -9968,6 +9994,19 @@ __metadata: languageName: node linkType: hard +"istanbul-lib-instrument@npm:^6.0.0": + version: 6.0.1 + resolution: "istanbul-lib-instrument@npm:6.0.1" + dependencies: + "@babel/core": "npm:^7.12.3" + "@babel/parser": "npm:^7.14.7" + "@istanbuljs/schema": "npm:^0.1.2" + istanbul-lib-coverage: "npm:^3.2.0" + semver: "npm:^7.5.4" + checksum: 313d61aca3f82a04ad9377841d05061d603ea3d4a4dd281fdda2479ec4ddbc86dc1792c73651f21c93480570d1ecadc5f63011e2df86f30ee662b62c0c00e3d8 + languageName: node + linkType: hard + "istanbul-lib-report@npm:^3.0.0": version: 3.0.1 resolution: "istanbul-lib-report@npm:3.0.1" @@ -10040,59 +10079,59 @@ __metadata: languageName: node linkType: hard -"jest-changed-files@npm:^29.5.0": - version: 29.5.0 - resolution: "jest-changed-files@npm:29.5.0" +"jest-changed-files@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-changed-files@npm:29.7.0" dependencies: execa: "npm:^5.0.0" + jest-util: "npm:^29.7.0" p-limit: "npm:^3.1.0" - checksum: 96334c78507a13c0f11f1360d893ade78fba7fd169825ca4acf7565156ceddd89b952be81c00378fa87ab642d3f44902c34a20f21b561e985e79f6e81fa7e9a8 + checksum: e071384d9e2f6bb462231ac53f29bff86f0e12394c1b49ccafbad225ce2ab7da226279a8a94f421949920bef9be7ef574fd86aee22e8adfa149be73554ab828b languageName: node linkType: hard -"jest-circus@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-circus@npm:29.6.2" +"jest-circus@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-circus@npm:29.7.0" dependencies: - "@jest/environment": "npm:^29.6.2" - "@jest/expect": "npm:^29.6.2" - "@jest/test-result": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/environment": "npm:^29.7.0" + "@jest/expect": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" chalk: "npm:^4.0.0" co: "npm:^4.6.0" dedent: "npm:^1.0.0" is-generator-fn: "npm:^2.0.0" - jest-each: "npm:^29.6.2" - jest-matcher-utils: "npm:^29.6.2" - jest-message-util: "npm:^29.6.2" - jest-runtime: "npm:^29.6.2" - jest-snapshot: "npm:^29.6.2" - jest-util: "npm:^29.6.2" + jest-each: "npm:^29.7.0" + jest-matcher-utils: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-runtime: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + jest-util: "npm:^29.7.0" p-limit: "npm:^3.1.0" - pretty-format: "npm:^29.6.2" + pretty-format: "npm:^29.7.0" pure-rand: "npm:^6.0.0" slash: "npm:^3.0.0" stack-utils: "npm:^2.0.3" - checksum: 04f3176bcc3adf0a5d5895f3ce2cb86fafa5d0d03d246cddd0a39021ec4bbc1092ef30792a9d8cdfb1cb6fcee75a277354d65aef6ca8c364fd3747d8ce67e255 + checksum: 8d15344cf7a9f14e926f0deed64ed190c7a4fa1ed1acfcd81e4cc094d3cc5bf7902ebb7b874edc98ada4185688f90c91e1747e0dfd7ac12463b097968ae74b5e languageName: node linkType: hard -"jest-cli@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-cli@npm:29.6.2" +"jest-cli@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-cli@npm:29.7.0" dependencies: - "@jest/core": "npm:^29.6.2" - "@jest/test-result": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/core": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" chalk: "npm:^4.0.0" + create-jest: "npm:^29.7.0" exit: "npm:^0.1.2" - graceful-fs: "npm:^4.2.9" import-local: "npm:^3.0.2" - jest-config: "npm:^29.6.2" - jest-util: "npm:^29.6.2" - jest-validate: "npm:^29.6.2" - prompts: "npm:^2.0.1" + jest-config: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" yargs: "npm:^17.3.1" peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -10101,34 +10140,34 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: 76d359427a573821b0b4f80a8b752e54778b8da1e09e737ae1ff5c29487d762a6f0d16becd5c1d2017cd337295945be82448539f90d04d173c72ee577c6cf897 + checksum: a658fd55050d4075d65c1066364595962ead7661711495cfa1dfeecf3d6d0a8ffec532f3dbd8afbb3e172dd5fd2fb2e813c5e10256e7cf2fea766314942fb43a languageName: node linkType: hard -"jest-config@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-config@npm:29.6.2" +"jest-config@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-config@npm:29.7.0" dependencies: "@babel/core": "npm:^7.11.6" - "@jest/test-sequencer": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" - babel-jest: "npm:^29.6.2" + "@jest/test-sequencer": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + babel-jest: "npm:^29.7.0" chalk: "npm:^4.0.0" ci-info: "npm:^3.2.0" deepmerge: "npm:^4.2.2" glob: "npm:^7.1.3" graceful-fs: "npm:^4.2.9" - jest-circus: "npm:^29.6.2" - jest-environment-node: "npm:^29.6.2" - jest-get-type: "npm:^29.4.3" - jest-regex-util: "npm:^29.4.3" - jest-resolve: "npm:^29.6.2" - jest-runner: "npm:^29.6.2" - jest-util: "npm:^29.6.2" - jest-validate: "npm:^29.6.2" + jest-circus: "npm:^29.7.0" + jest-environment-node: "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + jest-regex-util: "npm:^29.6.3" + jest-resolve: "npm:^29.7.0" + jest-runner: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" micromatch: "npm:^4.0.4" parse-json: "npm:^5.2.0" - pretty-format: "npm:^29.6.2" + pretty-format: "npm:^29.7.0" slash: "npm:^3.0.0" strip-json-comments: "npm:^3.1.1" peerDependencies: @@ -10139,11 +10178,11 @@ __metadata: optional: true ts-node: optional: true - checksum: 334b8cf02c9c9f5f3685fd6f673d634691a370c9a96f1a855234c7513c409a1cc842f2c8e786da9ef8734d33b6ee95d7b7b4d586c1a4f22bcae59118755d7d2a + checksum: bab23c2eda1fff06e0d104b00d6adfb1d1aabb7128441899c9bff2247bd26710b050a5364281ce8d52b46b499153bf7e3ee88b19831a8f3451f1477a0246a0f1 languageName: node linkType: hard -"jest-diff@npm:^29.6.2, jest-diff@npm:^29.7.0": +"jest-diff@npm:^29.7.0": version: 29.7.0 resolution: "jest-diff@npm:29.7.0" dependencies: @@ -10155,104 +10194,104 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:^29.4.3": - version: 29.4.3 - resolution: "jest-docblock@npm:29.4.3" +"jest-docblock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-docblock@npm:29.7.0" dependencies: detect-newline: "npm:^3.0.0" - checksum: 25cdea8fe77ff09d958abd347e26dcd8766ca69d9935bc626a89d694c91d33be06d4c088b02e4b3f143f532f726a10dff0bfe1e2387a0972a95addf5d64ed407 + checksum: d932a8272345cf6b6142bb70a2bb63e0856cc0093f082821577ea5bdf4643916a98744dfc992189d2b1417c38a11fa42466f6111526bc1fb81366f56410f3be9 languageName: node linkType: hard -"jest-each@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-each@npm:29.6.2" +"jest-each@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-each@npm:29.7.0" dependencies: - "@jest/types": "npm:^29.6.1" + "@jest/types": "npm:^29.6.3" chalk: "npm:^4.0.0" - jest-get-type: "npm:^29.4.3" - jest-util: "npm:^29.6.2" - pretty-format: "npm:^29.6.2" - checksum: b586f5c811011589308f2d8e0d5e596fa26d101e1116b55c624342327b932d3644aac37ce7b6c4eb8ef018893d2a41610ed7edbabfe125c3b46cf9a2b0f03d9b + jest-get-type: "npm:^29.6.3" + jest-util: "npm:^29.7.0" + pretty-format: "npm:^29.7.0" + checksum: f7f9a90ebee80cc688e825feceb2613627826ac41ea76a366fa58e669c3b2403d364c7c0a74d862d469b103c843154f8456d3b1c02b487509a12afa8b59edbb4 languageName: node linkType: hard "jest-environment-jsdom@npm:^29.5.0": - version: 29.6.2 - resolution: "jest-environment-jsdom@npm:29.6.2" + version: 29.7.0 + resolution: "jest-environment-jsdom@npm:29.7.0" dependencies: - "@jest/environment": "npm:^29.6.2" - "@jest/fake-timers": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/environment": "npm:^29.7.0" + "@jest/fake-timers": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/jsdom": "npm:^20.0.0" "@types/node": "npm:*" - jest-mock: "npm:^29.6.2" - jest-util: "npm:^29.6.2" + jest-mock: "npm:^29.7.0" + jest-util: "npm:^29.7.0" jsdom: "npm:^20.0.0" peerDependencies: canvas: ^2.5.0 peerDependenciesMeta: canvas: optional: true - checksum: 7f5885f6fa42d7d14d7dbdc58186283d3ed409a0abc8289bf365a4a2e92ea84d0eeb2087cd5ce6db39394652d817e4c7505d28555e2594309a324634d2b45718 + checksum: 139b94e2c8ec1bb5a46ce17df5211da65ce867354b3fd4e00fa6a0d1da95902df4cf7881273fc6ea937e5c325d39d6773f0d41b6c469363334de9d489d2c321f languageName: node linkType: hard -"jest-environment-node@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-environment-node@npm:29.6.2" +"jest-environment-node@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-environment-node@npm:29.7.0" dependencies: - "@jest/environment": "npm:^29.6.2" - "@jest/fake-timers": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/environment": "npm:^29.7.0" + "@jest/fake-timers": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" - jest-mock: "npm:^29.6.2" - jest-util: "npm:^29.6.2" - checksum: fea7c71e2b6ef901679983809918f670551d0122380f60695df554ca1dc9a065ec347e14c516c9b5a184494572320cd1696bd5bc817853a3e6cdb89b44d4054e + jest-mock: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + checksum: 61f04fec077f8b1b5c1a633e3612fc0c9aa79a0ab7b05600683428f1e01a4d35346c474bde6f439f9fcc1a4aa9a2861ff852d079a43ab64b02105d1004b2592b languageName: node linkType: hard -"jest-get-type@npm:^29.4.3, jest-get-type@npm:^29.6.3": +"jest-get-type@npm:^29.6.3": version: 29.6.3 resolution: "jest-get-type@npm:29.6.3" checksum: 552e7a97a983d3c2d4e412a44eb7de0430ff773dd99f7500962c268d6dfbfa431d7d08f919c9d960530e5f7f78eb47f267ad9b318265e5092b3ff9ede0db7c2b languageName: node linkType: hard -"jest-haste-map@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-haste-map@npm:29.6.2" +"jest-haste-map@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-haste-map@npm:29.7.0" dependencies: - "@jest/types": "npm:^29.6.1" + "@jest/types": "npm:^29.6.3" "@types/graceful-fs": "npm:^4.1.3" "@types/node": "npm:*" anymatch: "npm:^3.0.3" fb-watchman: "npm:^2.0.0" fsevents: "npm:^2.3.2" graceful-fs: "npm:^4.2.9" - jest-regex-util: "npm:^29.4.3" - jest-util: "npm:^29.6.2" - jest-worker: "npm:^29.6.2" + jest-regex-util: "npm:^29.6.3" + jest-util: "npm:^29.7.0" + jest-worker: "npm:^29.7.0" micromatch: "npm:^4.0.4" walker: "npm:^1.0.8" dependenciesMeta: fsevents: optional: true - checksum: 12c921ff059613b67e8b3a0730fe8f5f38e39a1aeb2050948a5c6890c4705f39decd4f7da8ebc7ede22e0eeef37fef2e9256952ac6557dd3bcd62416cab0612f + checksum: 2683a8f29793c75a4728787662972fedd9267704c8f7ef9d84f2beed9a977f1cf5e998c07b6f36ba5603f53cb010c911fe8cd0ac9886e073fe28ca66beefd30c languageName: node linkType: hard -"jest-leak-detector@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-leak-detector@npm:29.6.2" +"jest-leak-detector@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-leak-detector@npm:29.7.0" dependencies: - jest-get-type: "npm:^29.4.3" - pretty-format: "npm:^29.6.2" - checksum: 70eb538bb137b769908d4d1e15d9b380a06285ea31c1d2ae05bcc9269863efe6369484cb33bf6c6f3e325dd53cd252cd7e868bdbd2b31367a9b41b449eb8e4a9 + jest-get-type: "npm:^29.6.3" + pretty-format: "npm:^29.7.0" + checksum: 71bb9f77fc489acb842a5c7be030f2b9acb18574dc9fb98b3100fc57d422b1abc55f08040884bd6e6dbf455047a62f7eaff12aa4058f7cbdc11558718ca6a395 languageName: node linkType: hard -"jest-matcher-utils@npm:^29.6.2, jest-matcher-utils@npm:^29.7.0": +"jest-matcher-utils@npm:^29.7.0": version: 29.7.0 resolution: "jest-matcher-utils@npm:29.7.0" dependencies: @@ -10264,7 +10303,7 @@ __metadata: languageName: node linkType: hard -"jest-message-util@npm:^29.6.2, jest-message-util@npm:^29.7.0": +"jest-message-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-message-util@npm:29.7.0" dependencies: @@ -10281,14 +10320,14 @@ __metadata: languageName: node linkType: hard -"jest-mock@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-mock@npm:29.6.2" +"jest-mock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-mock@npm:29.7.0" dependencies: - "@jest/types": "npm:^29.6.1" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" - jest-util: "npm:^29.6.2" - checksum: 34e8119876696d640db1b33b2c88f3bbd56b676f5e82ae65babdb56b0dab054d856b903785d38e1e8e3274549622b9a4556bfaa301d75fe4e2b30494cac5b8ee + jest-util: "npm:^29.7.0" + checksum: 7b9f8349ee87695a309fe15c46a74ab04c853369e5c40952d68061d9dc3159a0f0ed73e215f81b07ee97a9faaf10aebe5877a9d6255068a0977eae6a9ff1d5ac languageName: node linkType: hard @@ -10304,128 +10343,128 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^29.4.3": - version: 29.4.3 - resolution: "jest-regex-util@npm:29.4.3" - checksum: a7a4508bda47c5177e7337fb6fb22e9adab414ba141f224c9992c86973da1ccf5c69040e63636090ad26ef3a123d28bec950fa99496c157444b4f847e5e5a670 +"jest-regex-util@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-regex-util@npm:29.6.3" + checksum: 4e33fb16c4f42111159cafe26397118dcfc4cf08bc178a67149fb05f45546a91928b820894572679d62559839d0992e21080a1527faad65daaae8743a5705a3b languageName: node linkType: hard -"jest-resolve-dependencies@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-resolve-dependencies@npm:29.6.2" +"jest-resolve-dependencies@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve-dependencies@npm:29.7.0" dependencies: - jest-regex-util: "npm:^29.4.3" - jest-snapshot: "npm:^29.6.2" - checksum: b80172d164fe36a3cd9b19c458c3e8075e7935cdaa191f6e2e335f9b5c603faf0785efc35f9cf6c496729de34a3bd98f6cb8dd877c11fa6e17adf385d1ca85a6 + jest-regex-util: "npm:^29.6.3" + jest-snapshot: "npm:^29.7.0" + checksum: b6e9ad8ae5b6049474118ea6441dfddd385b6d1fc471db0136f7c8fbcfe97137a9665e4f837a9f49f15a29a1deb95a14439b7aec812f3f99d08f228464930f0d languageName: node linkType: hard -"jest-resolve@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-resolve@npm:29.6.2" +"jest-resolve@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve@npm:29.7.0" dependencies: chalk: "npm:^4.0.0" graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.2" + jest-haste-map: "npm:^29.7.0" jest-pnp-resolver: "npm:^1.2.2" - jest-util: "npm:^29.6.2" - jest-validate: "npm:^29.6.2" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" resolve: "npm:^1.20.0" resolve.exports: "npm:^2.0.0" slash: "npm:^3.0.0" - checksum: df6ace45facf1f9d8f2911fcc1eefcc871afa107748f41a2f84a3d7b707d2211be1450ba5044fe8fa1ffc497b6814309f71f376aac139683ddc7b05b263d45f9 + checksum: 59da5c9c5b50563e959a45e09e2eace783d7f9ac0b5dcc6375dea4c0db938d2ebda97124c8161310082760e8ebbeff9f6b177c15ca2f57fb424f637a5d2adb47 languageName: node linkType: hard -"jest-runner@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-runner@npm:29.6.2" +"jest-runner@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runner@npm:29.7.0" dependencies: - "@jest/console": "npm:^29.6.2" - "@jest/environment": "npm:^29.6.2" - "@jest/test-result": "npm:^29.6.2" - "@jest/transform": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/console": "npm:^29.7.0" + "@jest/environment": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" chalk: "npm:^4.0.0" emittery: "npm:^0.13.1" graceful-fs: "npm:^4.2.9" - jest-docblock: "npm:^29.4.3" - jest-environment-node: "npm:^29.6.2" - jest-haste-map: "npm:^29.6.2" - jest-leak-detector: "npm:^29.6.2" - jest-message-util: "npm:^29.6.2" - jest-resolve: "npm:^29.6.2" - jest-runtime: "npm:^29.6.2" - jest-util: "npm:^29.6.2" - jest-watcher: "npm:^29.6.2" - jest-worker: "npm:^29.6.2" + jest-docblock: "npm:^29.7.0" + jest-environment-node: "npm:^29.7.0" + jest-haste-map: "npm:^29.7.0" + jest-leak-detector: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-resolve: "npm:^29.7.0" + jest-runtime: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-watcher: "npm:^29.7.0" + jest-worker: "npm:^29.7.0" p-limit: "npm:^3.1.0" source-map-support: "npm:0.5.13" - checksum: d0f2fc80b01c40b28bb86ace6a1f913a346dbdd81d8ed84e689bc0e21b27f7e9d1b963e6d8ece44df1a870ba14016730ce08444b15f3fdee92a15dff0c6c1aa3 + checksum: 2194b4531068d939f14c8d3274fe5938b77fa73126aedf9c09ec9dec57d13f22c72a3b5af01ac04f5c1cf2e28d0ac0b4a54212a61b05f10b5d6b47f2a1097bb4 languageName: node linkType: hard -"jest-runtime@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-runtime@npm:29.6.2" +"jest-runtime@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runtime@npm:29.7.0" dependencies: - "@jest/environment": "npm:^29.6.2" - "@jest/fake-timers": "npm:^29.6.2" - "@jest/globals": "npm:^29.6.2" - "@jest/source-map": "npm:^29.6.0" - "@jest/test-result": "npm:^29.6.2" - "@jest/transform": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/environment": "npm:^29.7.0" + "@jest/fake-timers": "npm:^29.7.0" + "@jest/globals": "npm:^29.7.0" + "@jest/source-map": "npm:^29.6.3" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" chalk: "npm:^4.0.0" cjs-module-lexer: "npm:^1.0.0" collect-v8-coverage: "npm:^1.0.0" glob: "npm:^7.1.3" graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.6.2" - jest-message-util: "npm:^29.6.2" - jest-mock: "npm:^29.6.2" - jest-regex-util: "npm:^29.4.3" - jest-resolve: "npm:^29.6.2" - jest-snapshot: "npm:^29.6.2" - jest-util: "npm:^29.6.2" + jest-haste-map: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-mock: "npm:^29.7.0" + jest-regex-util: "npm:^29.6.3" + jest-resolve: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + jest-util: "npm:^29.7.0" slash: "npm:^3.0.0" strip-bom: "npm:^4.0.0" - checksum: 026a5fa33fa370561e6ab33a01b59e3e382b72f8eb7a42a85d1c9619bc9123a274ec791b823ad4bf58e20285758e9e895e53da6ae971c92124612f99fe7c7ffe + checksum: 7cd89a1deda0bda7d0941835434e44f9d6b7bd50b5c5d9b0fc9a6c990b2d4d2cab59685ab3cb2850ed4cc37059f6de903af5a50565d7f7f1192a77d3fd6dd2a6 languageName: node linkType: hard -"jest-snapshot@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-snapshot@npm:29.6.2" +"jest-snapshot@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-snapshot@npm:29.7.0" dependencies: "@babel/core": "npm:^7.11.6" "@babel/generator": "npm:^7.7.2" "@babel/plugin-syntax-jsx": "npm:^7.7.2" "@babel/plugin-syntax-typescript": "npm:^7.7.2" "@babel/types": "npm:^7.3.3" - "@jest/expect-utils": "npm:^29.6.2" - "@jest/transform": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/expect-utils": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" babel-preset-current-node-syntax: "npm:^1.0.0" chalk: "npm:^4.0.0" - expect: "npm:^29.6.2" + expect: "npm:^29.7.0" graceful-fs: "npm:^4.2.9" - jest-diff: "npm:^29.6.2" - jest-get-type: "npm:^29.4.3" - jest-matcher-utils: "npm:^29.6.2" - jest-message-util: "npm:^29.6.2" - jest-util: "npm:^29.6.2" + jest-diff: "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + jest-matcher-utils: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" natural-compare: "npm:^1.4.0" - pretty-format: "npm:^29.6.2" + pretty-format: "npm:^29.7.0" semver: "npm:^7.5.3" - checksum: 79f02c2becf90a1b5c5d06833b0a4c9f6e0d7a9fcd36e69f81750ab147180dd06e3565e83c1d79a1ef8b7943c5af3eb3e0119c45e92f78e1189279c4fba2e136 + checksum: 6e9003c94ec58172b4a62864a91c0146513207bedf4e0a06e1e2ac70a4484088a2683e3a0538d8ea913bcfd53dc54a9b98a98cdfa562e7fe1d1339aeae1da570 languageName: node linkType: hard -"jest-util@npm:^29.6.2, jest-util@npm:^29.7.0": +"jest-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-util@npm:29.7.0" dependencies: @@ -10439,33 +10478,33 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-validate@npm:29.6.2" +"jest-validate@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-validate@npm:29.7.0" dependencies: - "@jest/types": "npm:^29.6.1" + "@jest/types": "npm:^29.6.3" camelcase: "npm:^6.2.0" chalk: "npm:^4.0.0" - jest-get-type: "npm:^29.4.3" + jest-get-type: "npm:^29.6.3" leven: "npm:^3.1.0" - pretty-format: "npm:^29.6.2" - checksum: 79af1153268d896deb183230fba547398fde7b8a4f45fe33f1cd5c3b6b84d317e4b87ea7988d1137348c693e7f9450cce7af4529d5b190891bf493bc93024e40 + pretty-format: "npm:^29.7.0" + checksum: a20b930480c1ed68778c739f4739dce39423131bc070cd2505ddede762a5570a256212e9c2401b7ae9ba4d7b7c0803f03c5b8f1561c62348213aba18d9dbece2 languageName: node linkType: hard -"jest-watcher@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-watcher@npm:29.6.2" +"jest-watcher@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-watcher@npm:29.7.0" dependencies: - "@jest/test-result": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/test-result": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" ansi-escapes: "npm:^4.2.1" chalk: "npm:^4.0.0" emittery: "npm:^0.13.1" - jest-util: "npm:^29.6.2" + jest-util: "npm:^29.7.0" string-length: "npm:^4.0.1" - checksum: ba567798961d52b3ca1f853169a5860111ae764de90634b86a4a5cc676848c147bee5d95cd168b5c5941533ed384f677764474d009437a03b6b6a15da6232eb3 + checksum: ec6c75030562fc8f8c727cb8f3b94e75d831fc718785abfc196e1f2a2ebc9a2e38744a15147170039628a853d77a3b695561ce850375ede3a4ee6037a2574567 languageName: node linkType: hard @@ -10480,26 +10519,26 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^29.6.2": - version: 29.6.2 - resolution: "jest-worker@npm:29.6.2" +"jest-worker@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-worker@npm:29.7.0" dependencies: "@types/node": "npm:*" - jest-util: "npm:^29.6.2" + jest-util: "npm:^29.7.0" merge-stream: "npm:^2.0.0" supports-color: "npm:^8.0.0" - checksum: 8b978cb4851222e536aef552bdc06a60db580d0f921107fe1a1b94cdc8b39ddeb076b23e5bb96b69752c2f936b803295cdff11484f7c5efaf4562952e2cc0897 + checksum: 5570a3a005b16f46c131968b8a5b56d291f9bbb85ff4217e31c80bd8a02e7de799e59a54b95ca28d5c302f248b54cbffde2d177c2f0f52ffcee7504c6eabf660 languageName: node linkType: hard "jest@npm:^29.5.0": - version: 29.6.2 - resolution: "jest@npm:29.6.2" + version: 29.7.0 + resolution: "jest@npm:29.7.0" dependencies: - "@jest/core": "npm:^29.6.2" - "@jest/types": "npm:^29.6.1" + "@jest/core": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" import-local: "npm:^3.0.2" - jest-cli: "npm:^29.6.2" + jest-cli: "npm:^29.7.0" peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -10507,7 +10546,7 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: fdb4df81f2bf1ad58f98f74b6d6f74d7727bd8fd5a8ddefc1e7612b8a68cbd0a4ae134060c5b987b01281f1fe93276c1abb034ef1ce06a0ea1468f288fafc7c1 + checksum: f40eb8171cf147c617cc6ada49d062fbb03b4da666cb8d39cdbfb739a7d75eea4c3ca150fb072d0d273dce0c753db4d0467d54906ad0293f59c54f9db4a09d8b languageName: node linkType: hard @@ -10824,10 +10863,10 @@ __metadata: languageName: node linkType: hard -"known-css-properties@npm:^0.27.0": - version: 0.27.0 - resolution: "known-css-properties@npm:0.27.0" - checksum: 49bf8d0a773039d07726d263c92145fa73be9a18990d54c3b3cebf472fdfb0095124a3fcfca3ccd1225231d4bdf9615c82e029b2d0d508de130f6be7467af9e4 +"known-css-properties@npm:^0.29.0": + version: 0.29.0 + resolution: "known-css-properties@npm:0.29.0" + checksum: f66e9992097b8f54e97dbe729943d4a11b8d3ba15f68dbb3deb8bb0122cb89c22c90c9221ecb1e3f2e236838fe3c0faae319b43908c81b6e254ac43cafde2906 languageName: node linkType: hard @@ -10879,8 +10918,8 @@ __metadata: linkType: hard "lint-staged@npm:^15.0.0": - version: 15.0.2 - resolution: "lint-staged@npm:15.0.2" + version: 15.1.0 + resolution: "lint-staged@npm:15.1.0" dependencies: chalk: "npm:5.3.0" commander: "npm:11.1.0" @@ -10891,10 +10930,10 @@ __metadata: micromatch: "npm:4.0.5" pidtree: "npm:0.6.0" string-argv: "npm:0.3.2" - yaml: "npm:2.3.3" + yaml: "npm:2.3.4" bin: lint-staged: bin/lint-staged.js - checksum: 5c8806137c8c9c63e1156e16f2a2763586a9eab8f24713b95bbfd099308c83f85af2df622fdc326a9f0e455e657718f61f6d4a81067a5c77243e65e822c8f16c + checksum: d427408be98df7558e918593cb765d5caaa67a5cdca89671fb54280a6c959f4e448db36d4f85e8e0bd9c2c1e996aa133916925cf47c9df573b47308d5e298d84 languageName: node linkType: hard @@ -13152,12 +13191,12 @@ __metadata: languageName: node linkType: hard -"postcss-scss@npm:^4.0.7": - version: 4.0.7 - resolution: "postcss-scss@npm:4.0.7" +"postcss-scss@npm:^4.0.9": + version: 4.0.9 + resolution: "postcss-scss@npm:4.0.9" peerDependencies: - postcss: ^8.4.19 - checksum: 2f86938fef39bd766ada496d8ccac840bf9f2dee0d9c6006dc2903ba0fbdc9f5c2d6ead1f3e7508f8d82eee6ad25df7d77e9196c4c6bec8952ef9a7403f30efc + postcss: ^8.4.29 + checksum: f917ecfd4b9113a6648e966a41f027ff7e14238393914978d44596e227a50f084667dc8818742348dc7d8b20130b30d4259aca1d4db86754a9c141202ae03714 languageName: node linkType: hard @@ -13201,7 +13240,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.25": +"postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.28": version: 8.4.31 resolution: "postcss@npm:8.4.31" dependencies: @@ -13296,11 +13335,11 @@ __metadata: linkType: hard "prettier@npm:^3.0.0": - version: 3.0.1 - resolution: "prettier@npm:3.0.1" + version: 3.1.0 + resolution: "prettier@npm:3.1.0" bin: prettier: bin/prettier.cjs - checksum: 7231768b6e0f0f17cbaa83a4f7cdb100df0229ef1910b0b2cf72ce5ed8ee25ae7ec0d30cde20dcd898a002c6d1fcdb8a6ab0f8f5d8fc1275b7c29ea9e56305f2 + checksum: a45ea70aa97fde162ea4c4aba3dfc7859aa6a732a1db34458d9535dc3c2c16d3bc3fb5689e6cd76aa835562555303b02d9449fd2e15af3b73c8053557e25c5b6 languageName: node linkType: hard @@ -13322,7 +13361,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.0.0, pretty-format@npm:^29.6.2, pretty-format@npm:^29.7.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" dependencies: @@ -15720,20 +15759,20 @@ __metadata: languageName: node linkType: hard -"stylelint-config-recommended-scss@npm:^13.0.0": - version: 13.0.0 - resolution: "stylelint-config-recommended-scss@npm:13.0.0" +"stylelint-config-recommended-scss@npm:^13.1.0": + version: 13.1.0 + resolution: "stylelint-config-recommended-scss@npm:13.1.0" dependencies: - postcss-scss: "npm:^4.0.7" + postcss-scss: "npm:^4.0.9" stylelint-config-recommended: "npm:^13.0.0" - stylelint-scss: "npm:^5.1.0" + stylelint-scss: "npm:^5.3.0" peerDependencies: postcss: ^8.3.3 stylelint: ^15.10.0 peerDependenciesMeta: postcss: optional: true - checksum: 370152e20e6395800ac89517019f03153b121ce7a7dfa0865442365bf2725935da9df2eb3e8b5ee4e240d1b3a7438ee2cd1932009bdc59da8c2a790066379387 + checksum: e07d0172c7936b4f644138e4129df2f187d297f1f96ce5865ab21ccd1c22caf94220f7caf9d6985e93e515de4c0356f6cb9c924d00df2eee5b3bc237f7e5bb48 languageName: node linkType: hard @@ -15747,10 +15786,10 @@ __metadata: linkType: hard "stylelint-config-standard-scss@npm:^11.0.0": - version: 11.0.0 - resolution: "stylelint-config-standard-scss@npm:11.0.0" + version: 11.1.0 + resolution: "stylelint-config-standard-scss@npm:11.1.0" dependencies: - stylelint-config-recommended-scss: "npm:^13.0.0" + stylelint-config-recommended-scss: "npm:^13.1.0" stylelint-config-standard: "npm:^34.0.0" peerDependencies: postcss: ^8.3.3 @@ -15758,7 +15797,7 @@ __metadata: peerDependenciesMeta: postcss: optional: true - checksum: 9b0766ec11f1e6f690c1e22d74e7f7103f64569bdca966c26ff43f81f55f13797fdb1503338f973672c001daf50b13682361dd4105d22497841437c148f86be5 + checksum: 22d00e75c1eacce9883fd48c3d67b1107b0e39d7d86e9f73deaa332b11c39a9678c947ae2c34cd5159a452ec9a857694ed58b5a851087480d3c9a66dab629415 languageName: node linkType: hard @@ -15773,37 +15812,38 @@ __metadata: languageName: node linkType: hard -"stylelint-scss@npm:^5.1.0": - version: 5.1.0 - resolution: "stylelint-scss@npm:5.1.0" +"stylelint-scss@npm:^5.3.0": + version: 5.3.1 + resolution: "stylelint-scss@npm:5.3.1" dependencies: + known-css-properties: "npm:^0.29.0" postcss-media-query-parser: "npm:^0.2.3" postcss-resolve-nested-selector: "npm:^0.1.1" postcss-selector-parser: "npm:^6.0.13" postcss-value-parser: "npm:^4.2.0" peerDependencies: stylelint: ^14.5.1 || ^15.0.0 - checksum: af176340227e77942429d2032cd345ebc8e40e4ff17a2ce69b6000252da178f21d1a97311a258a81c76c0610a96650c1e2ecdfa0d598a6fc41e31d6a7cd03847 + checksum: 5dfed5f9ac9812cd2ac6ef0272c720dee0326aaaee2998315a23bdcd71b8f04427f29cad634793eea2b45984182e20f03e90d43501e8e4d55bc956f80e2de477 languageName: node linkType: hard "stylelint@npm:^15.10.1": - version: 15.10.2 - resolution: "stylelint@npm:15.10.2" + version: 15.11.0 + resolution: "stylelint@npm:15.11.0" dependencies: - "@csstools/css-parser-algorithms": "npm:^2.3.0" - "@csstools/css-tokenizer": "npm:^2.1.1" - "@csstools/media-query-list-parser": "npm:^2.1.2" + "@csstools/css-parser-algorithms": "npm:^2.3.1" + "@csstools/css-tokenizer": "npm:^2.2.0" + "@csstools/media-query-list-parser": "npm:^2.1.4" "@csstools/selector-specificity": "npm:^3.0.0" balanced-match: "npm:^2.0.0" colord: "npm:^2.9.3" cosmiconfig: "npm:^8.2.0" - css-functions-list: "npm:^3.2.0" + css-functions-list: "npm:^3.2.1" css-tree: "npm:^2.3.1" debug: "npm:^4.3.4" - fast-glob: "npm:^3.3.0" + fast-glob: "npm:^3.3.1" fastest-levenshtein: "npm:^1.0.16" - file-entry-cache: "npm:^6.0.1" + file-entry-cache: "npm:^7.0.0" global-modules: "npm:^2.0.0" globby: "npm:^11.1.0" globjoin: "npm:^0.1.4" @@ -15812,13 +15852,13 @@ __metadata: import-lazy: "npm:^4.0.0" imurmurhash: "npm:^0.1.4" is-plain-object: "npm:^5.0.0" - known-css-properties: "npm:^0.27.0" + known-css-properties: "npm:^0.29.0" mathml-tag-names: "npm:^2.1.3" meow: "npm:^10.1.5" micromatch: "npm:^4.0.5" normalize-path: "npm:^3.0.0" picocolors: "npm:^1.0.0" - postcss: "npm:^8.4.25" + postcss: "npm:^8.4.28" postcss-resolve-nested-selector: "npm:^0.1.1" postcss-safe-parser: "npm:^6.0.0" postcss-selector-parser: "npm:^6.0.13" @@ -15833,7 +15873,7 @@ __metadata: write-file-atomic: "npm:^5.0.1" bin: stylelint: bin/stylelint.mjs - checksum: 8378ee868b09322d2b7e07b03461c524736778a391b2ce6d4ad46c636e55a90ed98723f253db10d9a762cfefec60200d0b9c5cd7798b2f373efd2d986768ebc7 + checksum: 2d88b7293e308b7e418c14ba4130777b1a28b214304957f03b41a6dc8e00005266caf47479f718a6ec5e572cb52e903ca34aabf3febbe3a3ae32fff6b018d9fd languageName: node linkType: hard @@ -17724,10 +17764,10 @@ __metadata: languageName: node linkType: hard -"yaml@npm:2.3.3": - version: 2.3.3 - resolution: "yaml@npm:2.3.3" - checksum: a0c56bf682159b0567e9cbbddf23efc2f6806f6450716d9be6ec5eb1af1b941e95c8d3dc9c47da20d1b6883a9d6c61e31cf98bb4b77ebca4396bf772657f2f00 +"yaml@npm:2.3.4": + version: 2.3.4 + resolution: "yaml@npm:2.3.4" + checksum: cf03b68f8fef5e8516b0f0b54edaf2459f1648317fc6210391cf606d247e678b449382f4bd01f77392538429e306c7cba8ff46ff6b37cac4de9a76aff33bd9e1 languageName: node linkType: hard From a36b59be8ad7656b7ceab9751c9ec5b3563e3a30 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 13 Nov 2023 09:32:36 -0500 Subject: [PATCH 15/15] Spec coverage for `api/v1/trends` controllers (#27837) --- .../api/v1/trends/links_controller_spec.rb | 38 +++++++++++++++-- .../api/v1/trends/statuses_controller_spec.rb | 38 +++++++++++++++-- .../api/v1/trends/tags_controller_spec.rb | 41 +++++++++++++++---- 3 files changed, 101 insertions(+), 16 deletions(-) diff --git a/spec/controllers/api/v1/trends/links_controller_spec.rb b/spec/controllers/api/v1/trends/links_controller_spec.rb index 71a7e2e477..12d4198aaf 100644 --- a/spec/controllers/api/v1/trends/links_controller_spec.rb +++ b/spec/controllers/api/v1/trends/links_controller_spec.rb @@ -2,14 +2,44 @@ require 'rails_helper' -describe Api::V1::Trends::LinksController do +RSpec.describe Api::V1::Trends::LinksController do render_views describe 'GET #index' do - it 'returns http success' do - get :index + around do |example| + previous = Setting.trends + example.run + Setting.trends = previous + end - expect(response).to have_http_status(200) + context 'when trends are disabled' do + before { Setting.trends = false } + + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end + + context 'when trends are enabled' do + before { Setting.trends = true } + + it 'returns http success' do + prepare_trends + stub_const('Api::V1::Trends::LinksController::DEFAULT_LINKS_LIMIT', 2) + get :index + + expect(response).to have_http_status(200) + expect(response.headers).to include('Link') + end + + def prepare_trends + Fabricate.times(3, :preview_card, trendable: true, language: 'en').each do |link| + 2.times { |i| Trends.links.add(link, i) } + end + Trends::Links.new(threshold: 1).refresh + end end end end diff --git a/spec/controllers/api/v1/trends/statuses_controller_spec.rb b/spec/controllers/api/v1/trends/statuses_controller_spec.rb index e9892bb140..69fdb270d5 100644 --- a/spec/controllers/api/v1/trends/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/trends/statuses_controller_spec.rb @@ -2,14 +2,44 @@ require 'rails_helper' -describe Api::V1::Trends::StatusesController do +RSpec.describe Api::V1::Trends::StatusesController do render_views describe 'GET #index' do - it 'returns http success' do - get :index + around do |example| + previous = Setting.trends + example.run + Setting.trends = previous + end - expect(response).to have_http_status(200) + context 'when trends are disabled' do + before { Setting.trends = false } + + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end + + context 'when trends are enabled' do + before { Setting.trends = true } + + it 'returns http success' do + prepare_trends + stub_const('Api::BaseController::DEFAULT_STATUSES_LIMIT', 2) + get :index + + expect(response).to have_http_status(200) + expect(response.headers).to include('Link') + end + + def prepare_trends + Fabricate.times(3, :status, trendable: true, language: 'en').each do |status| + 2.times { |i| Trends.statuses.add(status, i) } + end + Trends::Statuses.new(threshold: 1, decay_threshold: -1).refresh + end end end end diff --git a/spec/controllers/api/v1/trends/tags_controller_spec.rb b/spec/controllers/api/v1/trends/tags_controller_spec.rb index 84370d8412..9311392cd9 100644 --- a/spec/controllers/api/v1/trends/tags_controller_spec.rb +++ b/spec/controllers/api/v1/trends/tags_controller_spec.rb @@ -6,16 +6,41 @@ RSpec.describe Api::V1::Trends::TagsController do render_views describe 'GET #index' do - before do - Fabricate.times(10, :tag).each do |tag| - 10.times { |i| Trends.tags.add(tag, i) } - end - - get :index + around do |example| + previous = Setting.trends + example.run + Setting.trends = previous end - it 'returns http success' do - expect(response).to have_http_status(200) + context 'when trends are disabled' do + before { Setting.trends = false } + + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + expect(response.headers).to_not include('Link') + end + end + + context 'when trends are enabled' do + before { Setting.trends = true } + + it 'returns http success' do + prepare_trends + stub_const('Api::V1::Trends::TagsController::DEFAULT_TAGS_LIMIT', 2) + get :index + + expect(response).to have_http_status(200) + expect(response.headers).to include('Link') + end + + def prepare_trends + Fabricate.times(3, :tag, trendable: true).each do |tag| + 2.times { |i| Trends.tags.add(tag, i) } + end + Trends::Tags.new(threshold: 1).refresh + end end end end