diff options
| author | Marie <marie@kaifa.ch> | 2024-02-09 19:22:06 +0100 |
|---|---|---|
| committer | Marie <marie@kaifa.ch> | 2024-02-09 19:22:06 +0100 |
| commit | 85355813ad07724a2fad4abdbf694d696482d439 (patch) | |
| tree | 79bbf9a76c17f4022754cb09a6db5b22b673d31a | |
| parent | merge: more upstream changes (diff) | |
| parent | fix misskey-js version (diff) | |
| download | sharkey-85355813ad07724a2fad4abdbf694d696482d439.tar.gz sharkey-85355813ad07724a2fad4abdbf694d696482d439.tar.bz2 sharkey-85355813ad07724a2fad4abdbf694d696482d439.zip | |
merge: latest changes
91 files changed, 1103 insertions, 494 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 652c7ea7c5..1d788e1522 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ - Fix: リモートユーザーのリアクション一覧がすべて見えてしまうのを修正 * すべてのリモートユーザーのリアクション一覧を見えないようにします - Enhance: モデレーターはすべてのユーザーのリアクション一覧を見られるように +- Fix: 特定のキーワードを含むノートが投稿された際、エラーに出来るような設定項目を追加 #13207 + * デフォルトは空欄なので適用前と同等の動作になります ### Client - Feat: 新しいゲームを追加 @@ -74,6 +76,7 @@ - Fix: プロフィールを編集してもリロードするまで反映されない問題を修正 - Fix: エラー画像URLを設定した後解除すると,デフォルトの画像が表示されない問題の修正 - Fix: MkCodeEditorで行がずれていってしまう問題の修正 +- Fix: Summaly proxy利用時にプレイヤーが動作しないことがあるのを修正 #13196 ### Server - Enhance: 連合先のレートリミットに引っかかった際にリトライするようになりました diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7f6c1f4f82..ac0a1ba3c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -286,18 +286,17 @@ export const argTypes = { min: 1, max: 4, }, + }, }; ``` Also, you can use msw to mock API requests in the storybook. Creating a `MyComponent.stories.msw.ts` file to define the mock handlers. ```ts -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; export const handlers = [ - rest.post('/api/notes/timeline', (req, res, ctx) => { - return res( - ctx.json([]), - ); + http.post('/api/notes/timeline', ({ request }) => { + return HttpResponse.json([]); }), ]; ``` diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 02e1d3e362..13bbb43f76 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -1041,6 +1041,9 @@ resetPasswordConfirm: "Vols canviar la teva contrasenya?" sensitiveWords: "Paraules sensibles" sensitiveWordsDescription: "La visibilitat de totes les notes que continguin qualsevol de les paraules configurades seran, automàticament, afegides a \"Inici\". Pots llistar diferents paraules separant les per línies noves." sensitiveWordsDescription2: "Fent servir espais crearà expressions AND si l'expressió s'envolta amb barres inclinades es converteix en una expressió regular." +prohibitedWords: "Paraules prohibides" +prohibitedWordsDescription: "Quan intenteu publicar una Nota que conté una paraula prohibida, feu que es converteixi en un error. Es poden dividir i establir múltiples línies." +prohibitedWordsDescription2: "Fent servir espais crearà expressions AND si l'expressió s'envolta amb barres inclinades es converteix en una expressió regular." hiddenTags: "Etiquetes ocultes" hiddenTagsDescription: "La visibilitat de totes les notes que continguin qualsevol de les paraules configurades seran, automàticament, afegides a \"Inici\". Pots llistar diferents paraules separant les per línies noves." notesSearchNotAvailable: "La cerca de notes no es troba disponible." @@ -1518,12 +1521,82 @@ _achievements: title: "Nocturn" description: "Publica una nota a altes hores de la nit " flavor: "És hora d'anar a dormir." + _postedAt0min0sec: + title: "Rellotge xerraire" + description: "Publica una nota a les 0:00" + flavor: "Tic tac, tic tac, tic tac, DING!" + _selfQuote: + title: "Autoreferència " + description: "Cita una nota teva" + _htl20npm: + title: "Línia de temps fluida" + description: "La teva línia de temps va a més de 20npm (notes per minut)" + _viewInstanceChart: + title: "Analista " + description: "Mira els gràfics de la teva instància " + _outputHelloWorldOnScratchpad: + title: "Hola, món!" + description: "Escriu \"hola, món\" al bloc de notes" _open3windows: title: "Multi finestres" description: "I va obrir més de tres finestres" _driveFolderCircularReference: title: "Consulteu la secció de bucle" + description: "Intenta crear carpetes recursives al Disc" + _reactWithoutRead: + title: "De veritat has llegit això?" + description: "Reaccions a una nota de més de 100 caràcters publicada fa menys de 3 segons " + _clickedClickHere: + title: "Fer clic" + description: "Has fet clic aquí " + _justPlainLucky: + title: "Ha sigut sort" + description: "Oportunitat de guanyar-lo amb una probabilitat d'un 0.005% cada 10 segons" + _setNameToSyuilo: + title: "soc millor" + description: "Posat \"siuylo\" com a nom" + _passedSinceAccountCreated1: + title: "Primer aniversari" + description: "Ja ha passat un any d'ençà que vas crear el teu compte" + _passedSinceAccountCreated2: + title: "Segon aniversari" + description: "Ja han passat dos anys d'ençà que vas crear el teu compte" + _passedSinceAccountCreated3: + title: "Tres anys" + description: "Ja han passat tres anys d'ençà que vas crear el teu compte" + _loggedInOnBirthday: + title: "Felicitats!" + description: "T'has identificat el dia del teu aniversari" + _loggedInOnNewYearsDay: + title: "Bon any nou!" + description: "T'has identificat el primer dia de l'any " + flavor: "A per un altre any memorable a la teva instància " + _cookieClicked: + title: "Un joc en què fas clic a les galetes" + description: "Pica galetes" + flavor: "Espera, ets al lloc web correcte?" + _brainDiver: + title: "Busseja Ments" + description: "Publica un enllaç al Busseja Ments" + flavor: "Misskey-Misskey La-Tu-Ma" + _smashTestNotificationButton: + title: "Sobrecàrrega de proves" + description: "Envia moltes notificacions de prova en un període de temps molt curt" + _tutorialCompleted: + title: "Diploma del Curs Elemental de Misskey" + description: "Has completat el tutorial" + _bubbleGameExplodingHead: + title: "🤯" + description: "L'objecte més gran del joc de la bombolla " + _bubbleGameDoubleExplodingHead: + title: "Doble 🤯" + description: "Dos dels objectes més grans del joc de la bombolla al mateix temps" + flavor: "Pots emplenar una carmanyola com aquesta 🤯🤯 una mica" _role: + new: "Nou rol" + edit: "Editar el rol" + name: "Nom del rol" + description: "Descripció del rol" permission: "Permisos de rol" descriptionOfPermission: "Els <b>Moderadors</b> poden fer operacions bàsiques de moderació.\nEls <b>Administradors</b> poden canviar tots els ajustos del servidor." assignTarget: "Assignar " @@ -1545,35 +1618,259 @@ _role: asBadge: "Mostrar com a insígnia " descriptionOfAsBadge: "La icona d'aquest rol es mostrarà al costat dels noms d'usuaris que tinguin assignats aquest rol." isExplorable: "Fer el rol explorable" + descriptionOfIsExplorable: "La línia de temps d'aquest rol i la llista d'usuaris seran públics si s'activa." + displayOrder: "Posició " + descriptionOfDisplayOrder: "Com més gran és el número, més dalt la seva posició a la interfície." + canEditMembersByModerator: "Permetre que els moderadors editin la llista d'usuaris en aquest rol" + descriptionOfCanEditMembersByModerator: "Quan s'activa, els moderadors, així com els administradors, podran afegir i treure usuaris d'aquest rol. Si es troba desactivat, només els administradors poden assignar usuaris." priority: "Prioritat" _priority: low: "Baixa" middle: "Mitjà" high: "Alta" _options: + gtlAvailable: "Pot veure la línia de temps global" + ltlAvailable: "Pot veure la línia de temps local" + canPublicNote: "Pot enviar notes públiques" + canInvite: "Pot crear invitacions a la instància " + inviteLimit: "Límit d'invitacions " + inviteLimitCycle: "Temps de refresc de les invitacions" + inviteExpirationTime: "Interval de caducitat de les invitacions" canManageCustomEmojis: "Gestiona els emojis personalitzats" canManageAvatarDecorations: "Gestiona les decoracions dels avatars " + driveCapacity: "Capacitat del disc" + alwaysMarkNsfw: "Marca sempre els fitxers com a sensibles" + pinMax: "Nombre màxim de notes fixades" antennaMax: "Nombre màxim d'antenes" + wordMuteMax: "Nombre màxim de caràcters permesos a les paraules silenciades" + webhookMax: "Nombre màxim de Webhooks" + clipMax: "Nombre màxim de clips" + noteEachClipsMax: "Nombre màxim de notes dintre d'un clip" + userListMax: "Nombre màxim de llistes d'usuaris " + userEachUserListsMax: "Nombre màxim d'usuaris dintre d'una llista d'usuaris " + rateLimitFactor: "Limitador" + descriptionOfRateLimitFactor: "Límits baixos són menys restrictius, límits alts són més restrictius." + canHideAds: "Pot amagar els anuncis" + canSearchNotes: "Pot cercar notes" + canUseTranslator: "Pot fer servir el traductor" + avatarDecorationLimit: "Nombre màxim de decoracions que es poden aplicar els avatars" + _condition: + isLocal: "Usuari local" + isRemote: "Usuari remot" + createdLessThan: "Han passat menys de X a passat des de la creació del compte" + createdMoreThan: "Han passat més de X des de la creació del compte" + followersLessThanOrEq: "Té menys de X seguidors" + followersMoreThanOrEq: "Té X o més seguidors" + followingLessThanOrEq: "Segueix X o menys comptes" + followingMoreThanOrEq: "Segueix a X o més comptes" + notesLessThanOrEq: "Les publicacions són menys o igual a " + notesMoreThanOrEq: "Les publicacions són més o igual a " + and: "AND condicional " + or: "OR condicional" + not: "NOT condicional" +_sensitiveMediaDetection: + description: "Redueix els esforços de moderació gràcies al reconeixement automàtic dels fitxers amb contingut sensible mitjançant Machine Learing. Això augmentarà la càrrega del servidor." + sensitivity: "Sensibilitat de la detecció " + sensitivityDescription: "Reduint la sensibilitat provocarà menys falsos positius. D'altra banda incrementant-ho generarà més falsos negatius." + setSensitiveFlagAutomatically: "Marcar com a sensible" + setSensitiveFlagAutomaticallyDescription: "Els resultats de la detecció interna seran desats, inclòs si aquesta opció es troba desactivada." + analyzeVideos: "Activar anàlisis de vídeos " + analyzeVideosDescription: "Analitzar els vídeos a més de les imatges. Això incrementarà lleugerament la càrrega del servidor." +_emailUnavailable: + used: "Aquest correu electrònic ja s'està fent servir" + format: "El format del correu electrònic és invàlid " + disposable: "No es poden fer servir adreces de correu electrònic d'un sol ús " + mx: "Aquest servidor de correu electrònic no és vàlid " + smtp: "Aquest servidor de correu electrònic no respon" + banned: "No pots registrar-te amb aquesta adreça de correu electrònic " _ffVisibility: public: "Publicar" + followers: "Visible només per a seguidors " + private: "Privat" +_signup: + almostThere: "Ja quasi estem" + emailAddressInfo: "Si us plau, escriu la teva adreça de correu electrònic. No es farà pública." + emailSent: "S'ha enviat un correu de confirmació a ({email}). Si us plau, fes clic a l'enllaç per completar el registre." +_accountDelete: + accountDelete: "Eliminar el compte" + mayTakeTime: "Com l'eliminació d'un compte consumeix bastants recursos, pot trigar un temps perquè es completi l'esborrat, depenent si tens molt contingut i la quantitat de fitxer que hagis pujat." + sendEmail: "Una vegada hagi finalitzat l'esborrat del compte rebràs un correu electrònic a l'adreça que tinguis registrada en aquest compte." + requestAccountDelete: "Demanar l'eliminació del compte" + started: "Ha començat l'esborrat del compte." + inProgress: "L'esborrat es troba en procés " _ad: back: "Tornar" + reduceFrequencyOfThisAd: "Mostrar menys aquest anunci" + hide: "No mostrar mai" + timezoneinfo: "El dia de la setmana ve determinat del fus horari del servidor." + adsSettings: "Configuració d'anuncis " + notesPerOneAd: "Interval d'emplaçament d'anuncis en temps real (Notes per anuncis)" + setZeroToDisable: "Ajusta aquest valor a 0 per deshabilitar l'actualització d'anuncis en temps real" + adsTooClose: "L'interval actual pot fer que l'experiència de l'usuari sigui dolenta perquè l'interval és molt baix." +_forgotPassword: + enterEmail: "Escriu l'adreça de correu electrònic amb la que et vas registrar. S'enviarà un correu electrònic amb un enllaç perquè puguis canviar-la." + ifNoEmail: "Si no vas fer servir una adreça de correu electrònic per registrar-te, si us plau posa't en contacte amb l'administrador." + contactAdmin: "Aquesta instància no suporta registrar-se amb correu electrònic. Si us plau, contacta amb l'administrador del servidor." +_gallery: + my: "La meva Galeria " + liked: "Publicacions que t'han agradat" + like: "M'agrada " + unlike: "Ja no m'agrada" _email: _follow: title: "t'ha seguit" + _receiveFollowRequest: + title: "Has rebut una sol·licitud de seguiment" +_plugin: + install: "Instal·lar un afegit " + installWarn: "Si us plau, no instal·lis afegits que no siguin de confiança." + manage: "Gestionar els afegits" + viewSource: "Veure l'origen " +_preferencesBackups: + list: "Llista de còpies de seguretat" + saveNew: "Fer una còpia de seguretat nova" + loadFile: "Carregar des d'un fitxer" + apply: "Aplicar en aquest dispositiu" + save: "Desar els canvis" + inputName: "Escriu un nom per aquesta còpia de seguretat" + cannotSave: "No s'ha pogut desar" + nameAlreadyExists: "Ja existeix una còpia de seguretat anomenada \"{name}\". Escriu un nom diferent." + applyConfirm: "Vols aplicar la còpia de seguretat \"{name}\" a aquest dispositiu? La configuració actual del dispositiu serà esborrada." + saveConfirm: "Desar còpia de seguretat com {name}?" + deleteConfirm: "Esborrar la còpia de seguretat {name}?" + renameConfirm: "Vols canvia el nom de la còpia de seguretat de \"{old}\" a \"{new}\"?" + noBackups: "No hi ha còpies de seguretat. Pots fer una còpia de seguretat de la configuració d'aquest dispositiu al servidor fent servir \"Crear nova còpia de seguretat\"" + createdAt: "Creat el: {date} {time}" + updatedAt: "Actualitzat el: {date} {time}" + cannotLoad: "Hi ha hagut un error al carregar" + invalidFile: "Format del fitxer no vàlid " +_registry: + scope: "Àmbit " + key: "Clau" + keys: "Claus" + domain: "Domini" + createKey: "Crear una clau" +_aboutMisskey: + about: "Misskey és un programa de codi obert desenvolupar per syuilo des de 2014" + contributors: "Col·laboradors principals" + allContributors: "Tots els col·laboradors " + source: "Codi font" + translation: "Tradueix Misskey" + donate: "Fes un donatiu a Misskey" + morePatrons: "També agraïm el suport d'altres col·laboradors que no surten en aquesta llista. Gràcies! 🥰" + patrons: "Patrocinadors" + projectMembers: "Membres del projecte" +_displayOfSensitiveMedia: + respect: "Ocultar imatges o vídeos marcats com a sensibles" + ignore: "Mostrar imatges o vídeos marcats com a sensibles" + force: "Ocultar totes les imatges o vídeos " +_instanceTicker: + none: "No mostrar mai" + remote: "Mostrar per usuaris remots" + always: "Mostrar sempre" +_serverDisconnectedBehavior: + reload: "Recarregar automàticament " + dialog: "Mostrar finestres de confirmació " + quiet: "Mostrar un avís que no molesti" +_channel: + create: "Crear un canal" + edit: "Editar canal" + setBanner: "Estableix el bàner " + removeBanner: "Eliminar el.bàner" + featured: "Popular" + owned: "Propietat" + following: "Seguin" + usersCount: "{n} Participants" + notesCount: "{n} Notes" + nameAndDescription: "Nom i descripció " + nameOnly: "Nom només " + allowRenoteToExternal: "Permet la citació i l'impuls fora del canal" _instanceMute: instanceMuteDescription: "Silencia tots els impulsos dels servidors seleccionats, també els usuaris que responen a altres d'un servidor silenciat." _theme: description: "Descripció" keys: + navHoverFg: "Text barra lateral (en passar per sobre)" + navActive: "Text barra lateral (actiu)" + navIndicator: "Indicador barra lateral" + link: "Enllaç" + hashtag: "Etiqueta" mention: "Menció" + mentionMe: "Mencions (jo)" renote: "Renotar" + modalBg: "Fons del modal" divider: "Divisor" + scrollbarHandle: "Maneta de la barra de desplaçament" + scrollbarHandleHover: "Maneta de la barra de desplaçament (en passar-hi per sobre)" + dateLabelFg: "Text de l'etiqueta de la data" + infoBg: "Fons d'informació " + infoFg: "Text d'informació " + infoWarnBg: "Fons avís " + infoWarnFg: "Text avís " + toastBg: "Fons notificació " + toastFg: "Text notificació " + buttonBg: "Fons botó " + buttonHoverBg: "Fons botó (en passar-hi per sobre)" + inputBorder: "Contorn del cap d'introducció " + listItemHoverBg: "Fons dels elements d'una llista" + driveFolderBg: "Fons de la carpeta Disc" + wallpaperOverlay: "Superposició del fons de pantalla " + badge: "Insígnia " + messageBg: "Fons del xat" + accentDarken: "Accent (fosc)" + accentLighten: "Accent (clar)" + fgHighlighted: "Text ressaltat" _sfx: note: "Notes" + noteMy: "Nota (per mi)" notification: "Notificacions" antenna: "Antenes" + channel: "Notificacions dels canals" + reaction: "Quan se selecciona una reacció " +_soundSettings: + driveFile: "Fer servir un fitxer d'àudio del disc" + driveFileWarn: "Seleccionar un fitxer d'àudio del disc" + driveFileTypeWarn: "Fitxer no suportat " + driveFileTypeWarnDescription: "Seleccionar un fitxer d'àudio " + driveFileDurationWarn: "L'àudio és massa llarg" + driveFileDurationWarnDescription: "Els àudios molt llargs pot interrompre l'ús de Misskey. Vols continuar?" +_ago: + future: "Futur " + justNow: "Ara mateix" + secondsAgo: "Fa {n} segons" + minutesAgo: "Fa {n} minuts" + hoursAgo: "Fa {n} hores" + daysAgo: "Fa {n} dies" + weeksAgo: "Fa {n} setmanes" + monthsAgo: "Fa {n} mesos" + yearsAgo: "Fa {n} anys" + invalid: "Res" +_timeIn: + seconds: "En {n} segons" + minutes: "En {n} minuts" + hours: "En {n} hores" + days: "En {n} dies" + weeks: "En {n} setmanes" + months: "En {n} mesos" + years: "En {n} anys" +_time: + second: "Segon(s)" + minute: "Minut(s)" + hour: "Hor(a)(es)" + day: "Di(a)(es)" _2fa: + alreadyRegistered: "J has registrat un dispositiu d'autenticació de doble factor." + registerTOTP: "Registrar una aplicació autenticadora" + step1: "Primer instal·la una aplicació autenticadora (com {a} o {b}) al teu dispositiu." + step2: "Després escaneja el codi QR que es mostra en aquesta pantalla." + step2Click: "Fent clic en aquest codi QR et permetrà registrar l'autenticació de doble factor a la teva clau de seguretat o en l'aplicació d'autenticació del teu dispositiu." + step2Uri: "Escriu la següent URI si estàs fent servir una aplicació d'escriptori " + step3Title: "Escriu un codi d'autenticació" + step3: "Escriu el codi d'autenticació (token) que es mostra a la teva aplicació per finalitzar la configuració." + setupCompleted: "Configuració terminada" + step4: "D'ara endavant quan accedeixis se't demanarà el token que has introduït." + securityKeyNotSupported: "El teu navegador no suporta claus de seguretat" + removeKeyConfirm: "Esborrar la còpia de seguretat {name}?" renewTOTPCancel: "No, gràcies" _antennaSources: all: "Totes les publicacions" @@ -1592,6 +1889,8 @@ _widgets: chooseList: "Tria una llista" _cw: show: "Carregar més" +_poll: + deadlineTime: "Hor(a)(es)" _visibility: home: "Inici" followers: "Seguidors" diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index 241e4cfc7b..6f838d4880 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -1005,6 +1005,7 @@ resetPasswordConfirm: "Opravdu chcete resetovat heslo?" sensitiveWords: "Citlivá slova" sensitiveWordsDescription: "Viditelnost všech poznámek obsahujících některé z nakonfigurovaných slov bude automaticky nastavena na \"Domů\". Můžete jich uvést více tak, že je oddělíte pomocí řádků." sensitiveWordsDescription2: "Použití mezer vytvoří výrazy AND a obklopení klíčových slov lomítky je změní na regulární výraz." +prohibitedWordsDescription2: "Použití mezer vytvoří výrazy AND a obklopení klíčových slov lomítky je změní na regulární výraz." notesSearchNotAvailable: "Vyhledávání poznámek je nedostupné." license: "Licence" unfavoriteConfirm: "Opravdu chcete odstranit z oblíbených?" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 909ee5d45c..67178924e3 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1037,6 +1037,7 @@ resetPasswordConfirm: "Wirklich Passwort zurücksetzen?" sensitiveWords: "Sensible Wörter" sensitiveWordsDescription: "Die Notizsichtbarkeit aller Notizen, die diese Wörter enthalten, wird automatisch auf \"Startseite\" gesetzt. Durch Zeilenumbrüche können mehrere konfiguriert werden." sensitiveWordsDescription2: "Durch die Verwendung von Leerzeichen können AND-Verknüpfungen angegeben werden und durch das Umgeben von Schrägstrichen können reguläre Ausdrücke verwendet werden." +prohibitedWordsDescription2: "Durch die Verwendung von Leerzeichen können AND-Verknüpfungen angegeben werden und durch das Umgeben von Schrägstrichen können reguläre Ausdrücke verwendet werden." hiddenTags: "Ausgeblendete Hashtags" hiddenTagsDescription: "Die hier eingestellten Tags werden nicht mehr in den Trends angezeigt. Mit der Umschalttaste können mehrere ausgewählt werden." notesSearchNotAvailable: "Die Notizsuche ist nicht verfügbar." diff --git a/locales/en-US.yml b/locales/en-US.yml index 4c859861f7..8a32d8307c 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1078,6 +1078,7 @@ resetPasswordConfirm: "Really reset your password?" sensitiveWords: "Sensitive words" sensitiveWordsDescription: "The visibility of all notes containing any of the configured words will be set to \"Home\" automatically. You can list multiple by separating them via line breaks." sensitiveWordsDescription2: "Using spaces will create AND expressions and surrounding keywords with slashes will turn them into a regular expression." +prohibitedWordsDescription2: "Using spaces will create AND expressions and surrounding keywords with slashes will turn them into a regular expression." hiddenTags: "Hidden hashtags" hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines." notesSearchNotAvailable: "Note search is unavailable." @@ -2023,54 +2024,30 @@ _permissions: "read:flash-likes": "View list of liked Plays" "write:flash-likes": "Edit list of liked Plays" "read:admin:abuse-user-reports": "View user reports" - "write:admin:delete-account": "Delete account" + "write:admin:delete-account": "Delete user account" "write:admin:delete-all-files-of-a-user": "Delete all files of a user" - "read:admin:index-stats": "View information about database indexes" - "read:admin:table-stats": "View information about database tables" - "read:admin:user-ips": "View user IP address" "read:admin:meta": "View instance metadata" - "write:admin:reset-password": "Reset user passwords" - "write:admin:resolve-abuse-user-report": "Resolve user reports" - "write:admin:send-email": "Send Email" + "write:admin:reset-password": "Reset user password" + "write:admin:send-email": "Send email" "read:admin:server-info": "View server info" "read:admin:show-moderation-log": "View moderation log" - "read:admin:show-user": "View user information" - "read:admin:show-users": "View users" + "read:admin:show-user": "View private user info" + "read:admin:show-users": "View private user info" "write:admin:suspend-user": "Suspend user" - "write:admin:unset-user-avatar": "Remove avatar from user" - "write:admin:unset-user-banner": "Remove banner from user" + "write:admin:unset-user-avatar": "Remove user avatar" + "write:admin:unset-user-banner": "Remove user banner" "write:admin:unsuspend-user": "Unsuspend user" - "write:admin:meta": "Edit instance metadata" - "write:admin:user-note": "Edit user note" - "write:admin:roles": "Edit roles" + "write:admin:meta": "Manage instance metadata" + "write:admin:user-note": "Manage moderation note" + "write:admin:roles": "Manage roles" "read:admin:roles": "View roles" - "write:admin:relays": "Edit relays" + "write:admin:relays": "Manage relays" "read:admin:relays": "View relays" - "write:admin:invite-codes": "Edit invite codes" + "write:admin:invite-codes": "Manage invite codes" "read:admin:invite-codes": "View invite codes" - "write:admin:announcements": "Edit announcements" + "write:admin:announcements": "Manage announcements" "read:admin:announcements": "View announcements" - "write:admin:avatar-decorations": "Edit avatar decorations" - "read:admin:avatar-decorations": "View avatar decorations" - "write:admin:federation": "Edit remote instance information" - "write:admin:account": "Edit users" - "read:admin:account": "View information about user" - "write:admin:emoji": "Edit emojis" - "read:admin:emoji": "View emojis" - "write:admin:queue": "Edit queue" - "read:admin:queue": "View queue" - "write:admin:promo": "Edit promo" - "write:admin:drive": "Edit user drive" - "read:admin:drive": "View user drive" - "read:admin:stream": "Using the Websocket API for Admin" - "write:admin:ad": "Edit ads" - "read:admin:ad": "View ads" - "write:invite-codes": "Create Invitation Code" - "read:invite-codes": "View Invitation Code" - "write:clip-favorite": "Edit clips and likes" - "read:clip-favorite": "View clips and likes" - "read:federation": "View information about remote instance" - "write:report-abuse": "Report abuse" + "write:admin:avatar-decorations": "Manage avatar decorations" _auth: shareAccessTitle: "Granting application permissions" shareAccess: "Would you like to authorize \"{name}\" to access this account?" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index e8e9761d26..96926dc38d 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "¿Realmente quieres cambiar la contraseña?" sensitiveWords: "Palabras sensibles" sensitiveWordsDescription: "La visibilidad de todas las notas que contienen cualquiera de las palabras configuradas serán puestas en \"Inicio\" automáticamente. Puedes enumerás varias separándolas con saltos de línea" sensitiveWordsDescription2: "Si se usan espacios se crearán expresiones AND y las palabras subsecuentes con barras inclinadas se convertirán en expresiones regulares." +prohibitedWordsDescription2: "Si se usan espacios se crearán expresiones AND y las palabras subsecuentes con barras inclinadas se convertirán en expresiones regulares." hiddenTags: "Hashtags ocultos" hiddenTagsDescription: "Selecciona las etiquetas que no se mostrarán en tendencias. Una etiqueta por línea." notesSearchNotAvailable: "No se puede buscar una nota" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 4093dee6d3..30a5955ff3 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -1038,6 +1038,7 @@ resetPasswordConfirm: "Yakin untuk mereset kata sandimu?" sensitiveWords: "Kata sensitif" sensitiveWordsDescription: "Visibilitas dari semua catatan mengandung kata yang telah diatur akan dijadikan \"Beranda\" secara otomatis. Kamu dapat mendaftarkan kata tersebut lebih dari satu dengan menuliskannya di baris baru." sensitiveWordsDescription2: "Menggunakan spasi akan membuat ekspresi AND dan kata kunci disekitarnya dengan garis miring akan mengubahnya menjadi ekspresi reguler." +prohibitedWordsDescription2: "Menggunakan spasi akan membuat ekspresi AND dan kata kunci disekitarnya dengan garis miring akan mengubahnya menjadi ekspresi reguler." hiddenTags: "Tagar tersembunyi" hiddenTagsDescription: "Pilih tanda yang mana akan tidak diperlihatkan dalam daftar tren.\nTanda lebih dari satu dapat didaftarkan dengan tiap baris." notesSearchNotAvailable: "Pencarian catatan tidak tersedia." diff --git a/locales/index.d.ts b/locales/index.d.ts index 686fa57cd5..012cbe055a 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4330,6 +4330,18 @@ export interface Locale extends ILocale { */ "sensitiveWordsDescription2": string; /** + * 禁止ワード + */ + "prohibitedWords": string; + /** + * 設定したワードが含まれるノートを投稿しようとした際、エラーとなるようにします。改行で区切って複数設定できます。 + */ + "prohibitedWordsDescription": string; + /** + * スペースで区切るとAND指定になり、キーワードをスラッシュで囲むと正規表現になります。 + */ + "prohibitedWordsDescription2": string; + /** * 非表示ハッシュタグ */ "hiddenTags": string; diff --git a/locales/it-IT.yml b/locales/it-IT.yml index db98eaaa24..69720871c9 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -1045,6 +1045,7 @@ resetPasswordConfirm: "Vuoi davvero ripristinare la password?" sensitiveWords: "Parole esplicite" sensitiveWordsDescription: "Imposta automaticamente \"Home\" alla visibilità delle Note che contengono una qualsiasi parola tra queste configurate. Puoi separarle per riga." sensitiveWordsDescription2: "Gli spazi creano la relazione \"E\" tra parole (questo E quello). Racchiudere una parola nelle slash \"/\" la trasforma in Espressione Regolare." +prohibitedWordsDescription2: "Gli spazi creano la relazione \"E\" tra parole (questo E quello). Racchiudere una parola nelle slash \"/\" la trasforma in Espressione Regolare." hiddenTags: "Hashtag nascosti" hiddenTagsDescription: "Impedire la visualizzazione del tag impostato nei trend. Puoi impostare più valori, uno per riga." notesSearchNotAvailable: "Non è possibile cercare tra le Note." diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index f6879acda1..9714f8f668 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1078,6 +1078,9 @@ resetPasswordConfirm: "パスワードリセットしますか?" sensitiveWords: "センシティブワード" sensitiveWordsDescription: "設定したワードが含まれるノートの公開範囲をホームにします。改行で区切って複数設定できます。" sensitiveWordsDescription2: "スペースで区切るとAND指定になり、キーワードをスラッシュで囲むと正規表現になります。" +prohibitedWords: "禁止ワード" +prohibitedWordsDescription: "設定したワードが含まれるノートを投稿しようとした際、エラーとなるようにします。改行で区切って複数設定できます。" +prohibitedWordsDescription2: "スペースで区切るとAND指定になり、キーワードをスラッシュで囲むと正規表現になります。" hiddenTags: "非表示ハッシュタグ" hiddenTagsDescription: "設定したタグをトレンドに表示させないようにします。改行で区切って複数設定できます。" notesSearchNotAvailable: "ノート検索は利用できません。" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 5d5b175e0c..b4787c636f 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -1043,6 +1043,7 @@ resetPasswordConfirm: "パスワード作り直すんでええな?" sensitiveWords: "けったいな単語" sensitiveWordsDescription: "設定した単語が入っとるノートの公開範囲をホームにしたるわ。改行で区切ったら複数設定できるで。" sensitiveWordsDescription2: "スペースで区切るとAND指定、キーワードをスラッシュで囲んだら正規表現や。" +prohibitedWordsDescription2: "スペースで区切るとAND指定、キーワードをスラッシュで囲んだら正規表現や。" hiddenTags: "見えてへんハッシュタグ" hiddenTagsDescription: "設定したタグを最近流行りのとこに見えんようにすんで。複数設定するときは改行で区切ってな。" notesSearchNotAvailable: "なんかノート探せへん。" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 2a59ab9a23..1231209b36 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "비밀번호를 재설정하시겠습니까?" sensitiveWords: "민감한 단어" sensitiveWordsDescription: "설정한 단어가 포함된 노트의 공개 범위를 '홈'으로 강제합니다. 개행으로 구분하여 여러 개를 지정할 수 있습니다." sensitiveWordsDescription2: "공백으로 구분하면 AND 지정이 되며, 키워드를 슬래시로 둘러싸면 정규 표현식이 됩니다." +prohibitedWordsDescription2: "공백으로 구분하면 AND 지정이 되며, 키워드를 슬래시로 둘러싸면 정규 표현식이 됩니다." hiddenTags: "숨긴 해시태그" hiddenTagsDescription: "설정한 태그를 트렌드에 표시하지 않도록 합니다. 줄 바꿈으로 하나씩 나눠서 설정할 수 있습니다." notesSearchNotAvailable: "노트 검색을 이용하실 수 없습니다." diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 60682fe961..d014b7fc25 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -1015,6 +1015,7 @@ resetPasswordConfirm: "Сбросить пароль?" sensitiveWords: "Чувствительные слова" sensitiveWordsDescription: "Установите общедоступный диапазон заметки, содержащей заданное слово, на домашний. Можно сделать несколько настроек, разделив их переносами строк." sensitiveWordsDescription2: "Разделение пробелом создаёт спецификацию AND, а разделение косой чертой создаёт регулярное выражение." +prohibitedWordsDescription2: "Разделение пробелом создаёт спецификацию AND, а разделение косой чертой создаёт регулярное выражение." notesSearchNotAvailable: "Поиск заметок недоступен" license: "Лицензия" unfavoriteConfirm: "Удалить избранное?" diff --git a/locales/th-TH.yml b/locales/th-TH.yml index b14d855566..cfba65685b 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "รีเซ็ตรหัสผ่านของคุ sensitiveWords: "คำที่มีเนื้อหาละเอียดอ่อน" sensitiveWordsDescription: "การเปิดเผยโน้ตทั้งหมดที่มีคำที่กำหนดค่าไว้จะถูกตั้งค่าเป็น \"หน้าแรก\" โดยอัตโนมัติ คุณยังสามารถแสดงหลายรายการได้โดยแยกรายการโดยใช้ตัวแบ่งบรรทัดได้นะ" sensitiveWordsDescription2: "การใช้ช่องว่างนั้นอาจจะสร้างนิพจน์ AND และคำหลักที่มีเครื่องหมายทับล้อมรอบจะเปลี่ยนเป็นนิพจน์ทั่วไปนะ" +prohibitedWordsDescription2: "การใช้ช่องว่างนั้นอาจจะสร้างนิพจน์ AND และคำหลักที่มีเครื่องหมายทับล้อมรอบจะเปลี่ยนเป็นนิพจน์ทั่วไปนะ" hiddenTags: "แฮชแท็กที่ซ่อนอยู่" hiddenTagsDescription: "เลือกแท็กที่จะไม่แสดงในรายการเทรนด์ สามารถลงทะเบียนหลายแท็กได้โดยขึ้นบรรทัดใหม่" notesSearchNotAvailable: "การค้นหาโน้ตไม่พร้อมใช้งาน" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 09c210011c..4a36e30db8 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "确定重置密码?" sensitiveWords: "敏感词" sensitiveWordsDescription: "将包含设置词的帖子的可见范围设置为首页。可以通过用换行符分隔来设置多个。" sensitiveWordsDescription2: "AND 条件用空格分隔,正则表达式用斜线包裹。" +prohibitedWordsDescription2: "AND 条件用空格分隔,正则表达式用斜线包裹。" hiddenTags: "隐藏标签" hiddenTagsDescription: "设定的标签将不会在时间线上显示。可使用换行来设置多个标签。" notesSearchNotAvailable: "帖子检索不可用" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 872a90bc6a..ed2bd1cf3a 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "重設密碼?" sensitiveWords: "敏感詞" sensitiveWordsDescription: "將含有設定詞彙的貼文可見性設為發送至首頁。可以用換行來進行複數的設定。" sensitiveWordsDescription2: "空格代表「以及」(AND),斜線包圍關鍵字代表使用正規表達式。" +prohibitedWordsDescription2: "空格代表「以及」(AND),斜線包圍關鍵字代表使用正規表達式。" hiddenTags: "隱藏標籤" hiddenTagsDescription: "設定的標籤不會在趨勢中顯示,換行可以設定多個標籤。" notesSearchNotAvailable: "無法使用搜尋貼文功能。" diff --git a/package.json b/package.json index 171adc0da3..fdd23f02c6 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "sharkey", - "version": "2024.2.0-beta.10", + "version": "2024.2.0-beta.11", "codename": "shonk", "repository": { "type": "git", "url": "https://git.joinsharkey.org/Sharkey/Sharkey.git" }, - "packageManager": "pnpm@8.12.1", + "packageManager": "pnpm@8.15.1", "workspaces": [ "packages/frontend", "packages/backend", diff --git a/packages/backend/migration/1707429690000-prohibited-words.js b/packages/backend/migration/1707429690000-prohibited-words.js new file mode 100644 index 0000000000..2dd62d8ff8 --- /dev/null +++ b/packages/backend/migration/1707429690000-prohibited-words.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class prohibitedWords1707429690000 { + name = 'prohibitedWords1707429690000' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "prohibitedWords" character varying(1024) array NOT NULL DEFAULT '{}'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "prohibitedWords"`); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 296eddfe3c..e5c70d1209 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -84,7 +84,7 @@ "@nestjs/testing": "10.2.10", "@peertube/http-signature": "1.7.0", "@transfem-org/sfm-js": "0.24.4", - "@simplewebauthn/server": "9.0.1", + "@simplewebauthn/server": "9.0.2", "@sinonjs/fake-timers": "11.2.2", "@smithy/node-http-handler": "2.1.10", "@swc/cli": "0.1.63", @@ -98,12 +98,12 @@ "bcryptjs": "2.4.3", "blurhash": "2.0.5", "body-parser": "1.20.2", - "bullmq": "5.1.5", + "bullmq": "5.1.9", "cacheable-lookup": "7.0.0", - "cbor": "9.0.1", + "cbor": "9.0.2", "chalk": "5.3.0", "chalk-template": "1.1.0", - "chokidar": "3.5.3", + "chokidar": "3.6.0", "cli-highlight": "2.1.11", "color-convert": "2.0.1", "content-disposition": "0.5.4", @@ -205,7 +205,7 @@ "@types/jsrsasign": "10.5.12", "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", - "@types/node": "20.11.10", + "@types/node": "20.11.17", "@types/node-fetch": "3.0.3", "@types/nodemailer": "6.4.14", "@types/oauth": "0.9.4", diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 5a1fe3d089..1de71212e9 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -408,7 +408,7 @@ export class CustomEmojiService implements OnApplicationShutdown { */ @bindThis public checkDuplicate(name: string): Promise<boolean> { - return this.emojisRepository.exist({ where: { name, host: IsNull() } }); + return this.emojisRepository.exists({ where: { name, host: IsNull() } }); } @bindThis diff --git a/packages/backend/src/core/HashtagService.ts b/packages/backend/src/core/HashtagService.ts index 5a2417c9cd..712530108e 100644 --- a/packages/backend/src/core/HashtagService.ts +++ b/packages/backend/src/core/HashtagService.ts @@ -163,7 +163,7 @@ export class HashtagService { const instance = await this.metaService.fetch(); const hiddenTags = instance.hiddenTags.map(t => normalizeForSearch(t)); if (hiddenTags.includes(hashtag)) return; - if (this.utilityService.isSensitiveWordIncluded(hashtag, instance.sensitiveWords)) return; + if (this.utilityService.isKeyWordIncluded(hashtag, instance.sensitiveWords)) return; // YYYYMMDDHHmm (10分間隔) const now = new Date(); diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 2848be9fe1..34f3736446 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -153,6 +153,8 @@ type Option = { export class NoteCreateService implements OnApplicationShutdown { #shutdownController = new AbortController(); + public static ContainsProhibitedWordsError = class extends Error {}; + constructor( @Inject(DI.config) private config: Config, @@ -429,13 +431,19 @@ export class NoteCreateService implements OnApplicationShutdown { if (data.visibility === 'public' && data.channel == null) { const sensitiveWords = meta.sensitiveWords; - if (this.utilityService.isSensitiveWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { + if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { data.visibility = 'home'; } else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) { data.visibility = 'home'; } } + if (!user.host) { + if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', meta.prohibitedWords)) { + throw new NoteCreateService.ContainsProhibitedWordsError(); + } + } + const inSilencedInstance = this.utilityService.isSilencedHost(meta.silencedHosts, user.host); if (data.visibility === 'public' && inSilencedInstance && user.host !== null) { @@ -795,7 +803,7 @@ export class NoteCreateService implements OnApplicationShutdown { }); // 通知 if (data.reply.userHost === null) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: data.reply.userId, threadId: data.reply.threadId ?? data.reply.id, @@ -830,7 +838,7 @@ export class NoteCreateService implements OnApplicationShutdown { // Notify if (data.renote.userHost === null) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: data.renote.userId, threadId: data.renote.threadId ?? data.renote.id, @@ -1057,7 +1065,7 @@ export class NoteCreateService implements OnApplicationShutdown { @bindThis private async createMentionedEvents(mentionedUsers: MinimumUser[], note: MiNote, nm: NotificationManager) { for (const u of mentionedUsers.filter(u => this.userEntityService.isLocalUser(u))) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: u.id, threadId: note.threadId ?? note.id, diff --git a/packages/backend/src/core/NoteEditService.ts b/packages/backend/src/core/NoteEditService.ts index 98762f790e..a6f7edb05c 100644 --- a/packages/backend/src/core/NoteEditService.ts +++ b/packages/backend/src/core/NoteEditService.ts @@ -612,7 +612,7 @@ export class NoteEditService implements OnApplicationShutdown { if (data.reply) { // 通知 if (data.reply.userHost === null) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: data.reply.userId, threadId: data.reply.threadId ?? data.reply.id, @@ -647,7 +647,7 @@ export class NoteEditService implements OnApplicationShutdown { // Notify if (data.renote.userHost === null) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: data.renote.userId, threadId: data.renote.threadId ?? data.renote.id, @@ -751,7 +751,7 @@ export class NoteEditService implements OnApplicationShutdown { @bindThis private async createMentionedEvents(mentionedUsers: MinimumUser[], note: MiNote, nm: NotificationManager) { for (const u of mentionedUsers.filter(u => this.userEntityService.isLocalUser(u))) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: u.id, threadId: note.threadId ?? note.id, diff --git a/packages/backend/src/core/NoteReadService.ts b/packages/backend/src/core/NoteReadService.ts index c73cf76592..11791a4412 100644 --- a/packages/backend/src/core/NoteReadService.ts +++ b/packages/backend/src/core/NoteReadService.ts @@ -49,7 +49,7 @@ export class NoteReadService implements OnApplicationShutdown { //#endregion // スレッドミュート - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: userId, threadId: note.threadId ?? note.id, @@ -70,7 +70,7 @@ export class NoteReadService implements OnApplicationShutdown { // 2秒経っても既読にならなかったら「未読の投稿がありますよ」イベントを発行する setTimeout(2000, 'unread note', { signal: this.#shutdownController.signal }).then(async () => { - const exist = await this.noteUnreadsRepository.exist({ where: { id: unread.id } }); + const exist = await this.noteUnreadsRepository.exists({ where: { id: unread.id } }); if (!exist) return; diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts index 11c972982e..6cce4a61ea 100644 --- a/packages/backend/src/core/ReactionService.ts +++ b/packages/backend/src/core/ReactionService.ts @@ -248,7 +248,7 @@ export class ReactionService { // リアクションされたユーザーがローカルユーザーなら通知を作成 if (note.userHost === null) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: note.userId, threadId: note.threadId ?? note.id, diff --git a/packages/backend/src/core/SignupService.ts b/packages/backend/src/core/SignupService.ts index 6b8c64488f..5941944a20 100644 --- a/packages/backend/src/core/SignupService.ts +++ b/packages/backend/src/core/SignupService.ts @@ -77,12 +77,12 @@ export class SignupService { const secret = generateUserToken(); // Check username duplication - if (await this.usersRepository.exist({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { + if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { throw new Error('DUPLICATED_USERNAME'); } // Check deleted username duplication - if (await this.usedUsernamesRepository.exist({ where: { username: username.toLowerCase() } })) { + if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) { throw new Error('USED_USERNAME'); } diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 93e9fbbd70..e82a7e06f9 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -144,7 +144,7 @@ export class UserFollowingService implements OnModuleInit { let autoAccept = false; // 鍵アカウントであっても、既にフォローされていた場合はスルー - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: followee.id, @@ -156,7 +156,7 @@ export class UserFollowingService implements OnModuleInit { // フォローしているユーザーは自動承認オプション if (!autoAccept && (this.userEntityService.isLocalUser(followee) && followeeProfile.autoAcceptFollowed)) { - const isFollowed = await this.followingsRepository.exist({ + const isFollowed = await this.followingsRepository.exists({ where: { followerId: followee.id, followeeId: follower.id, @@ -170,7 +170,7 @@ export class UserFollowingService implements OnModuleInit { if (followee.isLocked && !autoAccept) { autoAccept = !!(await this.accountMoveService.validateAlsoKnownAs( follower, - (oldSrc, newSrc) => this.followingsRepository.exist({ + (oldSrc, newSrc) => this.followingsRepository.exists({ where: { followeeId: followee.id, followerId: newSrc.id, @@ -233,7 +233,7 @@ export class UserFollowingService implements OnModuleInit { this.cacheService.userFollowingsCache.refresh(follower.id); - const requestExist = await this.followRequestsRepository.exist({ + const requestExist = await this.followRequestsRepository.exists({ where: { followeeId: followee.id, followerId: follower.id, @@ -531,7 +531,7 @@ export class UserFollowingService implements OnModuleInit { } } - const requestExist = await this.followRequestsRepository.exist({ + const requestExist = await this.followRequestsRepository.exists({ where: { followeeId: followee.id, followerId: follower.id, diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts index 5dec36c89e..15b98abe63 100644 --- a/packages/backend/src/core/UtilityService.ts +++ b/packages/backend/src/core/UtilityService.ts @@ -43,13 +43,13 @@ export class UtilityService { } @bindThis - public isSensitiveWordIncluded(text: string, sensitiveWords: string[]): boolean { - if (sensitiveWords.length === 0) return false; + public isKeyWordIncluded(text: string, keyWords: string[]): boolean { + if (keyWords.length === 0) return false; if (text === '') return false; const regexpregexp = /^\/(.+)\/(.*)$/; - const matched = sensitiveWords.some(filter => { + const matched = keyWords.some(filter => { // represents RegExp const regexp = filter.match(regexpregexp); // This should never happen due to input sanitisation. diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 3f01c0289a..acbe59b8bd 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -629,7 +629,7 @@ export class ApInboxService { return 'skip: follower not found'; } - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: actor.id, @@ -686,14 +686,14 @@ export class ApInboxService { return 'skip: フォロー解除しようとしているユーザーはローカルユーザーではありません'; } - const requestExist = await this.followRequestsRepository.exist({ + const requestExist = await this.followRequestsRepository.exists({ where: { followerId: actor.id, followeeId: followee.id, }, }); - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followerId: actor.id, followeeId: followee.id, diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index be3ebbaf96..e07bb8be78 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -345,7 +345,7 @@ export class ApRendererService { inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId }); if (inReplyToNote != null) { - const inReplyToUserExist = await this.usersRepository.exist({ where: { id: inReplyToNote.userId } }); + const inReplyToUserExist = await this.usersRepository.exists({ where: { id: inReplyToNote.userId } }); if (inReplyToUserExist) { if (inReplyToNote.uri) { @@ -636,7 +636,7 @@ export class ApRendererService { inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId }); if (inReplyToNote != null) { - const inReplyToUserExist = await this.usersRepository.exist({ where: { id: inReplyToNote.userId } }); + const inReplyToUserExist = await this.usersRepository.exists({ where: { id: inReplyToNote.userId } }); if (inReplyToUserExist) { if (inReplyToNote.uri) { diff --git a/packages/backend/src/core/entities/ChannelEntityService.ts b/packages/backend/src/core/entities/ChannelEntityService.ts index 305946b8a6..f358875f72 100644 --- a/packages/backend/src/core/entities/ChannelEntityService.ts +++ b/packages/backend/src/core/entities/ChannelEntityService.ts @@ -51,14 +51,14 @@ export class ChannelEntityService { const banner = channel.bannerId ? await this.driveFilesRepository.findOneBy({ id: channel.bannerId }) : null; - const isFollowing = meId ? await this.channelFollowingsRepository.exist({ + const isFollowing = meId ? await this.channelFollowingsRepository.exists({ where: { followerId: meId, followeeId: channel.id, }, }) : false; - const isFavorited = meId ? await this.channelFavoritesRepository.exist({ + const isFavorited = meId ? await this.channelFavoritesRepository.exists({ where: { userId: meId, channelId: channel.id, diff --git a/packages/backend/src/core/entities/ClipEntityService.ts b/packages/backend/src/core/entities/ClipEntityService.ts index 96422894fd..2133f80f1a 100644 --- a/packages/backend/src/core/entities/ClipEntityService.ts +++ b/packages/backend/src/core/entities/ClipEntityService.ts @@ -46,7 +46,7 @@ export class ClipEntityService { description: clip.description, isPublic: clip.isPublic, favoritedCount: await this.clipFavoritesRepository.countBy({ clipId: clip.id }), - isFavorited: meId ? await this.clipFavoritesRepository.exist({ where: { clipId: clip.id, userId: meId } }) : undefined, + isFavorited: meId ? await this.clipFavoritesRepository.exists({ where: { clipId: clip.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/FlashEntityService.ts b/packages/backend/src/core/entities/FlashEntityService.ts index 70faa2b380..c1b9f9a791 100644 --- a/packages/backend/src/core/entities/FlashEntityService.ts +++ b/packages/backend/src/core/entities/FlashEntityService.ts @@ -47,7 +47,7 @@ export class FlashEntityService { summary: flash.summary, script: flash.script, likedCount: flash.likedCount, - isLiked: meId ? await this.flashLikesRepository.exist({ where: { flashId: flash.id, userId: meId } }) : undefined, + isLiked: meId ? await this.flashLikesRepository.exists({ where: { flashId: flash.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/GalleryPostEntityService.ts b/packages/backend/src/core/entities/GalleryPostEntityService.ts index d7b960e0d9..2a615a9216 100644 --- a/packages/backend/src/core/entities/GalleryPostEntityService.ts +++ b/packages/backend/src/core/entities/GalleryPostEntityService.ts @@ -53,7 +53,7 @@ export class GalleryPostEntityService { tags: post.tags.length > 0 ? post.tags : undefined, isSensitive: post.isSensitive, likedCount: post.likedCount, - isLiked: meId ? await this.galleryLikesRepository.exist({ where: { postId: post.id, userId: meId } }) : undefined, + isLiked: meId ? await this.galleryLikesRepository.exists({ where: { postId: post.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index 1cbd5cb70c..a59de4985c 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -114,7 +114,7 @@ export class NoteEntityService implements OnModuleInit { hide = false; } else { if (packedNote.renote) { - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followeeId: packedNote.renote.userId, followerId: meId, @@ -124,7 +124,7 @@ export class NoteEntityService implements OnModuleInit { hide = !isFollowing; } else { // フォロワーかどうか - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followeeId: packedNote.userId, followerId: meId, diff --git a/packages/backend/src/core/entities/PageEntityService.ts b/packages/backend/src/core/entities/PageEntityService.ts index bc26362aba..27c9011f6d 100644 --- a/packages/backend/src/core/entities/PageEntityService.ts +++ b/packages/backend/src/core/entities/PageEntityService.ts @@ -104,7 +104,7 @@ export class PageEntityService { eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId) : null, attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter((x): x is MiDriveFile => x != null)), likedCount: page.likedCount, - isLiked: meId ? await this.pageLikesRepository.exist({ where: { pageId: page.id, userId: meId } }) : undefined, + isLiked: meId ? await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 6c1a02d9d8..d24d97ed17 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -153,43 +153,43 @@ export class UserEntityService implements OnModuleInit { followerId: me, followeeId: target, }), - this.followingsRepository.exist({ + this.followingsRepository.exists({ where: { followerId: target, followeeId: me, }, }), - this.followRequestsRepository.exist({ + this.followRequestsRepository.exists({ where: { followerId: me, followeeId: target, }, }), - this.followRequestsRepository.exist({ + this.followRequestsRepository.exists({ where: { followerId: target, followeeId: me, }, }), - this.blockingsRepository.exist({ + this.blockingsRepository.exists({ where: { blockerId: me, blockeeId: target, }, }), - this.blockingsRepository.exist({ + this.blockingsRepository.exists({ where: { blockerId: target, blockeeId: me, }, }), - this.mutingsRepository.exist({ + this.mutingsRepository.exists({ where: { muterId: me, muteeId: target, }, }), - this.renoteMutingsRepository.exist({ + this.renoteMutingsRepository.exists({ where: { muterId: me, muteeId: target, @@ -216,7 +216,7 @@ export class UserEntityService implements OnModuleInit { /* const myAntennas = (await this.antennaService.getAntennas()).filter(a => a.userId === userId); - const isUnread = (myAntennas.length > 0 ? await this.antennaNotesRepository.exist({ + const isUnread = (myAntennas.length > 0 ? await this.antennaNotesRepository.exists({ where: { antennaId: In(myAntennas.map(x => x.id)), read: false, diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts index 9629012c74..149955aa5a 100644 --- a/packages/backend/src/models/Meta.ts +++ b/packages/backend/src/models/Meta.ts @@ -79,6 +79,11 @@ export class MiMeta { @Column('varchar', { length: 1024, array: true, default: '{}', }) + public prohibitedWords: string[]; + + @Column('varchar', { + length: 1024, array: true, default: '{}', + }) public silencedHosts: string[]; @Column('varchar', { diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index d2e6185aa3..584853c1f3 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -176,12 +176,12 @@ export class SignupApiService { } if (instance.emailRequiredForSignup) { - if (await this.usersRepository.exist({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { + if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { throw new FastifyReplyError(400, 'DUPLICATED_USERNAME'); } // Check deleted username duplication - if (await this.usedUsernamesRepository.exist({ where: { username: username.toLowerCase() } })) { + if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) { throw new FastifyReplyError(400, 'USED_USERNAME'); } diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index c6edd6c9a1..6201d1554d 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -160,6 +160,13 @@ export const meta = { type: 'string', }, }, + prohibitedWords: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'string', + }, + }, bannedEmailDomains: { type: 'array', optional: true, nullable: false, @@ -549,6 +556,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- blockedHosts: instance.blockedHosts, silencedHosts: instance.silencedHosts, sensitiveWords: instance.sensitiveWords, + prohibitedWords: instance.prohibitedWords, preservedUsernames: instance.preservedUsernames, bubbleInstances: instance.bubbleInstances, hcaptchaSecretKey: instance.hcaptchaSecretKey, diff --git a/packages/backend/src/server/api/endpoints/admin/promo/create.ts b/packages/backend/src/server/api/endpoints/admin/promo/create.ts index ab69dfba96..339b7a8aa4 100644 --- a/packages/backend/src/server/api/endpoints/admin/promo/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/promo/create.ts @@ -55,7 +55,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- throw e; }); - const exist = await this.promoNotesRepository.exist({ where: { noteId: note.id } }); + const exist = await this.promoNotesRepository.exists({ where: { noteId: note.id } }); if (exist) { throw new ApiError(meta.errors.alreadyPromoted); diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index 8c0d2f8876..dce0253271 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -41,6 +41,11 @@ export const paramDef = { type: 'string', }, }, + prohibitedWords: { + type: 'array', nullable: true, items: { + type: 'string', + }, + }, themeColor: { type: 'string', nullable: true, pattern: '^#[0-9a-fA-F]{6}$' }, mascotImageUrl: { type: 'string', nullable: true }, bannerUrl: { type: 'string', nullable: true }, @@ -185,6 +190,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (Array.isArray(ps.sensitiveWords)) { set.sensitiveWords = ps.sensitiveWords.filter(Boolean); } + if (Array.isArray(ps.prohibitedWords)) { + set.prohibitedWords = ps.prohibitedWords.filter(Boolean); + } if (Array.isArray(ps.silencedHosts)) { let lastValue = ''; set.silencedHosts = ps.silencedHosts.sort().filter((h) => { diff --git a/packages/backend/src/server/api/endpoints/auth/accept.ts b/packages/backend/src/server/api/endpoints/auth/accept.ts index e0baeb3565..602c34b1e6 100644 --- a/packages/backend/src/server/api/endpoints/auth/accept.ts +++ b/packages/backend/src/server/api/endpoints/auth/accept.ts @@ -62,7 +62,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const accessToken = secureRndstr(32); // Fetch exist access token - const exist = await this.accessTokensRepository.exist({ + const exist = await this.accessTokensRepository.exists({ where: { appId: session.appId, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/blocking/create.ts b/packages/backend/src/server/api/endpoints/blocking/create.ts index 1dc4563180..ea7d2076b0 100644 --- a/packages/backend/src/server/api/endpoints/blocking/create.ts +++ b/packages/backend/src/server/api/endpoints/blocking/create.ts @@ -88,7 +88,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check if already blocking - const exist = await this.blockingsRepository.exist({ + const exist = await this.blockingsRepository.exists({ where: { blockerId: blocker.id, blockeeId: blockee.id, diff --git a/packages/backend/src/server/api/endpoints/blocking/delete.ts b/packages/backend/src/server/api/endpoints/blocking/delete.ts index a6e6bcb5b3..b0d66fd05c 100644 --- a/packages/backend/src/server/api/endpoints/blocking/delete.ts +++ b/packages/backend/src/server/api/endpoints/blocking/delete.ts @@ -88,7 +88,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check not blocking - const exist = await this.blockingsRepository.exist({ + const exist = await this.blockingsRepository.exists({ where: { blockerId: blocker.id, blockeeId: blockee.id, diff --git a/packages/backend/src/server/api/endpoints/clips/favorite.ts b/packages/backend/src/server/api/endpoints/clips/favorite.ts index 015b2cfa85..b4c6a4940b 100644 --- a/packages/backend/src/server/api/endpoints/clips/favorite.ts +++ b/packages/backend/src/server/api/endpoints/clips/favorite.ts @@ -62,7 +62,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- throw new ApiError(meta.errors.noSuchClip); } - const exist = await this.clipFavoritesRepository.exist({ + const exist = await this.clipFavoritesRepository.exists({ where: { clipId: clip.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts index 85e6312b6a..8c1f491f8d 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts @@ -38,7 +38,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- private driveFilesRepository: DriveFilesRepository, ) { super(meta, paramDef, async (ps, me) => { - const exist = await this.driveFilesRepository.exist({ + const exist = await this.driveFilesRepository.exists({ where: { md5: ps.md5, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/flash/like.ts b/packages/backend/src/server/api/endpoints/flash/like.ts index 1003249c0c..5878200828 100644 --- a/packages/backend/src/server/api/endpoints/flash/like.ts +++ b/packages/backend/src/server/api/endpoints/flash/like.ts @@ -70,7 +70,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // if already liked - const exist = await this.flashLikesRepository.exist({ + const exist = await this.flashLikesRepository.exists({ where: { flashId: flash.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts index 9037944ef9..1d0691407d 100644 --- a/packages/backend/src/server/api/endpoints/following/create.ts +++ b/packages/backend/src/server/api/endpoints/following/create.ts @@ -101,7 +101,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check if already following - const exist = await this.followingsRepository.exist({ + const exist = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: followee.id, diff --git a/packages/backend/src/server/api/endpoints/following/delete.ts b/packages/backend/src/server/api/endpoints/following/delete.ts index f44692ba6d..f761968c90 100644 --- a/packages/backend/src/server/api/endpoints/following/delete.ts +++ b/packages/backend/src/server/api/endpoints/following/delete.ts @@ -85,7 +85,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check not following - const exist = await this.followingsRepository.exist({ + const exist = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: followee.id, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts index cc424261b4..576cff4e91 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts @@ -72,7 +72,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // if already liked - const exist = await this.galleryLikesRepository.exist({ + const exist = await this.galleryLikesRepository.exists({ where: { postId: post.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/i/import-antennas.ts b/packages/backend/src/server/api/endpoints/i/import-antennas.ts index 71db8710af..771f3395ce 100644 --- a/packages/backend/src/server/api/endpoints/i/import-antennas.ts +++ b/packages/backend/src/server/api/endpoints/i/import-antennas.ts @@ -71,7 +71,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { private downloadService: DownloadService, ) { super(meta, paramDef, async (ps, me) => { - const userExist = await this.usersRepository.exist({ where: { id: me.id } }); + const userExist = await this.usersRepository.exists({ where: { id: me.id } }); if (!userExist) throw new ApiError(meta.errors.noSuchUser); const file = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); if (file === null) throw new ApiError(meta.errors.noSuchFile); diff --git a/packages/backend/src/server/api/endpoints/i/revoke-token.ts b/packages/backend/src/server/api/endpoints/i/revoke-token.ts index 98d866f867..545d16082c 100644 --- a/packages/backend/src/server/api/endpoints/i/revoke-token.ts +++ b/packages/backend/src/server/api/endpoints/i/revoke-token.ts @@ -34,7 +34,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- ) { super(meta, paramDef, async (ps, me) => { if (ps.tokenId) { - const tokenExist = await this.accessTokensRepository.exist({ where: { id: ps.tokenId } }); + const tokenExist = await this.accessTokensRepository.exists({ where: { id: ps.tokenId } }); if (tokenExist) { await this.accessTokensRepository.delete({ @@ -43,7 +43,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); } } else if (ps.token) { - const tokenExist = await this.accessTokensRepository.exist({ where: { token: ps.token } }); + const tokenExist = await this.accessTokensRepository.exists({ where: { token: ps.token } }); if (tokenExist) { await this.accessTokensRepository.delete({ diff --git a/packages/backend/src/server/api/endpoints/mute/create.ts b/packages/backend/src/server/api/endpoints/mute/create.ts index 49c2b5707d..1d931150e1 100644 --- a/packages/backend/src/server/api/endpoints/mute/create.ts +++ b/packages/backend/src/server/api/endpoints/mute/create.ts @@ -83,7 +83,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check if already muting - const exist = await this.mutingsRepository.exist({ + const exist = await this.mutingsRepository.exists({ where: { muterId: muter.id, muteeId: mutee.id, diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 44ca1b9c16..dbcea2932e 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -17,6 +17,8 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteCreateService } from '@/core/NoteCreateService.js'; import { DI } from '@/di-symbols.js'; import { isPureRenote } from '@/misc/is-pure-renote.js'; +import { MetaService } from '@/core/MetaService.js'; +import { UtilityService } from '@/core/UtilityService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -117,6 +119,12 @@ export const meta = { code: 'CANNOT_RENOTE_OUTSIDE_OF_CHANNEL', id: '33510210-8452-094c-6227-4a6c05d99f00', }, + + containsProhibitedWords: { + message: 'Cannot post because it contains prohibited words.', + code: 'CONTAINS_PROHIBITED_WORDS', + id: 'aa6e01d3-a85c-669d-758a-76aab43af334', + }, }, } as const; @@ -271,7 +279,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (renote.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: renote.userId, blockeeId: me.id, @@ -319,7 +327,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (reply.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: reply.userId, blockeeId: me.id, @@ -351,31 +359,40 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // 投稿を作成 - const note = await this.noteCreateService.create(me, { - createdAt: new Date(), - files: files, - poll: ps.poll ? { - choices: ps.poll.choices, - multiple: ps.poll.multiple ?? false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, - } : undefined, - text: ps.text ?? undefined, - reply, - renote, - cw: ps.cw, - localOnly: ps.localOnly, - reactionAcceptance: ps.reactionAcceptance, - visibility: ps.visibility, - visibleUsers, - channel, - apMentions: ps.noExtractMentions ? [] : undefined, - apHashtags: ps.noExtractHashtags ? [] : undefined, - apEmojis: ps.noExtractEmojis ? [] : undefined, - }); + try { + const note = await this.noteCreateService.create(me, { + createdAt: new Date(), + files: files, + poll: ps.poll ? { + choices: ps.poll.choices, + multiple: ps.poll.multiple ?? false, + expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, + } : undefined, + text: ps.text ?? undefined, + reply, + renote, + cw: ps.cw, + localOnly: ps.localOnly, + reactionAcceptance: ps.reactionAcceptance, + visibility: ps.visibility, + visibleUsers, + channel, + apMentions: ps.noExtractMentions ? [] : undefined, + apHashtags: ps.noExtractHashtags ? [] : undefined, + apEmojis: ps.noExtractEmojis ? [] : undefined, + }); - return { - createdNote: await this.noteEntityService.pack(note, me), - }; + return { + createdNote: await this.noteEntityService.pack(note, me), + }; + } catch (e) { + // TODO: 他のErrorもここでキャッチしてエラーメッセージを当てるようにしたい + if (e instanceof NoteCreateService.ContainsProhibitedWordsError) { + throw new ApiError(meta.errors.containsProhibitedWords); + } + + throw e; + } }); } } diff --git a/packages/backend/src/server/api/endpoints/notes/edit.ts b/packages/backend/src/server/api/endpoints/notes/edit.ts index 0c9c0d3baf..44796d9290 100644 --- a/packages/backend/src/server/api/endpoints/notes/edit.ts +++ b/packages/backend/src/server/api/endpoints/notes/edit.ts @@ -311,7 +311,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (renote.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: renote.userId, blockeeId: me.id, @@ -349,7 +349,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (reply.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: reply.userId, blockeeId: me.id, diff --git a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts index ed3dce7f35..bfa621aa38 100644 --- a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts @@ -67,7 +67,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // if already favorited - const exist = await this.noteFavoritesRepository.exist({ + const exist = await this.noteFavoritesRepository.exists({ where: { noteId: note.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/pages/like.ts b/packages/backend/src/server/api/endpoints/pages/like.ts index 8c18982b50..bee60f080d 100644 --- a/packages/backend/src/server/api/endpoints/pages/like.ts +++ b/packages/backend/src/server/api/endpoints/pages/like.ts @@ -70,7 +70,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // if already liked - const exist = await this.pageLikesRepository.exist({ + const exist = await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/promo/read.ts b/packages/backend/src/server/api/endpoints/promo/read.ts index f427939a7a..4899408ddd 100644 --- a/packages/backend/src/server/api/endpoints/promo/read.ts +++ b/packages/backend/src/server/api/endpoints/promo/read.ts @@ -49,7 +49,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- throw err; }); - const exist = await this.promoReadsRepository.exist({ + const exist = await this.promoReadsRepository.exists({ where: { noteId: note.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts index 5706e46b96..314a45ed61 100644 --- a/packages/backend/src/server/api/endpoints/users/followers.ts +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -101,7 +101,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (me == null) { throw new ApiError(meta.errors.forbidden); } else if (me.id !== user.id) { - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followeeId: user.id, followerId: me.id, diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts index 794fb04f10..86f55c5a12 100644 --- a/packages/backend/src/server/api/endpoints/users/following.ts +++ b/packages/backend/src/server/api/endpoints/users/following.ts @@ -109,7 +109,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (me == null) { throw new ApiError(meta.errors.forbidden); } else if (me.id !== user.id) { - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followeeId: user.id, followerId: me.id, diff --git a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts index fa2e3338b8..dd9b459a1f 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts @@ -90,7 +90,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { - const listExist = await this.userListsRepository.exist({ + const listExist = await this.userListsRepository.exists({ where: { id: ps.listId, isPublic: true, @@ -121,7 +121,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); if (currentUser.id !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: currentUser.id, blockeeId: me.id, @@ -132,7 +132,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } } - const exist = await this.userListMembershipsRepository.exist({ + const exist = await this.userListMembershipsRepository.exists({ where: { userListId: userList.id, userId: currentUser.id, diff --git a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts index 864cdc2ee0..e5b3a73b55 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts @@ -47,7 +47,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { - const userListExist = await this.userListsRepository.exist({ + const userListExist = await this.userListsRepository.exists({ where: { id: ps.listId, isPublic: true, @@ -58,7 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { throw new ApiError(meta.errors.noSuchList); } - const exist = await this.userListFavoritesRepository.exist({ + const exist = await this.userListFavoritesRepository.exists({ where: { userId: me.id, userListId: ps.listId, diff --git a/packages/backend/src/server/api/endpoints/users/lists/push.ts b/packages/backend/src/server/api/endpoints/users/lists/push.ts index c4ceec575b..0984270943 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/push.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/push.ts @@ -104,7 +104,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (user.id !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: user.id, blockeeId: me.id, @@ -115,7 +115,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } } - const exist = await this.userListMembershipsRepository.exist({ + const exist = await this.userListMembershipsRepository.exists({ where: { userListId: userList.id, userId: user.id, diff --git a/packages/backend/src/server/api/endpoints/users/lists/show.ts b/packages/backend/src/server/api/endpoints/users/lists/show.ts index df44870b04..10efbaafd8 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/show.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/show.ts @@ -74,7 +74,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { userListId: ps.listId, }); if (me !== null) { - additionalProperties.isLiked = await this.userListFavoritesRepository.exist({ + additionalProperties.isLiked = await this.userListFavoritesRepository.exists({ where: { userId: me.id, userListId: ps.listId, diff --git a/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts b/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts index d51d57343e..0935584cbc 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts @@ -45,7 +45,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { private userListFavoritesRepository: UserListFavoritesRepository, ) { super(meta, paramDef, async (ps, me) => { - const userListExist = await this.userListsRepository.exist({ + const userListExist = await this.userListsRepository.exists({ where: { id: ps.listId, isPublic: true, diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index e0245814c4..0434833df8 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -43,7 +43,7 @@ class UserListChannel extends Channel { this.withRenotes = params.withRenotes ?? true; // Check existence and owner - const listExist = await this.userListsRepository.exist({ + const listExist = await this.userListsRepository.exists({ where: { id: this.listId, userId: this.user!.id, diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index 0280b051f5..1bc8cb591c 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -16,12 +16,14 @@ describe('Note', () => { let alice: misskey.entities.SignupResponse; let bob: misskey.entities.SignupResponse; + let tom: misskey.entities.SignupResponse; beforeAll(async () => { const connection = await initTestDb(true); Notes = connection.getRepository(MiNote); alice = await signup({ username: 'alice' }); bob = await signup({ username: 'bob' }); + tom = await signup({ username: 'tom', host: 'example.com' }); }, 1000 * 60 * 2); test('投稿できる', async () => { @@ -607,6 +609,77 @@ describe('Note', () => { assert.strictEqual(note2.status, 200); assert.strictEqual(note2.body.createdNote.visibility, 'home'); }); + + test('禁止ワードを含む投稿はエラーになる (単語指定)', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + 'test', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + await new Promise(x => setTimeout(x, 2)); + + const note1 = await api('/notes/create', { + text: 'hogetesthuge', + }, alice); + + assert.strictEqual(note1.status, 400); + assert.strictEqual(note1.body.error.code, 'CONTAINS_PROHIBITED_WORDS'); + }); + + test('禁止ワードを含む投稿はエラーになる (正規表現)', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + '/Test/i', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + const note2 = await api('/notes/create', { + text: 'hogetesthuge', + }, alice); + + assert.strictEqual(note2.status, 400); + assert.strictEqual(note2.body.error.code, 'CONTAINS_PROHIBITED_WORDS'); + }); + + test('禁止ワードを含む投稿はエラーになる (スペースアンド)', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + 'Test hoge', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + const note2 = await api('/notes/create', { + text: 'hogeTesthuge', + }, alice); + + assert.strictEqual(note2.status, 400); + assert.strictEqual(note2.body.error.code, 'CONTAINS_PROHIBITED_WORDS'); + }); + + test('禁止ワードを含んでいてもリモートノートはエラーにならない', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + 'test', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + await new Promise(x => setTimeout(x, 2)); + + const note1 = await api('/notes/create', { + text: 'hogetesthuge', + }, tom); + + assert.strictEqual(note1.status, 200); + }); }); describe('notes/delete', () => { diff --git a/packages/frontend/.storybook/mocks.ts b/packages/frontend/.storybook/mocks.ts index 80e5157c5a..f0feff9f78 100644 --- a/packages/frontend/.storybook/mocks.ts +++ b/packages/frontend/.storybook/mocks.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { type SharedOptions, rest } from 'msw'; +import { type SharedOptions, http, HttpResponse } from 'msw'; export const onUnhandledRequest = ((req, print) => { if (req.url.hostname !== 'localhost' || /^\/(?:client-assets\/|fluent-emojis?\/|iframe.html$|node_modules\/|src\/|sb-|static-assets\/|vite\/)/.test(req.url.pathname)) { @@ -13,19 +13,31 @@ export const onUnhandledRequest = ((req, print) => { }) satisfies SharedOptions['onUnhandledRequest']; export const commonHandlers = [ - rest.get('/fluent-emoji/:codepoints.png', async (req, res, ctx) => { - const { codepoints } = req.params; + http.get('/fluent-emoji/:codepoints.png', async ({ params }) => { + const { codepoints } = params; const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob()); - return res(ctx.set('Content-Type', 'image/png'), ctx.body(value)); + return new HttpResponse(value, { + headers: { + 'Content-Type': 'image/png', + }, + }); }), - rest.get('/fluent-emojis/:codepoints.png', async (req, res, ctx) => { - const { codepoints } = req.params; + http.get('/fluent-emojis/:codepoints.png', async ({ params }) => { + const { codepoints } = params; const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob()); - return res(ctx.set('Content-Type', 'image/png'), ctx.body(value)); + return new HttpResponse(value, { + headers: { + 'Content-Type': 'image/png', + }, + }); }), - rest.get('/twemoji/:codepoints.svg', async (req, res, ctx) => { - const { codepoints } = req.params; + http.get('/twemoji/:codepoints.svg', async ({ params }) => { + const { codepoints } = params; const value = await fetch(`https://unpkg.com/@discordapp/twemoji@15.0.2/dist/svg/${codepoints}.svg`).then((response) => response.blob()); - return res(ctx.set('Content-Type', 'image/svg+xml'), ctx.body(value)); + return new HttpResponse(value, { + headers: { + 'Content-Type': 'image/svg+xml', + }, + }); }), ]; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 707c15f5c7..22553dc687 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -29,8 +29,8 @@ "@phosphor-icons/web": "^2.0.3", "@twemoji/parser": "15.0.0", "@vitejs/plugin-vue": "5.0.3", - "@vue/compiler-sfc": "3.4.15", - "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6", + "@vue/compiler-sfc": "3.4.18", + "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.2", "astring": "1.8.6", "broadcast-channel": "7.0.0", "buraha": "0.0.1", @@ -72,8 +72,8 @@ "typescript": "5.3.3", "uuid": "9.0.1", "v-code-diff": "1.7.2", - "vite": "5.0.12", - "vue": "3.4.15", + "vite": "5.1.0", + "vue": "3.4.18", "vuedraggable": "next" }, "devDependencies": { @@ -97,12 +97,12 @@ "@storybook/types": "7.6.10", "@storybook/vue3": "7.6.10", "@storybook/vue3-vite": "7.6.10", - "@testing-library/vue": "8.0.1", + "@testing-library/vue": "8.0.2", "@types/escape-regexp": "0.0.3", "@types/estree": "1.0.5", "@types/matter-js": "0.19.6", "@types/micromatch": "4.0.6", - "@types/node": "20.11.10", + "@types/node": "20.11.17", "@types/punycode": "2.1.3", "@types/sanitize-html": "2.9.5", "@types/throttle-debounce": "5.0.2", @@ -112,10 +112,10 @@ "@typescript-eslint/eslint-plugin": "6.18.1", "@typescript-eslint/parser": "6.18.1", "@vitest/coverage-v8": "0.34.6", - "@vue/runtime-core": "3.4.15", + "@vue/runtime-core": "3.4.18", "acorn": "8.11.3", "cross-env": "7.0.3", - "cypress": "13.6.3", + "cypress": "13.6.4", "eslint": "8.56.0", "eslint-plugin-import": "2.29.1", "eslint-plugin-vue": "9.20.1", @@ -123,10 +123,10 @@ "happy-dom": "10.0.3", "intersection-observer": "0.12.2", "micromatch": "4.0.5", - "msw": "2.1.2", - "msw-storybook-addon": "1.10.0", + "msw": "2.1.7", + "msw-storybook-addon": "2.0.0-beta.1", "nodemon": "3.0.3", - "prettier": "3.2.4", + "prettier": "3.2.5", "react": "18.2.0", "react-dom": "18.2.0", "start-server-and-test": "2.0.3", diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index f6a3e40305..65bd7cf0f1 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -60,12 +60,6 @@ export async function common(createVue: () => App<Element>) { }); } - const splash = document.getElementById('splash'); - // 念のためnullチェック(HTMLが古い場合があるため(そのうち消す)) - if (splash) splash.addEventListener('transitionend', () => { - splash.remove(); - }); - let isClientUpdated = false; //#region クライアントが更新されたかチェック @@ -293,5 +287,10 @@ function removeSplash() { if (splash) { splash.style.opacity = '0'; splash.style.pointerEvents = 'none'; + + // transitionendイベントが発火しない場合があるため + window.setTimeout(() => { + splash.remove(); + }, 1000); } } diff --git a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts index 77e7c84d5c..dc2697f25c 100644 --- a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts +++ b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts @@ -6,7 +6,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { action } from '@storybook/addon-actions'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { abuseUserReport } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAbuseReport from './MkAbuseReport.vue'; @@ -44,9 +44,9 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/admin/resolve-abuse-user-report', async (req, res, ctx) => { - action('POST /api/admin/resolve-abuse-user-report')(await req.json()); - return res(ctx.json({})); + http.post('/api/admin/resolve-abuse-user-report', async ({ request }) => { + action('POST /api/admin/resolve-abuse-user-report')(await request.json()); + return HttpResponse.json({}); }), ], }, diff --git a/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts b/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts index dc842b3d1b..771452cb5f 100644 --- a/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts +++ b/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts @@ -6,7 +6,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { action } from '@storybook/addon-actions'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAbuseReportWindow from './MkAbuseReportWindow.vue'; @@ -44,9 +44,9 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/report-abuse', async (req, res, ctx) => { - action('POST /api/users/report-abuse')(await req.json()); - return res(ctx.json({})); + http.post('/api/users/report-abuse', async ({ request }) => { + action('POST /api/users/report-abuse')(await request.json()); + return HttpResponse.json({}); }), ], }, diff --git a/packages/frontend/src/components/MkAchievements.stories.impl.ts b/packages/frontend/src/components/MkAchievements.stories.impl.ts index 6d972467b1..81e9529de2 100644 --- a/packages/frontend/src/components/MkAchievements.stories.impl.ts +++ b/packages/frontend/src/components/MkAchievements.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAchievements from './MkAchievements.vue'; @@ -39,8 +39,8 @@ export const Empty = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/achievements', (req, res, ctx) => { - return res(ctx.json([])); + http.post('/api/users/achievements', () => { + return HttpResponse.json([]); }), ], }, @@ -52,8 +52,8 @@ export const All = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/achievements', (req, res, ctx) => { - return res(ctx.json(ACHIEVEMENT_TYPES.map((name) => ({ name, unlockedAt: 0 })))); + http.post('/api/users/achievements', () => { + return HttpResponse.json(ACHIEVEMENT_TYPES.map((name) => ({ name, unlockedAt: 0 }))); }), ], }, diff --git a/packages/frontend/src/components/MkAutocomplete.stories.impl.ts b/packages/frontend/src/components/MkAutocomplete.stories.impl.ts index 969519386f..3ca8c5b864 100644 --- a/packages/frontend/src/components/MkAutocomplete.stories.impl.ts +++ b/packages/frontend/src/components/MkAutocomplete.stories.impl.ts @@ -8,7 +8,7 @@ import { action } from '@storybook/addon-actions'; import { expect } from '@storybook/jest'; import { userEvent, waitFor, within } from '@storybook/testing-library'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAutocomplete from './MkAutocomplete.vue'; @@ -99,11 +99,11 @@ export const User = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/search-by-username-and-host', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users/search-by-username-and-host', () => { + return HttpResponse.json([ userDetailed('44', 'mizuki', 'misskey-hub.net', 'Mizuki'), userDetailed('49', 'momoko', 'misskey-hub.net', 'Momoko'), - ])); + ]); }), ], }, @@ -132,12 +132,12 @@ export const Hashtag = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/hashtags/search', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/hashtags/search', () => { + return HttpResponse.json([ '気象警報注意報', '気象警報', '気象情報', - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/MkAvatars.stories.impl.ts b/packages/frontend/src/components/MkAvatars.stories.impl.ts index d41b64695f..a9b4540ca9 100644 --- a/packages/frontend/src/components/MkAvatars.stories.impl.ts +++ b/packages/frontend/src/components/MkAvatars.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAvatars from './MkAvatars.vue'; @@ -38,12 +38,12 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/show', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users/show', () => { + return HttpResponse.json([ userDetailed('17'), userDetailed('20'), userDetailed('18'), - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/MkInviteCode.stories.impl.ts b/packages/frontend/src/components/MkInviteCode.stories.impl.ts index 2ea32dd3b6..2abe1a8770 100644 --- a/packages/frontend/src/components/MkInviteCode.stories.impl.ts +++ b/packages/frontend/src/components/MkInviteCode.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed, inviteCode } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkInviteCode from './MkInviteCode.vue'; @@ -39,8 +39,8 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/show', (req, res, ctx) => { - return res(ctx.json(userDetailed(req.params.userId as string))); + http.post('/api/users/show', ({ params }) => { + return HttpResponse.json(userDetailed(params.userId as string)); }), ], }, diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue index 95bbe71f96..e998b081ee 100644 --- a/packages/frontend/src/components/MkTimeline.vue +++ b/packages/frontend/src/components/MkTimeline.vue @@ -19,7 +19,6 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, watch, onUnmounted, provide, ref, shallowRef } from 'vue'; import * as Misskey from 'misskey-js'; -import { ChannelConnection as Connection } from 'misskey-js'; import MkNotes from '@/components/MkNotes.vue'; import MkPullToRefresh from '@/components/MkPullToRefresh.vue'; import { useStream } from '@/stream.js'; @@ -90,8 +89,8 @@ function prepend(note) { } } -let connection: Connection; -let connection2: Connection; +let connection: Misskey.ChannelConnection | null = null; +let connection2: Misskey.ChannelConnection | null = null; let paginationQuery: Paging | null = null; const stream = useStream(); @@ -163,7 +162,7 @@ function connectChannel() { roleId: props.role, }); } - if (props.src !== 'directs' && props.src !== 'mentions') connection.on('note', prepend); + if (props.src !== 'directs' && props.src !== 'mentions') connection?.on('note', prepend); } function disconnectChannel() { diff --git a/packages/frontend/src/components/MkUrlPreview.vue b/packages/frontend/src/components/MkUrlPreview.vue index 440dcd84fa..9fa6fb1ab6 100644 --- a/packages/frontend/src/components/MkUrlPreview.vue +++ b/packages/frontend/src/components/MkUrlPreview.vue @@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only v-if="player.url.startsWith('http://') || player.url.startsWith('https://')" sandbox="allow-popups allow-scripts allow-storage-access-by-user-activation allow-same-origin" scrolling="no" - :allow="player.allow.join(';')" + :allow="player.allow == null ? 'autoplay;encrypted-media;fullscreen' : player.allow.filter(x => ['autoplay', 'clipboard-write', 'fullscreen', 'encrypted-media', 'picture-in-picture', 'web-share'].includes(x)).join(';')" :class="$style.playerIframe" :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :style="{ border: 0 }" diff --git a/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts index 45c7da40ce..c1b380bd1b 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts +++ b/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { commonHandlers } from '../../.storybook/mocks.js'; import { userDetailed } from '../../.storybook/fakes.js'; import MkUserSetupDialog_Follow from './MkUserSetupDialog.Follow.vue'; @@ -38,17 +38,17 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), - rest.post('/api/pinned-users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/pinned-users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/MkUserSetupDialog.Follow.vue b/packages/frontend/src/components/MkUserSetupDialog.Follow.vue index 46459df6a6..86a5c812bd 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.Follow.vue +++ b/packages/frontend/src/components/MkUserSetupDialog.Follow.vue @@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import Misskey from 'misskey-js'; +import * as Misskey from 'misskey-js'; import { i18n } from '@/i18n.js'; import MkFolder from '@/components/MkFolder.vue'; import XUser from '@/components/MkUserSetupDialog.User.vue'; diff --git a/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts index 5182db12b2..7177d256e1 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts +++ b/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { commonHandlers } from '../../.storybook/mocks.js'; import { userDetailed } from '../../.storybook/fakes.js'; import MkUserSetupDialog from './MkUserSetupDialog.vue'; @@ -38,17 +38,17 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), - rest.post('/api/pinned-users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/pinned-users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/global/MkUrl.stories.impl.ts b/packages/frontend/src/components/global/MkUrl.stories.impl.ts index b35b6114fd..d053069087 100644 --- a/packages/frontend/src/components/global/MkUrl.stories.impl.ts +++ b/packages/frontend/src/components/global/MkUrl.stories.impl.ts @@ -7,7 +7,7 @@ import { expect } from '@storybook/jest'; import { userEvent, waitFor, within } from '@storybook/testing-library'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { commonHandlers } from '../../../.storybook/mocks.js'; import MkUrl from './MkUrl.vue'; export const Default = { @@ -59,8 +59,8 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.get('/url', (req, res, ctx) => { - return res(ctx.json({ + http.get('/url', () => { + return HttpResponse.json({ title: 'Misskey Hub', icon: 'https://misskey-hub.net/favicon.ico', description: 'Misskeyはオープンソースの分散型ソーシャルネットワーキングプラットフォームです。', @@ -74,7 +74,7 @@ export const Default = { sitename: 'misskey-hub.net', sensitive: false, url: 'https://misskey-hub.net/', - })); + }); }), ], }, diff --git a/packages/frontend/src/pages/admin/moderation.vue b/packages/frontend/src/pages/admin/moderation.vue index e8b0e306fc..965793bf4f 100644 --- a/packages/frontend/src/pages/admin/moderation.vue +++ b/packages/frontend/src/pages/admin/moderation.vue @@ -49,6 +49,11 @@ SPDX-License-Identifier: AGPL-3.0-only <template #caption>{{ i18n.ts.sensitiveWordsDescription }}<br>{{ i18n.ts.sensitiveWordsDescription2 }}</template> </MkTextarea> + <MkTextarea v-model="prohibitedWords"> + <template #label>{{ i18n.ts.prohibitedWords }}</template> + <template #caption>{{ i18n.ts.prohibitedWordsDescription }}<br>{{ i18n.ts.prohibitedWordsDescription2 }}</template> + </MkTextarea> + <MkTextarea v-model="hiddenTags"> <template #label>{{ i18n.ts.hiddenTags }}</template> <template #caption>{{ i18n.ts.hiddenTagsDescription }}</template> @@ -87,6 +92,7 @@ const emailRequiredForSignup = ref<boolean>(false); const approvalRequiredForSignup = ref<boolean>(false); const bubbleTimelineEnabled = ref<boolean>(false); const sensitiveWords = ref<string>(''); +const prohibitedWords = ref<string>(''); const hiddenTags = ref<string>(''); const preservedUsernames = ref<string>(''); const bubbleTimeline = ref<string>(''); @@ -99,6 +105,7 @@ async function init() { emailRequiredForSignup.value = meta.emailRequiredForSignup; approvalRequiredForSignup.value = meta.approvalRequiredForSignup; sensitiveWords.value = meta.sensitiveWords.join('\n'); + prohibitedWords.value = meta.prohibitedWords.join('\n'); hiddenTags.value = meta.hiddenTags.join('\n'); preservedUsernames.value = meta.preservedUsernames.join('\n'); tosUrl.value = meta.tosUrl; @@ -115,6 +122,7 @@ function save() { tosUrl: tosUrl.value, privacyPolicyUrl: privacyPolicyUrl.value, sensitiveWords: sensitiveWords.value.split('\n'), + prohibitedWords: prohibitedWords.value.split('\n'), hiddenTags: hiddenTags.value.split('\n'), preservedUsernames: preservedUsernames.value.split('\n'), bubbleInstances: bubbleTimeline.value.split('\n'), diff --git a/packages/frontend/src/pages/user/home.stories.impl.ts b/packages/frontend/src/pages/user/home.stories.impl.ts index a2ef5d50d1..1e67d96c71 100644 --- a/packages/frontend/src/pages/user/home.stories.impl.ts +++ b/packages/frontend/src/pages/user/home.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../../.storybook/fakes.js'; import { commonHandlers } from '../../../.storybook/mocks.js'; import home_ from './home.vue'; @@ -39,12 +39,13 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/notes', (req, res, ctx) => { - return res(ctx.json([])); + http.post('/api/users/notes', () => { + return HttpResponse.json([]); }), - rest.get('/api/charts/user/notes', (req, res, ctx) => { - const length = Math.max(Math.min(parseInt(req.url.searchParams.get('limit') ?? '30', 10), 1), 300); - return res(ctx.json({ + http.get('/api/charts/user/notes', ({ request }) => { + const url = new URL(request.url); + const length = Math.max(Math.min(parseInt(url.searchParams.get('limit') ?? '30', 10), 1), 300); + return HttpResponse.json({ total: Array.from({ length }, () => 0), inc: Array.from({ length }, () => 0), dec: Array.from({ length }, () => 0), @@ -54,11 +55,12 @@ export const Default = { renote: Array.from({ length }, () => 0), withFile: Array.from({ length }, () => 0), }, - })); + }); }), - rest.get('/api/charts/user/pv', (req, res, ctx) => { - const length = Math.max(Math.min(parseInt(req.url.searchParams.get('limit') ?? '30', 10), 1), 300); - return res(ctx.json({ + http.get('/api/charts/user/pv', ({ request }) => { + const url = new URL(request.url); + const length = Math.max(Math.min(parseInt(url.searchParams.get('limit') ?? '30', 10), 1), 300); + return HttpResponse.json({ upv: { user: Array.from({ length }, () => 0), visitor: Array.from({ length }, () => 0), @@ -67,7 +69,7 @@ export const Default = { user: Array.from({ length }, () => 0), visitor: Array.from({ length }, () => 0), }, - })); + }); }), ], }, diff --git a/packages/frontend/src/scripts/code-highlighter.ts b/packages/frontend/src/scripts/code-highlighter.ts index b11dfed41a..2733897bab 100644 --- a/packages/frontend/src/scripts/code-highlighter.ts +++ b/packages/frontend/src/scripts/code-highlighter.ts @@ -20,7 +20,7 @@ export async function getTheme(mode: 'light' | 'dark', getName = false): Promise const base = [lightTheme, darkTheme].find(x => x.id === theme.base); if (base && base.codeHighlighter) theme.codeHighlighter = Object.assign({}, base.codeHighlighter, theme.codeHighlighter); } - + if (theme.codeHighlighter) { let _res: ThemeRegistration = {}; if (theme.codeHighlighter.base === '_none_') { @@ -55,7 +55,7 @@ export async function getHighlighter(): Promise<Highlighter> { export async function initHighlighter() { const aiScriptGrammar = await import('aiscript-vscode/aiscript/syntaxes/aiscript.tmLanguage.json'); - + await loadWasm(import('shiki/onig.wasm?init')); // テーマの重複を消す @@ -68,10 +68,7 @@ export async function initHighlighter() { themes, langs: [ import('shiki/langs/javascript.mjs'), - { - aliases: ['is', 'ais'], - ...aiScriptGrammar.default, - } as unknown as LanguageRegistration, + aiScriptGrammar.default as unknown as LanguageRegistration, ], }); diff --git a/packages/frontend/test/url-preview.test.ts b/packages/frontend/test/url-preview.test.ts index 6cf8317c07..b7587754c6 100644 --- a/packages/frontend/test/url-preview.test.ts +++ b/packages/frontend/test/url-preview.test.ts @@ -116,6 +116,34 @@ describe('MkUrlPreview', () => { assert.strictEqual(iframe?.allow, 'fullscreen;web-share'); }); + test('A Summaly proxy response without allow falls back to the default', async () => { + const iframe = await renderAndOpenPreview({ + url: 'https://example.local', + player: { + url: 'https://example.local/player', + width: null, + height: null, + allow: undefined as any, + }, + }); + assert.exists(iframe, 'iframe should exist'); + assert.strictEqual(iframe?.allow, 'autoplay;encrypted-media;fullscreen'); + }); + + test('Filtering the allow list from the Summaly proxy', async () => { + const iframe = await renderAndOpenPreview({ + url: 'https://example.local', + player: { + url: 'https://example.local/player', + width: null, + height: null, + allow: ['autoplay', 'camera', 'fullscreen'], + }, + }); + assert.exists(iframe, 'iframe should exist'); + assert.strictEqual(iframe?.allow, 'autoplay;fullscreen'); + }); + test('Having a player width should keep the fixed aspect ratio', async () => { const iframe = await renderAndOpenPreview({ url: 'https://example.local', diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 0c4dd52d14..26b682f1c4 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2024.2.0-beta.10", + "version": "2024.2.0-beta.11", "description": "Misskey SDK for JavaScript", "types": "./built/dts/index.d.ts", "exports": { @@ -39,7 +39,7 @@ "@misskey-dev/eslint-plugin": "1.0.0", "@swc/jest": "0.2.31", "@types/jest": "29.5.11", - "@types/node": "20.11.10", + "@types/node": "20.11.17", "@typescript-eslint/eslint-plugin": "6.18.1", "@typescript-eslint/parser": "6.18.1", "eslint": "8.56.0", diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 08a2bd7412..dee7caba99 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4793,6 +4793,7 @@ export type operations = { hiddenTags: string[]; blockedHosts: string[]; sensitiveWords: string[]; + prohibitedWords: string[]; bannedEmailDomains?: string[]; preservedUsernames: string[]; bubbleInstances: string[]; @@ -8814,6 +8815,7 @@ export type operations = { hiddenTags?: string[] | null; blockedHosts?: string[] | null; sensitiveWords?: string[] | null; + prohibitedWords?: string[] | null; themeColor?: string | null; mascotImageUrl?: string | null; bannerUrl?: string | null; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 913f0ec2e1..7f8bc28742 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -116,8 +116,8 @@ importers: specifier: 1.7.0 version: 1.7.0 '@simplewebauthn/server': - specifier: 9.0.1 - version: 9.0.1 + specifier: 9.0.2 + version: 9.0.2 '@sinonjs/fake-timers': specifier: 11.2.2 version: 11.2.2 @@ -161,14 +161,14 @@ importers: specifier: 1.20.2 version: 1.20.2 bullmq: - specifier: 5.1.5 - version: 5.1.5 + specifier: 5.1.9 + version: 5.1.9 cacheable-lookup: specifier: 7.0.0 version: 7.0.0 cbor: - specifier: 9.0.1 - version: 9.0.1 + specifier: 9.0.2 + version: 9.0.2 chalk: specifier: 5.3.0 version: 5.3.0 @@ -559,8 +559,8 @@ importers: specifier: 0.7.34 version: 0.7.34 '@types/node': - specifier: 20.11.10 - version: 20.11.10 + specifier: 20.11.17 + version: 20.11.17 '@types/node-fetch': specifier: 3.0.3 version: 3.0.3 @@ -656,7 +656,7 @@ importers: version: 9.0.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.11.10) + version: 29.7.0(@types/node@20.11.17) jest-mock: specifier: 29.7.0 version: 29.7.0 @@ -707,13 +707,13 @@ importers: version: 15.0.0 '@vitejs/plugin-vue': specifier: 5.0.3 - version: 5.0.3(vite@5.0.12)(vue@3.4.15) + version: 5.0.3(vite@5.1.0)(vue@3.4.18) '@vue/compiler-sfc': - specifier: 3.4.15 - version: 3.4.15 + specifier: 3.4.18 + version: 3.4.18 aiscript-vscode: - specifier: github:aiscript-dev/aiscript-vscode#v0.0.6 - version: github.com/aiscript-dev/aiscript-vscode/b5a8aa0ad927831a0b867d1c183460a14e6c48cd + specifier: github:aiscript-dev/aiscript-vscode#v0.1.2 + version: github.com/aiscript-dev/aiscript-vscode/793211d40243c8775f6b85f015c221c82cbffb07 astring: specifier: 1.8.6 version: 1.8.6 @@ -836,16 +836,16 @@ importers: version: 9.0.1 v-code-diff: specifier: 1.7.2 - version: 1.7.2(vue@3.4.15) + version: 1.7.2(vue@3.4.18) vite: - specifier: 5.0.12 - version: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + specifier: 5.1.0 + version: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) vue: - specifier: 3.4.15 - version: 3.4.15(typescript@5.3.3) + specifier: 3.4.18 + version: 3.4.18(typescript@5.3.3) vuedraggable: specifier: next - version: 4.1.0(vue@3.4.15) + version: 4.1.0(vue@3.4.18) devDependencies: '@misskey-dev/eslint-plugin': specifier: 1.0.0 @@ -891,7 +891,7 @@ importers: version: 7.6.10(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@storybook/react-vite': specifier: 7.6.10 - version: 7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.0.12) + version: 7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.1.0) '@storybook/testing-library': specifier: 0.2.2 version: 0.2.2 @@ -903,13 +903,13 @@ importers: version: 7.6.10 '@storybook/vue3': specifier: 7.6.10 - version: 7.6.10(vue@3.4.15) + version: 7.6.10(vue@3.4.18) '@storybook/vue3-vite': specifier: 7.6.10 - version: 7.6.10(typescript@5.3.3)(vite@5.0.12)(vue@3.4.15) + version: 7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18) '@testing-library/vue': - specifier: 8.0.1 - version: 8.0.1(@vue/compiler-sfc@3.4.15)(vue@3.4.15) + specifier: 8.0.2 + version: 8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18) '@types/escape-regexp': specifier: 0.0.3 version: 0.0.3 @@ -923,8 +923,8 @@ importers: specifier: 4.0.6 version: 4.0.6 '@types/node': - specifier: 20.11.10 - version: 20.11.10 + specifier: 20.11.17 + version: 20.11.17 '@types/punycode': specifier: 2.1.3 version: 2.1.3 @@ -953,8 +953,8 @@ importers: specifier: 0.34.6 version: 0.34.6(vitest@0.34.6) '@vue/runtime-core': - specifier: 3.4.15 - version: 3.4.15 + specifier: 3.4.18 + version: 3.4.18 acorn: specifier: 8.11.3 version: 8.11.3 @@ -962,8 +962,8 @@ importers: specifier: 7.0.3 version: 7.0.3 cypress: - specifier: 13.6.3 - version: 13.6.3 + specifier: 13.6.4 + version: 13.6.4 eslint: specifier: 8.56.0 version: 8.56.0 @@ -986,17 +986,17 @@ importers: specifier: 4.0.5 version: 4.0.5 msw: - specifier: 2.1.2 - version: 2.1.2(typescript@5.3.3) + specifier: 2.1.7 + version: 2.1.7(typescript@5.3.3) msw-storybook-addon: - specifier: 1.10.0 - version: 1.10.0(msw@2.1.2) + specifier: 2.0.0-beta.1 + version: 2.0.0-beta.1(msw@2.1.7) nodemon: specifier: 3.0.3 version: 3.0.3 prettier: - specifier: 3.2.4 - version: 3.2.4 + specifier: 3.2.5 + version: 3.2.5 react: specifier: 18.2.0 version: 18.2.0 @@ -1105,7 +1105,7 @@ importers: version: 9.0.0(eslint@8.54.0) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.11.10) + version: 29.7.0(@types/node@20.11.17) jest-worker: specifier: ^29.7.0 version: 29.7.0 @@ -1185,7 +1185,7 @@ importers: devDependencies: '@microsoft/api-extractor': specifier: 7.39.1 - version: 7.39.1(@types/node@20.11.10) + version: 7.39.1(@types/node@20.11.17) '@misskey-dev/eslint-plugin': specifier: 1.0.0 version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0) @@ -1196,8 +1196,8 @@ importers: specifier: 29.5.11 version: 29.5.11 '@types/node': - specifier: 20.11.10 - version: 20.11.10 + specifier: 20.11.17 + version: 20.11.17 '@typescript-eslint/eslint-plugin': specifier: 6.18.1 version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3) @@ -1209,7 +1209,7 @@ importers: version: 8.56.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.11.10) + version: 29.7.0(@types/node@20.11.17) jest-fetch-mock: specifier: 3.0.3 version: 3.0.3 @@ -2281,6 +2281,14 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.4 + dev: true + + /@babel/parser@7.23.9: + resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.4 /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.3): resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} @@ -3261,13 +3269,6 @@ packages: dependencies: regenerator-runtime: 0.13.11 - /@babel/runtime@7.23.2: - resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.0 - dev: true - /@babel/runtime@7.23.4: resolution: {integrity: sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==} engines: {node: '>=6.9.0'} @@ -3356,12 +3357,6 @@ packages: cookie: 0.5.0 dev: true - /@bundled-es-modules/js-levenshtein@2.0.1: - resolution: {integrity: sha512-DERMS3yfbAljKsQc0U2wcqGKUWpdFjwqWuoMugEJlqBnKO180/n+4SR/J8MRDt1AN48X1ovgoD9KrdVXcaa3Rg==} - dependencies: - js-levenshtein: 1.1.6 - dev: true - /@bundled-es-modules/statuses@1.0.1: resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} dependencies: @@ -4317,7 +4312,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -4338,14 +4333,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.11.10) + jest-config: 29.7.0(@types/node@20.11.17) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -4380,7 +4375,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-mock: 29.7.0 dev: true @@ -4406,7 +4401,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -4439,7 +4434,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.20 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -4532,7 +4527,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/yargs': 16.0.5 chalk: 4.1.2 dev: true @@ -4544,11 +4539,11 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/yargs': 17.0.32 chalk: 4.1.2 - /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.3)(vite@5.0.12): + /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.3)(vite@5.1.0): resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==} peerDependencies: typescript: '>= 4.3.x' @@ -4562,7 +4557,7 @@ packages: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.3.3) typescript: 5.3.3 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) dev: true /@jridgewell/gen-mapping@0.3.3: @@ -4655,24 +4650,24 @@ packages: react: 18.2.0 dev: true - /@microsoft/api-extractor-model@7.28.4(@types/node@20.11.10): + /@microsoft/api-extractor-model@7.28.4(@types/node@20.11.17): resolution: {integrity: sha512-vucgyPmgHrJ/D4/xQywAmjTmSfxAx2/aDmD6TkIoLu51FdsAfuWRbijWA48AePy60OO+l+mmy9p2P/CEeBZqig==} dependencies: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.63.0(@types/node@20.11.10) + '@rushstack/node-core-library': 3.63.0(@types/node@20.11.17) transitivePeerDependencies: - '@types/node' dev: true - /@microsoft/api-extractor@7.39.1(@types/node@20.11.10): + /@microsoft/api-extractor@7.39.1(@types/node@20.11.17): resolution: {integrity: sha512-V0HtCufWa8hZZvSmlEzQZfINcJkHAU/bmpyJQj6w+zpI87EkR8DuBOW6RWrO9c7mUYFZoDaNgUTyKo83ytv+QQ==} hasBin: true dependencies: - '@microsoft/api-extractor-model': 7.28.4(@types/node@20.11.10) + '@microsoft/api-extractor-model': 7.28.4(@types/node@20.11.17) '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.63.0(@types/node@20.11.10) + '@rushstack/node-core-library': 3.63.0(@types/node@20.11.17) '@rushstack/rig-package': 0.5.1 '@rushstack/ts-command-line': 4.17.1 colors: 1.2.5 @@ -4817,8 +4812,8 @@ packages: engines: {node: '>=18'} dev: true - /@mswjs/interceptors@0.25.14: - resolution: {integrity: sha512-2dnIxl+obqIqjoPXTFldhe6pcdOrqiz+GcLaQQ6hmL02OldAF7nIC+rUgTWm+iF6lvmyCVhFFqbgbapNhR8eag==} + /@mswjs/interceptors@0.25.16: + resolution: {integrity: sha512-8QC8JyKztvoGAdPgyZy49c9vSHHAZjHagwl4RY9E8carULk8ym3iTaiawrT1YoLF/qb449h48f71XDPgkUSOUg==} engines: {node: '>=18'} dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -5751,7 +5746,7 @@ packages: requiresBuild: true optional: true - /@rushstack/node-core-library@3.63.0(@types/node@20.11.10): + /@rushstack/node-core-library@3.63.0(@types/node@20.11.17): resolution: {integrity: sha512-Q7B3dVpBQF1v+mUfxNcNZh5uHVR8ntcnkN5GYjbBLrxUYHBGKbnCM+OdcN+hzCpFlLBH6Ob0dEHhZ0spQwf24A==} peerDependencies: '@types/node': '*' @@ -5759,7 +5754,7 @@ packages: '@types/node': optional: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 colors: 1.2.5 fs-extra: 7.0.1 import-lazy: 4.0.0 @@ -5803,8 +5798,8 @@ packages: resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} dev: true - /@simplewebauthn/server@9.0.1: - resolution: {integrity: sha512-XnilMoBygy2BOZjIHPxby+7ENx5ChN2wXfhd14mOgO/XitYMqdphTo/kwgxEI4/Je3lELK1h/eLDJqM2fIKS1w==} + /@simplewebauthn/server@9.0.2: + resolution: {integrity: sha512-aaWA+qVOU4byk5IDb/l+M1+7dmrAJhTb4ISJHucpsgRQcMMEes76tbGIqO2JQuA7N50tc/OBrnGKBjoKYG1kSw==} engines: {node: '>=16.0.0'} dependencies: '@hexagon/base64': 1.1.27 @@ -5813,15 +5808,15 @@ packages: '@peculiar/asn1-rsa': 2.3.8 '@peculiar/asn1-schema': 2.3.8 '@peculiar/asn1-x509': 2.3.8 - '@simplewebauthn/types': 9.0.0 + '@simplewebauthn/types': 9.0.1 cbor-x: 1.5.4 cross-fetch: 4.0.0 transitivePeerDependencies: - encoding dev: false - /@simplewebauthn/types@9.0.0: - resolution: {integrity: sha512-Lo6LLNQee66D//KueYy9AyX7oiQ7BBKJgdLzP3l0HJDrV4GRSzSAii8AtigBGOeNc8hOQsF/D8itItyuZX9djA==} + /@simplewebauthn/types@9.0.1: + resolution: {integrity: sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==} dev: false /@simplewebauthn/typescript-types@8.3.4: @@ -6579,7 +6574,7 @@ packages: - supports-color dev: true - /@storybook/builder-vite@7.6.10(typescript@5.3.3)(vite@5.0.12): + /@storybook/builder-vite@7.6.10(typescript@5.3.3)(vite@5.1.0): resolution: {integrity: sha512-qxe19axiNJVdIKj943e1ucAmADwU42fTGgMSdBzzrvfH3pSOmx2057aIxRzd8YtBRnj327eeqpgCHYIDTunMYQ==} peerDependencies: '@preact/preset-vite': '*' @@ -6611,7 +6606,7 @@ packages: magic-string: 0.30.5 rollup: 3.29.4 typescript: 5.3.3 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - encoding - supports-color @@ -6968,7 +6963,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/react-vite@7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.0.12): + /@storybook/react-vite@7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.1.0): resolution: {integrity: sha512-YE2+J1wy8nO+c6Nv/hBMu91Edew3K184L1KSnfoZV8vtq2074k1Me/8pfe0QNuq631AncpfCYNb37yBAXQ/80w==} engines: {node: '>=16'} peerDependencies: @@ -6976,16 +6971,16 @@ packages: react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 vite: ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.3)(vite@5.0.12) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.3)(vite@5.1.0) '@rollup/pluginutils': 5.1.0(rollup@4.9.6) - '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.0.12) + '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.1.0) '@storybook/react': 7.6.10(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) - '@vitejs/plugin-react': 3.1.0(vite@5.0.12) + '@vitejs/plugin-react': 3.1.0(vite@5.1.0) magic-string: 0.30.5 react: 18.2.0 react-docgen: 7.0.1 react-dom: 18.2.0(react@18.2.0) - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - '@preact/preset-vite' - encoding @@ -7100,19 +7095,19 @@ packages: file-system-cache: 2.3.0 dev: true - /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.0.12)(vue@3.4.15): + /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18): resolution: {integrity: sha512-5f0Rh4PTVEeAI86ybihfN+rHGXXLNiRsoGKinpJSb7hkfsq/L7u3sVCXJwH/qsG+rUJlZyHs3kfa4/Kgyyi3Mg==} engines: {node: ^14.18 || >=16} peerDependencies: vite: ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: - '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.0.12) + '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.1.0) '@storybook/core-server': 7.6.10 - '@storybook/vue3': 7.6.10(vue@3.4.15) - '@vitejs/plugin-vue': 4.5.2(vite@5.0.12)(vue@3.4.15) + '@storybook/vue3': 7.6.10(vue@3.4.18) + '@vitejs/plugin-vue': 4.5.2(vite@5.1.0)(vue@3.4.18) magic-string: 0.30.5 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vue-docgen-api: 4.64.1(vue@3.4.15) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vue-docgen-api: 4.64.1(vue@3.4.18) transitivePeerDependencies: - '@preact/preset-vite' - bufferutil @@ -7124,7 +7119,7 @@ packages: - vue dev: true - /@storybook/vue3@7.6.10(vue@3.4.15): + /@storybook/vue3@7.6.10(vue@3.4.18): resolution: {integrity: sha512-FeZ9zjuudQgCdKPs2K8sU6TgEyrMjKrCN3e8+XXX5CAMSwLDV8IfexaaMF0ehYW6Wp0dgCIm0cVNBV3u8vtRRw==} engines: {node: '>=16.0.0'} peerDependencies: @@ -7139,7 +7134,7 @@ packages: lodash: 4.17.21 ts-dedent: 2.2.0 type-fest: 2.19.0 - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) vue-component-type-helpers: 1.8.27 transitivePeerDependencies: - encoding @@ -7581,7 +7576,7 @@ packages: engines: {node: '>=14'} dependencies: '@babel/code-frame': 7.23.4 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@types/aria-query': 5.0.1 aria-query: 5.1.3 chalk: 4.1.2 @@ -7609,7 +7604,7 @@ packages: optional: true dependencies: '@adobe/css-tools': 4.3.1 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@types/jest': 28.1.3 aria-query: 5.1.3 chalk: 3.0.0 @@ -7629,18 +7624,21 @@ packages: '@testing-library/dom': 9.2.0 dev: true - /@testing-library/vue@8.0.1(@vue/compiler-sfc@3.4.15)(vue@3.4.15): - resolution: {integrity: sha512-l51ZEpjTQ6glq3wM+asQ1GbKJMGcxwgHEygETx0aCRN4TjFEGvMZy4YdWKs/y7bu4bmLrxcxhbEPP7iPSW/2OQ==} + /@testing-library/vue@8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18): + resolution: {integrity: sha512-A8wWX+qQn0o0izpQWnGCpwQt8wAdpsVP8vPP2h5Q/jcGhZ5yKXz9PPUqhQv+45LTFaWlyRf8bArTVaB/KFFd5A==} engines: {node: '>=14'} peerDependencies: '@vue/compiler-sfc': '>= 3' vue: '>= 3' + peerDependenciesMeta: + '@vue/compiler-sfc': + optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@testing-library/dom': 9.3.3 - '@vue/compiler-sfc': 3.4.15 - '@vue/test-utils': 2.4.1(vue@3.4.15) - vue: 3.4.15(typescript@5.3.3) + '@vue/compiler-sfc': 3.4.18 + '@vue/test-utils': 2.4.1(vue@3.4.18) + vue: 3.4.18(typescript@5.3.3) transitivePeerDependencies: - '@vue/server-renderer' dev: true @@ -7672,7 +7670,7 @@ packages: /@types/accepts@1.3.7: resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/archiver@6.0.2: @@ -7726,7 +7724,7 @@ packages: resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/braces@3.0.1: @@ -7738,14 +7736,14 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/responselike': 1.0.0 dev: false /@types/cbor@6.0.0: resolution: {integrity: sha512-mGQ1lbYOwVti5Xlarn1bTeBZqgY0kstsdjnkoEovgohYKdBjGejHyNGXHdMBeqyQazIv32Jjp33+5pBEaSRy2w==} dependencies: - cbor: 9.0.1 + cbor: 9.0.2 dev: true /@types/chai-subset@1.3.5: @@ -7771,7 +7769,7 @@ packages: /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/content-disposition@0.5.8: @@ -7789,7 +7787,7 @@ packages: /@types/cross-spawn@6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/detect-port@1.3.2: @@ -7841,7 +7839,7 @@ packages: /@types/express-serve-static-core@4.17.33: resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -7862,7 +7860,7 @@ packages: /@types/fluent-ffmpeg@2.1.24: resolution: {integrity: sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/form-data@2.5.0: @@ -7876,13 +7874,13 @@ packages: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/http-cache-semantics@4.0.4: @@ -7891,7 +7889,7 @@ packages: /@types/http-link-header@1.0.5: resolution: {integrity: sha512-AxhIKR8UbyoqCTNp9rRepkktHuUOw3DjfOfDCaO9kwI8AYzjhxyrvZq4+mRw/2daD3hYDknrtSeV6SsPwmc71w==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/istanbul-lib-coverage@2.0.4: @@ -7944,10 +7942,6 @@ packages: pretty-format: 29.7.0 dev: true - /@types/js-levenshtein@1.1.3: - resolution: {integrity: sha512-jd+Q+sD20Qfu9e2aEXogiO3vpOC1PYJOUdyN9gvs4Qrvkg4wF43L5OhqrPeokdv8TL0/mXoYfpkcoGZMNN2pkQ==} - dev: true - /@types/js-yaml@4.0.9: resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} dev: true @@ -7955,7 +7949,7 @@ packages: /@types/jsdom@21.1.6: resolution: {integrity: sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/tough-cookie': 4.0.2 parse5: 7.1.2 dev: true @@ -7979,7 +7973,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: false /@types/lodash@4.14.191: @@ -8023,7 +8017,7 @@ packages: /@types/node-fetch@2.6.4: resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 form-data: 3.0.1 dev: true @@ -8037,8 +8031,8 @@ packages: resolution: {integrity: sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==} dev: true - /@types/node@20.11.10: - resolution: {integrity: sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==} + /@types/node@20.11.17: + resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==} dependencies: undici-types: 5.26.5 @@ -8057,7 +8051,7 @@ packages: /@types/nodemailer@6.4.14: resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/normalize-package-data@2.4.1: @@ -8074,13 +8068,13 @@ packages: resolution: {integrity: sha512-Ali0fUUn+zgr4Yy/pCTFbuiaiJpq7l7OQwFnxYVchNbNGIx0c4Wkcdje6WO89I91RAaYF+gVc1pOaizA4YKZmA==} dependencies: '@types/express': 4.17.17 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/oauth@0.9.4: resolution: {integrity: sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 /@types/object-assign-deep@0.4.3: resolution: {integrity: sha512-d9Gxaj5j1hzrxJ61EFEg13B4g4FgrT/DYtcDWFXPehR8DF2SUZbVMFtZIs8exkVRiqrqBpdTc/lUUZjncsPpMw==} @@ -8093,7 +8087,7 @@ packages: /@types/pg@8.11.0: resolution: {integrity: sha512-sDAlRiBNthGjNFfvt0k6mtotoVYVQ63pA8R4EMWka7crawSR60waVYR0HAgmPRs/e2YaeJTD/43OoZ3PFw80pw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 pg-protocol: 1.6.0 pg-types: 4.0.1 dev: true @@ -8117,7 +8111,7 @@ packages: /@types/qrcode@1.5.5: resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/qs@6.9.7: @@ -8147,7 +8141,7 @@ packages: /@types/readdir-glob@1.1.1: resolution: {integrity: sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/rename@1.0.7: @@ -8161,7 +8155,7 @@ packages: /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: false /@types/sanitize-html@2.9.5: @@ -8186,7 +8180,7 @@ packages: resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} dependencies: '@types/mime': 3.0.1 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/serviceworker@0.0.67: @@ -8264,19 +8258,19 @@ packages: /@types/vary@1.1.3: resolution: {integrity: sha512-XJT8/ZQCL7NUut9QDLf6l24JfAEl7bnNdgxfj50cHIpEPRJLHHDDFOAq6i+GsEmeFfH7NamhBE4c4Thtb2egWg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/web-push@3.6.3: resolution: {integrity: sha512-v3oT4mMJsHeJ/rraliZ+7TbZtr5bQQuxcgD7C3/1q/zkAj29c8RE0F9lVZVu3hiQe5Z9fYcBreV7TLnfKR+4mg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 /@types/yargs-parser@21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} @@ -8300,7 +8294,7 @@ packages: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true optional: true @@ -8702,7 +8696,7 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-react@3.1.0(vite@5.0.12): + /@vitejs/plugin-react@3.1.0(vite@5.1.0): resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -8713,31 +8707,31 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.23.3) magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - supports-color dev: true - /@vitejs/plugin-vue@4.5.2(vite@5.0.12)(vue@3.4.15): + /@vitejs/plugin-vue@4.5.2(vite@5.1.0)(vue@3.4.18): resolution: {integrity: sha512-UGR3DlzLi/SaVBPX0cnSyE37vqxU3O6chn8l0HJNzQzDia6/Au2A4xKv+iIJW8w2daf80G7TYHhi1pAUjdZ0bQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.0.0 || ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vue: 3.4.15(typescript@5.3.3) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vue: 3.4.18(typescript@5.3.3) dev: true - /@vitejs/plugin-vue@5.0.3(vite@5.0.12)(vue@3.4.15): + /@vitejs/plugin-vue@5.0.3(vite@5.1.0)(vue@3.4.18): resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vue: 3.4.15(typescript@5.3.3) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vue: 3.4.18(typescript@5.3.3) dev: false /@vitest/coverage-v8@0.34.6(vitest@0.34.6): @@ -8835,6 +8829,16 @@ packages: entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.0.2 + dev: true + + /@vue/compiler-core@3.4.18: + resolution: {integrity: sha512-F7YK8lMK0iv6b9/Gdk15A67wM0KKZvxDxed0RR60C1z9tIJTKta+urs4j0RTN5XqHISzI3etN3mX0uHhjmoqjQ==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/shared': 3.4.18 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.0.2 /@vue/compiler-core@3.4.3: resolution: {integrity: sha512-u8jzgFg0EDtSrb/hG53Wwh1bAOQFtc1ZCegBpA/glyvTlgHl+tq13o1zvRfLbegYUw/E4mSTGOiCnAJ9SJ+lsg==} @@ -8858,25 +8862,32 @@ packages: dependencies: '@vue/compiler-core': 3.4.15 '@vue/shared': 3.4.15 + dev: true - /@vue/compiler-sfc@3.4.15: - resolution: {integrity: sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==} + /@vue/compiler-dom@3.4.18: + resolution: {integrity: sha512-24Eb8lcMfInefvQ6YlEVS18w5Q66f4+uXWVA+yb7praKbyjHRNuKVWGuinfSSjM0ZIiPi++QWukhkgznBaqpEA==} dependencies: - '@babel/parser': 7.23.6 - '@vue/compiler-core': 3.4.15 - '@vue/compiler-dom': 3.4.15 - '@vue/compiler-ssr': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/compiler-core': 3.4.18 + '@vue/shared': 3.4.18 + + /@vue/compiler-sfc@3.4.18: + resolution: {integrity: sha512-rG5tqtnzwrVpMqAQ7FHtvHaV70G6LLfJIWLYZB/jZ9m/hrnZmIQh+H3ewnC5onwe/ibljm9+ZupxeElzqCkTAw==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/compiler-core': 3.4.18 + '@vue/compiler-dom': 3.4.18 + '@vue/compiler-ssr': 3.4.18 + '@vue/shared': 3.4.18 estree-walker: 2.0.2 - magic-string: 0.30.5 + magic-string: 0.30.7 postcss: 8.4.33 source-map-js: 1.0.2 - /@vue/compiler-ssr@3.4.15: - resolution: {integrity: sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==} + /@vue/compiler-ssr@3.4.18: + resolution: {integrity: sha512-hSlv20oUhPxo2UYUacHgGaxtqP0tvFo6ixxxD6JlXIkwzwoZ9eKK6PFQN4hNK/R13JlNyldwWt/fqGBKgWJ6nQ==} dependencies: - '@vue/compiler-dom': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/compiler-dom': 3.4.18 + '@vue/shared': 3.4.18 /@vue/language-core@1.8.27(typescript@5.3.3): resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} @@ -8898,32 +8909,32 @@ packages: vue-template-compiler: 2.7.14 dev: true - /@vue/reactivity@3.4.15: - resolution: {integrity: sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==} + /@vue/reactivity@3.4.18: + resolution: {integrity: sha512-7uda2/I0jpLiRygprDo5Jxs2HJkOVXcOMlyVlY54yRLxoycBpwGJRwJT9EdGB4adnoqJDXVT2BilUAYwI7qvmg==} dependencies: - '@vue/shared': 3.4.15 + '@vue/shared': 3.4.18 - /@vue/runtime-core@3.4.15: - resolution: {integrity: sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==} + /@vue/runtime-core@3.4.18: + resolution: {integrity: sha512-7mU9diCa+4e+8/wZ7Udw5pwTH10A11sZ1nldmHOUKJnzCwvZxfJqAtw31mIf4T5H2FsLCSBQT3xgioA9vIjyDQ==} dependencies: - '@vue/reactivity': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/reactivity': 3.4.18 + '@vue/shared': 3.4.18 - /@vue/runtime-dom@3.4.15: - resolution: {integrity: sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==} + /@vue/runtime-dom@3.4.18: + resolution: {integrity: sha512-2y1Mkzcw1niSfG7z3Qx+2ir9Gb4hdTkZe5p/I8x1aTIKQE0vY0tPAEUPhZm5tx6183gG3D/KwHG728UR0sIufA==} dependencies: - '@vue/runtime-core': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/runtime-core': 3.4.18 + '@vue/shared': 3.4.18 csstype: 3.1.3 - /@vue/server-renderer@3.4.15(vue@3.4.15): - resolution: {integrity: sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==} + /@vue/server-renderer@3.4.18(vue@3.4.18): + resolution: {integrity: sha512-YJd1wa7mzUN3NRqLEsrwEYWyO+PUBSROIGlCc3J/cvn7Zu6CxhNLgXa8Z4zZ5ja5/nviYO79J1InoPeXgwBTZA==} peerDependencies: - vue: 3.4.15 + vue: 3.4.18 dependencies: - '@vue/compiler-ssr': 3.4.15 - '@vue/shared': 3.4.15 - vue: 3.4.15(typescript@5.3.3) + '@vue/compiler-ssr': 3.4.18 + '@vue/shared': 3.4.18 + vue: 3.4.18(typescript@5.3.3) /@vue/shared@3.3.12: resolution: {integrity: sha512-6p0Yin0pclvnER7BLNOQuod9Z+cxSYh8pSh7CzHnWNjAIP6zrTlCdHRvSCb1aYEx6i3Q3kvfuWU7nG16CgG1ag==} @@ -8931,12 +8942,16 @@ packages: /@vue/shared@3.4.15: resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} + dev: true + + /@vue/shared@3.4.18: + resolution: {integrity: sha512-CxouGFxxaW5r1WbrSmWwck3No58rApXgRSBxrqgnY1K+jk20F6DrXJkHdH9n4HVT+/B6G2CAn213Uq3npWiy8Q==} /@vue/shared@3.4.3: resolution: {integrity: sha512-rIwlkkP1n4uKrRzivAKPZIEkHiuwY5mmhMJ2nZKCBLz8lTUlE73rQh4n1OnnMurXt1vcUNyH4ZPfdh8QweTjpQ==} dev: true - /@vue/test-utils@2.4.1(vue@3.4.15): + /@vue/test-utils@2.4.1(vue@3.4.18): resolution: {integrity: sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==} peerDependencies: '@vue/server-renderer': ^3.0.1 @@ -8946,7 +8961,7 @@ packages: optional: true dependencies: js-beautify: 1.14.9 - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) vue-component-type-helpers: 1.8.4 dev: true @@ -9880,8 +9895,8 @@ packages: dependencies: node-gyp-build: 4.6.0 - /bullmq@5.1.5: - resolution: {integrity: sha512-Rc9QGHrj/wJ8RMENKa839o1pJmdicg7KBTfmVU8YqYuEK2JcMSJaKMg2XrAi7sdYSawgOJgC/kiW9fCGYEj6Yg==} + /bullmq@5.1.9: + resolution: {integrity: sha512-9MfcQxYyfkG8kxpIxRsRXWYlTRQ1o8xWqgdoFR5pLClVTjtMI8qeDO5basRQLZPfp/uiPtv+gpzJ3OTNrm2ZNg==} dependencies: cron-parser: 4.8.1 glob: 8.1.0 @@ -10060,8 +10075,8 @@ packages: cbor-extract: 2.1.1 dev: false - /cbor@9.0.1: - resolution: {integrity: sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ==} + /cbor@9.0.2: + resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} engines: {node: '>=16'} dependencies: nofilter: 3.1.0 @@ -10600,7 +10615,7 @@ packages: readable-stream: 3.6.2 dev: false - /create-jest@29.7.0(@types/node@20.11.10): + /create-jest@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -10609,7 +10624,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.11.10) + jest-config: 29.7.0(@types/node@20.11.17) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -10856,6 +10871,56 @@ packages: yauzl: 2.10.0 dev: true + /cypress@13.6.4: + resolution: {integrity: sha512-pYJjCfDYB+hoOoZuhysbbYhEmNW7DEDsqn+ToCLwuVowxUXppIWRr7qk4TVRIU471ksfzyZcH+mkoF0CQUKnpw==} + engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} + hasBin: true + requiresBuild: true + dependencies: + '@cypress/request': 3.0.0 + '@cypress/xvfb': 1.2.4(supports-color@8.1.1) + '@types/sinonjs__fake-timers': 8.1.1 + '@types/sizzle': 2.3.3 + arch: 2.2.0 + blob-util: 2.0.2 + bluebird: 3.7.2 + buffer: 5.7.1 + cachedir: 2.3.0 + chalk: 4.1.2 + check-more-types: 2.24.0 + cli-cursor: 3.1.0 + cli-table3: 0.6.3 + commander: 6.2.1 + common-tags: 1.8.2 + dayjs: 1.11.10 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.3.6 + eventemitter2: 6.4.7 + execa: 4.1.0 + executable: 4.1.1 + extract-zip: 2.0.1(supports-color@8.1.1) + figures: 3.2.0 + fs-extra: 9.1.0 + getos: 3.2.1 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + lazy-ass: 1.6.0 + listr2: 3.14.0(enquirer@2.3.6) + lodash: 4.17.21 + log-symbols: 4.1.0 + minimist: 1.2.8 + ospath: 1.2.2 + pretty-bytes: 5.6.0 + process: 0.11.10 + proxy-from-env: 1.0.0 + request-progress: 3.0.0 + semver: 7.5.4 + supports-color: 8.1.1 + tmp: 0.2.1 + untildify: 4.0.0 + yauzl: 2.10.0 + dev: true + /dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} @@ -13869,7 +13934,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -13890,7 +13955,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.11.10): + /jest-cli@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -13904,10 +13969,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.11.10) + create-jest: 29.7.0(@types/node@20.11.17) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.11.10) + jest-config: 29.7.0(@types/node@20.11.17) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.6.2 @@ -13918,7 +13983,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.11.10): + /jest-config@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -13933,7 +13998,7 @@ packages: '@babel/core': 7.23.3 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 babel-jest: 29.7.0(@babel/core@7.23.3) chalk: 4.1.2 ci-info: 3.9.0 @@ -14012,7 +14077,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -14041,7 +14106,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.11.10 + '@types/node': 20.11.17 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -14100,7 +14165,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /jest-mock@29.7.0: @@ -14108,7 +14173,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-util: 29.7.0 dev: true @@ -14163,7 +14228,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -14194,7 +14259,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -14246,7 +14311,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -14270,7 +14335,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -14289,13 +14354,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.11.10): + /jest@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -14308,7 +14373,7 @@ packages: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.11.10) + jest-cli: 29.7.0(@types/node@20.11.17) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -14355,11 +14420,6 @@ packages: nopt: 6.0.0 dev: true - /js-levenshtein@1.1.6: - resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} - engines: {node: '>=0.10.0'} - dev: true - /js-stringify@1.0.2: resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} @@ -14880,6 +14940,12 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + /magic-string@0.30.7: + resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + /mailcheck@1.1.1: resolution: {integrity: sha512-3WjL8+ZDouZwKlyJBMp/4LeziLFXgleOdsYu87piGcMLqhBzCsy2QFdbtAwv757TFC/rtqd738fgJw1tFQCSgA==} dev: false @@ -15298,17 +15364,17 @@ packages: msgpackr-extract: 3.0.2 dev: false - /msw-storybook-addon@1.10.0(msw@2.1.2): - resolution: {integrity: sha512-soCTMTf7DnLeaMnFHPrtVgbyeFTJALVvnDHpzzXpJad+HOzJgQdwU4EAzVfDs1q+X5cVEgxOdAhSMC7ljvnSXg==} + /msw-storybook-addon@2.0.0-beta.1(msw@2.1.7): + resolution: {integrity: sha512-DRyIAMK3waEfC+pKTyiIq68OZfiZ4WZGUVAn6J4YwCRpDdoCvLzzoC2spN0Jgegx4dEmJ7589ATnS14NxqeBig==} peerDependencies: - msw: '>=0.35.0 <2.0.0' + msw: ^2.0.0 dependencies: is-node-process: 1.2.0 - msw: 2.1.2(typescript@5.3.3) + msw: 2.1.7(typescript@5.3.3) dev: true - /msw@2.1.2(typescript@5.3.3): - resolution: {integrity: sha512-7OKbeZNFQTCPFe++o+zZHMkQRIUi4D/5N1dAD3lOlaV+2Wpv3Srp3VFrFeH+2ftZJbb4jAiC0caZoW1efr80KQ==} + /msw@2.1.7(typescript@5.3.3): + resolution: {integrity: sha512-yTIYqEMqDSrdbVMrfmqP6rTKQsnIbglTvVmAHDWwNegyXPXRcV+RjsaFEqubRS266gwWCDLm9YdOkWSKLdDvJQ==} engines: {node: '>=18'} hasBin: true requiresBuild: true @@ -15319,13 +15385,11 @@ packages: optional: true dependencies: '@bundled-es-modules/cookie': 2.0.0 - '@bundled-es-modules/js-levenshtein': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 '@mswjs/cookies': 1.1.0 - '@mswjs/interceptors': 0.25.14 + '@mswjs/interceptors': 0.25.16 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 - '@types/js-levenshtein': 1.1.3 '@types/statuses': 2.0.4 chalk: 4.1.2 chokidar: 3.5.3 @@ -15333,7 +15397,6 @@ packages: headers-polyfill: 4.0.2 inquirer: 8.2.5 is-node-process: 1.2.0 - js-levenshtein: 1.1.6 outvariant: 1.4.2 path-to-regexp: 6.2.1 strict-event-emitter: 0.5.1 @@ -16680,6 +16743,14 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -16763,8 +16834,8 @@ packages: hasBin: true dev: true - /prettier@3.2.4: - resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==} + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true dev: true @@ -19008,7 +19079,7 @@ packages: '@babel/core': 7.23.3 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.11.10) + jest: 29.7.0(@types/node@20.11.17) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -19555,7 +19626,7 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - /v-code-diff@1.7.2(vue@3.4.15): + /v-code-diff@1.7.2(vue@3.4.18): resolution: {integrity: sha512-y+q8ZHf8GfphYLhcZbjAKcId/h6vZujS71Ryq5u+dI6Jg4ZLTdLrBNVSzYpHywHSSFFfBMdilm6XvVryEaH4+A==} requiresBuild: true peerDependencies: @@ -19568,8 +19639,8 @@ packages: diff: 5.1.0 diff-match-patch: 1.0.5 highlight.js: 11.8.0 - vue: 3.4.15(typescript@5.3.3) - vue-demi: 0.13.11(vue@3.4.15) + vue: 3.4.18(typescript@5.3.3) + vue-demi: 0.13.11(vue@3.4.18) dev: false /v8-to-istanbul@9.2.0: @@ -19605,7 +19676,7 @@ packages: core-util-is: 1.0.2 extsprintf: 1.3.0 - /vite-node@0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0): + /vite-node@0.34.6(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -19615,7 +19686,7 @@ packages: mlly: 1.5.0 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - '@types/node' - less @@ -19631,8 +19702,8 @@ packages: resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==} dev: true - /vite@5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0): - resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + /vite@5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0): + resolution: {integrity: sha512-STmSFzhY4ljuhz14bg9LkMTk3d98IO6DIArnTY6MeBwiD1Za2StcQtz7fzOUnRCqrHSD5+OS2reg4HOz1eoLnw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -19659,9 +19730,9 @@ packages: terser: optional: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 esbuild: 0.19.11 - postcss: 8.4.33 + postcss: 8.4.35 rollup: 4.9.6 sass: 1.70.0 terser: 5.27.0 @@ -19713,7 +19784,7 @@ packages: dependencies: '@types/chai': 4.3.11 '@types/chai-subset': 1.3.5 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@vitest/expect': 0.34.6 '@vitest/runner': 0.34.6 '@vitest/snapshot': 0.34.6 @@ -19733,8 +19804,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.6.0 tinypool: 0.7.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vite-node: 0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vite-node: 0.34.6(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -19750,6 +19821,42 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + /vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + dev: false + + /vscode-languageclient@9.0.1: + resolution: {integrity: sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==} + engines: {vscode: ^1.82.0} + dependencies: + minimatch: 5.1.6 + semver: 7.5.4 + vscode-languageserver-protocol: 3.17.5 + dev: false + + /vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + dev: false + + /vscode-languageserver-textdocument@1.0.11: + resolution: {integrity: sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==} + dev: false + + /vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + dev: false + + /vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + dependencies: + vscode-languageserver-protocol: 3.17.5 + dev: false + /vscode-oniguruma@1.7.0: resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} dev: true @@ -19766,7 +19873,7 @@ packages: resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==} dev: true - /vue-demi@0.13.11(vue@3.4.15): + /vue-demi@0.13.11(vue@3.4.18): resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} engines: {node: '>=12'} hasBin: true @@ -19778,23 +19885,23 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) dev: false - /vue-docgen-api@4.64.1(vue@3.4.15): + /vue-docgen-api@4.64.1(vue@3.4.18): resolution: {integrity: sha512-jbOf7ByE3Zvtuk+429Jorl+eIeh2aB2Fx1GUo3xJd1aByJWE8KDlSEa6b11PB1ze8f0sRUBraRDinICCk0KY7g==} dependencies: '@babel/parser': 7.23.6 '@babel/types': 7.23.4 '@vue/compiler-dom': 3.4.15 - '@vue/compiler-sfc': 3.4.15 + '@vue/compiler-sfc': 3.4.18 ast-types: 0.14.2 hash-sum: 2.0.0 lru-cache: 8.0.4 pug: 3.0.2 recast: 0.22.0 ts-map: 1.0.3 - vue-inbrowser-compiler-independent-utils: 4.64.1(vue@3.4.15) + vue-inbrowser-compiler-independent-utils: 4.64.1(vue@3.4.18) transitivePeerDependencies: - vue dev: true @@ -19817,12 +19924,12 @@ packages: - supports-color dev: true - /vue-inbrowser-compiler-independent-utils@4.64.1(vue@3.4.15): + /vue-inbrowser-compiler-independent-utils@4.64.1(vue@3.4.18): resolution: {integrity: sha512-Hn32n07XZ8j9W8+fmOXPQL+i+W2e/8i6mkH4Ju3H6nR0+cfvmWM95GhczYi5B27+Y8JlCKgAo04IUiYce4mKAw==} peerDependencies: vue: '>=2' dependencies: - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) dev: true /vue-template-compiler@2.7.14: @@ -19844,28 +19951,28 @@ packages: typescript: 5.3.3 dev: true - /vue@3.4.15(typescript@5.3.3): - resolution: {integrity: sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==} + /vue@3.4.18(typescript@5.3.3): + resolution: {integrity: sha512-0zLRYamFRe0wF4q2L3O24KQzLyLpL64ye1RUToOgOxuWZsb/FhaNRdGmeozdtVYLz6tl94OXLaK7/WQIrVCw1A==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.4.15 - '@vue/compiler-sfc': 3.4.15 - '@vue/runtime-dom': 3.4.15 - '@vue/server-renderer': 3.4.15(vue@3.4.15) - '@vue/shared': 3.4.15 + '@vue/compiler-dom': 3.4.18 + '@vue/compiler-sfc': 3.4.18 + '@vue/runtime-dom': 3.4.18 + '@vue/server-renderer': 3.4.18(vue@3.4.18) + '@vue/shared': 3.4.18 typescript: 5.3.3 - /vuedraggable@4.1.0(vue@3.4.15): + /vuedraggable@4.1.0(vue@3.4.18): resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} peerDependencies: vue: ^3.0.1 dependencies: sortablejs: 1.14.0 - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) dev: false /w3c-xmlserializer@5.0.0: @@ -20329,11 +20436,27 @@ packages: readable-stream: 3.6.0 dev: false - github.com/aiscript-dev/aiscript-vscode/b5a8aa0ad927831a0b867d1c183460a14e6c48cd: - resolution: {tarball: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/b5a8aa0ad927831a0b867d1c183460a14e6c48cd} + '@github.com/aiscript-dev/aiscript-languageserver/releases/download/0.1.5/aiscript-dev-aiscript-languageserver-0.1.5.tgz': + resolution: {tarball: https://github.com/aiscript-dev/aiscript-languageserver/releases/download/0.1.5/aiscript-dev-aiscript-languageserver-0.1.5.tgz} + name: '@aiscript-dev/aiscript-languageserver' + version: 0.1.5 + hasBin: true + dependencies: + seedrandom: 3.0.5 + stringz: 2.1.0 + uuid: 9.0.1 + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.11 + dev: false + + github.com/aiscript-dev/aiscript-vscode/793211d40243c8775f6b85f015c221c82cbffb07: + resolution: {tarball: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/793211d40243c8775f6b85f015c221c82cbffb07} name: aiscript-vscode - version: 0.0.6 + version: 0.1.2 engines: {vscode: ^1.83.0} + dependencies: + '@aiscript-dev/aiscript-languageserver': '@github.com/aiscript-dev/aiscript-languageserver/releases/download/0.1.5/aiscript-dev-aiscript-languageserver-0.1.5.tgz' + vscode-languageclient: 9.0.1 dev: false github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.6.10)(@storybook/components@7.6.10)(@storybook/core-events@7.6.10)(@storybook/manager-api@7.6.10)(@storybook/preview-api@7.6.10)(@storybook/theming@7.6.10)(@storybook/types@7.6.10)(react-dom@18.2.0)(react@18.2.0): |