{currentVersion.get('spoiler_text').length > 0 && (
-
diff --git a/app/javascript/mastodon/features/ui/components/compose_panel.jsx b/app/javascript/mastodon/features/ui/components/compose_panel.jsx
index 1c6f80ad5c..51cd2a5ecd 100644
--- a/app/javascript/mastodon/features/ui/components/compose_panel.jsx
+++ b/app/javascript/mastodon/features/ui/components/compose_panel.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import { PureComponent } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import SearchContainer from 'mastodon/features/compose/containers/search_container';
@@ -8,7 +8,7 @@ import LinkFooter from './link_footer';
import ServerBanner from 'mastodon/components/server_banner';
import { changeComposing, mountCompose, unmountCompose } from 'mastodon/actions/compose';
-class ComposePanel extends React.PureComponent {
+class ComposePanel extends PureComponent {
static contextTypes = {
identity: PropTypes.object.isRequired,
@@ -46,17 +46,17 @@ class ComposePanel extends React.PureComponent {
diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx b/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx
index 4437567a14..412993ea2c 100644
--- a/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx
+++ b/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx
@@ -1,9 +1,9 @@
-import React from 'react';
+import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, FormattedMessage } from 'react-intl';
import Button from '../../../components/button';
-class ConfirmationModal extends React.PureComponent {
+class ConfirmationModal extends PureComponent {
static propTypes = {
message: PropTypes.node.isRequired,
diff --git a/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx b/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx
index ea11cea44d..0fa497e8bf 100644
--- a/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx
+++ b/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
@@ -28,7 +28,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
},
});
-class DisabledAccountBanner extends React.PureComponent {
+class DisabledAccountBanner extends PureComponent {
static propTypes = {
disabledAcct: PropTypes.string.isRequired,
diff --git a/app/javascript/mastodon/features/ui/components/drawer_loading.jsx b/app/javascript/mastodon/features/ui/components/drawer_loading.jsx
index 08b0d23476..11072ad98c 100644
--- a/app/javascript/mastodon/features/ui/components/drawer_loading.jsx
+++ b/app/javascript/mastodon/features/ui/components/drawer_loading.jsx
@@ -1,5 +1,3 @@
-import React from 'react';
-
const DrawerLoading = () => (
diff --git a/app/javascript/mastodon/features/ui/components/embed_modal.jsx b/app/javascript/mastodon/features/ui/components/embed_modal.jsx
index 949c640421..6187bfeb20 100644
--- a/app/javascript/mastodon/features/ui/components/embed_modal.jsx
+++ b/app/javascript/mastodon/features/ui/components/embed_modal.jsx
@@ -1,4 +1,3 @@
-import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
diff --git a/app/javascript/mastodon/features/ui/components/filter_modal.jsx b/app/javascript/mastodon/features/ui/components/filter_modal.jsx
index 473fe4b360..7b5a1a03a6 100644
--- a/app/javascript/mastodon/features/ui/components/filter_modal.jsx
+++ b/app/javascript/mastodon/features/ui/components/filter_modal.jsx
@@ -1,4 +1,3 @@
-import React from 'react';
import { connect } from 'react-redux';
import { fetchStatus } from 'mastodon/actions/statuses';
import { fetchFilters, createFilter, createFilterStatus } from 'mastodon/actions/filters';
diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx
index d6f15e276b..d4d852d246 100644
--- a/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx
+++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import { PureComponent } from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import ImmutablePureComponent from 'react-immutable-pure-component';
@@ -69,7 +69,7 @@ const removeExtraLineBreaks = str => str.replace(/\n\n/g, '******')
.replace(/\n/g, ' ')
.replace(/\*\*\*\*\*\*/g, '\n\n');
-class ImageLoader extends React.PureComponent {
+class ImageLoader extends PureComponent {
static propTypes = {
src: PropTypes.string.isRequired,
@@ -315,7 +315,7 @@ class FocalPointModal extends ImmutablePureComponent {
{focals &&
}
{thumbnailable && (
-
+ <>
@@ -335,7 +335,7 @@ class FocalPointModal extends ImmutablePureComponent {
-
+ >
)}
{signedIn && (
-
+ <>
} text={intl.formatMessage(messages.notifications)} />
-
+ >
)}
{showTrends ? (
@@ -79,7 +79,7 @@ class NavigationPanel extends React.Component {
)}
{signedIn && (
-
+ <>
@@ -90,7 +90,7 @@ class NavigationPanel extends React.Component {
-
+ >
)}
diff --git a/app/javascript/mastodon/features/ui/components/report_modal.jsx b/app/javascript/mastodon/features/ui/components/report_modal.jsx
index f3ada9c07b..c7909040ed 100644
--- a/app/javascript/mastodon/features/ui/components/report_modal.jsx
+++ b/app/javascript/mastodon/features/ui/components/report_modal.jsx
@@ -1,4 +1,3 @@
-import React from 'react';
import { connect } from 'react-redux';
import { submitReport } from 'mastodon/actions/reports';
import { expandAccountTimeline } from 'mastodon/actions/timelines';
diff --git a/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx
index 39f0c71c34..984a574e56 100644
--- a/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx
+++ b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx
@@ -1,4 +1,4 @@
-import React, { useCallback } from 'react';
+import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { useDispatch } from 'react-redux';
import { registrationsOpen } from 'mastodon/initial_state';
diff --git a/app/javascript/mastodon/features/ui/components/upload_area.jsx b/app/javascript/mastodon/features/ui/components/upload_area.jsx
index cec4cf5b1e..64df8fbf7d 100644
--- a/app/javascript/mastodon/features/ui/components/upload_area.jsx
+++ b/app/javascript/mastodon/features/ui/components/upload_area.jsx
@@ -1,10 +1,10 @@
-import React from 'react';
+import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Motion from '../util/optional_motion';
import spring from 'react-motion/lib/spring';
import { FormattedMessage } from 'react-intl';
-export default class UploadArea extends React.PureComponent {
+export default class UploadArea extends PureComponent {
static propTypes = {
active: PropTypes.bool,
diff --git a/app/javascript/mastodon/features/ui/components/video_modal.jsx b/app/javascript/mastodon/features/ui/components/video_modal.jsx
index 99359a58cc..ffc863530d 100644
--- a/app/javascript/mastodon/features/ui/components/video_modal.jsx
+++ b/app/javascript/mastodon/features/ui/components/video_modal.jsx
@@ -1,4 +1,3 @@
-import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Video from 'mastodon/features/video';
diff --git a/app/javascript/mastodon/features/ui/components/zoomable_image.jsx b/app/javascript/mastodon/features/ui/components/zoomable_image.jsx
index 49be6d5c3b..47d8b63ed0 100644
--- a/app/javascript/mastodon/features/ui/components/zoomable_image.jsx
+++ b/app/javascript/mastodon/features/ui/components/zoomable_image.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { IconButton } from 'mastodon/components/icon_button';
import { defineMessages, injectIntl } from 'react-intl';
@@ -91,7 +91,7 @@ const normalizeWheel = event => {
};
};
-class ZoomableImage extends React.PureComponent {
+class ZoomableImage extends PureComponent {
static propTypes = {
alt: PropTypes.string,
@@ -411,7 +411,7 @@ class ZoomableImage extends React.PureComponent {
const zoomButtonTitle = this.state.zoomState === 'compress' ? intl.formatMessage(messages.compress) : intl.formatMessage(messages.expand);
return (
-
+ <>
-
+ >
);
}
diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx
index df6a1b3fa2..edf039dcb2 100644
--- a/app/javascript/mastodon/features/ui/index.jsx
+++ b/app/javascript/mastodon/features/ui/index.jsx
@@ -1,5 +1,5 @@
import classNames from 'classnames';
-import React from 'react';
+import { PureComponent } from 'react';
import { HotKeys } from 'react-hotkeys';
import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
@@ -114,7 +114,7 @@ const keyMap = {
openMedia: 'e',
};
-class SwitchingColumnsArea extends React.PureComponent {
+class SwitchingColumnsArea extends PureComponent {
static contextTypes = {
identity: PropTypes.object,
@@ -235,7 +235,7 @@ class SwitchingColumnsArea extends React.PureComponent {
}
-class UI extends React.PureComponent {
+class UI extends PureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
diff --git a/app/javascript/mastodon/features/ui/util/react_router_helpers.jsx b/app/javascript/mastodon/features/ui/util/react_router_helpers.jsx
index 21b3528785..64aad000ac 100644
--- a/app/javascript/mastodon/features/ui/util/react_router_helpers.jsx
+++ b/app/javascript/mastodon/features/ui/util/react_router_helpers.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import { Component, PureComponent, cloneElement, Children } from 'react';
import PropTypes from 'prop-types';
import { Switch, Route } from 'react-router-dom';
import StackTrace from 'stacktrace-js';
@@ -7,14 +7,14 @@ import BundleColumnError from '../components/bundle_column_error';
import BundleContainer from '../containers/bundle_container';
// Small wrapper to pass multiColumn to the route components
-export class WrappedSwitch extends React.PureComponent {
+export class WrappedSwitch extends PureComponent {
render () {
const { multiColumn, children } = this.props;
return (
- {React.Children.map(children, child => React.cloneElement(child, { multiColumn }))}
+ {Children.map(children, child => cloneElement(child, { multiColumn }))}
);
}
@@ -29,7 +29,7 @@ WrappedSwitch.propTypes = {
// Small Wrapper to extract the params from the route and pass
// them to the rendered component, together with the content to
// be rendered inside (the children)
-export class WrappedRoute extends React.Component {
+export class WrappedRoute extends Component {
static propTypes = {
component: PropTypes.func.isRequired,
diff --git a/app/javascript/mastodon/features/ui/util/reduced_motion.jsx b/app/javascript/mastodon/features/ui/util/reduced_motion.jsx
index 1123b80ed9..85ede744c8 100644
--- a/app/javascript/mastodon/features/ui/util/reduced_motion.jsx
+++ b/app/javascript/mastodon/features/ui/util/reduced_motion.jsx
@@ -1,6 +1,6 @@
// Like react-motion's Motion, but reduces all animations to cross-fades
// for the benefit of users with motion sickness.
-import React from 'react';
+import { Component } from 'react';
import Motion from 'react-motion/lib/Motion';
import PropTypes from 'prop-types';
@@ -11,7 +11,7 @@ const extractValue = (value) => {
return (typeof value === 'object' && value && 'val' in value) ? value.val : value;
};
-class ReducedMotion extends React.Component {
+class ReducedMotion extends Component {
static propTypes = {
defaultStyle: PropTypes.object,
diff --git a/app/javascript/mastodon/features/video/index.jsx b/app/javascript/mastodon/features/video/index.jsx
index 560dbc6d6a..81ed457c99 100644
--- a/app/javascript/mastodon/features/video/index.jsx
+++ b/app/javascript/mastodon/features/video/index.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { is } from 'immutable';
@@ -94,7 +94,7 @@ export const fileNameFromURL = str => {
return pathname.slice(index + 1);
};
-class Video extends React.PureComponent {
+class Video extends PureComponent {
static propTypes = {
preview: PropTypes.string,
diff --git a/app/javascript/mastodon/main.jsx b/app/javascript/mastodon/main.jsx
index b31540cb55..8f45e18f72 100644
--- a/app/javascript/mastodon/main.jsx
+++ b/app/javascript/mastodon/main.jsx
@@ -1,4 +1,3 @@
-import React from 'react';
import { createRoot } from 'react-dom/client';
import { setupBrowserNotifications } from 'mastodon/actions/notifications';
import Mastodon from 'mastodon/containers/mastodon';
diff --git a/app/javascript/mastodon/utils/icons.jsx b/app/javascript/mastodon/utils/icons.jsx
index c3e362e39a..be566032e0 100644
--- a/app/javascript/mastodon/utils/icons.jsx
+++ b/app/javascript/mastodon/utils/icons.jsx
@@ -1,5 +1,3 @@
-import React from 'react';
-
// Copied from emoji-mart for consistency with emoji picker and since
// they don't export the icons in the package
export const loupeIcon = (
diff --git a/app/lib/admin/metrics/dimension.rb b/app/lib/admin/metrics/dimension.rb
index 81b89d9b32..e0122a65b5 100644
--- a/app/lib/admin/metrics/dimension.rb
+++ b/app/lib/admin/metrics/dimension.rb
@@ -14,9 +14,9 @@ class Admin::Metrics::Dimension
}.freeze
def self.retrieve(dimension_keys, start_at, end_at, limit, params)
- Array(dimension_keys).map do |key|
+ Array(dimension_keys).filter_map do |key|
klass = DIMENSIONS[key.to_sym]
klass&.new(start_at, end_at, limit, klass.with_params? ? params.require(key.to_sym) : nil)
- end.compact
+ end
end
end
diff --git a/app/lib/admin/metrics/measure.rb b/app/lib/admin/metrics/measure.rb
index 0b510eb256..fe7e049290 100644
--- a/app/lib/admin/metrics/measure.rb
+++ b/app/lib/admin/metrics/measure.rb
@@ -19,9 +19,9 @@ class Admin::Metrics::Measure
}.freeze
def self.retrieve(measure_keys, start_at, end_at, params)
- Array(measure_keys).map do |key|
+ Array(measure_keys).filter_map do |key|
klass = MEASURES[key.to_sym]
klass&.new(start_at, end_at, klass.with_params? ? params.require(key.to_sym) : nil)
- end.compact
+ end
end
end
diff --git a/app/lib/extractor.rb b/app/lib/extractor.rb
index 540bbe1a92..9090773ae9 100644
--- a/app/lib/extractor.rb
+++ b/app/lib/extractor.rb
@@ -64,7 +64,7 @@ module Extractor
end_position = match_data.char_end(1)
after = ::Regexp.last_match.post_match
- if %r{\A://}.match?(after)
+ if after.start_with?('://')
hash_text.match(/(.+)(https?\Z)/) do |matched|
hash_text = matched[1]
end_position -= matched[2].codepoint_length
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 3b64f62631..aef20dc52e 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -188,7 +188,7 @@ class FeedManager
timeline_key = key(:home, account.id)
timeline_status_ids = redis.zrange(timeline_key, 0, -1)
statuses = Status.where(id: timeline_status_ids).select(:id, :reblog_of_id, :account_id).to_a
- reblogged_ids = Status.where(id: statuses.map(&:reblog_of_id).compact, account: target_account).pluck(:id)
+ reblogged_ids = Status.where(id: statuses.filter_map(&:reblog_of_id), account: target_account).pluck(:id)
with_mentions_ids = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact, account: target_account).pluck(:status_id)
target_statuses = statuses.select do |status|
@@ -208,7 +208,7 @@ class FeedManager
timeline_key = key(:list, list.id)
timeline_status_ids = redis.zrange(timeline_key, 0, -1)
statuses = Status.where(id: timeline_status_ids).select(:id, :reblog_of_id, :account_id).to_a
- reblogged_ids = Status.where(id: statuses.map(&:reblog_of_id).compact, account: target_account).pluck(:id)
+ reblogged_ids = Status.where(id: statuses.filter_map(&:reblog_of_id), account: target_account).pluck(:id)
with_mentions_ids = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact, account: target_account).pluck(:status_id)
target_statuses = statuses.select do |status|
@@ -543,9 +543,9 @@ class FeedManager
arr
end
- crutches[:following] = Follow.where(account_id: receiver_id, target_account_id: statuses.map(&:in_reply_to_account_id).compact).pluck(:target_account_id).index_with(true)
+ crutches[:following] = Follow.where(account_id: receiver_id, target_account_id: statuses.filter_map(&:in_reply_to_account_id)).pluck(:target_account_id).index_with(true)
crutches[:languages] = Follow.where(account_id: receiver_id, target_account_id: statuses.map(&:account_id)).pluck(:target_account_id, :languages).to_h
- crutches[:hiding_reblogs] = Follow.where(account_id: receiver_id, target_account_id: statuses.map { |s| s.account_id if s.reblog? }.compact, show_reblogs: false).pluck(:target_account_id).index_with(true)
+ crutches[:hiding_reblogs] = Follow.where(account_id: receiver_id, target_account_id: statuses.filter_map { |s| s.account_id if s.reblog? }, show_reblogs: false).pluck(:target_account_id).index_with(true)
crutches[:blocking] = Block.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).index_with(true)
crutches[:muting] = Mute.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).index_with(true)
crutches[:domain_blocking] = AccountDomainBlock.where(account_id: receiver_id, domain: statuses.flat_map { |s| [s.account.domain, s.reblog&.account&.domain] }.compact).pluck(:domain).index_with(true)
diff --git a/app/models/account.rb b/app/models/account.rb
index 357d62404a..b31194d512 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -378,11 +378,11 @@ class Account < ApplicationRecord
end
def fields
- (self[:fields] || []).map do |f|
+ (self[:fields] || []).filter_map do |f|
Account::Field.new(self, f)
rescue
nil
- end.compact
+ end
end
def fields_attributes=(attributes)
diff --git a/app/models/account_statuses_cleanup_policy.rb b/app/models/account_statuses_cleanup_policy.rb
index 17bbb4943d..83a17c7700 100644
--- a/app/models/account_statuses_cleanup_policy.rb
+++ b/app/models/account_statuses_cleanup_policy.rb
@@ -123,12 +123,12 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
private
def update_last_inspected
- if EXCEPTION_BOOLS.map { |name| attribute_change_to_be_saved(name) }.compact.include?([true, false])
+ if EXCEPTION_BOOLS.filter_map { |name| attribute_change_to_be_saved(name) }.include?([true, false])
# Policy has been widened in such a way that any previously-inspected status
# may need to be deleted, so we'll have to start again.
redis.del("account_cleanup:#{account_id}")
end
- redis.del("account_cleanup:#{account_id}") if EXCEPTION_THRESHOLDS.map { |name| attribute_change_to_be_saved(name) }.compact.any? { |old, new| old.present? && (new.nil? || new > old) }
+ redis.del("account_cleanup:#{account_id}") if EXCEPTION_THRESHOLDS.filter_map { |name| attribute_change_to_be_saved(name) }.any? { |old, new| old.present? && (new.nil? || new > old) }
end
def validate_local_account
diff --git a/app/models/account_suggestions/setting_source.rb b/app/models/account_suggestions/setting_source.rb
index 7b8873e0c5..6185732b4b 100644
--- a/app/models/account_suggestions/setting_source.rb
+++ b/app/models/account_suggestions/setting_source.rb
@@ -48,14 +48,14 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source
end
def setting_to_usernames_and_domains
- setting.split(',').map do |str|
+ setting.split(',').filter_map do |str|
username, domain = str.strip.gsub(/\A@/, '').split('@', 2)
domain = nil if TagManager.instance.local_domain?(domain)
next if username.blank?
[username.downcase, domain&.downcase]
- end.compact
+ end
end
def setting
diff --git a/app/models/account_suggestions/source.rb b/app/models/account_suggestions/source.rb
index be462cd0f5..504d26a8bd 100644
--- a/app/models/account_suggestions/source.rb
+++ b/app/models/account_suggestions/source.rb
@@ -20,7 +20,7 @@ class AccountSuggestions::Source
map = scope.index_by { |account| to_ordered_list_key(account) }
- ordered_list.map { |ordered_list_key| map[ordered_list_key] }.compact.map do |account|
+ ordered_list.filter_map { |ordered_list_key| map[ordered_list_key] }.map do |account|
AccountSuggestions::Suggestion.new(
account: account,
source: key
diff --git a/app/models/follow_recommendation_filter.rb b/app/models/follow_recommendation_filter.rb
index 5313326143..2fab975698 100644
--- a/app/models/follow_recommendation_filter.rb
+++ b/app/models/follow_recommendation_filter.rb
@@ -22,7 +22,7 @@ class FollowRecommendationFilter
account_ids = redis.zrevrange("follow_recommendations:#{@language}", 0, -1).map(&:to_i)
accounts = Account.where(id: account_ids).index_by(&:id)
- account_ids.map { |id| accounts[id] }.compact
+ account_ids.filter_map { |id| accounts[id] }
end
end
end
diff --git a/app/models/identity.rb b/app/models/identity.rb
index 6f10fed4d7..c95a68a6f6 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -13,7 +13,7 @@
#
class Identity < ApplicationRecord
- belongs_to :user, dependent: :destroy
+ belongs_to :user
validates :uid, presence: true, uniqueness: { scope: :provider }
validates :provider, presence: true
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 3e6b10f9c8..4bee407ea9 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -122,7 +122,7 @@ class Notification < ApplicationRecord
ActiveRecord::Associations::Preloader.new.preload(grouped_notifications, associations)
end
- unique_target_statuses = notifications.map(&:target_status).compact.uniq
+ unique_target_statuses = notifications.filter_map(&:target_status).uniq
# Call cache_collection in block
cached_statuses_by_id = yield(unique_target_statuses).index_by(&:id)
diff --git a/app/models/user_role.rb b/app/models/user_role.rb
index a1b91dc0f5..5472646c60 100644
--- a/app/models/user_role.rb
+++ b/app/models/user_role.rb
@@ -125,7 +125,7 @@ class UserRole < ApplicationRecord
end
def permissions_as_keys=(value)
- self.permissions = value.map(&:presence).compact.reduce(Flags::NONE) { |bitmask, privilege| FLAGS.key?(privilege.to_sym) ? (bitmask | FLAGS[privilege.to_sym]) : bitmask }
+ self.permissions = value.filter_map(&:presence).reduce(Flags::NONE) { |bitmask, privilege| FLAGS.key?(privilege.to_sym) ? (bitmask | FLAGS[privilege.to_sym]) : bitmask }
end
def can?(*any_of_privileges)
diff --git a/app/models/webhook.rb b/app/models/webhook.rb
index 9a056a3862..c556bcc2bb 100644
--- a/app/models/webhook.rb
+++ b/app/models/webhook.rb
@@ -53,7 +53,7 @@ class Webhook < ApplicationRecord
end
def strip_events
- self.events = events.map { |str| str.strip.presence }.compact if events.present?
+ self.events = events.filter_map { |str| str.strip.presence } if events.present?
end
def generate_secret
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index b3b279147d..f3fbb80210 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -68,7 +68,7 @@ class ProcessMentionsService < BaseService
def assign_mentions!
# Make sure we never mention blocked accounts
unless @current_mentions.empty?
- mentioned_domains = @current_mentions.map { |m| m.account.domain }.compact.uniq
+ mentioned_domains = @current_mentions.filter_map { |m| m.account.domain }.uniq
blocked_domains = Set.new(mentioned_domains.empty? ? [] : AccountDomainBlock.where(account_id: @status.account_id, domain: mentioned_domains))
mentioned_account_ids = @current_mentions.map(&:account_id)
blocked_account_ids = Set.new(@status.account.block_relationships.where(target_account_id: mentioned_account_ids).pluck(:target_account_id))
diff --git a/app/validators/existing_username_validator.rb b/app/validators/existing_username_validator.rb
index 45de4f4a44..037d92f39b 100644
--- a/app/validators/existing_username_validator.rb
+++ b/app/validators/existing_username_validator.rb
@@ -4,14 +4,14 @@ class ExistingUsernameValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.blank?
- usernames_and_domains = value.split(',').map do |str|
+ usernames_and_domains = value.split(',').filter_map do |str|
username, domain = str.strip.gsub(/\A@/, '').split('@', 2)
domain = nil if TagManager.instance.local_domain?(domain)
next if username.blank?
[str, username, domain]
- end.compact
+ end
usernames_with_no_accounts = usernames_and_domains.filter_map do |(str, username, domain)|
str unless Account.find_remote(username, domain)
diff --git a/babel.config.js b/babel.config.js
index abfdc5b2ca..0a2e69a476 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -3,6 +3,7 @@ module.exports = (api) => {
const reactOptions = {
development: false,
+ runtime: 'automatic',
};
const envOptions = {
diff --git a/db/migrate/20200407202420_migrate_unavailable_inboxes.rb b/db/migrate/20200407202420_migrate_unavailable_inboxes.rb
index 8f9c687942..05a01be284 100644
--- a/db/migrate/20200407202420_migrate_unavailable_inboxes.rb
+++ b/db/migrate/20200407202420_migrate_unavailable_inboxes.rb
@@ -5,9 +5,9 @@ class MigrateUnavailableInboxes < ActiveRecord::Migration[5.2]
redis = RedisConfiguration.pool.checkout
urls = redis.smembers('unavailable_inboxes')
- hosts = urls.map do |url|
+ hosts = urls.filter_map do |url|
Addressable::URI.parse(url).normalized_host
- end.compact.uniq
+ end.uniq
UnavailableDomain.delete_all
diff --git a/package.json b/package.json
index 57dcf8c9e7..38eaa7bf87 100644
--- a/package.json
+++ b/package.json
@@ -64,7 +64,7 @@
"file-loader": "^6.2.0",
"font-awesome": "^4.7.0",
"fuzzysort": "^2.0.4",
- "glob": "^10.2.2",
+ "glob": "^10.2.6",
"history": "^4.10.1",
"http-link-header": "^1.1.1",
"immutable": "^4.3.0",
@@ -113,7 +113,7 @@
"regenerator-runtime": "^0.13.11",
"requestidlecallback": "^0.3.0",
"reselect": "^4.1.8",
- "rimraf": "^5.0.0",
+ "rimraf": "^5.0.1",
"sass": "^1.62.1",
"sass-loader": "^10.2.0",
"stacktrace-js": "^2.0.2",
@@ -128,7 +128,7 @@
"webpack-assets-manifest": "^4.0.6",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^3.3.12",
- "webpack-merge": "^5.8.0",
+ "webpack-merge": "^5.9.0",
"wicg-inert": "^3.1.2",
"workbox-expiration": "^6.5.4",
"workbox-precaching": "^6.5.4",
@@ -175,8 +175,8 @@
"@types/uuid": "^9.0.0",
"@types/webpack": "^4.41.33",
"@types/yargs": "^17.0.24",
- "@typescript-eslint/eslint-plugin": "^5.59.6",
- "@typescript-eslint/parser": "^5.59.6",
+ "@typescript-eslint/eslint-plugin": "^5.59.7",
+ "@typescript-eslint/parser": "^5.59.7",
"babel-jest": "^29.5.0",
"eslint": "^8.40.0",
"eslint-config-prettier": "^8.8.0",
@@ -196,7 +196,7 @@
"prettier": "^2.8.8",
"react-intl-translations-manager": "^5.0.3",
"react-test-renderer": "^18.2.0",
- "stylelint": "^15.6.1",
+ "stylelint": "^15.6.2",
"stylelint-config-standard-scss": "^9.0.0",
"typescript": "^5.0.4",
"webpack-dev-server": "^3.11.3",
@@ -213,7 +213,7 @@
},
"lint-staged": {
"*": "prettier --ignore-unknown --write",
- "Capfile|Gemfile|*.{rb,ruby,ru,rake}": "bundle exec rubocop -a",
+ "Capfile|Gemfile|*.{rb,ruby,ru,rake}": "bundle exec rubocop --force-exclusion -a",
"*.{js,jsx,ts,tsx}": "eslint --fix",
"*.{css,scss}": "stylelint --fix"
}
diff --git a/spec/controllers/admin/announcements_controller_spec.rb b/spec/controllers/admin/announcements_controller_spec.rb
index 288ac1d713..a8905160f5 100644
--- a/spec/controllers/admin/announcements_controller_spec.rb
+++ b/spec/controllers/admin/announcements_controller_spec.rb
@@ -18,4 +18,59 @@ describe Admin::AnnouncementsController do
expect(response).to have_http_status(:success)
end
end
+
+ describe 'GET #new' do
+ it 'returns http success and renders new' do
+ get :new
+
+ expect(response).to have_http_status(:success)
+ expect(response).to render_template(:new)
+ end
+ end
+
+ describe 'GET #edit' do
+ let(:announcement) { Fabricate(:announcement) }
+
+ it 'returns http success and renders edit' do
+ get :edit, params: { id: announcement.id }
+
+ expect(response).to have_http_status(:success)
+ expect(response).to render_template(:edit)
+ end
+ end
+
+ describe 'POST #create' do
+ it 'creates a new announcement and redirects' do
+ expect do
+ post :create, params: { announcement: { text: 'The announcement message.' } }
+ end.to change(Announcement, :count).by(1)
+
+ expect(response).to redirect_to(admin_announcements_path)
+ expect(flash.notice).to match(I18n.t('admin.announcements.published_msg'))
+ end
+ end
+
+ describe 'PUT #update' do
+ let(:announcement) { Fabricate(:announcement, text: 'Original text') }
+
+ it 'updates an announcement and redirects' do
+ put :update, params: { id: announcement.id, announcement: { text: 'Updated text.' } }
+
+ expect(response).to redirect_to(admin_announcements_path)
+ expect(flash.notice).to match(I18n.t('admin.announcements.updated_msg'))
+ end
+ end
+
+ describe 'DELETE #destroy' do
+ let!(:announcement) { Fabricate(:announcement, text: 'Original text') }
+
+ it 'destroys an announcement and redirects' do
+ expect do
+ delete :destroy, params: { id: announcement.id }
+ end.to change(Announcement, :count).by(-1)
+
+ expect(response).to redirect_to(admin_announcements_path)
+ expect(flash.notice).to match(I18n.t('admin.announcements.destroyed_msg'))
+ end
+ end
end
diff --git a/spec/controllers/api/v1/featured_tags_controller_spec.rb b/spec/controllers/api/v1/featured_tags_controller_spec.rb
deleted file mode 100644
index aac9429015..0000000000
--- a/spec/controllers/api/v1/featured_tags_controller_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V1::FeaturedTagsController do
- render_views
-
- let(:user) { Fabricate(:user) }
- let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
- let(:account) { Fabricate(:account) }
-
- before do
- allow(controller).to receive(:doorkeeper_token) { token }
- end
-
- describe 'GET #index' do
- it 'returns http success' do
- get :index, params: { account_id: account.id, limit: 2 }
-
- expect(response).to have_http_status(200)
- end
- end
-end
diff --git a/spec/fabricators/featured_tag_fabricator.rb b/spec/fabricators/featured_tag_fabricator.rb
index 747d8e36a5..838364056b 100644
--- a/spec/fabricators/featured_tag_fabricator.rb
+++ b/spec/fabricators/featured_tag_fabricator.rb
@@ -3,5 +3,5 @@
Fabricator(:featured_tag) do
account
tag
- name 'Tag'
+ name { sequence(:name) { |i| "Tag#{i}" } }
end
diff --git a/spec/policies/status_policy_spec.rb b/spec/policies/status_policy_spec.rb
index 9ae54780eb..36ac8d8027 100644
--- a/spec/policies/status_policy_spec.rb
+++ b/spec/policies/status_policy_spec.rb
@@ -11,127 +11,139 @@ RSpec.describe StatusPolicy, type: :model do
let(:bob) { Fabricate(:account, username: 'bob') }
let(:status) { Fabricate(:status, account: alice) }
- permissions :show?, :reblog? do
- it 'grants access when no viewer' do
- expect(subject).to permit(nil, status)
- end
+ context 'with the permissions of show? and reblog?' do
+ permissions :show?, :reblog? do
+ it 'grants access when no viewer' do
+ expect(subject).to permit(nil, status)
+ end
- it 'denies access when viewer is blocked' do
- block = Fabricate(:block)
- status.visibility = :private
- status.account = block.target_account
+ it 'denies access when viewer is blocked' do
+ block = Fabricate(:block)
+ status.visibility = :private
+ status.account = block.target_account
- expect(subject).to_not permit(block.account, status)
+ expect(subject).to_not permit(block.account, status)
+ end
end
end
- permissions :show? do
- it 'grants access when direct and account is viewer' do
- status.visibility = :direct
+ context 'with the permission of show?' do
+ permissions :show? do
+ it 'grants access when direct and account is viewer' do
+ status.visibility = :direct
- expect(subject).to permit(status.account, status)
- end
+ expect(subject).to permit(status.account, status)
+ end
- it 'grants access when direct and viewer is mentioned' do
- status.visibility = :direct
- status.mentions = [Fabricate(:mention, account: alice)]
+ it 'grants access when direct and viewer is mentioned' do
+ status.visibility = :direct
+ status.mentions = [Fabricate(:mention, account: alice)]
- expect(subject).to permit(alice, status)
- end
+ expect(subject).to permit(alice, status)
+ end
- it 'grants access when direct and non-owner viewer is mentioned and mentions are loaded' do
- status.visibility = :direct
- status.mentions = [Fabricate(:mention, account: bob)]
- status.mentions.load
+ it 'grants access when direct and non-owner viewer is mentioned and mentions are loaded' do
+ status.visibility = :direct
+ status.mentions = [Fabricate(:mention, account: bob)]
+ status.mentions.load
- expect(subject).to permit(bob, status)
- end
+ expect(subject).to permit(bob, status)
+ end
- it 'denies access when direct and viewer is not mentioned' do
- viewer = Fabricate(:account)
- status.visibility = :direct
+ it 'denies access when direct and viewer is not mentioned' do
+ viewer = Fabricate(:account)
+ status.visibility = :direct
- expect(subject).to_not permit(viewer, status)
- end
+ expect(subject).to_not permit(viewer, status)
+ end
- it 'grants access when private and account is viewer' do
- status.visibility = :private
+ it 'grants access when private and account is viewer' do
+ status.visibility = :private
- expect(subject).to permit(status.account, status)
- end
+ expect(subject).to permit(status.account, status)
+ end
- it 'grants access when private and account is following viewer' do
- follow = Fabricate(:follow)
- status.visibility = :private
- status.account = follow.target_account
+ it 'grants access when private and account is following viewer' do
+ follow = Fabricate(:follow)
+ status.visibility = :private
+ status.account = follow.target_account
- expect(subject).to permit(follow.account, status)
- end
+ expect(subject).to permit(follow.account, status)
+ end
- it 'grants access when private and viewer is mentioned' do
- status.visibility = :private
- status.mentions = [Fabricate(:mention, account: alice)]
+ it 'grants access when private and viewer is mentioned' do
+ status.visibility = :private
+ status.mentions = [Fabricate(:mention, account: alice)]
- expect(subject).to permit(alice, status)
- end
+ expect(subject).to permit(alice, status)
+ end
- it 'denies access when private and viewer is not mentioned or followed' do
- viewer = Fabricate(:account)
- status.visibility = :private
+ it 'denies access when private and viewer is not mentioned or followed' do
+ viewer = Fabricate(:account)
+ status.visibility = :private
- expect(subject).to_not permit(viewer, status)
+ expect(subject).to_not permit(viewer, status)
+ end
end
end
- permissions :reblog? do
- it 'denies access when private' do
- viewer = Fabricate(:account)
- status.visibility = :private
+ context 'with the permission of reblog?' do
+ permissions :reblog? do
+ it 'denies access when private' do
+ viewer = Fabricate(:account)
+ status.visibility = :private
- expect(subject).to_not permit(viewer, status)
- end
+ expect(subject).to_not permit(viewer, status)
+ end
- it 'denies access when direct' do
- viewer = Fabricate(:account)
- status.visibility = :direct
+ it 'denies access when direct' do
+ viewer = Fabricate(:account)
+ status.visibility = :direct
- expect(subject).to_not permit(viewer, status)
+ expect(subject).to_not permit(viewer, status)
+ end
end
end
- permissions :destroy?, :unreblog? do
- it 'grants access when account is deleter' do
- expect(subject).to permit(status.account, status)
- end
+ context 'with the permissions of destroy? and unreblog?' do
+ permissions :destroy?, :unreblog? do
+ it 'grants access when account is deleter' do
+ expect(subject).to permit(status.account, status)
+ end
- it 'denies access when account is not deleter' do
- expect(subject).to_not permit(bob, status)
- end
+ it 'denies access when account is not deleter' do
+ expect(subject).to_not permit(bob, status)
+ end
- it 'denies access when no deleter' do
- expect(subject).to_not permit(nil, status)
+ it 'denies access when no deleter' do
+ expect(subject).to_not permit(nil, status)
+ end
end
end
- permissions :favourite? do
- it 'grants access when viewer is not blocked' do
- follow = Fabricate(:follow)
- status.account = follow.target_account
+ context 'with the permission of favourite?' do
+ permissions :favourite? do
+ it 'grants access when viewer is not blocked' do
+ follow = Fabricate(:follow)
+ status.account = follow.target_account
- expect(subject).to permit(follow.account, status)
- end
+ expect(subject).to permit(follow.account, status)
+ end
- it 'denies when viewer is blocked' do
- block = Fabricate(:block)
- status.account = block.target_account
+ it 'denies when viewer is blocked' do
+ block = Fabricate(:block)
+ status.account = block.target_account
- expect(subject).to_not permit(block.account, status)
+ expect(subject).to_not permit(block.account, status)
+ end
end
end
- permissions :update? do
- it 'grants access if owner' do
- expect(subject).to permit(status.account, status)
+ context 'with the permission of update?' do
+ permissions :update? do
+ it 'grants access if owner' do
+ expect(subject).to permit(status.account, status)
+ end
end
end
end
diff --git a/spec/presenters/status_relationships_presenter_spec.rb b/spec/presenters/status_relationships_presenter_spec.rb
index 11116cabd2..a62fa004a1 100644
--- a/spec/presenters/status_relationships_presenter_spec.rb
+++ b/spec/presenters/status_relationships_presenter_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe StatusRelationshipsPresenter do
let(:presenter) { StatusRelationshipsPresenter.new(statuses, current_account_id, **options) }
let(:current_account_id) { Fabricate(:account).id }
let(:statuses) { [Fabricate(:status)] }
- let(:status_ids) { statuses.map(&:id) + statuses.map(&:reblog_of_id).compact }
+ let(:status_ids) { statuses.map(&:id) + statuses.filter_map(&:reblog_of_id) }
let(:default_map) { { 1 => true } }
context 'when options are not set' do
diff --git a/spec/requests/api/v1/featured_tags_spec.rb b/spec/requests/api/v1/featured_tags_spec.rb
new file mode 100644
index 0000000000..8a552c1d4b
--- /dev/null
+++ b/spec/requests/api/v1/featured_tags_spec.rb
@@ -0,0 +1,201 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'FeaturedTags' do
+ let(:user) { Fabricate(:user) }
+ let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
+ let(:scopes) { 'read:accounts write:accounts' }
+ let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
+
+ shared_examples 'forbidden for wrong scope' do |wrong_scope|
+ let(:scopes) { wrong_scope }
+
+ it 'returns http forbidden' do
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ describe 'GET /api/v1/featured_tags' do
+ context 'with wrong scope' do
+ before do
+ get '/api/v1/featured_tags', headers: headers
+ end
+
+ it_behaves_like 'forbidden for wrong scope', 'read:statuses'
+ end
+
+ context 'when Authorization header is missing' do
+ it 'returns http unauthorized' do
+ get '/api/v1/featured_tags'
+
+ expect(response).to have_http_status(401)
+ end
+ end
+
+ it 'returns http success' do
+ get '/api/v1/featured_tags', headers: headers
+
+ expect(response).to have_http_status(200)
+ end
+
+ context 'when the requesting user has no featured tag' do
+ before { Fabricate.times(3, :featured_tag) }
+
+ it 'returns an empty body' do
+ get '/api/v1/featured_tags', headers: headers
+
+ body = body_as_json
+
+ expect(body).to be_empty
+ end
+ end
+
+ context 'when the requesting user has featured tags' do
+ let!(:user_featured_tags) { Fabricate.times(5, :featured_tag, account: user.account) }
+
+ it 'returns only the featured tags belonging to the requesting user' do
+ get '/api/v1/featured_tags', headers: headers
+
+ body = body_as_json
+ expected_ids = user_featured_tags.pluck(:id).map(&:to_s)
+
+ expect(body.pluck(:id)).to match_array(expected_ids)
+ end
+ end
+ end
+
+ describe 'POST /api/v1/featured_tags' do
+ let(:params) { { name: 'tag' } }
+
+ it 'returns http success' do
+ post '/api/v1/featured_tags', headers: headers, params: params
+
+ expect(response).to have_http_status(200)
+ end
+
+ it 'returns the correct tag name' do
+ post '/api/v1/featured_tags', headers: headers, params: params
+
+ body = body_as_json
+
+ expect(body[:name]).to eq(params[:name])
+ end
+
+ it 'creates a new featured tag for the requesting user' do
+ post '/api/v1/featured_tags', headers: headers, params: params
+
+ featured_tag = FeaturedTag.find_by(name: params[:name], account: user.account)
+
+ expect(featured_tag).to be_present
+ end
+
+ context 'with wrong scope' do
+ before do
+ post '/api/v1/featured_tags', headers: headers, params: params
+ end
+
+ it_behaves_like 'forbidden for wrong scope', 'read:statuses'
+ end
+
+ context 'when Authorization header is missing' do
+ it 'returns http unauthorized' do
+ post '/api/v1/featured_tags', params: params
+
+ expect(response).to have_http_status(401)
+ end
+ end
+
+ context 'when required param "name" is not provided' do
+ it 'returns http bad request' do
+ post '/api/v1/featured_tags', headers: headers
+
+ expect(response).to have_http_status(400)
+ end
+ end
+
+ context 'when provided tag name is invalid' do
+ let(:params) { { name: 'asj&*!' } }
+
+ it 'returns http unprocessable entity' do
+ post '/api/v1/featured_tags', headers: headers, params: params
+
+ expect(response).to have_http_status(422)
+ end
+ end
+
+ context 'when tag name is already taken' do
+ before do
+ FeaturedTag.create(name: params[:name], account: user.account)
+ end
+
+ it 'returns http unprocessable entity' do
+ post '/api/v1/featured_tags', headers: headers, params: params
+
+ expect(response).to have_http_status(422)
+ end
+ end
+ end
+
+ describe 'DELETE /api/v1/featured_tags' do
+ let!(:featured_tag) { FeaturedTag.create(name: 'tag', account: user.account) }
+ let(:id) { featured_tag.id }
+
+ it 'returns http success' do
+ delete "/api/v1/featured_tags/#{id}", headers: headers
+
+ expect(response).to have_http_status(200)
+ end
+
+ it 'returns an empty body' do
+ delete "/api/v1/featured_tags/#{id}", headers: headers
+
+ body = body_as_json
+
+ expect(body).to be_empty
+ end
+
+ it 'deletes the featured tag' do
+ delete "/api/v1/featured_tags/#{id}", headers: headers
+
+ featured_tag = FeaturedTag.find_by(id: id)
+
+ expect(featured_tag).to be_nil
+ end
+
+ context 'with wrong scope' do
+ before do
+ delete "/api/v1/featured_tags/#{id}", headers: headers
+ end
+
+ it_behaves_like 'forbidden for wrong scope', 'read:statuses'
+ end
+
+ context 'when Authorization header is missing' do
+ it 'returns http unauthorized' do
+ delete "/api/v1/featured_tags/#{id}"
+
+ expect(response).to have_http_status(401)
+ end
+ end
+
+ context 'when featured tag with given id does not exist' do
+ it 'returns http not found' do
+ delete '/api/v1/featured_tags/0', headers: headers
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when deleting a featured tag of another user' do
+ let!(:other_user_featured_tag) { Fabricate(:featured_tag) }
+ let(:id) { other_user_featured_tag.id }
+
+ it 'returns http not found' do
+ delete "/api/v1/featured_tags/#{id}", headers: headers
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+end
diff --git a/tsconfig.json b/tsconfig.json
index 2c2193d55f..ff9da29497 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "jsx": "react",
+ "jsx": "react-jsx",
"target": "esnext",
"module": "CommonJS",
"moduleResolution": "node",
diff --git a/yarn.lock b/yarn.lock
index 2a480cea3a..88603113bd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2449,15 +2449,15 @@
dependencies:
"@types/yargs-parser" "*"
-"@typescript-eslint/eslint-plugin@^5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz#a350faef1baa1e961698240f922d8de1761a9e2b"
- integrity sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==
+"@typescript-eslint/eslint-plugin@^5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz#e470af414f05ecfdc05a23e9ce6ec8f91db56fe2"
+ integrity sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==
dependencies:
"@eslint-community/regexpp" "^4.4.0"
- "@typescript-eslint/scope-manager" "5.59.6"
- "@typescript-eslint/type-utils" "5.59.6"
- "@typescript-eslint/utils" "5.59.6"
+ "@typescript-eslint/scope-manager" "5.59.7"
+ "@typescript-eslint/type-utils" "5.59.7"
+ "@typescript-eslint/utils" "5.59.7"
debug "^4.3.4"
grapheme-splitter "^1.0.4"
ignore "^5.2.0"
@@ -2465,31 +2465,31 @@
semver "^7.3.7"
tsutils "^3.21.0"
-"@typescript-eslint/parser@^5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.6.tgz#bd36f71f5a529f828e20b627078d3ed6738dbb40"
- integrity sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==
+"@typescript-eslint/parser@^5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.7.tgz#02682554d7c1028b89aa44a48bf598db33048caa"
+ integrity sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==
dependencies:
- "@typescript-eslint/scope-manager" "5.59.6"
- "@typescript-eslint/types" "5.59.6"
- "@typescript-eslint/typescript-estree" "5.59.6"
+ "@typescript-eslint/scope-manager" "5.59.7"
+ "@typescript-eslint/types" "5.59.7"
+ "@typescript-eslint/typescript-estree" "5.59.7"
debug "^4.3.4"
-"@typescript-eslint/scope-manager@5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz#d43a3687aa4433868527cfe797eb267c6be35f19"
- integrity sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==
+"@typescript-eslint/scope-manager@5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz#0243f41f9066f3339d2f06d7f72d6c16a16769e2"
+ integrity sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==
dependencies:
- "@typescript-eslint/types" "5.59.6"
- "@typescript-eslint/visitor-keys" "5.59.6"
+ "@typescript-eslint/types" "5.59.7"
+ "@typescript-eslint/visitor-keys" "5.59.7"
-"@typescript-eslint/type-utils@5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz#37c51d2ae36127d8b81f32a0a4d2efae19277c48"
- integrity sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==
+"@typescript-eslint/type-utils@5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz#89c97291371b59eb18a68039857c829776f1426d"
+ integrity sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==
dependencies:
- "@typescript-eslint/typescript-estree" "5.59.6"
- "@typescript-eslint/utils" "5.59.6"
+ "@typescript-eslint/typescript-estree" "5.59.7"
+ "@typescript-eslint/utils" "5.59.7"
debug "^4.3.4"
tsutils "^3.21.0"
@@ -2498,10 +2498,10 @@
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.0.tgz#3fcdac7dbf923ec5251545acdd9f1d42d7c4fe32"
integrity sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==
-"@typescript-eslint/types@5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.6.tgz#5a6557a772af044afe890d77c6a07e8c23c2460b"
- integrity sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==
+"@typescript-eslint/types@5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.7.tgz#6f4857203fceee91d0034ccc30512d2939000742"
+ integrity sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==
"@typescript-eslint/typescript-estree@5.59.0":
version "5.59.0"
@@ -2516,30 +2516,30 @@
semver "^7.3.7"
tsutils "^3.21.0"
-"@typescript-eslint/typescript-estree@5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz#2fb80522687bd3825504925ea7e1b8de7bb6251b"
- integrity sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==
+"@typescript-eslint/typescript-estree@5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz#b887acbd4b58e654829c94860dbff4ac55c5cff8"
+ integrity sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==
dependencies:
- "@typescript-eslint/types" "5.59.6"
- "@typescript-eslint/visitor-keys" "5.59.6"
+ "@typescript-eslint/types" "5.59.7"
+ "@typescript-eslint/visitor-keys" "5.59.7"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
-"@typescript-eslint/utils@5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.6.tgz#82960fe23788113fc3b1f9d4663d6773b7907839"
- integrity sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==
+"@typescript-eslint/utils@5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.7.tgz#7adf068b136deae54abd9a66ba5a8780d2d0f898"
+ integrity sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12"
- "@typescript-eslint/scope-manager" "5.59.6"
- "@typescript-eslint/types" "5.59.6"
- "@typescript-eslint/typescript-estree" "5.59.6"
+ "@typescript-eslint/scope-manager" "5.59.7"
+ "@typescript-eslint/types" "5.59.7"
+ "@typescript-eslint/typescript-estree" "5.59.7"
eslint-scope "^5.1.1"
semver "^7.3.7"
@@ -2551,12 +2551,12 @@
"@typescript-eslint/types" "5.59.0"
eslint-visitor-keys "^3.3.0"
-"@typescript-eslint/visitor-keys@5.59.6":
- version "5.59.6"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz#673fccabf28943847d0c8e9e8d008e3ada7be6bb"
- integrity sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==
+"@typescript-eslint/visitor-keys@5.59.7":
+ version "5.59.7"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz#09c36eaf268086b4fbb5eb9dc5199391b6485fc5"
+ integrity sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==
dependencies:
- "@typescript-eslint/types" "5.59.6"
+ "@typescript-eslint/types" "5.59.7"
eslint-visitor-keys "^3.3.0"
"@webassemblyjs/ast@1.9.0":
@@ -5876,15 +5876,15 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
-glob@^10.0.0, glob@^10.2.2:
- version "10.2.2"
- resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.2.tgz#ce2468727de7e035e8ecf684669dc74d0526ab75"
- integrity sha512-Xsa0BcxIC6th9UwNjZkhrMtNo/MnyRL8jGCP+uEwhA5oFOCY1f2s1/oNKY47xQ0Bg5nkjsfAEIej1VeH62bDDQ==
+glob@^10.2.5, glob@^10.2.6:
+ version "10.2.6"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.6.tgz#1e27edbb3bbac055cb97113e27a066c100a4e5e1"
+ integrity sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==
dependencies:
foreground-child "^3.1.0"
jackspeak "^2.0.3"
- minimatch "^9.0.0"
- minipass "^5.0.0"
+ minimatch "^9.0.1"
+ minipass "^5.0.0 || ^6.0.2"
path-scurry "^1.7.0"
glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
@@ -8120,10 +8120,10 @@ minimatch@^5.0.1:
dependencies:
brace-expansion "^2.0.1"
-minimatch@^9.0.0:
- version "9.0.0"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.0.tgz#bfc8e88a1c40ffd40c172ddac3decb8451503b56"
- integrity sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==
+minimatch@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253"
+ integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==
dependencies:
brace-expansion "^2.0.1"
@@ -8174,6 +8174,11 @@ minipass@^5.0.0:
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
+"minipass@^5.0.0 || ^6.0.2":
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81"
+ integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==
+
minizlib@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
@@ -10147,12 +10152,12 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
-rimraf@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.0.tgz#5bda14e410d7e4dd522154891395802ce032c2cb"
- integrity sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==
+rimraf@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0"
+ integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==
dependencies:
- glob "^10.0.0"
+ glob "^10.2.5"
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
@@ -11030,10 +11035,10 @@ stylelint-scss@^4.6.0:
postcss-selector-parser "^6.0.11"
postcss-value-parser "^4.2.0"
-stylelint@^15.6.1:
- version "15.6.1"
- resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-15.6.1.tgz#e4cd33a3af88587b99a5d1328aedd8c298b6dc81"
- integrity sha512-d8icFBlVl93Elf3Z5ABQNOCe4nx69is3D/NZhDLAie1eyYnpxfeKe7pCfqzT5W4F8vxHCLSDfV8nKNJzogvV2Q==
+stylelint@^15.6.2:
+ version "15.6.2"
+ resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-15.6.2.tgz#06d9005b62a83b72887eed623520e9b472af8c15"
+ integrity sha512-fjQWwcdUye4DU+0oIxNGwawIPC5DvG5kdObY5Sg4rc87untze3gC/5g/ikePqVjrAsBUZjwMN+pZsAYbDO6ArQ==
dependencies:
"@csstools/css-parser-algorithms" "^2.1.1"
"@csstools/css-tokenizer" "^2.1.1"
@@ -11953,10 +11958,10 @@ webpack-log@^2.0.0:
ansi-colors "^3.0.0"
uuid "^3.3.2"
-webpack-merge@^5.8.0:
- version "5.8.0"
- resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
- integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
+webpack-merge@^5.9.0:
+ version "5.9.0"
+ resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.9.0.tgz#dc160a1c4cf512ceca515cc231669e9ddb133826"
+ integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==
dependencies:
clone-deep "^4.0.1"
wildcard "^2.0.0"