Merge commit 'd20a5c3ec9ed40a991245fe32d0acb6187dd48c4' into glitch-soc/merge-upstream

Conflicts:
- `yarn.lock`:
  Not a real conflict, just a line adjacent to a glitch-soc only dependency
  getting updated.
  Updated dependencies as upstream did.
shrike
Claire 2024-05-29 17:03:24 +02:00
commit c827a98f19
80 changed files with 543 additions and 499 deletions

View File

@ -2,6 +2,7 @@ version: '3'
services: services:
app: app:
working_dir: /workspaces/mastodon/
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile

View File

@ -176,12 +176,6 @@ Style/SafeNavigation:
Exclude: Exclude:
- 'app/models/concerns/account/finder_concern.rb' - 'app/models/concerns/account/finder_concern.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Mode.
Style/StringConcatenation:
Exclude:
- 'config/initializers/paperclip.rb'
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: WordRegex. # Configuration parameters: WordRegex.
# SupportedStyles: percent, brackets # SupportedStyles: percent, brackets

View File

@ -231,7 +231,7 @@ GEM
tzinfo tzinfo
excon (0.110.0) excon (0.110.0)
fabrication (2.31.0) fabrication (2.31.0)
faker (3.3.1) faker (3.4.1)
i18n (>= 1.8.11, < 2) i18n (>= 1.8.11, < 2)
faraday (1.10.3) faraday (1.10.3)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
@ -425,7 +425,7 @@ GEM
mime-types-data (3.2024.0507) mime-types-data (3.2024.0507)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.6) mini_portile2 (2.8.6)
minitest (5.23.0) minitest (5.23.1)
msgpack (1.7.2) msgpack (1.7.2)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.4.0) multipart-post (2.4.0)
@ -799,7 +799,7 @@ GEM
thor (>= 0.20, < 3.0) thor (>= 0.20, < 3.0)
simple-navigation (4.4.0) simple-navigation (4.4.0)
activesupport (>= 2.3.2) activesupport (>= 2.3.2)
simple_form (5.3.0) simple_form (5.3.1)
actionpack (>= 5.2) actionpack (>= 5.2)
activemodel (>= 5.2) activemodel (>= 5.2)
simplecov (0.22.0) simplecov (0.22.0)

View File

@ -106,11 +106,11 @@ class Api::V1::AccountsController < Api::BaseController
end end
def account_ids def account_ids
Array(accounts_params[:ids]).uniq.map(&:to_i) Array(accounts_params[:id]).uniq.map(&:to_i)
end end
def accounts_params def accounts_params
params.permit(ids: []) params.permit(id: [])
end end
def account_params def account_params

View File

@ -38,15 +38,15 @@ class Api::V1::ConversationsController < Api::BaseController
def paginated_conversations def paginated_conversations
AccountConversation.where(account: current_account) AccountConversation.where(account: current_account)
.includes( .includes(
account: :account_stat, account: [:account_stat, user: :role],
last_status: [ last_status: [
:media_attachments, :media_attachments,
:status_stat, :status_stat,
:tags, :tags,
{ {
preview_cards_status: :preview_card, preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
active_mentions: [account: :account_stat], active_mentions: :account,
account: :account_stat, account: [:account_stat, user: :role],
}, },
] ]
) )

View File

@ -143,11 +143,11 @@ class Api::V1::StatusesController < Api::BaseController
end end
def status_ids def status_ids
Array(statuses_params[:ids]).uniq.map(&:to_i) Array(statuses_params[:id]).uniq.map(&:to_i)
end end
def statuses_params def statuses_params
params.permit(ids: []) params.permit(id: [])
end end
def status_params def status_params

View File

@ -65,7 +65,7 @@ window.addEventListener('message', (e) => {
{ {
type: 'setHeight', type: 'setHeight',
id: data.id, id: data.id,
height: document.getElementsByTagName('html')[0].scrollHeight, height: document.getElementsByTagName('html')[0]?.scrollHeight,
}, },
'*', '*',
); );
@ -135,7 +135,7 @@ function loaded() {
); );
}; };
const todayFormat = new IntlMessageFormat( const todayFormat = new IntlMessageFormat(
localeData['relative_format.today'] || 'Today at {time}', localeData['relative_format.today'] ?? 'Today at {time}',
locale, locale,
); );
@ -288,13 +288,13 @@ function loaded() {
if (statusEl.dataset.spoiler === 'expanded') { if (statusEl.dataset.spoiler === 'expanded') {
statusEl.dataset.spoiler = 'folded'; statusEl.dataset.spoiler = 'folded';
this.textContent = new IntlMessageFormat( this.textContent = new IntlMessageFormat(
localeData['status.show_more'] || 'Show more', localeData['status.show_more'] ?? 'Show more',
locale, locale,
).format() as string; ).format() as string;
} else { } else {
statusEl.dataset.spoiler = 'expanded'; statusEl.dataset.spoiler = 'expanded';
this.textContent = new IntlMessageFormat( this.textContent = new IntlMessageFormat(
localeData['status.show_less'] || 'Show less', localeData['status.show_less'] ?? 'Show less',
locale, locale,
).format() as string; ).format() as string;
} }
@ -316,8 +316,8 @@ function loaded() {
const message = const message =
statusEl.dataset.spoiler === 'expanded' statusEl.dataset.spoiler === 'expanded'
? localeData['status.show_less'] || 'Show less' ? localeData['status.show_less'] ?? 'Show less'
: localeData['status.show_more'] || 'Show more'; : localeData['status.show_more'] ?? 'Show more';
spoilerLink.textContent = new IntlMessageFormat( spoilerLink.textContent = new IntlMessageFormat(
message, message,
locale, locale,

View File

@ -67,7 +67,9 @@ const fetchInteractionURLFailure = () => {
); );
}; };
const isValidDomain = (value: string) => { const isValidDomain = (value: unknown) => {
if (typeof value !== 'string') return false;
const url = new URL('https:///path'); const url = new URL('https:///path');
url.hostname = value; url.hostname = value;
return url.hostname === value; return url.hostname === value;
@ -124,6 +126,11 @@ const fromAcct = (acct: string) => {
const domain = segments[1]; const domain = segments[1];
const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`; const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`;
if (!domain) {
fetchInteractionURLFailure();
return;
}
axios axios
.get(`https://${domain}/.well-known/webfinger`, { .get(`https://${domain}/.well-known/webfinger`, {
params: { resource: `acct:${acct}` }, params: { resource: `acct:${acct}` },

View File

@ -48,8 +48,9 @@ export const AnimatedNumber: React.FC<Props> = ({ value }) => {
<span <span
key={key} key={key}
style={{ style={{
position: direction * style.y > 0 ? 'absolute' : 'static', position:
transform: `translateY(${style.y * 100}%)`, direction * (style.y ?? 0) > 0 ? 'absolute' : 'static',
transform: `translateY(${(style.y ?? 0) * 100}%)`,
}} }}
> >
<ShortNumber value={data as number} /> <ShortNumber value={data as number} />

View File

@ -52,7 +52,10 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
); );
return Object.values(groups).map((tags) => { return Object.values(groups).map((tags) => {
if (tags.length === 1) return tags[0]; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know that the array has at least one element
const firstTag = tags[0]!;
if (tags.length === 1) return firstTag;
// The best match is the one where we have the less difference between upper and lower case letter count // The best match is the one where we have the less difference between upper and lower case letter count
const best = minBy(tags, (tag) => { const best = minBy(tags, (tag) => {
@ -66,7 +69,7 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) {
return Math.abs(lowerCase - upperCase); return Math.abs(lowerCase - upperCase);
}); });
return best ?? tags[0]; return best ?? firstTag;
}); });
} }

View File

@ -48,7 +48,7 @@ const ShortNumberCounter: React.FC<ShortNumberCounterProps> = ({ value }) => {
const count = ( const count = (
<FormattedNumber <FormattedNumber
value={rawNumber} value={rawNumber ?? 0}
maximumFractionDigits={maxFractionDigits} maximumFractionDigits={maxFractionDigits}
/> />
); );

View File

@ -29,7 +29,10 @@ const emojis: Emojis = {};
// decompress // decompress
Object.keys(shortCodesToEmojiData).forEach((shortCode) => { Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
const [_filenameData, searchData] = shortCodesToEmojiData[shortCode]; const emojiData = shortCodesToEmojiData[shortCode];
if (!emojiData) return;
const [_filenameData, searchData] = emojiData;
const [native, short_names, search, unified] = searchData; const [native, short_names, search, unified] = searchData;
emojis[shortCode] = { emojis[shortCode] = {

View File

@ -46,7 +46,10 @@ function processEmojiMapData(
Object.keys(shortCodesToEmojiData).forEach( Object.keys(shortCodesToEmojiData).forEach(
(shortCode: ShortCodesToEmojiDataKey) => { (shortCode: ShortCodesToEmojiDataKey) => {
if (shortCode === undefined) return; if (shortCode === undefined) return;
const [filenameData, _searchData] = shortCodesToEmojiData[shortCode];
const emojiData = shortCodesToEmojiData[shortCode];
if (!emojiData) return;
const [filenameData, _searchData] = emojiData;
filenameData.forEach((emojiMapData) => { filenameData.forEach((emojiMapData) => {
processEmojiMapData(emojiMapData, shortCode); processEmojiMapData(emojiMapData, shortCode);
}); });

View File

@ -6,6 +6,8 @@ import { PureComponent } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import { Link } from 'react-router-dom';
import Immutable from 'immutable'; import Immutable from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
@ -13,6 +15,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import DescriptionIcon from '@/material-icons/400-24px/description-fill.svg?react'; import DescriptionIcon from '@/material-icons/400-24px/description-fill.svg?react';
import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react'; import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react';
import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react'; import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react';
import { Avatar } from 'mastodon/components/avatar';
import { Blurhash } from 'mastodon/components/blurhash'; import { Blurhash } from 'mastodon/components/blurhash';
import { Icon } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
@ -56,6 +59,20 @@ const addAutoPlay = html => {
return html; return html;
}; };
const MoreFromAuthor = ({ author }) => (
<div className='more-from-author'>
<svg viewBox='0 0 79 79' className='logo logo--icon' role='img'>
<use xlinkHref='#logo-symbol-icon' />
</svg>
<FormattedMessage id='link_preview.more_from_author' defaultMessage='More from {name}' values={{ name: <Link to={`/@${author.get('acct')}`}><Avatar account={author} size={16} /> {author.get('display_name')}</Link> }} />
</div>
);
MoreFromAuthor.propTypes = {
author: ImmutablePropTypes.map,
};
export default class Card extends PureComponent { export default class Card extends PureComponent {
static propTypes = { static propTypes = {
@ -136,6 +153,7 @@ export default class Card extends PureComponent {
const interactive = card.get('type') === 'video'; const interactive = card.get('type') === 'video';
const language = card.get('language') || ''; const language = card.get('language') || '';
const largeImage = (card.get('image')?.length > 0 && card.get('width') > card.get('height')) || interactive; const largeImage = (card.get('image')?.length > 0 && card.get('width') > card.get('height')) || interactive;
const showAuthor = !!card.get('author_account');
const description = ( const description = (
<div className='status-card__content'> <div className='status-card__content'>
@ -146,7 +164,7 @@ export default class Card extends PureComponent {
<strong className='status-card__title' title={card.get('title')} lang={language}>{card.get('title')}</strong> <strong className='status-card__title' title={card.get('title')} lang={language}>{card.get('title')}</strong>
{card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>} {!showAuthor && (card.get('author_name').length > 0 ? <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span> : <span className='status-card__description' lang={language}>{card.get('description')}</span>)}
</div> </div>
); );
@ -235,10 +253,14 @@ export default class Card extends PureComponent {
} }
return ( return (
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage })} target='_blank' rel='noopener noreferrer' ref={this.setRef}> <>
<a href={card.get('url')} className={classNames('status-card', { expanded: largeImage, bottomless: showAuthor })} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
{embed} {embed}
{description} {description}
</a> </a>
{showAuthor && <MoreFromAuthor author={card.get('author_account')} />}
</>
); );
} }

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostra el perfil de totes maneres", "limited_account_hint.action": "Mostra el perfil de totes maneres",
"limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.", "limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.",
"link_preview.author": "Per {name}", "link_preview.author": "Per {name}",
"link_preview.more_from_author": "Més de {name}",
"lists.account.add": "Afegeix a la llista", "lists.account.add": "Afegeix a la llista",
"lists.account.remove": "Elimina de la llista", "lists.account.remove": "Elimina de la llista",
"lists.delete": "Elimina la llista", "lists.delete": "Elimina la llista",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Show profile anyway", "limited_account_hint.action": "Show profile anyway",
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.", "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
"link_preview.author": "By {name}", "link_preview.author": "By {name}",
"link_preview.more_from_author": "More from {name}",
"lists.account.add": "Add to list", "lists.account.add": "Add to list",
"lists.account.remove": "Remove from list", "lists.account.remove": "Remove from list",
"lists.delete": "Delete list", "lists.delete": "Delete list",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostrar perfil de todos modos", "limited_account_hint.action": "Mostrar perfil de todos modos",
"limited_account_hint.title": "Este perfil fue ocultado por los moderadores de {domain}.", "limited_account_hint.title": "Este perfil fue ocultado por los moderadores de {domain}.",
"link_preview.author": "Por {name}", "link_preview.author": "Por {name}",
"link_preview.more_from_author": "Más de {name}",
"lists.account.add": "Agregar a lista", "lists.account.add": "Agregar a lista",
"lists.account.remove": "Quitar de lista", "lists.account.remove": "Quitar de lista",
"lists.delete": "Eliminar lista", "lists.delete": "Eliminar lista",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Näytä profiili joka tapauksessa", "limited_account_hint.action": "Näytä profiili joka tapauksessa",
"limited_account_hint.title": "Palvelimen {domain} valvojat ovat piilottaneet tämän käyttäjätilin.", "limited_account_hint.title": "Palvelimen {domain} valvojat ovat piilottaneet tämän käyttäjätilin.",
"link_preview.author": "Julkaissut {name}", "link_preview.author": "Julkaissut {name}",
"link_preview.more_from_author": "Lisää käyttäjältä {name}",
"lists.account.add": "Lisää listalle", "lists.account.add": "Lisää listalle",
"lists.account.remove": "Poista listalta", "lists.account.remove": "Poista listalta",
"lists.delete": "Poista lista", "lists.delete": "Poista lista",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostrar perfil igualmente", "limited_account_hint.action": "Mostrar perfil igualmente",
"limited_account_hint.title": "Este perfil foi agochado pola moderación de {domain}.", "limited_account_hint.title": "Este perfil foi agochado pola moderación de {domain}.",
"link_preview.author": "Por {name}", "link_preview.author": "Por {name}",
"link_preview.more_from_author": "Máis de {name}",
"lists.account.add": "Engadir á listaxe", "lists.account.add": "Engadir á listaxe",
"lists.account.remove": "Eliminar da listaxe", "lists.account.remove": "Eliminar da listaxe",
"lists.delete": "Eliminar listaxe", "lists.delete": "Eliminar listaxe",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Mostra comunque il profilo", "limited_account_hint.action": "Mostra comunque il profilo",
"limited_account_hint.title": "Questo profilo è stato nascosto dai moderatori di {domain}.", "limited_account_hint.title": "Questo profilo è stato nascosto dai moderatori di {domain}.",
"link_preview.author": "Di {name}", "link_preview.author": "Di {name}",
"link_preview.more_from_author": "Altro da {name}",
"lists.account.add": "Aggiungi all'elenco", "lists.account.add": "Aggiungi all'elenco",
"lists.account.remove": "Rimuovi dall'elenco", "lists.account.remove": "Rimuovi dall'elenco",
"lists.delete": "Elimina elenco", "lists.delete": "Elimina elenco",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "그래도 프로필 보기", "limited_account_hint.action": "그래도 프로필 보기",
"limited_account_hint.title": "이 프로필은 {domain}의 중재자에 의해 숨겨진 상태입니다.", "limited_account_hint.title": "이 프로필은 {domain}의 중재자에 의해 숨겨진 상태입니다.",
"link_preview.author": "{name}", "link_preview.author": "{name}",
"link_preview.more_from_author": "{name} 더 둘러보기",
"lists.account.add": "리스트에 추가", "lists.account.add": "리스트에 추가",
"lists.account.remove": "리스트에서 제거", "lists.account.remove": "리스트에서 제거",
"lists.delete": "리스트 삭제", "lists.delete": "리스트 삭제",

View File

@ -466,6 +466,7 @@
"notification.follow_request": "{name} paprašė tave sekti", "notification.follow_request": "{name} paprašė tave sekti",
"notification.mention": "{name} paminėjo tave", "notification.mention": "{name} paminėjo tave",
"notification.moderation-warning.learn_more": "Sužinoti daugiau", "notification.moderation-warning.learn_more": "Sužinoti daugiau",
"notification.moderation_warning": "Gavai prižiūrėjimo įspėjimą",
"notification.moderation_warning.action_delete_statuses": "Kai kurie tavo įrašai buvo pašalintos.", "notification.moderation_warning.action_delete_statuses": "Kai kurie tavo įrašai buvo pašalintos.",
"notification.moderation_warning.action_disable": "Tavo paskyra buvo išjungta.", "notification.moderation_warning.action_disable": "Tavo paskyra buvo išjungta.",
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Kai kurie tavo įrašai buvo pažymėtos kaip jautrios.", "notification.moderation_warning.action_mark_statuses_as_sensitive": "Kai kurie tavo įrašai buvo pažymėtos kaip jautrios.",

View File

@ -673,7 +673,7 @@
"search.quick_action.account_search": "Profiler som samsvarer med {x}", "search.quick_action.account_search": "Profiler som samsvarer med {x}",
"search.quick_action.go_to_account": "Gå til profil {x}", "search.quick_action.go_to_account": "Gå til profil {x}",
"search.quick_action.go_to_hashtag": "Gå til emneknagg {x}", "search.quick_action.go_to_hashtag": "Gå til emneknagg {x}",
"search.quick_action.open_url": "Åpne URL i Mastodon", "search.quick_action.open_url": "Opne adressa i Mastodon",
"search.quick_action.status_search": "Innlegg som samsvarer med {x}", "search.quick_action.status_search": "Innlegg som samsvarer med {x}",
"search.search_or_paste": "Søk eller lim inn URL", "search.search_or_paste": "Søk eller lim inn URL",
"search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.", "search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Pokaż profil mimo to", "limited_account_hint.action": "Pokaż profil mimo to",
"limited_account_hint.title": "Ten profil został ukryty przez moderatorów {domain}.", "limited_account_hint.title": "Ten profil został ukryty przez moderatorów {domain}.",
"link_preview.author": "{name}", "link_preview.author": "{name}",
"link_preview.more_from_author": "Więcej od {name}",
"lists.account.add": "Dodaj do listy", "lists.account.add": "Dodaj do listy",
"lists.account.remove": "Usunąć z listy", "lists.account.remove": "Usunąć z listy",
"lists.delete": "Usuń listę", "lists.delete": "Usuń listę",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Exibir perfil mesmo assim", "limited_account_hint.action": "Exibir perfil mesmo assim",
"limited_account_hint.title": "Este perfil foi ocultado pelos moderadores do {domain}.", "limited_account_hint.title": "Este perfil foi ocultado pelos moderadores do {domain}.",
"link_preview.author": "Por {name}", "link_preview.author": "Por {name}",
"link_preview.more_from_author": "Mais de {name}",
"lists.account.add": "Adicionar à lista", "lists.account.add": "Adicionar à lista",
"lists.account.remove": "Remover da lista", "lists.account.remove": "Remover da lista",
"lists.delete": "Excluir lista", "lists.delete": "Excluir lista",
@ -474,6 +475,7 @@
"notification.follow_request": "{name} quer te seguir", "notification.follow_request": "{name} quer te seguir",
"notification.mention": "{name} te mencionou", "notification.mention": "{name} te mencionou",
"notification.moderation-warning.learn_more": "Aprender mais", "notification.moderation-warning.learn_more": "Aprender mais",
"notification.moderation_warning": "Você recebeu um aviso de moderação",
"notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.", "notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.",
"notification.moderation_warning.action_disable": "Sua conta foi desativada.", "notification.moderation_warning.action_disable": "Sua conta foi desativada.",
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas de suas publicações foram marcadas por ter conteúdo sensível.", "notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas de suas publicações foram marcadas por ter conteúdo sensível.",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Exibir perfil mesmo assim", "limited_account_hint.action": "Exibir perfil mesmo assim",
"limited_account_hint.title": "Este perfil foi ocultado pelos moderadores de {domain}.", "limited_account_hint.title": "Este perfil foi ocultado pelos moderadores de {domain}.",
"link_preview.author": "Por {name}", "link_preview.author": "Por {name}",
"link_preview.more_from_author": "Mais de {name}",
"lists.account.add": "Adicionar à lista", "lists.account.add": "Adicionar à lista",
"lists.account.remove": "Remover da lista", "lists.account.remove": "Remover da lista",
"lists.delete": "Eliminar lista", "lists.delete": "Eliminar lista",

View File

@ -18,6 +18,7 @@
"account.edit_profile": "පැතිකඩ සංස්කරණය", "account.edit_profile": "පැතිකඩ සංස්කරණය",
"account.enable_notifications": "@{name} පළ කරන විට මට දැනුම් දෙන්න", "account.enable_notifications": "@{name} පළ කරන විට මට දැනුම් දෙන්න",
"account.endorse": "පැතිකඩෙහි විශේෂාංගය", "account.endorse": "පැතිකඩෙහි විශේෂාංගය",
"account.featured_tags.last_status_at": "අවසාන ලිපිය: {date}",
"account.featured_tags.last_status_never": "ලිපි නැත", "account.featured_tags.last_status_never": "ලිපි නැත",
"account.follow": "අනුගමනය", "account.follow": "අනුගමනය",
"account.followers": "අනුගාමිකයින්", "account.followers": "අනුගාමිකයින්",
@ -104,6 +105,7 @@
"compose_form.poll.duration": "මත විමසීමේ කාලය", "compose_form.poll.duration": "මත විමසීමේ කාලය",
"compose_form.poll.switch_to_multiple": "තේරීම් කිහිපයකට මත විමසුම වෙනස් කරන්න", "compose_form.poll.switch_to_multiple": "තේරීම් කිහිපයකට මත විමසුම වෙනස් කරන්න",
"compose_form.poll.switch_to_single": "තනි තේරීමකට මත විමසුම වෙනස් කරන්න", "compose_form.poll.switch_to_single": "තනි තේරීමකට මත විමසුම වෙනස් කරන්න",
"compose_form.publish": "ප්‍රකාශනය",
"compose_form.publish_form": "නව ලිපිය", "compose_form.publish_form": "නව ලිපිය",
"compose_form.spoiler.marked": "අන්තර්ගත අවවාදය ඉවත් කරන්න", "compose_form.spoiler.marked": "අන්තර්ගත අවවාදය ඉවත් කරන්න",
"compose_form.spoiler.unmarked": "අන්තර්ගත අවවාදයක් එක් කරන්න", "compose_form.spoiler.unmarked": "අන්තර්ගත අවවාදයක් එක් කරන්න",
@ -154,6 +156,7 @@
"empty_column.bookmarked_statuses": "ඔබ සතුව පොත්යොමු තබන ලද ලිපි කිසිවක් නැත. ඔබ පොත්යොමුවක් තබන විට, එය මෙහි දිස්වනු ඇත.", "empty_column.bookmarked_statuses": "ඔබ සතුව පොත්යොමු තබන ලද ලිපි කිසිවක් නැත. ඔබ පොත්යොමුවක් තබන විට, එය මෙහි දිස්වනු ඇත.",
"empty_column.domain_blocks": "අවහිර කරන ලද වසම් නැත.", "empty_column.domain_blocks": "අවහිර කරන ලද වසම් නැත.",
"empty_column.explore_statuses": "දැන් කිසිවක් නැඹුරු නොවේ. පසුව නැවත පරීක්ෂා කරන්න!", "empty_column.explore_statuses": "දැන් කිසිවක් නැඹුරු නොවේ. පසුව නැවත පරීක්ෂා කරන්න!",
"empty_column.favourited_statuses": "ඔබ සතුව ප්‍රියතම ලිපි කිසිවක් නැත. ඔබ යමකට ප්‍රිය කළ විට එය මෙහි පෙන්වනු ඇත.",
"empty_column.follow_requests": "ඔබට තවමත් අනුගමන ඉල්ලීම් ලැබී නැත. ඉල්ලීමක් ලැබුණු විට, එය මෙහි පෙන්වනු ඇත.", "empty_column.follow_requests": "ඔබට තවමත් අනුගමන ඉල්ලීම් ලැබී නැත. ඉල්ලීමක් ලැබුණු විට, එය මෙහි පෙන්වනු ඇත.",
"empty_column.home": "මුල් පිටුව හිස් ය! මෙය පිරවීමට බොහෝ පුද්ගලයින් අනුගමනය කරන්න.", "empty_column.home": "මුල් පිටුව හිස් ය! මෙය පිරවීමට බොහෝ පුද්ගලයින් අනුගමනය කරන්න.",
"empty_column.lists": "ඔබට තවමත් ලැයිස්තු කිසිවක් නැත. ඔබ එකක් සාදන විට, එය මෙහි පෙන්වනු ඇත.", "empty_column.lists": "ඔබට තවමත් ලැයිස්තු කිසිවක් නැත. ඔබ එකක් සාදන විට, එය මෙහි පෙන්වනු ඇත.",
@ -205,6 +208,7 @@
"interaction_modal.on_this_server": "මෙම සේවාදායකයෙහි", "interaction_modal.on_this_server": "මෙම සේවාදායකයෙහි",
"interaction_modal.title.favourite": "{name}ගේ ලිපිය ප්‍රිය කරන්න", "interaction_modal.title.favourite": "{name}ගේ ලිපිය ප්‍රිය කරන්න",
"interaction_modal.title.follow": "{name} අනුගමනය", "interaction_modal.title.follow": "{name} අනුගමනය",
"interaction_modal.title.reply": "{name}ගේ ලිපියට පිළිතුරු",
"intervals.full.days": "{number, plural, one {දවස් #} other {දවස් #}}", "intervals.full.days": "{number, plural, one {දවස් #} other {දවස් #}}",
"intervals.full.hours": "{number, plural, one {පැය #} other {පැය #}}", "intervals.full.hours": "{number, plural, one {පැය #} other {පැය #}}",
"intervals.full.minutes": "{number, plural, one {විනාඩි #} other {විනාඩි #}}", "intervals.full.minutes": "{number, plural, one {විනාඩි #} other {විනාඩි #}}",
@ -239,6 +243,7 @@
"lists.delete": "ලැයිස්තුව මකන්න", "lists.delete": "ලැයිස්තුව මකන්න",
"lists.edit": "ලැයිස්තුව සංස්කරණය", "lists.edit": "ලැයිස්තුව සංස්කරණය",
"lists.edit.submit": "සිරැසිය සංශෝධනය", "lists.edit.submit": "සිරැසිය සංශෝධනය",
"lists.new.create": "එකතු",
"lists.new.title_placeholder": "නව ලැයිස්තුවේ සිරැසිය", "lists.new.title_placeholder": "නව ලැයිස්තුවේ සිරැසිය",
"lists.replies_policy.list": "ලැයිස්තුවේ සාමාජිකයින්", "lists.replies_policy.list": "ලැයිස්තුවේ සාමාජිකයින්",
"lists.replies_policy.none": "කිසිවෙක් නැත", "lists.replies_policy.none": "කිසිවෙක් නැත",
@ -266,6 +271,7 @@
"navigation_bar.search": "සොයන්න", "navigation_bar.search": "සොයන්න",
"navigation_bar.security": "ආරක්ෂාව", "navigation_bar.security": "ආරක්ෂාව",
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
"notification.favourite": "{name} ඔබගේ ලිපියට ප්‍රිය කළා",
"notification.follow": "{name} ඔබව අනුගමනය කළා", "notification.follow": "{name} ඔබව අනුගමනය කළා",
"notification.mention": "{name} ඔබව සඳහන් කර ඇත", "notification.mention": "{name} ඔබව සඳහන් කර ඇත",
"notification.own_poll": "ඔබගේ මත විමසුම නිමයි", "notification.own_poll": "ඔබගේ මත විමසුම නිමයි",
@ -395,6 +401,7 @@
"status.admin_status": "මෙම ලිපිය මැදිහත්කරණ අතුරුමුහුණතෙහි අරින්න", "status.admin_status": "මෙම ලිපිය මැදිහත්කරණ අතුරුමුහුණතෙහි අරින්න",
"status.block": "@{name} අවහිර", "status.block": "@{name} අවහිර",
"status.bookmark": "පොත්යොමුවක්", "status.bookmark": "පොත්යොමුවක්",
"status.copy": "ලිපියට සබැඳියේ පිටපතක්",
"status.delete": "මකන්න", "status.delete": "මකන්න",
"status.detailed_status": "විස්තරාත්මක සංවාද දැක්ම", "status.detailed_status": "විස්තරාත්මක සංවාද දැක්ම",
"status.edit": "සංස්කරණය", "status.edit": "සංස්කරණය",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Vseeno pokaži profil", "limited_account_hint.action": "Vseeno pokaži profil",
"limited_account_hint.title": "Profil so moderatorji strežnika {domain} skrili.", "limited_account_hint.title": "Profil so moderatorji strežnika {domain} skrili.",
"link_preview.author": "Avtor_ica {name}", "link_preview.author": "Avtor_ica {name}",
"link_preview.more_from_author": "Več od {name}",
"lists.account.add": "Dodaj na seznam", "lists.account.add": "Dodaj na seznam",
"lists.account.remove": "Odstrani s seznama", "lists.account.remove": "Odstrani s seznama",
"lists.delete": "Izbriši seznam", "lists.delete": "Izbriši seznam",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "Vẫn cứ xem", "limited_account_hint.action": "Vẫn cứ xem",
"limited_account_hint.title": "Người này đã bị ẩn bởi quản trị viên của {domain}.", "limited_account_hint.title": "Người này đã bị ẩn bởi quản trị viên của {domain}.",
"link_preview.author": "Bởi {name}", "link_preview.author": "Bởi {name}",
"link_preview.more_from_author": "Thêm từ {name}",
"lists.account.add": "Thêm vào danh sách", "lists.account.add": "Thêm vào danh sách",
"lists.account.remove": "Xóa khỏi danh sách", "lists.account.remove": "Xóa khỏi danh sách",
"lists.delete": "Xóa danh sách", "lists.delete": "Xóa danh sách",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "仍要显示个人资料", "limited_account_hint.action": "仍要显示个人资料",
"limited_account_hint.title": "此账号资料已被 {domain} 管理员隐藏。", "limited_account_hint.title": "此账号资料已被 {domain} 管理员隐藏。",
"link_preview.author": "由 {name}", "link_preview.author": "由 {name}",
"link_preview.more_from_author": "查看 {name} 的更多内容",
"lists.account.add": "添加到列表", "lists.account.add": "添加到列表",
"lists.account.remove": "从列表中移除", "lists.account.remove": "从列表中移除",
"lists.delete": "删除列表", "lists.delete": "删除列表",

View File

@ -414,6 +414,7 @@
"limited_account_hint.action": "一律顯示個人檔案", "limited_account_hint.action": "一律顯示個人檔案",
"limited_account_hint.title": "此個人檔案已被 {domain} 的管理員隱藏。", "limited_account_hint.title": "此個人檔案已被 {domain} 的管理員隱藏。",
"link_preview.author": "來自 {name}", "link_preview.author": "來自 {name}",
"link_preview.more_from_author": "來自 {name} 之更多內容",
"lists.account.add": "新增至列表", "lists.account.add": "新增至列表",
"lists.account.remove": "自列表中移除", "lists.account.remove": "自列表中移除",
"lists.delete": "刪除列表", "lists.delete": "刪除列表",

View File

@ -74,8 +74,9 @@ export const soundsMiddleware = (): Middleware<
if (isActionWithMetaSound(action)) { if (isActionWithMetaSound(action)) {
const sound = action.meta.sound; const sound = action.meta.sound;
if (sound && Object.hasOwn(soundCache, sound)) { if (sound) {
play(soundCache[sound]); const s = soundCache[sound];
if (s) play(s);
} }
} }

View File

@ -89,21 +89,17 @@ type OnData<LoadDataResult, ReturnedData> = (
}, },
) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>; ) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>;
type ArgsType = Record<string, unknown> | undefined;
// Overload when there is no `onData` method, the payload is the `onData` result // Overload when there is no `onData` method, the payload is the `onData` result
export function createDataLoadingThunk< export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
LoadDataResult,
Args extends Record<string, unknown>,
>(
name: string, name: string,
loadData: (args: Args) => Promise<LoadDataResult>, loadData: (args: Args) => Promise<LoadDataResult>,
thunkOptions?: AppThunkOptions, thunkOptions?: AppThunkOptions,
): ReturnType<typeof createThunk<Args, LoadDataResult>>; ): ReturnType<typeof createThunk<Args, LoadDataResult>>;
// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty // Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty
export function createDataLoadingThunk< export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
LoadDataResult,
Args extends Record<string, unknown>,
>(
name: string, name: string,
loadData: (args: Args) => Promise<LoadDataResult>, loadData: (args: Args) => Promise<LoadDataResult>,
onDataOrThunkOptions?: onDataOrThunkOptions?:
@ -113,10 +109,7 @@ export function createDataLoadingThunk<
): ReturnType<typeof createThunk<Args, void>>; ): ReturnType<typeof createThunk<Args, void>>;
// Overload when the `onData` method returns nothing, then the mayload is the `onData` result // Overload when the `onData` method returns nothing, then the mayload is the `onData` result
export function createDataLoadingThunk< export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
LoadDataResult,
Args extends Record<string, unknown>,
>(
name: string, name: string,
loadData: (args: Args) => Promise<LoadDataResult>, loadData: (args: Args) => Promise<LoadDataResult>,
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, void>, onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, void>,
@ -126,7 +119,7 @@ export function createDataLoadingThunk<
// Overload when there is an `onData` method returning something // Overload when there is an `onData` method returning something
export function createDataLoadingThunk< export function createDataLoadingThunk<
LoadDataResult, LoadDataResult,
Args extends Record<string, unknown>, Args extends ArgsType,
Returned, Returned,
>( >(
name: string, name: string,
@ -162,7 +155,7 @@ export function createDataLoadingThunk<
*/ */
export function createDataLoadingThunk< export function createDataLoadingThunk<
LoadDataResult, LoadDataResult,
Args extends Record<string, unknown>, Args extends ArgsType,
Returned, Returned,
>( >(
name: string, name: string,

View File

@ -3896,6 +3896,10 @@ $ui-header-logo-wordmark-width: 99px;
border: 1px solid var(--background-border-color); border: 1px solid var(--background-border-color);
border-radius: 8px; border-radius: 8px;
&.bottomless {
border-radius: 8px 8px 0 0;
}
&__actions { &__actions {
bottom: 0; bottom: 0;
inset-inline-start: 0; inset-inline-start: 0;
@ -10223,3 +10227,42 @@ noscript {
} }
} }
} }
.more-from-author {
font-size: 14px;
color: $darker-text-color;
background: var(--surface-background-color);
border: 1px solid var(--background-border-color);
border-top: 0;
border-radius: 0 0 8px 8px;
padding: 15px;
display: flex;
align-items: center;
gap: 8px;
.logo {
height: 16px;
color: $darker-text-color;
}
& > span {
display: flex;
align-items: center;
gap: 8px;
}
a {
display: inline-flex;
align-items: center;
gap: 4px;
font-weight: 500;
color: $primary-text-color;
text-decoration: none;
&:hover,
&:focus,
&:active {
color: $highlight-text-color;
}
}
}

View File

@ -110,7 +110,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
def process_status_params def process_status_params
@status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: @account.followers_url, object: @object) @status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: @account.followers_url, object: @object)
attachment_ids = process_attachments.take(4).map(&:id) attachment_ids = process_attachments.take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:id)
@params = { @params = {
uri: @status_parser.uri, uri: @status_parser.uri,
@ -260,7 +260,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
as_array(@object['attachment']).each do |attachment| as_array(@object['attachment']).each do |attachment|
media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment) media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment)
next if media_attachment_parser.remote_url.blank? || media_attachments.size >= 4 next if media_attachment_parser.remote_url.blank? || media_attachments.size >= Status::MEDIA_ATTACHMENTS_LIMIT
begin begin
media_attachment = MediaAttachment.create( media_attachment = MediaAttachment.create(

View File

@ -195,6 +195,10 @@ class LinkDetailsExtractor
structured_data&.author_url structured_data&.author_url
end end
def author_account
opengraph_tag('fediverse:creator')
end
def embed_url def embed_url
valid_url_or_nil(opengraph_tag('twitter:player:stream')) valid_url_or_nil(opengraph_tag('twitter:player:stream'))
end end

View File

@ -1,10 +0,0 @@
# frozen_string_literal: true
class Vacuum::ApplicationsVacuum
def perform
Doorkeeper::Application.where(owner_id: nil)
.where.missing(:created_users, :access_tokens, :access_grants)
.where(created_at: ...1.day.ago)
.in_batches.delete_all
end
end

View File

@ -142,6 +142,8 @@ class Account < ApplicationRecord
scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) } scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) }
scope :not_domain_blocked_by_account, ->(account) { where(arel_table[:domain].eq(nil).or(arel_table[:domain].not_in(account.excluded_from_timeline_domains))) } scope :not_domain_blocked_by_account, ->(account) { where(arel_table[:domain].eq(nil).or(arel_table[:domain].not_in(account.excluded_from_timeline_domains))) }
scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) } scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) }
scope :with_username, ->(value) { where arel_table[:username].lower.eq(value.to_s.downcase) }
scope :with_domain, ->(value) { where arel_table[:domain].lower.eq(value&.to_s&.downcase) }
after_update_commit :trigger_update_webhooks after_update_commit :trigger_update_webhooks

View File

@ -3,7 +3,7 @@
class AccountSuggestions::SettingSource < AccountSuggestions::Source class AccountSuggestions::SettingSource < AccountSuggestions::Source
def get(account, limit: DEFAULT_LIMIT) def get(account, limit: DEFAULT_LIMIT)
if setting_enabled? if setting_enabled?
base_account_scope(account).where(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle) base_account_scope(account).merge(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
else else
[] []
end end
@ -25,11 +25,9 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source
def setting_to_where_condition def setting_to_where_condition
usernames_and_domains.map do |(username, domain)| usernames_and_domains.map do |(username, domain)|
Arel::Nodes::Grouping.new( Account
Account.arel_table[:username].lower.eq(username.downcase).and( .with_username(username)
Account.arel_table[:domain].lower.eq(domain&.downcase) .with_domain(domain)
)
)
end.reduce(:or) end.reduce(:or)
end end

View File

@ -25,42 +25,11 @@ module Account::FinderConcern
end end
def find_remote(username, domain) def find_remote(username, domain)
AccountFinder.new(username, domain).account Account
end .with_username(username)
end .with_domain(domain)
.order(id: :asc)
class AccountFinder .take
attr_reader :username, :domain
def initialize(username, domain)
@username = username
@domain = domain
end
def account
scoped_accounts.order(id: :asc).take
end
private
def scoped_accounts
Account.unscoped.tap do |scope|
scope.merge! with_usernames
scope.merge! matching_username
scope.merge! matching_domain
end
end
def with_usernames
Account.where.not(Account.arel_table[:username].lower.eq '')
end
def matching_username
Account.where(Account.arel_table[:username].lower.eq username.to_s.downcase)
end
def matching_domain
Account.where(Account.arel_table[:domain].lower.eq(domain.nil? ? nil : domain.to_s.downcase))
end end
end end
end end

View File

@ -22,7 +22,7 @@ module User::LdapAuthenticable
safe_username = safe_username.gsub(keys, replacement) safe_username = safe_username.gsub(keys, replacement)
end end
resource = joins(:account).merge(Account.where(Account.arel_table[:username].lower.eq safe_username.downcase)).take resource = joins(:account).merge(Account.with_username(safe_username)).take
if resource.blank? if resource.blank?
resource = new( resource = new(

View File

@ -32,6 +32,7 @@
# link_type :integer # link_type :integer
# published_at :datetime # published_at :datetime
# image_description :string default(""), not null # image_description :string default(""), not null
# author_account_id :bigint(8)
# #
class PreviewCard < ApplicationRecord class PreviewCard < ApplicationRecord
@ -54,6 +55,7 @@ class PreviewCard < ApplicationRecord
has_many :statuses, through: :preview_cards_statuses has_many :statuses, through: :preview_cards_statuses
has_one :trend, class_name: 'PreviewCardTrend', inverse_of: :preview_card, dependent: :destroy has_one :trend, class_name: 'PreviewCardTrend', inverse_of: :preview_card, dependent: :destroy
belongs_to :author_account, class_name: 'Account', optional: true
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 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

View File

@ -41,6 +41,8 @@ class Status < ApplicationRecord
include Status::SnapshotConcern include Status::SnapshotConcern
include Status::ThreadingConcern include Status::ThreadingConcern
MEDIA_ATTACHMENTS_LIMIT = 4
rate_limit by: :account, family: :statuses rate_limit by: :account, family: :statuses
self.discard_column = :deleted_at self.discard_column = :deleted_at
@ -162,9 +164,9 @@ class Status < ApplicationRecord
:status_stat, :status_stat,
:tags, :tags,
:preloadable_poll, :preloadable_poll,
preview_cards_status: [:preview_card], preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
account: [:account_stat, user: :role], account: [:account_stat, user: :role],
active_mentions: { account: :account_stat }, active_mentions: :account,
reblog: [ reblog: [
:application, :application,
:tags, :tags,
@ -172,11 +174,11 @@ class Status < ApplicationRecord
:conversation, :conversation,
:status_stat, :status_stat,
:preloadable_poll, :preloadable_poll,
preview_cards_status: [:preview_card], preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
account: [:account_stat, user: :role], account: [:account_stat, user: :role],
active_mentions: { account: :account_stat }, active_mentions: :account,
], ],
thread: { account: :account_stat } thread: :account
delegate :domain, to: :account, prefix: true delegate :domain, to: :account, prefix: true

View File

@ -59,7 +59,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
statuses: { statuses: {
max_characters: StatusLengthValidator::MAX_CHARS, max_characters: StatusLengthValidator::MAX_CHARS,
max_media_attachments: 4, max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT,
characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS, characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS,
supported_mime_types: HtmlAwareFormatter::STATUS_MIME_TYPES, supported_mime_types: HtmlAwareFormatter::STATUS_MIME_TYPES,
}, },

View File

@ -8,6 +8,8 @@ class REST::PreviewCardSerializer < ActiveModel::Serializer
:provider_url, :html, :width, :height, :provider_url, :html, :width, :height,
:image, :image_description, :embed_url, :blurhash, :published_at :image, :image_description, :embed_url, :blurhash, :published_at
has_one :author_account, serializer: REST::AccountSerializer, if: -> { object.author_account.present? }
def url def url
object.original_url.presence || object.url object.original_url.presence || object.url
end end

View File

@ -77,7 +77,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
statuses: { statuses: {
max_characters: StatusLengthValidator::MAX_CHARS, max_characters: StatusLengthValidator::MAX_CHARS,
max_media_attachments: 4, max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT,
characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS, characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS,
supported_mime_types: HtmlAwareFormatter::STATUS_MIME_TYPES, supported_mime_types: HtmlAwareFormatter::STATUS_MIME_TYPES,
}, },

View File

@ -73,7 +73,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
as_array(@json['attachment']).each do |attachment| as_array(@json['attachment']).each do |attachment|
media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment) media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment)
next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > 4 next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > Status::MEDIA_ATTACHMENTS_LIMIT
begin begin
media_attachment = previous_media_attachments.find { |previous_media_attachment| previous_media_attachment.remote_url == media_attachment_parser.remote_url } media_attachment = previous_media_attachments.find { |previous_media_attachment| previous_media_attachment.remote_url == media_attachment_parser.remote_url }

View File

@ -147,9 +147,12 @@ class FetchLinkCardService < BaseService
return if html.nil? return if html.nil?
link_details_extractor = LinkDetailsExtractor.new(@url, @html, @html_charset) link_details_extractor = LinkDetailsExtractor.new(@url, @html, @html_charset)
provider = PreviewCardProvider.matching_domain(Addressable::URI.parse(link_details_extractor.canonical_url).normalized_host)
linked_account = ResolveAccountService.new.call(link_details_extractor.author_account, suppress_errors: true) if link_details_extractor.author_account.present? && provider&.trendable?
@card = PreviewCard.find_or_initialize_by(url: link_details_extractor.canonical_url) if link_details_extractor.canonical_url != @card.url @card = PreviewCard.find_or_initialize_by(url: link_details_extractor.canonical_url) if link_details_extractor.canonical_url != @card.url
@card.assign_attributes(link_details_extractor.to_preview_card_attributes) @card.assign_attributes(link_details_extractor.to_preview_card_attributes)
@card.author_account = linked_account
@card.save_with_optional_image! unless @card.title.blank? && @card.html.blank? @card.save_with_optional_image! unless @card.title.blank? && @card.html.blank?
end end
end end

View File

@ -146,9 +146,9 @@ class PostStatusService < BaseService
return return
end end
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present? raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > Status::MEDIA_ATTACHMENTS_LIMIT || @options[:poll].present?
@media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)) @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:to_i))
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?)
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?)

View File

@ -81,7 +81,7 @@ class ReportService < BaseService
# If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses. # If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses.
domain = @source_account.domain.to_s.downcase domain = @source_account.domain.to_s.downcase
has_followers = @target_account.followers.where(Account.arel_table[:domain].lower.eq(domain)).exists? has_followers = @target_account.followers.with_domain(domain).exists?
visibility = has_followers ? %i(public unlisted private) : %i(public unlisted) visibility = has_followers ? %i(public unlisted private) : %i(public unlisted)
scope = @target_account.statuses.with_discarded scope = @target_account.statuses.with_discarded
scope.merge!(scope.where(visibility: visibility).or(scope.where('EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)', domain))) scope.merge!(scope.where(visibility: visibility).or(scope.where('EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)', domain)))

View File

@ -70,9 +70,9 @@ class UpdateStatusService < BaseService
def validate_media! def validate_media!
return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable) return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present? raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > Status::MEDIA_ATTACHMENTS_LIMIT || @options[:poll].present?
media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)).to_a media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:to_i)).to_a
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media_attachments.size > 1 && media_attachments.find(&:audio_or_video?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media_attachments.size > 1 && media_attachments.find(&:audio_or_video?)
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if media_attachments.any?(&:not_processed?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if media_attachments.any?(&:not_processed?)

View File

@ -6,10 +6,7 @@ class UniqueUsernameValidator < ActiveModel::Validator
def validate(account) def validate(account)
return if account.username.blank? return if account.username.blank?
normalized_username = account.username.downcase scope = Account.with_username(account.username).with_domain(account.domain)
normalized_domain = account.domain&.downcase
scope = Account.where(Account.arel_table[:username].lower.eq normalized_username).where(Account.arel_table[:domain].lower.eq normalized_domain)
scope = scope.where.not(id: account.id) if account.persisted? scope = scope.where.not(id: account.id) if account.persisted?
account.errors.add(:username, :taken) if scope.exists? account.errors.add(:username, :taken) if scope.exists?

View File

@ -22,7 +22,6 @@ class Scheduler::VacuumScheduler
preview_cards_vacuum, preview_cards_vacuum,
backups_vacuum, backups_vacuum,
access_tokens_vacuum, access_tokens_vacuum,
applications_vacuum,
feeds_vacuum, feeds_vacuum,
imports_vacuum, imports_vacuum,
] ]
@ -56,10 +55,6 @@ class Scheduler::VacuumScheduler
Vacuum::ImportsVacuum.new Vacuum::ImportsVacuum.new
end end
def applications_vacuum
Vacuum::ApplicationsVacuum.new
end
def content_retention_policy def content_retention_policy
ContentRetentionPolicy.current ContentRetentionPolicy.current
end end

View File

@ -13,7 +13,7 @@ end
Paperclip.interpolates :prefix_path do |attachment, _style| Paperclip.interpolates :prefix_path do |attachment, _style|
if attachment.storage_schema_version >= 1 && attachment.instance.respond_to?(:local?) && !attachment.instance.local? if attachment.storage_schema_version >= 1 && attachment.instance.respond_to?(:local?) && !attachment.instance.local?
'cache' + File::SEPARATOR "cache#{File::SEPARATOR}"
else else
'' ''
end end
@ -159,7 +159,7 @@ else
Paperclip::Attachment.default_options.merge!( Paperclip::Attachment.default_options.merge!(
storage: :filesystem, storage: :filesystem,
path: File.join(ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system')), ':prefix_path:class', ':attachment', ':id_partition', ':style', ':filename'), path: File.join(ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system')), ':prefix_path:class', ':attachment', ':id_partition', ':style', ':filename'),
url: ENV.fetch('PAPERCLIP_ROOT_URL', '/system') + '/:prefix_url:class/:attachment/:id_partition/:style/:filename' url: "#{ENV.fetch('PAPERCLIP_ROOT_URL', '/system')}/:prefix_url:class/:attachment/:id_partition/:style/:filename"
) )
end end

View File

@ -105,6 +105,10 @@ class Rack::Attack
req.authenticated_user_id if (req.post? && req.path.match?(API_DELETE_REBLOG_REGEX)) || (req.delete? && req.path.match?(API_DELETE_STATUS_REGEX)) req.authenticated_user_id if (req.post? && req.path.match?(API_DELETE_REBLOG_REGEX)) || (req.delete? && req.path.match?(API_DELETE_STATUS_REGEX))
end end
throttle('throttle_oauth_application_registrations/ip', limit: 5, period: 10.minutes) do |req|
req.throttleable_remote_ip if req.post? && req.path == '/api/v1/apps'
end
throttle('throttle_sign_up_attempts/ip', limit: 25, period: 5.minutes) do |req| throttle('throttle_sign_up_attempts/ip', limit: 25, period: 5.minutes) do |req|
req.throttleable_remote_ip if req.post? && req.path_matches?('/auth') req.throttleable_remote_ip if req.post? && req.path_matches?('/auth')
end end

View File

@ -282,6 +282,7 @@ ja:
update_custom_emoji_html: "%{name}さんがカスタム絵文字 %{target}を更新しました" update_custom_emoji_html: "%{name}さんがカスタム絵文字 %{target}を更新しました"
update_domain_block_html: "%{name}さんが%{target}のドメインブロックを更新しました" update_domain_block_html: "%{name}さんが%{target}のドメインブロックを更新しました"
update_ip_block_html: "%{name} さんがIP %{target} のルールを更新しました" update_ip_block_html: "%{name} さんがIP %{target} のルールを更新しました"
update_report_html: "%{name}さんが通報 %{target} を更新しました"
update_status_html: "%{name}さんが%{target}さんの投稿を更新しました" update_status_html: "%{name}さんが%{target}さんの投稿を更新しました"
update_user_role_html: "%{name}さんがロール『%{target}』を変更しました" update_user_role_html: "%{name}さんがロール『%{target}』を変更しました"
deleted_account: 削除されたアカウント deleted_account: 削除されたアカウント
@ -933,6 +934,7 @@ ja:
delete: 削除 delete: 削除
edit_preset: プリセット警告文を編集 edit_preset: プリセット警告文を編集
empty: まだプリセット警告文が作成されていません。 empty: まだプリセット警告文が作成されていません。
title: プリセット警告文
webhooks: webhooks:
add_new: エンドポイントを追加 add_new: エンドポイントを追加
delete: 削除 delete: 削除

View File

@ -291,6 +291,7 @@ lt:
update_custom_emoji_html: "%{name} atnaujino jaustuką %{target}" update_custom_emoji_html: "%{name} atnaujino jaustuką %{target}"
update_domain_block_html: "%{name} atnaujino domeno bloką %{target}" update_domain_block_html: "%{name} atnaujino domeno bloką %{target}"
update_ip_block_html: "%{name} pakeitė taisyklę IP %{target}" update_ip_block_html: "%{name} pakeitė taisyklę IP %{target}"
update_report_html: "%{name} atnaujino ataskaitą %{target}"
update_status_html: "%{name} atnaujino įrašą %{target}" update_status_html: "%{name} atnaujino įrašą %{target}"
update_user_role_html: "%{name} pakeitė %{target} vaidmenį" update_user_role_html: "%{name} pakeitė %{target} vaidmenį"
deleted_account: ištrinta paskyra deleted_account: ištrinta paskyra
@ -344,6 +345,8 @@ lt:
shortcode: Trumpas kodas shortcode: Trumpas kodas
shortcode_hint: Bent du ženklai, tik raidiniai skaitmeniniai ženklai bei akcentai(_) shortcode_hint: Bent du ženklai, tik raidiniai skaitmeniniai ženklai bei akcentai(_)
title: Asmeniniai jaustukai title: Asmeniniai jaustukai
uncategorized: Be kategorijos
unlist: Išbraukti iš sąrašo
unlisted: Neįtrauktas į sąrašą unlisted: Neįtrauktas į sąrašą
update_failed_msg: Jaustukas negalėjo būti pakeistas update_failed_msg: Jaustukas negalėjo būti pakeistas
updated_msg: Jaustukas sėkmingai pakeistas! updated_msg: Jaustukas sėkmingai pakeistas!
@ -391,8 +394,16 @@ lt:
created_msg: Domenas buvo sėkmingai leistas federacijai. created_msg: Domenas buvo sėkmingai leistas federacijai.
destroyed_msg: Domenas buvo neleistas federacijai. destroyed_msg: Domenas buvo neleistas federacijai.
export: Eksportuoti export: Eksportuoti
import: Importuoti
undo: Neleisti federavimo su domenu
domain_blocks: domain_blocks:
add_new: Pridėti naują domeno bloką add_new: Pridėti naują domeno bloką
confirm_suspension:
cancel: Atšaukti
confirm: Pristabdyti
permanent_action: Atšaukus pristabdymą jokie duomenys ar sąryšiai nebus atkurti.
preamble_html: Jūs pristabdysite <strong>%{domain}</strong> ir jo subdomenus.
remove_all_data: Taip iš serverio bus pašalintas visas šio domeno paskyrų turinys, medija ir profilio duomenys.
created_msg: Domeno užblokavimas nagrinėjamas created_msg: Domeno užblokavimas nagrinėjamas
destroyed_msg: Domeno blokas pašalintas destroyed_msg: Domeno blokas pašalintas
domain: Domenas domain: Domenas
@ -410,6 +421,7 @@ lt:
silence: Riboti silence: Riboti
suspend: Pristabdyti suspend: Pristabdyti
title: Naujos domeno blokas title: Naujos domeno blokas
private_comment: Privatus komentaras
public_comment: Viešas komentaras public_comment: Viešas komentaras
public_comment_hint: Komentaras apie šį domeno apribojimą plačiajai visuomenei, jei įjungtas domenų apribojimų sąrašo reklamavimas. public_comment_hint: Komentaras apie šį domeno apribojimą plačiajai visuomenei, jei įjungtas domenų apribojimų sąrašo reklamavimas.
reject_media: Atmesti medijos failus reject_media: Atmesti medijos failus
@ -417,6 +429,7 @@ lt:
reject_reports: Atmesti ataskaitas reject_reports: Atmesti ataskaitas
reject_reports_hint: Ignoruoti visus skundus, kurie siunčiami iš šio domeno. Neliečia užblokavimu reject_reports_hint: Ignoruoti visus skundus, kurie siunčiami iš šio domeno. Neliečia užblokavimu
undo: Atkurti domeno bloką undo: Atkurti domeno bloką
view: Peržiūrėti domeno bloką
email_domain_blocks: email_domain_blocks:
add_new: Pridėti naują add_new: Pridėti naują
allow_registrations_with_approval: Leisti registracijas su patvirtinimu allow_registrations_with_approval: Leisti registracijas su patvirtinimu
@ -428,10 +441,16 @@ lt:
title: Naujas el pašto juodojo sąrašo įtraukimas title: Naujas el pašto juodojo sąrašo įtraukimas
title: El pašto juodasis sąrašas title: El pašto juodasis sąrašas
instances: instances:
availability:
title: Prieinamumas
back_to_all: Visi back_to_all: Visi
back_to_limited: Apribotas
back_to_warning: Įspėjimas
by_domain: Domenas by_domain: Domenas
content_policies: content_policies:
policy: Politika
reason: Viešoji priežastis reason: Viešoji priežastis
title: Turinio politika
delivery: delivery:
all: Visi all: Visi
delivery_available: Pristatymas galimas delivery_available: Pristatymas galimas
@ -624,6 +643,7 @@ lt:
add_new: Pridėti naują add_new: Pridėti naują
delete: Ištrinti delete: Ištrinti
edit_preset: Keisti įspėjimo nustatymus edit_preset: Keisti įspėjimo nustatymus
title: Įspėjamieji numatytieji
webhooks: webhooks:
description_html: "<strong>Webhook</strong> leidžia Mastodon siųsti <strong>realaus laiko pranešimus</strong> apie pasirinktus įvykius į tavo programą, kad programa galėtų <strong>automatiškai paleisti reakcijas</strong>." description_html: "<strong>Webhook</strong> leidžia Mastodon siųsti <strong>realaus laiko pranešimus</strong> apie pasirinktus įvykius į tavo programą, kad programa galėtų <strong>automatiškai paleisti reakcijas</strong>."
events: Įvykiai events: Įvykiai

View File

@ -461,13 +461,13 @@ nn:
title: Importer domeneblokkeringar title: Importer domeneblokkeringar
no_file: Inga fil vald no_file: Inga fil vald
follow_recommendations: follow_recommendations:
description_html: "<strong>Følgjeforslag hjelper nye brukarar å raskt finna interessant innhald</strong>. Om ein brukar ikkje har interagera nok med andre til å danne personlege følgjeforslag, vert disse kontiane føreslått i staden. Dei vert gjenkalkulert på dagleg basis ut frå ei blanding av dei konti med flest nylege engasjement og flest lokale følgjarar for eit gitt språk." description_html: "<strong>Fylgjeforslag hjelper nye brukarar å finna interessant innhald raskt</strong>. Om ein brukar ikkje har samhandla nok med andre til å få tilpassa fylgjeforslag, blir desse kontoane føreslått i staden. Dei blir rekna ut på nytt kvar dag ut frå ei blanding av kva kontoar som har mykje nyleg aktivitet og høgast tal på fylgjarar på eit bestemt språk."
language: For språk language: For språk
status: Status status: Status
suppress: Demp følgjeforslag suppress: Demp følgjeforslag
suppressed: Dempa suppressed: Dempa
title: Følgjeforslag title: Fylgjeforslag
unsuppress: Tilbakestill følgjeforslag unsuppress: Nullstill fylgjeforslag
instances: instances:
availability: availability:
description_html: description_html:
@ -746,7 +746,7 @@ nn:
preamble: Tilpasse web-grensesnittet. preamble: Tilpasse web-grensesnittet.
title: Utsjånad title: Utsjånad
branding: branding:
preamble: Profileringa av tenaren din skil den frå andre tenarar i nettverket. Informasjonen kan bli vist ulike stadar, til dømes i Mastodon sitt web-grensesnitt, i eigne applikasjonar, i førehandsvisningar på andre nettsider, i meldingsappar og så bortetter. På grunn av dette er det best å halde informasjonen enkel, kort og treffande. preamble: Profileringa av tenaren din skil den frå andre tenarar i nettverket. Informasjonen kan bli vist ulike stader, til dømes i Mastodon sitt web-grensesnitt, i eigne applikasjonar, i førehandsvisningar på andre nettsider, i meldingsappar og så bortetter. På grunn av dette er det best at denne informasjonen er enkel, kort og treffande.
title: Profilering title: Profilering
captcha_enabled: captcha_enabled:
desc_html: Dette baserer seg på eksterne skript frå hCaptcha, noko som kan vera eit tryggleiks- og personvernsproblem. <strong>I tillegg kan dette gjera registreringsprosessen monaleg mindre tilgjengeleg (særleg for folk med nedsett funksjonsevne)</strong>. Dette gjer at du bør du vurdera alternative tiltak, som til dømes godkjennings- eller invitasjonsbasert registrering. desc_html: Dette baserer seg på eksterne skript frå hCaptcha, noko som kan vera eit tryggleiks- og personvernsproblem. <strong>I tillegg kan dette gjera registreringsprosessen monaleg mindre tilgjengeleg (særleg for folk med nedsett funksjonsevne)</strong>. Dette gjer at du bør du vurdera alternative tiltak, som til dømes godkjennings- eller invitasjonsbasert registrering.
@ -759,7 +759,7 @@ nn:
desc_html: Påverkar alle brukarar som ikkje har justert denne innstillinga sjølve desc_html: Påverkar alle brukarar som ikkje har justert denne innstillinga sjølve
title: Ikkje la brukarar indekserast av søkjemotorar som standard title: Ikkje la brukarar indekserast av søkjemotorar som standard
discovery: discovery:
follow_recommendations: Følgjeforslag follow_recommendations: Fylgjeforslag
preamble: Å framheva interessant innhald er vitalt i mottakinga av nye brukarar som ikkje nødvendigvis kjenner nokon på Mastodon. Kontroller korleis oppdagingsfunksjonane på tenaren din fungerar. preamble: Å framheva interessant innhald er vitalt i mottakinga av nye brukarar som ikkje nødvendigvis kjenner nokon på Mastodon. Kontroller korleis oppdagingsfunksjonane på tenaren din fungerar.
profile_directory: Profilkatalog profile_directory: Profilkatalog
public_timelines: Offentlege tidsliner public_timelines: Offentlege tidsliner
@ -1562,7 +1562,7 @@ nn:
activity: Kontoaktivitet activity: Kontoaktivitet
confirm_follow_selected_followers: Er du sikker på at du ynskjer å fylgja dei valde fylgjarane? confirm_follow_selected_followers: Er du sikker på at du ynskjer å fylgja dei valde fylgjarane?
confirm_remove_selected_followers: Er du sikker på at du ynskjer å fjerna dei valde fylgjarane? confirm_remove_selected_followers: Er du sikker på at du ynskjer å fjerna dei valde fylgjarane?
confirm_remove_selected_follows: Er du sikker på at du ynskjer å fjerna det valde følgjet? confirm_remove_selected_follows: Er du sikker på at du ikkje vil fylgja desse?
dormant: I dvale dormant: I dvale
follow_failure: Greidde ikkje fylgja alle kontoane du valde. follow_failure: Greidde ikkje fylgja alle kontoane du valde.
follow_selected_followers: Følg valgte tilhengere follow_selected_followers: Følg valgte tilhengere

View File

@ -285,6 +285,7 @@ pt-BR:
update_custom_emoji_html: "%{name} atualizou o emoji %{target}" update_custom_emoji_html: "%{name} atualizou o emoji %{target}"
update_domain_block_html: "%{name} atualizou o bloqueio de domínio de %{target}" update_domain_block_html: "%{name} atualizou o bloqueio de domínio de %{target}"
update_ip_block_html: "%{name} alterou a regra para o IP %{target}" update_ip_block_html: "%{name} alterou a regra para o IP %{target}"
update_report_html: "%{name} atualizou o relatório %{target}"
update_status_html: "%{name} atualizou a publicação de %{target}" update_status_html: "%{name} atualizou a publicação de %{target}"
update_user_role_html: "%{name} alterou o cargo %{target}" update_user_role_html: "%{name} alterou o cargo %{target}"
deleted_account: conta excluída deleted_account: conta excluída
@ -950,6 +951,7 @@ pt-BR:
delete: Excluir delete: Excluir
edit_preset: Editar o aviso pré-definido edit_preset: Editar o aviso pré-definido
empty: Você ainda não definiu nenhuma predefinição de alerta. empty: Você ainda não definiu nenhuma predefinição de alerta.
title: Predefinições de aviso
webhooks: webhooks:
add_new: Adicionar endpoint add_new: Adicionar endpoint
delete: Excluir delete: Excluir

View File

@ -66,7 +66,7 @@ si:
inbox_url: එන ලිපි URL inbox_url: එන ලිපි URL
invite_request_text: එක්වීමට හේතුව invite_request_text: එක්වීමට හේතුව
invited_by: විසින් ආරාධනා කරන ලදී invited_by: විසින් ආරාධනා කරන ලදී
ip: අ.ජා. කෙ. (IP) ip: අ.ජා.කෙ. (IP)
joined: එක් වූ දිනය joined: එක් වූ දිනය
location: location:
all: සියල්ල all: සියල්ල
@ -87,7 +87,7 @@ si:
title: මැදිහත්කරණය title: මැදිහත්කරණය
moderation_notes: මැදිහත්කරණ සටහන් moderation_notes: මැදිහත්කරණ සටහන්
most_recent_activity: වඩාත්ම මෑත ක්රියාකාරිත්වය most_recent_activity: වඩාත්ම මෑත ක්රියාකාරිත්වය
most_recent_ip: මෑත අ.ජා.කෙ. (IP) most_recent_ip: මෑත අ.ජා.කෙ.
no_account_selected: කිසිවක් තෝරා නොගත් බැවින් ගිණුම් කිසිවක් වෙනස් කර නැත no_account_selected: කිසිවක් තෝරා නොගත් බැවින් ගිණුම් කිසිවක් වෙනස් කර නැත
no_limits_imposed: සීමාවන් පනවා නැත no_limits_imposed: සීමාවන් පනවා නැත
not_subscribed: දායක වී නැත not_subscribed: දායක වී නැත
@ -160,7 +160,7 @@ si:
create_custom_emoji: අභිරුචි ඉමොජි සාදන්න create_custom_emoji: අභිරුචි ඉමොජි සාදන්න
create_domain_allow: වසමකට ඉඩදීම සාදන්න create_domain_allow: වසමකට ඉඩදීම සාදන්න
create_email_domain_block: ඊමේල් ඩොමේන් බ්ලොක් එකක් සාදන්න create_email_domain_block: ඊමේල් ඩොමේන් බ්ලොක් එකක් සාදන්න
create_ip_block: අ.ජා. කෙ. (IP) නීතියක් සාදන්න create_ip_block: අ.ජා.කෙ. නීතියක් සාදන්න
create_unavailable_domain: ලබා ගත නොහැකි වසම සාදන්න create_unavailable_domain: ලබා ගත නොහැකි වසම සාදන්න
create_user_role: භූමිකාව සාදන්න create_user_role: භූමිකාව සාදන්න
demote_user: පරිශීලකයා පහත් කරන්න demote_user: පරිශීලකයා පහත් කරන්න
@ -473,7 +473,7 @@ si:
new: new:
title: නව අ.ජා.කෙ. නීතියක් සාදන්න title: නව අ.ජා.කෙ. නීතියක් සාදන්න
no_ip_block_selected: IP රීති කිසිවක් තෝරා නොගත් බැවින් වෙනස් කර නැත no_ip_block_selected: IP රීති කිසිවක් තෝරා නොගත් බැවින් වෙනස් කර නැත
title: අ.ජා. කෙ. (IP) නීති title: අ.ජා.කෙ. (IP) නීති
relationships: relationships:
title: "%{acct}හි සබඳතා" title: "%{acct}හි සබඳතා"
relays: relays:
@ -1239,7 +1239,7 @@ si:
current_session: වත්මන් වාරය current_session: වත්මන් වාරය
description: "%{platform} හි %{browser}" description: "%{platform} හි %{browser}"
explanation: ඔබගේ මාස්ටඩන් ගිණුමට පිවිසීම සඳහා භාවිතා කර තිබෙන අතිරික්සු. explanation: ඔබගේ මාස්ටඩන් ගිණුමට පිවිසීම සඳහා භාවිතා කර තිබෙන අතිරික්සු.
ip: අ.ජා. කෙ. (IP) ip: අ.ජා.කෙ.
platforms: platforms:
adobe_air: ඇඩෝබි එයාර් adobe_air: ඇඩෝබි එයාර්
android: ඇන්ඩ්‍රොයිඩ් android: ඇන්ඩ්‍රොයිඩ්
@ -1399,7 +1399,7 @@ si:
details: 'ප්‍රවේශයට අදාළ විස්තර:' details: 'ප්‍රවේශයට අදාළ විස්තර:'
explanation: ඔබගේ ගිණුමට නව අ.ජා.කෙ. (IP) ලිපිනයකින් ප්‍රවේශයක් අනාවරණය වී ඇත. explanation: ඔබගේ ගිණුමට නව අ.ජා.කෙ. (IP) ලිපිනයකින් ප්‍රවේශයක් අනාවරණය වී ඇත.
further_actions_html: මේ ඔබ නොවේ නම්, වහාම %{action}. ඔබගේ ගිණුම සුරක්‍ෂිතව තබා ගැනීමට ද්වි-සාධකය සබල කරන්න. further_actions_html: මේ ඔබ නොවේ නම්, වහාම %{action}. ඔබගේ ගිණුම සුරක්‍ෂිතව තබා ගැනීමට ද්වි-සාධකය සබල කරන්න.
subject: ඔබගේ ගිණුමට නව අ.ජා.කෙ. (IP) ලිපිනයකින් ප්‍රවේශ වී ඇත subject: ඔබගේ ගිණුමට නව අ.ජා.කෙ. ලිපිනයකින් ප්‍රවේශ වී ඇත
title: නව ප්‍රවේශයක් title: නව ප්‍රවේශයක්
warning: warning:
appeal: අභියාචනයක් ඉදිරිපත් කරන්න appeal: අභියාචනයක් ඉදිරිපත් කරන්න

View File

@ -74,8 +74,10 @@ lt:
warn: Slėpti filtruojamą turinį po įspėjimu, paminint filtro pavadinimą warn: Slėpti filtruojamą turinį po įspėjimu, paminint filtro pavadinimą
form_admin_settings: form_admin_settings:
activity_api_enabled: Vietinių paskelbtų įrašų, aktyvių naudotojų ir naujų registracijų skaičiai kas savaitę activity_api_enabled: Vietinių paskelbtų įrašų, aktyvių naudotojų ir naujų registracijų skaičiai kas savaitę
app_icon: WEBP, PNG, GIF arba JPG. Pakeičia numatytąją programos piktogramą mobiliuosiuose įrenginiuose pasirinktine piktograma.
backups_retention_period: Naudotojai gali generuoti savo įrašų archyvus, kuriuos vėliau galės atsisiųsti. Nustačius teigiamą reikšmę, šie archyvai po nurodyto dienų skaičiaus bus automatiškai ištrinti iš saugyklos. backups_retention_period: Naudotojai gali generuoti savo įrašų archyvus, kuriuos vėliau galės atsisiųsti. Nustačius teigiamą reikšmę, šie archyvai po nurodyto dienų skaičiaus bus automatiškai ištrinti iš saugyklos.
content_cache_retention_period: Visi įrašai iš kitų serverių (įskaitant pakėlimus ir atsakymus) bus ištrinti po nurodyto dienų skaičiaus, neatsižvelgiant į bet kokią vietinio naudotojo sąveiką su tais įrašais. Tai taikoma ir tiems įrašams, kuriuos vietinis naudotojas yra pažymėjęs kaip žymes ar mėgstamus. Privačios paminėjimai tarp naudotojų iš skirtingų instancijų taip pat bus prarastos ir jų bus neįmanoma atkurti. Šis nustatymas skirtas naudoti ypatingos paskirties instancijose, o įgyvendinus jį bendram naudojimui, pažeidžiami daugelio naudotojų lūkesčiai. content_cache_retention_period: Visi įrašai iš kitų serverių (įskaitant pakėlimus ir atsakymus) bus ištrinti po nurodyto dienų skaičiaus, neatsižvelgiant į bet kokią vietinio naudotojo sąveiką su tais įrašais. Tai taikoma ir tiems įrašams, kuriuos vietinis naudotojas yra pažymėjęs kaip žymes ar mėgstamus. Privačios paminėjimai tarp naudotojų iš skirtingų instancijų taip pat bus prarastos ir jų bus neįmanoma atkurti. Šis nustatymas skirtas naudoti ypatingos paskirties instancijose, o įgyvendinus jį bendram naudojimui, pažeidžiami daugelio naudotojų lūkesčiai.
favicon: WEBP, PNG, GIF arba JPG. Pakeičia numatytąją Mastodon svetaines piktogramą pasirinktine piktograma.
mascot: Pakeičia išplėstinės žiniatinklio sąsajos iliustraciją. mascot: Pakeičia išplėstinės žiniatinklio sąsajos iliustraciją.
media_cache_retention_period: Nuotolinių naudotojų įrašytų įrašų medijos failai talpinami tavo serveryje. Nustačius teigiamą reikšmę, medijos bus ištrinamos po nurodyto dienų skaičiaus. Jei medijos duomenų bus paprašyta po to, kai jie bus ištrinti, jie bus atsiųsti iš naujo, jei šaltinio turinys vis dar prieinamas. Dėl apribojimų, susijusių su nuorodų peržiūros kortelių apklausos dažnumu trečiųjų šalių svetainėse, rekomenduojama nustatyti šią reikšmę ne trumpesnę kaip 14 dienų, kitaip nuorodų peržiūros kortelės nebus atnaujinamos pagal pareikalavimą iki to laiko. media_cache_retention_period: Nuotolinių naudotojų įrašytų įrašų medijos failai talpinami tavo serveryje. Nustačius teigiamą reikšmę, medijos bus ištrinamos po nurodyto dienų skaičiaus. Jei medijos duomenų bus paprašyta po to, kai jie bus ištrinti, jie bus atsiųsti iš naujo, jei šaltinio turinys vis dar prieinamas. Dėl apribojimų, susijusių su nuorodų peržiūros kortelių apklausos dažnumu trečiųjų šalių svetainėse, rekomenduojama nustatyti šią reikšmę ne trumpesnę kaip 14 dienų, kitaip nuorodų peržiūros kortelės nebus atnaujinamos pagal pareikalavimą iki to laiko.
peers_api_enabled: Domenų pavadinimų sąrašas, su kuriais šis serveris susidūrė fediverse. Čia nėra duomenų apie tai, ar tu bendrauji su tam tikru serveriu, tik apie tai, kad tavo serveris apie jį žino. Tai naudojama tarnybose, kurios renka federacijos statistiką bendrąja prasme. peers_api_enabled: Domenų pavadinimų sąrašas, su kuriais šis serveris susidūrė fediverse. Čia nėra duomenų apie tai, ar tu bendrauji su tam tikru serveriu, tik apie tai, kad tavo serveris apie jį žino. Tai naudojama tarnybose, kurios renka federacijos statistiką bendrąja prasme.

View File

@ -8,8 +8,8 @@ nn:
fields: Heimesida di, pronomen, alder, eller kva du måtte ynskje. fields: Heimesida di, pronomen, alder, eller kva du måtte ynskje.
indexable: Dei offentlege innlegga dine kan dukka opp i søkjeresultat på Mastodon. Folk som har reagert på oinnlegga dine kan uansett søkja gjennom dei. indexable: Dei offentlege innlegga dine kan dukka opp i søkjeresultat på Mastodon. Folk som har reagert på oinnlegga dine kan uansett søkja gjennom dei.
note: 'Du kan @nemne folk eller #emneknaggar.' note: 'Du kan @nemne folk eller #emneknaggar.'
show_collections: Andre kan sjå kven du følgjer og kven som følgjer deg. Dei du følgjer kan alltid sjå at du følgjer dei. show_collections: Andre kan sjå kven du fylgjer og kven som fylgjer deg. Dei du fylgjer kan alltid sjå at du fylgjer dei.
unlocked: Alle kan følgje deg utan å måtte spørje om det. Vel bort om du vil gå gjennom førespurnadar om å følgje deg og seie ja eller nei. unlocked: Alle kan fylgja deg utan å måtta be om det. Vel bort dersom du vil gå gjennom førespurnader om å fylgja deg og seia ja eller nei til kvar av dei.
account_alias: account_alias:
acct: Angi brukarnamn@domene til brukaren du ynskjer å flytta frå acct: Angi brukarnamn@domene til brukaren du ynskjer å flytta frå
account_migration: account_migration:
@ -148,7 +148,7 @@ nn:
name: Merkelapp name: Merkelapp
value: Innhald value: Innhald
indexable: Ta med offentlege innlegg i søkjeresultat indexable: Ta med offentlege innlegg i søkjeresultat
show_collections: Vis følgjer og følgjare på profilen show_collections: Vis dei du fylgjer og dei som fylgjer deg på profilen din
unlocked: Godta nye følgjare automatisk unlocked: Godta nye følgjare automatisk
account_alias: account_alias:
acct: Brukarnamnet på den gamle kontoen acct: Brukarnamnet på den gamle kontoen

View File

@ -190,7 +190,7 @@ si:
text: ඔබට එක් වීමට අවශ්‍ය ඇයි? text: ඔබට එක් වීමට අවශ්‍ය ඇයි?
ip_block: ip_block:
comment: අදහස comment: අදහස
ip: අ.ජා. කෙ. (IP) ip: අ.ජා.කෙ. (IP)
severities: severities:
no_access: ප්‍රවේශය අවහිර කරන්න no_access: ප්‍රවේශය අවහිර කරන්න
sign_up_requires_approval: ලියාපදිංචි වීම සීමා කරන්න sign_up_requires_approval: ලියාපදිංචි වීම සීමා කරන්න

View File

@ -77,10 +77,15 @@ uk:
warn: Сховати відфільтрований вміст за попередженням, у якому вказано заголовок фільтра warn: Сховати відфільтрований вміст за попередженням, у якому вказано заголовок фільтра
form_admin_settings: form_admin_settings:
activity_api_enabled: Кількість локальних опублікованих дописів, активних і нових користувачів у тижневих розрізах activity_api_enabled: Кількість локальних опублікованих дописів, активних і нових користувачів у тижневих розрізах
app_icon: WEBP, PNG, GIF або JPG. Замінює іконку програми за замовчуванням на мобільних пристроях на власну іконку.
backups_retention_period: Користувачі мають можливість створювати архіви своїх дописів, щоб завантажити їх пізніше. Якщо встановлено додатне значення, ці архіви будуть автоматично видалені з вашого сховища через вказану кількість днів.
bootstrap_timeline_accounts: Ці облікові записи будуть закріплені в топі пропозицій для нових користувачів. bootstrap_timeline_accounts: Ці облікові записи будуть закріплені в топі пропозицій для нових користувачів.
closed_registrations_message: Показується, коли реєстрація закрита closed_registrations_message: Показується, коли реєстрація закрита
content_cache_retention_period: Усі дописи з інших серверів (включно з коментарями та відповідями) будуть видалені через певну кількість днів, незважаючи на будь-яку локальну взаємодію користувачів з цими дописами. Сюди входять дописи, які локальний користувач позначив як закладки або вибране. Приватні згадки між користувачами з різних інстанцій також будуть втрачені і не підлягатимуть відновленню. Використання цього параметра призначено для екземплярів спеціального призначення і порушує багато очікувань користувачів, якщо його застосовано для загального використання.
custom_css: Ви можете застосувати користувацькі стилі у вебверсії Mastodon. custom_css: Ви можете застосувати користувацькі стилі у вебверсії Mastodon.
favicon: WEBP, PNG, GIF або JPG. Замінює стандартну піктограму Mastodon на власну піктограму.
mascot: Змінює ілюстрацію в розширеному вебінтерфейсі. mascot: Змінює ілюстрацію в розширеному вебінтерфейсі.
media_cache_retention_period: Медіафайли з дописів віддалених користувачів кешуються на вашому сервері. Якщо встановлено додатне значення, медіа буде видалено через вказану кількість днів. Якщо медіа-дані будуть запитані після видалення, вони будуть завантажені повторно, якщо вихідний вміст все ще доступний. Через обмеження на частоту опитування карток попереднього перегляду посилань на сторонніх сайтах, рекомендується встановити це значення не менше 14 днів, інакше картки попереднього перегляду посилань не будуть оновлюватися на вимогу раніше цього часу.
peers_api_enabled: Список доменів імен цього сервера з'явився у федівсесвіті. Сюди не входять дані чи ви пов'язані федерацією з цим сервером, а лише відомості, що вашому серверу відомо про нього. Його використовують служби, які збирають загальну статистику про федерації. peers_api_enabled: Список доменів імен цього сервера з'явився у федівсесвіті. Сюди не входять дані чи ви пов'язані федерацією з цим сервером, а лише відомості, що вашому серверу відомо про нього. Його використовують служби, які збирають загальну статистику про федерації.
profile_directory: У каталозі профілів перераховані всі користувачі, які погодились бути видимими. profile_directory: У каталозі профілів перераховані всі користувачі, які погодились бути видимими.
require_invite_text: Якщо реєстрація вимагає власноручного затвердження, зробіть текстове поле «Чому ви хочете приєднатися?» обов'язковим, а не додатковим require_invite_text: Якщо реєстрація вимагає власноручного затвердження, зробіть текстове поле «Чому ви хочете приєднатися?» обов'язковим, а не додатковим

View File

@ -934,6 +934,7 @@ th:
delete: ลบ delete: ลบ
edit_preset: แก้ไขคำเตือนที่ตั้งไว้ล่วงหน้า edit_preset: แก้ไขคำเตือนที่ตั้งไว้ล่วงหน้า
empty: คุณยังไม่ได้กำหนดคำเตือนที่ตั้งไว้ล่วงหน้าใด ๆ empty: คุณยังไม่ได้กำหนดคำเตือนที่ตั้งไว้ล่วงหน้าใด ๆ
title: คำเตือนที่ตั้งไว้ล่วงหน้า
webhooks: webhooks:
add_new: เพิ่มปลายทาง add_new: เพิ่มปลายทาง
delete: ลบ delete: ลบ

View File

@ -291,6 +291,7 @@ uk:
update_custom_emoji_html: "%{name} оновлює емодзі %{target}" update_custom_emoji_html: "%{name} оновлює емодзі %{target}"
update_domain_block_html: "%{name} оновлює блокування домену для %{target}" update_domain_block_html: "%{name} оновлює блокування домену для %{target}"
update_ip_block_html: "%{name} змінює правило для IP %{target}" update_ip_block_html: "%{name} змінює правило для IP %{target}"
update_report_html: "%{name} оновлений звіт %{target}"
update_status_html: "%{name} оновлює допис %{target}" update_status_html: "%{name} оновлює допис %{target}"
update_user_role_html: "%{name} змінює роль %{target}" update_user_role_html: "%{name} змінює роль %{target}"
deleted_account: видалений обліковий запис deleted_account: видалений обліковий запис
@ -984,6 +985,7 @@ uk:
delete: Видалити delete: Видалити
edit_preset: Редагувати шаблон попередження edit_preset: Редагувати шаблон попередження
empty: Ви ще не визначили жодних попереджень. empty: Ви ще не визначили жодних попереджень.
title: Попереджувальні пресети
webhooks: webhooks:
add_new: Додати кінцеву точку add_new: Додати кінцеву точку
delete: Видалити delete: Видалити

View File

@ -934,6 +934,7 @@ vi:
delete: Xóa bỏ delete: Xóa bỏ
edit_preset: Sửa mẫu có sẵn edit_preset: Sửa mẫu có sẵn
empty: Bạn chưa thêm mẫu cảnh cáo nào cả. empty: Bạn chưa thêm mẫu cảnh cáo nào cả.
title: Cảnh báo cài sẵn
webhooks: webhooks:
add_new: Thêm endpoint add_new: Thêm endpoint
delete: Xóa bỏ delete: Xóa bỏ

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
class AddAuthorAccountIdToPreviewCards < ActiveRecord::Migration[7.1]
disable_ddl_transaction!
def change
safety_assured { add_reference :preview_cards, :author_account, null: true, foreign_key: { to_table: 'accounts', on_delete: :nullify }, index: false }
add_index :preview_cards, :author_account_id, algorithm: :concurrently, where: 'author_account_id IS NOT NULL'
end
end

View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2024_05_10_192043) do ActiveRecord::Schema[7.1].define(version: 2024_05_22_041528) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -877,6 +877,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_10_192043) do
t.integer "link_type" t.integer "link_type"
t.datetime "published_at" t.datetime "published_at"
t.string "image_description", default: "", null: false t.string "image_description", default: "", null: false
t.bigint "author_account_id"
t.index ["author_account_id"], name: "index_preview_cards_on_author_account_id", where: "(author_account_id IS NOT NULL)"
t.index ["url"], name: "index_preview_cards_on_url", unique: true t.index ["url"], name: "index_preview_cards_on_url", unique: true
end end
@ -1355,6 +1357,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_10_192043) do
add_foreign_key "polls", "accounts", on_delete: :cascade add_foreign_key "polls", "accounts", on_delete: :cascade
add_foreign_key "polls", "statuses", on_delete: :cascade add_foreign_key "polls", "statuses", on_delete: :cascade
add_foreign_key "preview_card_trends", "preview_cards", on_delete: :cascade add_foreign_key "preview_card_trends", "preview_cards", on_delete: :cascade
add_foreign_key "preview_cards", "accounts", column: "author_account_id", on_delete: :nullify
add_foreign_key "report_notes", "accounts", on_delete: :cascade add_foreign_key "report_notes", "accounts", on_delete: :cascade
add_foreign_key "report_notes", "reports", on_delete: :cascade add_foreign_key "report_notes", "reports", on_delete: :cascade
add_foreign_key "reports", "accounts", column: "action_taken_by_account_id", name: "fk_bca45b75fd", on_delete: :nullify add_foreign_key "reports", "accounts", column: "action_taken_by_account_id", name: "fk_bca45b75fd", on_delete: :nullify

View File

@ -8,6 +8,7 @@ class Mastodon::SidekiqMiddleware
rescue Mastodon::HostValidationError rescue Mastodon::HostValidationError
# Do not retry # Do not retry
rescue => e rescue => e
clean_up_elasticsearch_connections!
limit_backtrace_and_raise(e) limit_backtrace_and_raise(e)
ensure ensure
clean_up_sockets! clean_up_sockets!
@ -25,6 +26,32 @@ class Mastodon::SidekiqMiddleware
clean_up_statsd_socket! clean_up_statsd_socket!
end end
# This is a hack to immediately free up unused Elasticsearch connections.
#
# Indeed, Chewy creates one `Elasticsearch::Client` instance per thread,
# and each such client manages its long-lasting connection to
# Elasticsearch.
#
# As far as I know, neither `chewy`, `elasticsearch-transport` or even
# `faraday` provide a reliable way to immediately close a connection, and
# rely on the underlying object to be garbage-collected instead.
#
# Furthermore, `sidekiq` creates a new thread each time a job throws an
# exception, meaning that each failure will create a new connection, and
# the old one will only be closed on full garbage collection.
def clean_up_elasticsearch_connections!
return unless Chewy.enabled? && Chewy.current[:chewy_client].present?
Chewy.client.transport.transport.connections.each do |connection|
# NOTE: This bit of code is tailored for the HTTPClient Faraday adapter
connection.connection.app.instance_variable_get(:@client)&.reset_all
end
Chewy.current.delete(:chewy_client)
rescue
nil
end
def clean_up_redis_socket! def clean_up_redis_socket!
RedisConfiguration.pool.checkin if Thread.current[:redis] RedisConfiguration.pool.checkin if Thread.current[:redis]
Thread.current[:redis] = nil Thread.current[:redis] = nil

View File

@ -181,7 +181,7 @@
"eslint-plugin-import": "~2.29.0", "eslint-plugin-import": "~2.29.0",
"eslint-plugin-jsdoc": "^48.0.0", "eslint-plugin-jsdoc": "^48.0.0",
"eslint-plugin-jsx-a11y": "~6.8.0", "eslint-plugin-jsx-a11y": "~6.8.0",
"eslint-plugin-promise": "~6.1.1", "eslint-plugin-promise": "~6.2.0",
"eslint-plugin-react": "^7.33.2", "eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"husky": "^9.0.11", "husky": "^9.0.11",

View File

@ -131,4 +131,22 @@ describe Rack::Attack, type: :request do
it_behaves_like 'throttled endpoint' it_behaves_like 'throttled endpoint'
end end
end end
describe 'throttle excessive oauth application registration requests by IP address' do
let(:throttle) { 'throttle_oauth_application_registrations/ip' }
let(:limit) { 5 }
let(:period) { 10.minutes }
let(:path) { '/api/v1/apps' }
let(:params) do
{
client_name: 'Throttle Test',
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
scopes: 'read',
}
end
let(:request) { -> { post path, params: params, headers: { 'REMOTE_ADDR' => remote_ip } } }
it_behaves_like 'throttled endpoint'
end
end end

View File

@ -1,48 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Vacuum::ApplicationsVacuum do
subject { described_class.new }
describe '#perform' do
let!(:app_with_token) { Fabricate(:application, created_at: 1.month.ago) }
let!(:app_with_grant) { Fabricate(:application, created_at: 1.month.ago) }
let!(:app_with_signup) { Fabricate(:application, created_at: 1.month.ago) }
let!(:app_with_owner) { Fabricate(:application, created_at: 1.month.ago, owner: Fabricate(:user)) }
let!(:unused_app) { Fabricate(:application, created_at: 1.month.ago) }
let!(:recent_app) { Fabricate(:application, created_at: 1.hour.ago) }
before do
Fabricate(:access_token, application: app_with_token)
Fabricate(:access_grant, application: app_with_grant)
Fabricate(:user, created_by_application: app_with_signup)
subject.perform
end
it 'does not delete applications with valid access tokens' do
expect { app_with_token.reload }.to_not raise_error
end
it 'does not delete applications with valid access grants' do
expect { app_with_grant.reload }.to_not raise_error
end
it 'does not delete applications that were used to create users' do
expect { app_with_signup.reload }.to_not raise_error
end
it 'does not delete owned applications' do
expect { app_with_owner.reload }.to_not raise_error
end
it 'does not delete applications registered less than a day ago' do
expect { recent_app.reload }.to_not raise_error
end
it 'deletes unused applications' do
expect { unused_app.reload }.to raise_error ActiveRecord::RecordNotFound
end
end
end

View File

@ -8,13 +8,13 @@ describe '/api/v1/accounts' do
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
describe 'GET /api/v1/accounts?ids[]=:id' do describe 'GET /api/v1/accounts?id[]=:id' do
let(:account) { Fabricate(:account) } let(:account) { Fabricate(:account) }
let(:other_account) { Fabricate(:account) } let(:other_account) { Fabricate(:account) }
let(:scopes) { 'read:accounts' } let(:scopes) { 'read:accounts' }
it 'returns expected response' do it 'returns expected response' do
get '/api/v1/accounts', headers: headers, params: { ids: [account.id, other_account.id, 123_123] } get '/api/v1/accounts', headers: headers, params: { id: [account.id, other_account.id, 123_123] }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to contain_exactly( expect(body_as_json).to contain_exactly(

View File

@ -9,13 +9,13 @@ describe '/api/v1/statuses' do
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, application: client_app, scopes: scopes) } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, application: client_app, scopes: scopes) }
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
describe 'GET /api/v1/statuses?ids[]=:id' do describe 'GET /api/v1/statuses?id[]=:id' do
let(:status) { Fabricate(:status) } let(:status) { Fabricate(:status) }
let(:other_status) { Fabricate(:status) } let(:other_status) { Fabricate(:status) }
let(:scopes) { 'read:statuses' } let(:scopes) { 'read:statuses' }
it 'returns expected response' do it 'returns expected response' do
get '/api/v1/statuses', headers: headers, params: { ids: [status.id, other_status.id, 123_123] } get '/api/v1/statuses', headers: headers, params: { id: [status.id, other_status.id, 123_123] }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to contain_exactly( expect(body_as_json).to contain_exactly(

View File

@ -45,7 +45,7 @@ describe 'Instances' do
), ),
statuses: include( statuses: include(
max_characters: StatusLengthValidator::MAX_CHARS, max_characters: StatusLengthValidator::MAX_CHARS,
max_media_attachments: 4 # TODO, move to constant somewhere max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT
), ),
polls: include( polls: include(
max_options: PollValidator::MAX_OPTIONS max_options: PollValidator::MAX_OPTIONS

View File

@ -228,14 +228,15 @@ RSpec.describe PostStatusService do
expect(media.reload.status).to be_nil expect(media.reload.status).to be_nil
end end
it 'does not allow attaching more than 4 files' do it 'does not allow attaching more files than configured limit' do
stub_const('Status::MEDIA_ATTACHMENTS_LIMIT', 1)
account = Fabricate(:account) account = Fabricate(:account)
expect do expect do
subject.call( subject.call(
account, account,
text: 'test status update', text: 'test status update',
media_ids: Array.new(5) { Fabricate(:media_attachment, account: account) }.map(&:id) media_ids: Array.new(2) { Fabricate(:media_attachment, account: account) }.map(&:id)
) )
end.to raise_error( end.to raise_error(
Mastodon::ValidationError, Mastodon::ValidationError,

View File

@ -45,8 +45,8 @@ RSpec.describe StatusPinValidator do
end end
end end
context 'when pin.account.status_pins.count > 4 && pin.account.local?' do context 'when pin account is local and has too many pins' do
let(:count) { 5 } let(:count) { described_class::PIN_LIMIT + 1 }
let(:local) { true } let(:local) { true }
it 'calls errors.add' do it 'calls errors.add' do

View File

@ -7,6 +7,8 @@
"allowJs": true, "allowJs": true,
"noEmit": true, "noEmit": true,
"strict": true, "strict": true,
"noImplicitReturns": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true, "esModuleInterop": true,
"skipLibCheck": true, "skipLibCheck": true,
"baseUrl": "./", "baseUrl": "./",

518
yarn.lock
View File

@ -1590,7 +1590,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@csstools/css-parser-algorithms@npm:^2.6.1, @csstools/css-parser-algorithms@npm:^2.6.3": "@csstools/css-parser-algorithms@npm:^2.6.3":
version: 2.6.3 version: 2.6.3
resolution: "@csstools/css-parser-algorithms@npm:2.6.3" resolution: "@csstools/css-parser-algorithms@npm:2.6.3"
peerDependencies: peerDependencies:
@ -1599,14 +1599,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@csstools/css-tokenizer@npm:^2.2.4, @csstools/css-tokenizer@npm:^2.3.1": "@csstools/css-tokenizer@npm:^2.3.1":
version: 2.3.1 version: 2.3.1
resolution: "@csstools/css-tokenizer@npm:2.3.1" resolution: "@csstools/css-tokenizer@npm:2.3.1"
checksum: 10c0/fed6619fb5108e109d4dd10b0e967035a92793bae8fb84544e1342058b6df4e306d9d075623e2201fe88831b1ada797aea3546a8d12229d2d81cd7a5dfee4444 checksum: 10c0/fed6619fb5108e109d4dd10b0e967035a92793bae8fb84544e1342058b6df4e306d9d075623e2201fe88831b1ada797aea3546a8d12229d2d81cd7a5dfee4444
languageName: node languageName: node
linkType: hard linkType: hard
"@csstools/media-query-list-parser@npm:^2.1.11, @csstools/media-query-list-parser@npm:^2.1.9": "@csstools/media-query-list-parser@npm:^2.1.11":
version: 2.1.11 version: 2.1.11
resolution: "@csstools/media-query-list-parser@npm:2.1.11" resolution: "@csstools/media-query-list-parser@npm:2.1.11"
peerDependencies: peerDependencies:
@ -1982,7 +1982,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@csstools/selector-specificity@npm:^3.0.3, @csstools/selector-specificity@npm:^3.1.1": "@csstools/selector-specificity@npm:^3.1.1":
version: 3.1.1 version: 3.1.1
resolution: "@csstools/selector-specificity@npm:3.1.1" resolution: "@csstools/selector-specificity@npm:3.1.1"
peerDependencies: peerDependencies:
@ -2007,10 +2007,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@dual-bundle/import-meta-resolve@npm:^4.0.0": "@dual-bundle/import-meta-resolve@npm:^4.1.0":
version: 4.0.0 version: 4.1.0
resolution: "@dual-bundle/import-meta-resolve@npm:4.0.0" resolution: "@dual-bundle/import-meta-resolve@npm:4.1.0"
checksum: 10c0/868b8314fc753b7767887108535afe3288de941d92bc8453164dbcb1abe886b171e338f6f7d02ff556256dee69c90e4ac6360e0c6a856a5ad7190274ab52de2e checksum: 10c0/55069e550ee2710e738dd8bbd34aba796cede456287454b50c3be46fbef8695d00625677f3f41f5ffbec1174c0f57f314da9a908388bc9f8ad41a8438db884d9
languageName: node languageName: node
linkType: hard linkType: hard
@ -2248,16 +2248,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@formatjs/ecma402-abstract@npm:1.18.2":
version: 1.18.2
resolution: "@formatjs/ecma402-abstract@npm:1.18.2"
dependencies:
"@formatjs/intl-localematcher": "npm:0.5.4"
tslib: "npm:^2.4.0"
checksum: 10c0/87afb37dd937555e712ca85d5142a9083d617c491d1dddf8d660fdfb6186272d2bc75b78809b076388d26f016200c8bddbce73281fd707eb899da2bf3bc9b7ca
languageName: node
linkType: hard
"@formatjs/ecma402-abstract@npm:2.0.0": "@formatjs/ecma402-abstract@npm:2.0.0":
version: 2.0.0 version: 2.0.0
resolution: "@formatjs/ecma402-abstract@npm:2.0.0" resolution: "@formatjs/ecma402-abstract@npm:2.0.0"
@ -2277,17 +2267,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@formatjs/icu-messageformat-parser@npm:2.7.6":
version: 2.7.6
resolution: "@formatjs/icu-messageformat-parser@npm:2.7.6"
dependencies:
"@formatjs/ecma402-abstract": "npm:1.18.2"
"@formatjs/icu-skeleton-parser": "npm:1.8.0"
tslib: "npm:^2.4.0"
checksum: 10c0/9fc72c2075333a969601e2be4260638940b1abefd1a5fc15b93b0b10d2319c9df5778aa51fc2a173ce66ca5e8a47b4b64caca85a32d0eb6095e16e8d65cb4b00
languageName: node
linkType: hard
"@formatjs/icu-messageformat-parser@npm:2.7.8": "@formatjs/icu-messageformat-parser@npm:2.7.8":
version: 2.7.8 version: 2.7.8
resolution: "@formatjs/icu-messageformat-parser@npm:2.7.8" resolution: "@formatjs/icu-messageformat-parser@npm:2.7.8"
@ -2299,16 +2278,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@formatjs/icu-skeleton-parser@npm:1.8.0":
version: 1.8.0
resolution: "@formatjs/icu-skeleton-parser@npm:1.8.0"
dependencies:
"@formatjs/ecma402-abstract": "npm:1.18.2"
tslib: "npm:^2.4.0"
checksum: 10c0/10956732d70cc67049d216410b5dc3ef048935d1ea2ae76f5755bb9d0243af37ddeabd5d140ddbf5f6c7047068c3d02a05f93c68a89cedfaf7488d5062885ea4
languageName: node
linkType: hard
"@formatjs/icu-skeleton-parser@npm:1.8.2": "@formatjs/icu-skeleton-parser@npm:1.8.2":
version: 1.8.2 version: 1.8.2
resolution: "@formatjs/icu-skeleton-parser@npm:1.8.2" resolution: "@formatjs/icu-skeleton-parser@npm:1.8.2"
@ -2381,26 +2350,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@formatjs/ts-transformer@npm:3.13.12":
version: 3.13.12
resolution: "@formatjs/ts-transformer@npm:3.13.12"
dependencies:
"@formatjs/icu-messageformat-parser": "npm:2.7.6"
"@types/json-stable-stringify": "npm:^1.0.32"
"@types/node": "npm:14 || 16 || 17"
chalk: "npm:^4.0.0"
json-stable-stringify: "npm:^1.0.1"
tslib: "npm:^2.4.0"
typescript: "npm:5"
peerDependencies:
ts-jest: ">=27"
peerDependenciesMeta:
ts-jest:
optional: true
checksum: 10c0/68f72ee6379b87b7ef6340e118a5370cb2fa18cbbae08f5f3d10893803a52f0533e644002e0b5e9ffeded5b2f0aa9daad6adf8b487b10f5d2b61f9fb3fed0dbd
languageName: node
linkType: hard
"@formatjs/ts-transformer@npm:3.13.14": "@formatjs/ts-transformer@npm:3.13.14":
version: 3.13.14 version: 3.13.14
resolution: "@formatjs/ts-transformer@npm:3.13.14" resolution: "@formatjs/ts-transformer@npm:3.13.14"
@ -2874,7 +2823,7 @@ __metadata:
eslint-plugin-import: "npm:~2.29.0" eslint-plugin-import: "npm:~2.29.0"
eslint-plugin-jsdoc: "npm:^48.0.0" eslint-plugin-jsdoc: "npm:^48.0.0"
eslint-plugin-jsx-a11y: "npm:~6.8.0" eslint-plugin-jsx-a11y: "npm:~6.8.0"
eslint-plugin-promise: "npm:~6.1.1" eslint-plugin-promise: "npm:~6.2.0"
eslint-plugin-react: "npm:^7.33.2" eslint-plugin-react: "npm:^7.33.2"
eslint-plugin-react-hooks: "npm:^4.6.0" eslint-plugin-react-hooks: "npm:^4.6.0"
exif-js: "npm:^2.3.0" exif-js: "npm:^2.3.0"
@ -3736,7 +3685,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8": "@types/json-schema@npm:*, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8":
version: 7.0.15 version: 7.0.15
resolution: "@types/json-schema@npm:7.0.15" resolution: "@types/json-schema@npm:7.0.15"
checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db
@ -3979,12 +3928,12 @@ __metadata:
linkType: hard linkType: hard
"@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:>=16.9.11, @types/react@npm:^18.2.7": "@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:>=16.9.11, @types/react@npm:^18.2.7":
version: 18.3.2 version: 18.3.3
resolution: "@types/react@npm:18.3.2" resolution: "@types/react@npm:18.3.3"
dependencies: dependencies:
"@types/prop-types": "npm:*" "@types/prop-types": "npm:*"
csstype: "npm:^3.0.2" csstype: "npm:^3.0.2"
checksum: 10c0/9fb2f1fcf7e889ee4ea7c3c5978df595c66e770e5fd3a245dbdd2589b9b911524c11dab25a6275d8af4e336e4cb5fa850d447884b84c335a187a338c89df99ba checksum: 10c0/fe455f805c5da13b89964c3d68060cebd43e73ec15001a68b34634604a78140e6fc202f3f61679b9d809dde6d7a7c2cb3ed51e0fd1462557911db09879b55114
languageName: node languageName: node
linkType: hard linkType: hard
@ -4012,7 +3961,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/semver@npm:^7.5.0, @types/semver@npm:^7.5.8": "@types/semver@npm:^7.5.0":
version: 7.5.8 version: 7.5.8
resolution: "@types/semver@npm:7.5.8" resolution: "@types/semver@npm:7.5.8"
checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa
@ -4163,19 +4112,17 @@ __metadata:
linkType: hard linkType: hard
"@typescript-eslint/eslint-plugin@npm:^7.0.0": "@typescript-eslint/eslint-plugin@npm:^7.0.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/eslint-plugin@npm:7.8.0" resolution: "@typescript-eslint/eslint-plugin@npm:7.10.0"
dependencies: dependencies:
"@eslint-community/regexpp": "npm:^4.10.0" "@eslint-community/regexpp": "npm:^4.10.0"
"@typescript-eslint/scope-manager": "npm:7.8.0" "@typescript-eslint/scope-manager": "npm:7.10.0"
"@typescript-eslint/type-utils": "npm:7.8.0" "@typescript-eslint/type-utils": "npm:7.10.0"
"@typescript-eslint/utils": "npm:7.8.0" "@typescript-eslint/utils": "npm:7.10.0"
"@typescript-eslint/visitor-keys": "npm:7.8.0" "@typescript-eslint/visitor-keys": "npm:7.10.0"
debug: "npm:^4.3.4"
graphemer: "npm:^1.4.0" graphemer: "npm:^1.4.0"
ignore: "npm:^5.3.1" ignore: "npm:^5.3.1"
natural-compare: "npm:^1.4.0" natural-compare: "npm:^1.4.0"
semver: "npm:^7.6.0"
ts-api-utils: "npm:^1.3.0" ts-api-utils: "npm:^1.3.0"
peerDependencies: peerDependencies:
"@typescript-eslint/parser": ^7.0.0 "@typescript-eslint/parser": ^7.0.0
@ -4183,25 +4130,25 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/37ca22620d1834ff0baa28fa4b8fd92039a3903cb95748353de32d56bae2a81ce50d1bbaed27487eebc884e0a0f9387fcb0f1647593e4e6df5111ef674afa9f0 checksum: 10c0/bf3f0118ea5961c3eb01894678246458a329d82dda9ac7c2f5bfe77896410d05a08a4655e533bcb1ed2a3132ba6421981ec8c2ed0a3545779d9603ea231947ae
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/parser@npm:^7.0.0": "@typescript-eslint/parser@npm:^7.0.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/parser@npm:7.8.0" resolution: "@typescript-eslint/parser@npm:7.10.0"
dependencies: dependencies:
"@typescript-eslint/scope-manager": "npm:7.8.0" "@typescript-eslint/scope-manager": "npm:7.10.0"
"@typescript-eslint/types": "npm:7.8.0" "@typescript-eslint/types": "npm:7.10.0"
"@typescript-eslint/typescript-estree": "npm:7.8.0" "@typescript-eslint/typescript-estree": "npm:7.10.0"
"@typescript-eslint/visitor-keys": "npm:7.8.0" "@typescript-eslint/visitor-keys": "npm:7.10.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
peerDependencies: peerDependencies:
eslint: ^8.56.0 eslint: ^8.56.0
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/0dd994c1b31b810c25e1b755b8d352debb7bf21a31f9a91acaec34acf4e471320bcceaa67cf64c110c0b8f5fac10a037dbabac6ec423e17adf037e59a7bce9c1 checksum: 10c0/4c4fbf43b5b05d75b766acb803d3dd078c6e080641a77f9e48ba005713466738ea4a71f0564fa3ce520988d65158d14c8c952ba01ccbc431ab4a05935db5ce6d
languageName: node languageName: node
linkType: hard linkType: hard
@ -4215,22 +4162,22 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/scope-manager@npm:7.8.0": "@typescript-eslint/scope-manager@npm:7.10.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/scope-manager@npm:7.8.0" resolution: "@typescript-eslint/scope-manager@npm:7.10.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:7.8.0" "@typescript-eslint/types": "npm:7.10.0"
"@typescript-eslint/visitor-keys": "npm:7.8.0" "@typescript-eslint/visitor-keys": "npm:7.10.0"
checksum: 10c0/c253b98e96d4bf0375f473ca2c4d081726f1fd926cdfa65ee14c9ee99cca8eddb763b2d238ac365daa7246bef21b0af38180d04e56e9df7443c0e6f8474d097c checksum: 10c0/1d4f7ee137b95bd423b5a1b0d03251202dfc19bd8b6adfa5ff5df25fd5aa30e2d8ca50ab0d8d2e92441670ecbc2a82b3c2dbe39a4f268ec1ee1c1e267f7fd1d1
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/type-utils@npm:7.8.0": "@typescript-eslint/type-utils@npm:7.10.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/type-utils@npm:7.8.0" resolution: "@typescript-eslint/type-utils@npm:7.10.0"
dependencies: dependencies:
"@typescript-eslint/typescript-estree": "npm:7.8.0" "@typescript-eslint/typescript-estree": "npm:7.10.0"
"@typescript-eslint/utils": "npm:7.8.0" "@typescript-eslint/utils": "npm:7.10.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
ts-api-utils: "npm:^1.3.0" ts-api-utils: "npm:^1.3.0"
peerDependencies: peerDependencies:
@ -4238,7 +4185,7 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/00f6315626b64f7dbc1f7fba6f365321bb8d34141ed77545b2a07970e59a81dbdf768c1e024225ea00953750d74409ddd8a16782fc4a39261e507c04192dacab checksum: 10c0/55e9a6690f9cedb79d30abb1990b161affaa2684dac246b743223353812c9c1e3fd2d923c67b193c6a3624a07e1c82c900ce7bf5b6b9891c846f04cb480ebd9f
languageName: node languageName: node
linkType: hard linkType: hard
@ -4249,10 +4196,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/types@npm:7.8.0, @typescript-eslint/types@npm:^7.2.0": "@typescript-eslint/types@npm:7.10.0, @typescript-eslint/types@npm:^7.2.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/types@npm:7.8.0" resolution: "@typescript-eslint/types@npm:7.10.0"
checksum: 10c0/b2fdbfc21957bfa46f7d8809b607ad8c8b67c51821d899064d09392edc12f28b2318a044f0cd5d523d782e84e8f0558778877944964cf38e139f88790cf9d466 checksum: 10c0/f01d9330b93cc362ba7967ab5037396f64742076450e1f93139fa69cbe93a6ece3ed55d68ab780c9b7d07ef4a7c645da410305216a2cfc5dec7eba49ee65ab23
languageName: node languageName: node
linkType: hard linkType: hard
@ -4275,12 +4222,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/typescript-estree@npm:7.8.0": "@typescript-eslint/typescript-estree@npm:7.10.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/typescript-estree@npm:7.8.0" resolution: "@typescript-eslint/typescript-estree@npm:7.10.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:7.8.0" "@typescript-eslint/types": "npm:7.10.0"
"@typescript-eslint/visitor-keys": "npm:7.8.0" "@typescript-eslint/visitor-keys": "npm:7.10.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
globby: "npm:^11.1.0" globby: "npm:^11.1.0"
is-glob: "npm:^4.0.3" is-glob: "npm:^4.0.3"
@ -4290,24 +4237,21 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/1690b62679685073dcb0f62499f0b52b445b37ae6e12d02aa4acbafe3fb023cf999b01f714b6282e88f84fd934fe3e2eefb21a64455d19c348d22bbc68ca8e47 checksum: 10c0/6200695834c566e52e2fa7331f1a05019f7815969d8c1e1e237b85a99664d36f41ccc16384eff3f8582a0ecb75f1cc315b56ee9283b818da37f24fa4d42f1d7a
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/utils@npm:7.8.0": "@typescript-eslint/utils@npm:7.10.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/utils@npm:7.8.0" resolution: "@typescript-eslint/utils@npm:7.10.0"
dependencies: dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0" "@eslint-community/eslint-utils": "npm:^4.4.0"
"@types/json-schema": "npm:^7.0.15" "@typescript-eslint/scope-manager": "npm:7.10.0"
"@types/semver": "npm:^7.5.8" "@typescript-eslint/types": "npm:7.10.0"
"@typescript-eslint/scope-manager": "npm:7.8.0" "@typescript-eslint/typescript-estree": "npm:7.10.0"
"@typescript-eslint/types": "npm:7.8.0"
"@typescript-eslint/typescript-estree": "npm:7.8.0"
semver: "npm:^7.6.0"
peerDependencies: peerDependencies:
eslint: ^8.56.0 eslint: ^8.56.0
checksum: 10c0/31fb58388d15b082eb7bd5bce889cc11617aa1131dfc6950471541b3df64c82d1c052e2cccc230ca4ae80456d4f63a3e5dccb79899a8f3211ce36c089b7d7640 checksum: 10c0/6724471f94f2788f59748f7efa2a3a53ea910099993bee2fa5746ab5acacecdc9fcb110c568b18099ddc946ea44919ed394bff2bd055ba81fc69f5e6297b73bf
languageName: node languageName: node
linkType: hard linkType: hard
@ -4338,13 +4282,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/visitor-keys@npm:7.8.0": "@typescript-eslint/visitor-keys@npm:7.10.0":
version: 7.8.0 version: 7.10.0
resolution: "@typescript-eslint/visitor-keys@npm:7.8.0" resolution: "@typescript-eslint/visitor-keys@npm:7.10.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:7.8.0" "@typescript-eslint/types": "npm:7.10.0"
eslint-visitor-keys: "npm:^3.4.3" eslint-visitor-keys: "npm:^3.4.3"
checksum: 10c0/5892fb5d9c58efaf89adb225f7dbbb77f9363961f2ff420b6b130bdd102dddd7aa8a16c46a5a71c19889d27b781e966119a89270555ea2cb5653a04d8994123d checksum: 10c0/049e812bcd28869059d04c7bf3543bb55f5205f468b777439c4f120417fb856fb6024cb1d25291aa12556bd08e84f043a96d754ffb2cde37abb604d6f3c51634
languageName: node languageName: node
linkType: hard linkType: hard
@ -5619,12 +5563,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"braces@npm:^3.0.2, braces@npm:~3.0.2": "braces@npm:^3.0.3, braces@npm:~3.0.2":
version: 3.0.2 version: 3.0.3
resolution: "braces@npm:3.0.2" resolution: "braces@npm:3.0.3"
dependencies: dependencies:
fill-range: "npm:^7.0.1" fill-range: "npm:^7.1.1"
checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381 checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04
languageName: node languageName: node
linkType: hard linkType: hard
@ -5927,13 +5871,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"chalk@npm:5.3.0":
version: 5.3.0
resolution: "chalk@npm:5.3.0"
checksum: 10c0/8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09
languageName: node
linkType: hard
"chalk@npm:^2.4.1, chalk@npm:^2.4.2": "chalk@npm:^2.4.1, chalk@npm:^2.4.2":
version: 2.4.2 version: 2.4.2
resolution: "chalk@npm:2.4.2" resolution: "chalk@npm:2.4.2"
@ -5965,6 +5902,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"chalk@npm:~5.3.0":
version: 5.3.0
resolution: "chalk@npm:5.3.0"
checksum: 10c0/8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09
languageName: node
linkType: hard
"char-regex@npm:^1.0.2": "char-regex@npm:^1.0.2":
version: 1.0.2 version: 1.0.2
resolution: "char-regex@npm:1.0.2" resolution: "char-regex@npm:1.0.2"
@ -6257,13 +6201,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"commander@npm:11.1.0":
version: 11.1.0
resolution: "commander@npm:11.1.0"
checksum: 10c0/13cc6ac875e48780250f723fb81c1c1178d35c5decb1abb1b628b3177af08a8554e76b2c0f29de72d69eef7c864d12613272a71fabef8047922bc622ab75a179
languageName: node
linkType: hard
"commander@npm:^2.20.0": "commander@npm:^2.20.0":
version: 2.20.3 version: 2.20.3
resolution: "commander@npm:2.20.3" resolution: "commander@npm:2.20.3"
@ -6278,6 +6215,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"commander@npm:~12.1.0":
version: 12.1.0
resolution: "commander@npm:12.1.0"
checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9
languageName: node
linkType: hard
"comment-parser@npm:1.4.1": "comment-parser@npm:1.4.1":
version: 1.4.1 version: 1.4.1
resolution: "comment-parser@npm:1.4.1" resolution: "comment-parser@npm:1.4.1"
@ -6957,7 +6901,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4": "debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:~4.3.4":
version: 4.3.4 version: 4.3.4
resolution: "debug@npm:4.3.4" resolution: "debug@npm:4.3.4"
dependencies: dependencies:
@ -7835,11 +7779,11 @@ __metadata:
linkType: hard linkType: hard
"eslint-plugin-formatjs@npm:^4.10.1": "eslint-plugin-formatjs@npm:^4.10.1":
version: 4.13.1 version: 4.13.3
resolution: "eslint-plugin-formatjs@npm:4.13.1" resolution: "eslint-plugin-formatjs@npm:4.13.3"
dependencies: dependencies:
"@formatjs/icu-messageformat-parser": "npm:2.7.6" "@formatjs/icu-messageformat-parser": "npm:2.7.8"
"@formatjs/ts-transformer": "npm:3.13.12" "@formatjs/ts-transformer": "npm:3.13.14"
"@types/eslint": "npm:7 || 8" "@types/eslint": "npm:7 || 8"
"@types/picomatch": "npm:^2.3.0" "@types/picomatch": "npm:^2.3.0"
"@typescript-eslint/utils": "npm:^6.18.1" "@typescript-eslint/utils": "npm:^6.18.1"
@ -7851,7 +7795,7 @@ __metadata:
unicode-emoji-utils: "npm:^1.2.0" unicode-emoji-utils: "npm:^1.2.0"
peerDependencies: peerDependencies:
eslint: 7 || 8 eslint: 7 || 8
checksum: 10c0/ce18141dff84e8fe026127085c1a63279acb3a1bc0b70dc1ddce2fc65bb37d68ccf6d097231428745eda2caea42080e1c80a01a1895803155c15123a01bfeee3 checksum: 10c0/5e98f487a097189e3bdc64b678d19f4c83502c32d7c89a8959eda4ed9cb664bf16f13ad8871be89ca192cb39c1007d6a158c39bbf5b23c56962d949dbe9abfab
languageName: node languageName: node
linkType: hard linkType: hard
@ -7883,8 +7827,8 @@ __metadata:
linkType: hard linkType: hard
"eslint-plugin-jsdoc@npm:^48.0.0": "eslint-plugin-jsdoc@npm:^48.0.0":
version: 48.2.4 version: 48.2.6
resolution: "eslint-plugin-jsdoc@npm:48.2.4" resolution: "eslint-plugin-jsdoc@npm:48.2.6"
dependencies: dependencies:
"@es-joy/jsdoccomment": "npm:~0.43.0" "@es-joy/jsdoccomment": "npm:~0.43.0"
are-docs-informative: "npm:^0.0.2" are-docs-informative: "npm:^0.0.2"
@ -7892,12 +7836,11 @@ __metadata:
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
escape-string-regexp: "npm:^4.0.0" escape-string-regexp: "npm:^4.0.0"
esquery: "npm:^1.5.0" esquery: "npm:^1.5.0"
is-builtin-module: "npm:^3.2.1" semver: "npm:^7.6.1"
semver: "npm:^7.6.0"
spdx-expression-parse: "npm:^4.0.0" spdx-expression-parse: "npm:^4.0.0"
peerDependencies: peerDependencies:
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
checksum: 10c0/601c9d6ee41de56102c7813106ceb0b8b8342223670f7add010a8f89753c250cde4cc93e353e3911b7b29677f2634f3f4be45f27abb7a95c6fdbd058adfa3343 checksum: 10c0/9f01b3000aa31f17767786c62caf62f1e8c4b88bfef04b207d3b1de785be287cc2da3ad16ed32afacd5f6e6a9b76ebf3369069be416ce2228c44cd6d084fcd8f
languageName: node languageName: node
linkType: hard linkType: hard
@ -7927,12 +7870,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-plugin-promise@npm:~6.1.1": "eslint-plugin-promise@npm:~6.2.0":
version: 6.1.1 version: 6.2.0
resolution: "eslint-plugin-promise@npm:6.1.1" resolution: "eslint-plugin-promise@npm:6.2.0"
peerDependencies: peerDependencies:
eslint: ^7.0.0 || ^8.0.0 eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
checksum: 10c0/ec705741c110cd1cb4d702776e1c7f7fe60b671b71f706c88054ab443cf2767aae5a663928fb426373ba1095eaeda312a740a4f880546631f0e0727f298b3393 checksum: 10c0/5f42ee774023c089453ecb792076c64c6d0739ea6e9d6cdc9d6a63da5ba928c776e349d01cc110548f2c67045ec55343136aa7eb8b486e4ab145ac016c06a492
languageName: node languageName: node
linkType: hard linkType: hard
@ -8175,23 +8118,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"execa@npm:8.0.1":
version: 8.0.1
resolution: "execa@npm:8.0.1"
dependencies:
cross-spawn: "npm:^7.0.3"
get-stream: "npm:^8.0.1"
human-signals: "npm:^5.0.0"
is-stream: "npm:^3.0.0"
merge-stream: "npm:^2.0.0"
npm-run-path: "npm:^5.1.0"
onetime: "npm:^6.0.0"
signal-exit: "npm:^4.1.0"
strip-final-newline: "npm:^3.0.0"
checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af
languageName: node
linkType: hard
"execa@npm:^1.0.0": "execa@npm:^1.0.0":
version: 1.0.0 version: 1.0.0
resolution: "execa@npm:1.0.0" resolution: "execa@npm:1.0.0"
@ -8224,6 +8150,23 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"execa@npm:~8.0.1":
version: 8.0.1
resolution: "execa@npm:8.0.1"
dependencies:
cross-spawn: "npm:^7.0.3"
get-stream: "npm:^8.0.1"
human-signals: "npm:^5.0.0"
is-stream: "npm:^3.0.0"
merge-stream: "npm:^2.0.0"
npm-run-path: "npm:^5.1.0"
onetime: "npm:^6.0.0"
signal-exit: "npm:^4.1.0"
strip-final-newline: "npm:^3.0.0"
checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af
languageName: node
linkType: hard
"exif-js@npm:^2.3.0": "exif-js@npm:^2.3.0":
version: 2.3.0 version: 2.3.0
resolution: "exif-js@npm:2.3.0" resolution: "exif-js@npm:2.3.0"
@ -8356,10 +8299,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"fast-copy@npm:^3.0.0": "fast-copy@npm:^3.0.2":
version: 3.0.1 version: 3.0.2
resolution: "fast-copy@npm:3.0.1" resolution: "fast-copy@npm:3.0.2"
checksum: 10c0/a8310dbcc4c94ed001dc3e0bbc3c3f0491bb04e6c17163abe441a54997ba06cdf1eb532c2f05e54777c6f072c84548c23ef0ecd54665cd611be1d42f37eca258 checksum: 10c0/02e8b9fd03c8c024d2987760ce126456a0e17470850b51e11a1c3254eed6832e4733ded2d93316c82bc0b36aeb991ad1ff48d1ba95effe7add7c3ab8d8eb554a
languageName: node languageName: node
linkType: hard linkType: hard
@ -8517,12 +8460,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"fill-range@npm:^7.0.1": "fill-range@npm:^7.1.1":
version: 7.0.1 version: 7.1.1
resolution: "fill-range@npm:7.0.1" resolution: "fill-range@npm:7.1.1"
dependencies: dependencies:
to-regex-range: "npm:^5.0.1" to-regex-range: "npm:^5.0.1"
checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018
languageName: node languageName: node
linkType: hard linkType: hard
@ -9416,13 +9359,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"http-proxy-agent@npm:^7.0.0": "http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.2":
version: 7.0.0 version: 7.0.2
resolution: "http-proxy-agent@npm:7.0.0" resolution: "http-proxy-agent@npm:7.0.2"
dependencies: dependencies:
agent-base: "npm:^7.1.0" agent-base: "npm:^7.1.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
checksum: 10c0/a11574ff39436cee3c7bc67f259444097b09474605846ddd8edf0bf4ad8644be8533db1aa463426e376865047d05dc22755e638632819317c0c2f1b2196657c8 checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921
languageName: node languageName: node
linkType: hard linkType: hard
@ -9466,13 +9409,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": "https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.4":
version: 7.0.2 version: 7.0.4
resolution: "https-proxy-agent@npm:7.0.2" resolution: "https-proxy-agent@npm:7.0.4"
dependencies: dependencies:
agent-base: "npm:^7.0.2" agent-base: "npm:^7.0.2"
debug: "npm:4" debug: "npm:4"
checksum: 10c0/7735eb90073db087e7e79312e3d97c8c04baf7ea7ca7b013382b6a45abbaa61b281041a98f4e13c8c80d88f843785bcc84ba189165b4b4087b1e3496ba656d77 checksum: 10c0/bc4f7c38da32a5fc622450b6cb49a24ff596f9bd48dcedb52d2da3fa1c1a80e100fb506bd59b326c012f21c863c69b275c23de1a01d0b84db396822fdf25e52b
languageName: node languageName: node
linkType: hard linkType: hard
@ -11034,36 +10977,36 @@ __metadata:
linkType: hard linkType: hard
"jsdom@npm:^24.0.0": "jsdom@npm:^24.0.0":
version: 24.0.0 version: 24.1.0
resolution: "jsdom@npm:24.0.0" resolution: "jsdom@npm:24.1.0"
dependencies: dependencies:
cssstyle: "npm:^4.0.1" cssstyle: "npm:^4.0.1"
data-urls: "npm:^5.0.0" data-urls: "npm:^5.0.0"
decimal.js: "npm:^10.4.3" decimal.js: "npm:^10.4.3"
form-data: "npm:^4.0.0" form-data: "npm:^4.0.0"
html-encoding-sniffer: "npm:^4.0.0" html-encoding-sniffer: "npm:^4.0.0"
http-proxy-agent: "npm:^7.0.0" http-proxy-agent: "npm:^7.0.2"
https-proxy-agent: "npm:^7.0.2" https-proxy-agent: "npm:^7.0.4"
is-potential-custom-element-name: "npm:^1.0.1" is-potential-custom-element-name: "npm:^1.0.1"
nwsapi: "npm:^2.2.7" nwsapi: "npm:^2.2.10"
parse5: "npm:^7.1.2" parse5: "npm:^7.1.2"
rrweb-cssom: "npm:^0.6.0" rrweb-cssom: "npm:^0.7.0"
saxes: "npm:^6.0.0" saxes: "npm:^6.0.0"
symbol-tree: "npm:^3.2.4" symbol-tree: "npm:^3.2.4"
tough-cookie: "npm:^4.1.3" tough-cookie: "npm:^4.1.4"
w3c-xmlserializer: "npm:^5.0.0" w3c-xmlserializer: "npm:^5.0.0"
webidl-conversions: "npm:^7.0.0" webidl-conversions: "npm:^7.0.0"
whatwg-encoding: "npm:^3.1.1" whatwg-encoding: "npm:^3.1.1"
whatwg-mimetype: "npm:^4.0.0" whatwg-mimetype: "npm:^4.0.0"
whatwg-url: "npm:^14.0.0" whatwg-url: "npm:^14.0.0"
ws: "npm:^8.16.0" ws: "npm:^8.17.0"
xml-name-validator: "npm:^5.0.0" xml-name-validator: "npm:^5.0.0"
peerDependencies: peerDependencies:
canvas: ^2.11.2 canvas: ^2.11.2
peerDependenciesMeta: peerDependenciesMeta:
canvas: canvas:
optional: true optional: true
checksum: 10c0/7b35043d7af39ad6dcaef0fa5679d8c8a94c6c9b6cc4a79222b7c9987d57ab7150c50856684ae56b473ab28c7d82aec0fb7ca19dcbd4c3f46683c807d717a3af checksum: 10c0/34eadd8a7ae20c1505abe7a0f3988b2f0881cce7e27d75c4f5224f440f81f8ac08f4f449695b0f4178f048ed1c1709f3594e9d3f2fe0406c28e8da6eddd44f5a
languageName: node languageName: node
linkType: hard linkType: hard
@ -11253,10 +11196,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"known-css-properties@npm:^0.30.0": "known-css-properties@npm:^0.31.0":
version: 0.30.0 version: 0.31.0
resolution: "known-css-properties@npm:0.30.0" resolution: "known-css-properties@npm:0.31.0"
checksum: 10c0/8b487a6b33487affcec41eb392ceb77acf4d093558dde5c88b5ea06b9a3c81781876d7cb09872e0518b9602f27c8f4112c9ac333e02c90a91c8fbd12e202ed48 checksum: 10c0/8e643cbed32d7733278ba215c43dfc38fc7e77d391f66b81f07228af97d69ce2cebba03a9bc1ac859479e162aea812e258b30f4c93cb7b7adfd0622a141d36da
languageName: node languageName: node
linkType: hard linkType: hard
@ -11293,14 +11236,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lilconfig@npm:3.0.0": "lilconfig@npm:^3.1.1, lilconfig@npm:~3.1.1":
version: 3.0.0
resolution: "lilconfig@npm:3.0.0"
checksum: 10c0/7f5ee7a658dc016cacf146815e8d88b06f06f4402823b8b0934e305a57a197f55ccc9c5cd4fb5ea1b2b821c8ccaf2d54abd59602a4931af06eabda332388d3e6
languageName: node
linkType: hard
"lilconfig@npm:^3.1.1":
version: 3.1.1 version: 3.1.1
resolution: "lilconfig@npm:3.1.1" resolution: "lilconfig@npm:3.1.1"
checksum: 10c0/311b559794546894e3fe176663427326026c1c644145be9e8041c58e268aa9328799b8dfe7e4dd8c6a4ae305feae95a1c9e007db3569f35b42b6e1bc8274754c checksum: 10c0/311b559794546894e3fe176663427326026c1c644145be9e8041c58e268aa9328799b8dfe7e4dd8c6a4ae305feae95a1c9e007db3569f35b42b6e1bc8274754c
@ -11315,36 +11251,36 @@ __metadata:
linkType: hard linkType: hard
"lint-staged@npm:^15.0.0": "lint-staged@npm:^15.0.0":
version: 15.2.2 version: 15.2.5
resolution: "lint-staged@npm:15.2.2" resolution: "lint-staged@npm:15.2.5"
dependencies: dependencies:
chalk: "npm:5.3.0" chalk: "npm:~5.3.0"
commander: "npm:11.1.0" commander: "npm:~12.1.0"
debug: "npm:4.3.4" debug: "npm:~4.3.4"
execa: "npm:8.0.1" execa: "npm:~8.0.1"
lilconfig: "npm:3.0.0" lilconfig: "npm:~3.1.1"
listr2: "npm:8.0.1" listr2: "npm:~8.2.1"
micromatch: "npm:4.0.5" micromatch: "npm:~4.0.7"
pidtree: "npm:0.6.0" pidtree: "npm:~0.6.0"
string-argv: "npm:0.3.2" string-argv: "npm:~0.3.2"
yaml: "npm:2.3.4" yaml: "npm:~2.4.2"
bin: bin:
lint-staged: bin/lint-staged.js lint-staged: bin/lint-staged.js
checksum: 10c0/a1ba6c7ee53e30a0f6ea9a351d95d3d0d2be916a41b561e22907e9ea513eb18cb3dbe65bff3ec13fad15777999efe56b2e2a95427e31d12a9b7e7948c3630ee2 checksum: 10c0/89c54489783510f86df15756659facade82e849c0cbfb564fe047b82be91c5d2b1b5608a4bfc5237bd7b9fd0e1206e66aa3e4f8cad3ac51e37a098b8492c2fa6
languageName: node languageName: node
linkType: hard linkType: hard
"listr2@npm:8.0.1": "listr2@npm:~8.2.1":
version: 8.0.1 version: 8.2.1
resolution: "listr2@npm:8.0.1" resolution: "listr2@npm:8.2.1"
dependencies: dependencies:
cli-truncate: "npm:^4.0.0" cli-truncate: "npm:^4.0.0"
colorette: "npm:^2.0.20" colorette: "npm:^2.0.20"
eventemitter3: "npm:^5.0.1" eventemitter3: "npm:^5.0.1"
log-update: "npm:^6.0.0" log-update: "npm:^6.0.0"
rfdc: "npm:^1.3.0" rfdc: "npm:^1.3.1"
wrap-ansi: "npm:^9.0.0" wrap-ansi: "npm:^9.0.0"
checksum: 10c0/b565d6ceb3a4c2dbe0c1735c0fd907afd0d6f89de21aced8e05187b2d88ca2f8f9ebc5d743885396a00f05f13146f6be744d098a56ce0402cf1cd131485a7ff1 checksum: 10c0/ac32cba8e5c79bcf0dbbb43c2fcc73e47902320c1fa1891074fefb3aa3dfaeef9c76348da22909f65334ba9bee1140bfc903e2f0c64427dd08ef4ba8f6b1dbd0
languageName: node languageName: node
linkType: hard linkType: hard
@ -11786,16 +11722,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"micromatch@npm:4.0.5, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
version: 4.0.5
resolution: "micromatch@npm:4.0.5"
dependencies:
braces: "npm:^3.0.2"
picomatch: "npm:^2.3.1"
checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff
languageName: node
linkType: hard
"micromatch@npm:^3.0.4, micromatch@npm:^3.1.10, micromatch@npm:^3.1.4": "micromatch@npm:^3.0.4, micromatch@npm:^3.1.10, micromatch@npm:^3.1.4":
version: 3.1.10 version: 3.1.10
resolution: "micromatch@npm:3.1.10" resolution: "micromatch@npm:3.1.10"
@ -11817,6 +11743,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:~4.0.7":
version: 4.0.7
resolution: "micromatch@npm:4.0.7"
dependencies:
braces: "npm:^3.0.3"
picomatch: "npm:^2.3.1"
checksum: 10c0/58fa99bc5265edec206e9163a1d2cec5fabc46a5b473c45f4a700adce88c2520456ae35f2b301e4410fb3afb27e9521fb2813f6fc96be0a48a89430e0916a772
languageName: node
linkType: hard
"miller-rabin@npm:^4.0.0": "miller-rabin@npm:^4.0.0":
version: 4.0.1 version: 4.0.1
resolution: "miller-rabin@npm:4.0.1" resolution: "miller-rabin@npm:4.0.1"
@ -12363,10 +12299,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"nwsapi@npm:^2.2.2, nwsapi@npm:^2.2.7": "nwsapi@npm:^2.2.10, nwsapi@npm:^2.2.2":
version: 2.2.7 version: 2.2.10
resolution: "nwsapi@npm:2.2.7" resolution: "nwsapi@npm:2.2.10"
checksum: 10c0/44be198adae99208487a1c886c0a3712264f7bbafa44368ad96c003512fed2753d4e22890ca1e6edb2690c3456a169f2a3c33bfacde1905cf3bf01c7722464db checksum: 10c0/43dfa150387bd2a578e37556d0ae3330d5617f99e5a7b64e3400d4c2785620762aa6169caf8f5fbce17b7ef29c372060b602594320c374fba0a39da4163d77ed
languageName: node languageName: node
linkType: hard linkType: hard
@ -13010,10 +12946,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"picocolors@npm:^1.0.0": "picocolors@npm:^1.0.0, picocolors@npm:^1.0.1":
version: 1.0.0 version: 1.0.1
resolution: "picocolors@npm:1.0.0" resolution: "picocolors@npm:1.0.1"
checksum: 10c0/20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 checksum: 10c0/c63cdad2bf812ef0d66c8db29583802355d4ca67b9285d846f390cc15c2f6ccb94e8cb7eb6a6e97fc5990a6d3ad4ae42d86c84d3146e667c739a4234ed50d400
languageName: node languageName: node
linkType: hard linkType: hard
@ -13024,7 +12960,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pidtree@npm:0.6.0": "pidtree@npm:~0.6.0":
version: 0.6.0 version: 0.6.0
resolution: "pidtree@npm:0.6.0" resolution: "pidtree@npm:0.6.0"
bin: bin:
@ -13093,12 +13029,12 @@ __metadata:
linkType: hard linkType: hard
"pino-pretty@npm:^11.0.0": "pino-pretty@npm:^11.0.0":
version: 11.0.0 version: 11.1.0
resolution: "pino-pretty@npm:11.0.0" resolution: "pino-pretty@npm:11.1.0"
dependencies: dependencies:
colorette: "npm:^2.0.7" colorette: "npm:^2.0.7"
dateformat: "npm:^4.6.3" dateformat: "npm:^4.6.3"
fast-copy: "npm:^3.0.0" fast-copy: "npm:^3.0.2"
fast-safe-stringify: "npm:^2.1.1" fast-safe-stringify: "npm:^2.1.1"
help-me: "npm:^5.0.0" help-me: "npm:^5.0.0"
joycon: "npm:^3.1.1" joycon: "npm:^3.1.1"
@ -13108,11 +13044,11 @@ __metadata:
pump: "npm:^3.0.0" pump: "npm:^3.0.0"
readable-stream: "npm:^4.0.0" readable-stream: "npm:^4.0.0"
secure-json-parse: "npm:^2.4.0" secure-json-parse: "npm:^2.4.0"
sonic-boom: "npm:^3.0.0" sonic-boom: "npm:^4.0.1"
strip-json-comments: "npm:^3.1.1" strip-json-comments: "npm:^3.1.1"
bin: bin:
pino-pretty: bin.js pino-pretty: bin.js
checksum: 10c0/d42213f3fdf19d92152b0a14683b2bb8443423739c81ab7c1181a5dac0e0ca7621d232c8264ece81edc01106ca2a8e165783daca0a902f0fde480027075d5540 checksum: 10c0/418be6f854b0d62c83c65e75b0969d5311792bfadeefbfe77d8a7f8c5ba26b8bea40f549222b5f500439f440eb4d6c2fa99d712bdd02881ebae7be3a0193b581
languageName: node languageName: node
linkType: hard linkType: hard
@ -15224,10 +15160,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"rfdc@npm:^1.3.0": "rfdc@npm:^1.3.1":
version: 1.3.0 version: 1.3.1
resolution: "rfdc@npm:1.3.0" resolution: "rfdc@npm:1.3.1"
checksum: 10c0/a17fd7b81f42c7ae4cb932abd7b2f677b04cc462a03619fb46945ae1ccae17c3bc87c020ffdde1751cbfa8549860a2883486fdcabc9b9de3f3108af32b69a667 checksum: 10c0/69f65e3ed30970f8055fac9fbbef9ce578800ca19554eab1dcbffe73a4b8aef536bc4248313889cf25e3b4e38b212c721eabe30856575bf2b2bc3d90f8ba93ef
languageName: node languageName: node
linkType: hard linkType: hard
@ -15295,6 +15231,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"rrweb-cssom@npm:^0.7.0":
version: 0.7.0
resolution: "rrweb-cssom@npm:0.7.0"
checksum: 10c0/278350b1f383f76db20e37394361b709740bd4f5f27f924e1c3c3fdd7112b2ae37ed9bc7cee63776f7df395b9b0f644d1f8be104990e3028d276a3288cd7e564
languageName: node
linkType: hard
"run-parallel@npm:^1.1.9": "run-parallel@npm:^1.1.9":
version: 1.2.0 version: 1.2.0
resolution: "run-parallel@npm:1.2.0" resolution: "run-parallel@npm:1.2.0"
@ -15511,14 +15454,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": "semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.1":
version: 7.6.0 version: 7.6.2
resolution: "semver@npm:7.6.0" resolution: "semver@npm:7.6.2"
dependencies:
lru-cache: "npm:^6.0.0"
bin: bin:
semver: bin/semver.js semver: bin/semver.js
checksum: 10c0/fbfe717094ace0aa8d6332d7ef5ce727259815bd8d8815700853f4faf23aacbd7192522f0dc5af6df52ef4fa85a355ebd2f5d39f554bd028200d6cf481ab9b53 checksum: 10c0/97d3441e97ace8be4b1976433d1c32658f6afaff09f143e52c593bae7eef33de19e3e369c88bd985ce1042c6f441c80c6803078d1de2a9988080b66684cbb30c
languageName: node languageName: node
linkType: hard linkType: hard
@ -15889,15 +15830,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"sonic-boom@npm:^3.0.0":
version: 3.7.0
resolution: "sonic-boom@npm:3.7.0"
dependencies:
atomic-sleep: "npm:^1.0.0"
checksum: 10c0/57a3d560efb77f4576db111168ee2649c99e7869fda6ce0ec2a4e5458832d290ba58d74b073ddb5827d9a30f96d23cff79157993d919e1a6d5f28d8b6391c7f0
languageName: node
linkType: hard
"sonic-boom@npm:^4.0.1": "sonic-boom@npm:^4.0.1":
version: 4.0.1 version: 4.0.1
resolution: "sonic-boom@npm:4.0.1" resolution: "sonic-boom@npm:4.0.1"
@ -16204,7 +16136,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"string-argv@npm:0.3.2": "string-argv@npm:~0.3.2":
version: 0.3.2 version: 0.3.2
resolution: "string-argv@npm:0.3.2" resolution: "string-argv@npm:0.3.2"
checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82 checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82
@ -16528,14 +16460,14 @@ __metadata:
linkType: hard linkType: hard
"stylelint@npm:^16.0.2": "stylelint@npm:^16.0.2":
version: 16.5.0 version: 16.6.0
resolution: "stylelint@npm:16.5.0" resolution: "stylelint@npm:16.6.0"
dependencies: dependencies:
"@csstools/css-parser-algorithms": "npm:^2.6.1" "@csstools/css-parser-algorithms": "npm:^2.6.3"
"@csstools/css-tokenizer": "npm:^2.2.4" "@csstools/css-tokenizer": "npm:^2.3.1"
"@csstools/media-query-list-parser": "npm:^2.1.9" "@csstools/media-query-list-parser": "npm:^2.1.11"
"@csstools/selector-specificity": "npm:^3.0.3" "@csstools/selector-specificity": "npm:^3.1.1"
"@dual-bundle/import-meta-resolve": "npm:^4.0.0" "@dual-bundle/import-meta-resolve": "npm:^4.1.0"
balanced-match: "npm:^2.0.0" balanced-match: "npm:^2.0.0"
colord: "npm:^2.9.3" colord: "npm:^2.9.3"
cosmiconfig: "npm:^9.0.0" cosmiconfig: "npm:^9.0.0"
@ -16552,16 +16484,16 @@ __metadata:
ignore: "npm:^5.3.1" ignore: "npm:^5.3.1"
imurmurhash: "npm:^0.1.4" imurmurhash: "npm:^0.1.4"
is-plain-object: "npm:^5.0.0" is-plain-object: "npm:^5.0.0"
known-css-properties: "npm:^0.30.0" known-css-properties: "npm:^0.31.0"
mathml-tag-names: "npm:^2.1.3" mathml-tag-names: "npm:^2.1.3"
meow: "npm:^13.2.0" meow: "npm:^13.2.0"
micromatch: "npm:^4.0.5" micromatch: "npm:^4.0.5"
normalize-path: "npm:^3.0.0" normalize-path: "npm:^3.0.0"
picocolors: "npm:^1.0.0" picocolors: "npm:^1.0.1"
postcss: "npm:^8.4.38" postcss: "npm:^8.4.38"
postcss-resolve-nested-selector: "npm:^0.1.1" postcss-resolve-nested-selector: "npm:^0.1.1"
postcss-safe-parser: "npm:^7.0.0" postcss-safe-parser: "npm:^7.0.0"
postcss-selector-parser: "npm:^6.0.16" postcss-selector-parser: "npm:^6.1.0"
postcss-value-parser: "npm:^4.2.0" postcss-value-parser: "npm:^4.2.0"
resolve-from: "npm:^5.0.0" resolve-from: "npm:^5.0.0"
string-width: "npm:^4.2.3" string-width: "npm:^4.2.3"
@ -16572,7 +16504,7 @@ __metadata:
write-file-atomic: "npm:^5.0.1" write-file-atomic: "npm:^5.0.1"
bin: bin:
stylelint: bin/stylelint.mjs stylelint: bin/stylelint.mjs
checksum: 10c0/9281693ff6c1918e07fdcf7a950531f79678a28261a0d5bd36ca2fcf524e53d7305158d20ba890f5dd01c0ff90c09a13453dce2fe6887f4c157d8c2c0acf3666 checksum: 10c0/acfb7983a0b71677d066b2aa570eefdac0a7be2e21351bac8884b8156deaeec19e53ad128ae7ae7933c79f6045f1de8d759ba06cfbc373b2711015860805a3e7
languageName: node languageName: node
linkType: hard linkType: hard
@ -16973,15 +16905,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tough-cookie@npm:^4.1.2, tough-cookie@npm:^4.1.3": "tough-cookie@npm:^4.1.2, tough-cookie@npm:^4.1.4":
version: 4.1.3 version: 4.1.4
resolution: "tough-cookie@npm:4.1.3" resolution: "tough-cookie@npm:4.1.4"
dependencies: dependencies:
psl: "npm:^1.1.33" psl: "npm:^1.1.33"
punycode: "npm:^2.1.1" punycode: "npm:^2.1.1"
universalify: "npm:^0.2.0" universalify: "npm:^0.2.0"
url-parse: "npm:^1.5.3" url-parse: "npm:^1.5.3"
checksum: 10c0/4fc0433a0cba370d57c4b240f30440c848906dee3180bb6e85033143c2726d322e7e4614abb51d42d111ebec119c4876ed8d7247d4113563033eebbc1739c831 checksum: 10c0/aca7ff96054f367d53d1e813e62ceb7dd2eda25d7752058a74d64b7266fd07be75908f3753a32ccf866a2f997604b414cfb1916d6e7f69bc64d9d9939b0d6c45
languageName: node languageName: node
linkType: hard linkType: hard
@ -18395,7 +18327,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.16.0": "ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.17.0":
version: 8.17.0 version: 8.17.0
resolution: "ws@npm:8.17.0" resolution: "ws@npm:8.17.0"
peerDependencies: peerDependencies:
@ -18466,13 +18398,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"yaml@npm:2.3.4":
version: 2.3.4
resolution: "yaml@npm:2.3.4"
checksum: 10c0/cf03b68f8fef5e8516b0f0b54edaf2459f1648317fc6210391cf606d247e678b449382f4bd01f77392538429e306c7cba8ff46ff6b37cac4de9a76aff33bd9e1
languageName: node
linkType: hard
"yaml@npm:^1.10.0": "yaml@npm:^1.10.0":
version: 1.10.2 version: 1.10.2
resolution: "yaml@npm:1.10.2" resolution: "yaml@npm:1.10.2"
@ -18480,6 +18405,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"yaml@npm:~2.4.2":
version: 2.4.2
resolution: "yaml@npm:2.4.2"
bin:
yaml: bin.mjs
checksum: 10c0/280ddb2e43ffa7d91a95738e80c8f33e860749cdc25aa6d9e4d350a28e174fd7e494e4aa023108aaee41388e451e3dc1292261d8f022aabcf90df9c63d647549
languageName: node
linkType: hard
"yargs-parser@npm:^13.1.2": "yargs-parser@npm:^13.1.2":
version: 13.1.2 version: 13.1.2
resolution: "yargs-parser@npm:13.1.2" resolution: "yargs-parser@npm:13.1.2"