From e1bd9b944a9b2f12aec7d2222efe449417a8c186 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 28 Oct 2025 16:17:33 +0100 Subject: [PATCH] chore(deps): update dependency eslint-plugin-jsdoc to v60 (#36466) --- app/javascript/mastodon/actions/streaming.js | 37 ++++-- app/javascript/mastodon/stream.js | 12 +- package.json | 2 +- streaming/database.js | 2 +- streaming/index.js | 124 ++++++++++++------- streaming/logging.js | 2 +- streaming/redis.js | 1 + streaming/utils.js | 8 +- yarn.lock | 70 ++++++++--- 9 files changed, 177 insertions(+), 81 deletions(-) diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js index 478e0cae45..4299bad5c3 100644 --- a/app/javascript/mastodon/actions/streaming.js +++ b/app/javascript/mastodon/actions/streaming.js @@ -32,13 +32,20 @@ import { const randomUpTo = max => Math.floor(Math.random() * Math.floor(max)); +/** + * @typedef {import('mastodon/store').AppDispatch} Dispatch + * @typedef {import('mastodon/store').GetState} GetState + * @typedef {import('redux').UnknownAction} UnknownAction + * @typedef {function(Dispatch, GetState): Promise} FallbackFunction + */ + /** * @param {string} timelineId * @param {string} channelName * @param {Object.} params * @param {Object} options - * @param {function(Function, Function): Promise} [options.fallback] - * @param {function(): void} [options.fillGaps] + * @param {FallbackFunction} [options.fallback] + * @param {function(): UnknownAction} [options.fillGaps] * @param {function(object): boolean} [options.accept] * @returns {function(): void} */ @@ -46,13 +53,14 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti const { messages } = getLocale(); return connectStream(channelName, params, (dispatch, getState) => { + // @ts-ignore const locale = getState().getIn(['meta', 'locale']); // @ts-expect-error let pollingId; /** - * @param {function(Function, Function): Promise} fallback + * @param {FallbackFunction} fallback */ const useFallback = async fallback => { @@ -132,7 +140,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti }; /** - * @param {Function} dispatch + * @param {Dispatch} dispatch */ async function refreshHomeTimelineAndNotification(dispatch) { await dispatch(expandHomeTimeline({ maxId: undefined })); @@ -151,7 +159,11 @@ async function refreshHomeTimelineAndNotification(dispatch) { * @returns {function(): void} */ export const connectUserStream = () => - connectTimelineStream('home', 'user', {}, { fallback: refreshHomeTimelineAndNotification, fillGaps: fillHomeTimelineGaps }); + connectTimelineStream('home', 'user', {}, { + fallback: refreshHomeTimelineAndNotification, + // @ts-expect-error + fillGaps: fillHomeTimelineGaps + }); /** * @param {Object} options @@ -159,7 +171,10 @@ export const connectUserStream = () => * @returns {function(): void} */ export const connectCommunityStream = ({ onlyMedia } = {}) => - connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`, {}, { fillGaps: () => (fillCommunityTimelineGaps({ onlyMedia })) }); + connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`, {}, { + // @ts-expect-error + fillGaps: () => (fillCommunityTimelineGaps({ onlyMedia })) + }); /** * @param {Object} options @@ -168,7 +183,10 @@ export const connectCommunityStream = ({ onlyMedia } = {}) => * @returns {function(): void} */ export const connectPublicStream = ({ onlyMedia, onlyRemote } = {}) => - connectTimelineStream(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, `public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, {}, { fillGaps: () => fillPublicTimelineGaps({ onlyMedia, onlyRemote }) }); + connectTimelineStream(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, `public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, {}, { + // @ts-expect-error + fillGaps: () => fillPublicTimelineGaps({ onlyMedia, onlyRemote }) + }); /** * @param {string} columnId @@ -191,4 +209,7 @@ export const connectDirectStream = () => * @returns {function(): void} */ export const connectListStream = listId => - connectTimelineStream(`list:${listId}`, 'list', { list: listId }, { fillGaps: () => fillListTimelineGaps(listId) }); + connectTimelineStream(`list:${listId}`, 'list', { list: listId }, { + // @ts-expect-error + fillGaps: () => fillListTimelineGaps(listId) + }); diff --git a/app/javascript/mastodon/stream.js b/app/javascript/mastodon/stream.js index 59b2fd7582..27fbc25ba5 100644 --- a/app/javascript/mastodon/stream.js +++ b/app/javascript/mastodon/stream.js @@ -138,10 +138,15 @@ const channelNameWithInlineParams = (channelName, params) => { return `${channelName}&${Object.keys(params).map(key => `${key}=${params[key]}`).join('&')}`; }; +/** + * @typedef {import('mastodon/store').AppDispatch} Dispatch + * @typedef {import('mastodon/store').GetState} GetState + */ + /** * @param {string} channelName * @param {Object.} params - * @param {function(Function, Function): { onConnect: (function(): void), onReceive: (function(StreamEvent): void), onDisconnect: (function(): void) }} callbacks + * @param {function(Dispatch, GetState): { onConnect: (function(): void), onReceive: (function(StreamEvent): void), onDisconnect: (function(): void) }} callbacks * @returns {function(): void} */ // @ts-expect-error @@ -229,7 +234,7 @@ const handleEventSourceMessage = (e, received) => { * @param {string} streamingAPIBaseURL * @param {string} accessToken * @param {string} channelName - * @param {{ connected: Function, received: function(StreamEvent): void, disconnected: Function, reconnected: Function }} callbacks + * @param {{ connected: function(): void, received: function(StreamEvent): void, disconnected: function(): void, reconnected: function(): void }} callbacks * @returns {WebSocketClient | EventSource} */ const createConnection = (streamingAPIBaseURL, accessToken, channelName, { connected, received, disconnected, reconnected }) => { @@ -242,12 +247,9 @@ const createConnection = (streamingAPIBaseURL, accessToken, channelName, { conne // @ts-expect-error const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken); - // @ts-expect-error ws.onopen = connected; ws.onmessage = e => received(JSON.parse(e.data)); - // @ts-expect-error ws.onclose = disconnected; - // @ts-expect-error ws.onreconnect = reconnected; return ws; diff --git a/package.json b/package.json index 16095441d8..ae482f478a 100644 --- a/package.json +++ b/package.json @@ -171,7 +171,7 @@ "eslint-import-resolver-typescript": "^4.2.5", "eslint-plugin-formatjs": "^5.3.1", "eslint-plugin-import": "~2.32.0", - "eslint-plugin-jsdoc": "^54.0.0", + "eslint-plugin-jsdoc": "^60.0.0", "eslint-plugin-jsx-a11y": "~6.10.2", "eslint-plugin-promise": "~7.2.1", "eslint-plugin-react": "^7.37.4", diff --git a/streaming/database.js b/streaming/database.js index 553c9149cc..9dd7a97cfe 100644 --- a/streaming/database.js +++ b/streaming/database.js @@ -65,7 +65,7 @@ export function configFromEnv(env, environment) { if (typeof parsedUrl.ssl === 'boolean') { baseConfig.ssl = parsedUrl.ssl; } else if (typeof parsedUrl.ssl === 'object' && !Array.isArray(parsedUrl.ssl) && parsedUrl.ssl !== null) { - /** @type {Record} */ + /** @type {Record} */ const sslOptions = parsedUrl.ssl; baseConfig.ssl = {}; diff --git a/streaming/index.js b/streaming/index.js index 113eabc03a..637baf21a9 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -48,14 +48,25 @@ initializeLogLevel(process.env, environment); * @property {number} permissions */ +/** + * @typedef {http.IncomingMessage & ResolvedAccount & { + * path: string + * query: Record + * remoteAddress?: string + * cachedFilters: unknown + * scopes: string[] + * necessaryScopes: string[] + * }} Request + */ + /** * Attempts to safely parse a string as JSON, used when both receiving a message * from redis and when receiving a message from a client over a websocket * connection, this is why it accepts a `req` argument. * @param {string} json - * @param {any?} req - * @returns {Object.|null} + * @param {Request?} req + * @returns {Object.|null} */ const parseJSON = (json, req) => { try { @@ -172,6 +183,7 @@ const startServer = async () => { let resolvedAccount; try { + // @ts-expect-error resolvedAccount = await accountFromRequest(request); } catch (err) { // Unfortunately for using the on('upgrade') setup, we need to manually @@ -222,7 +234,7 @@ const startServer = async () => { }); /** - * @type {Object.): void>>} + * @type {Object.): void>>} */ const subs = {}; @@ -340,7 +352,7 @@ const startServer = async () => { }; /** - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {string[]} necessaryScopes * @returns {boolean} */ @@ -349,7 +361,7 @@ const startServer = async () => { /** * @param {string} token - * @param {any} req + * @param {Request} req * @returns {Promise} */ const accountFromToken = async (token, req) => { @@ -374,13 +386,13 @@ const startServer = async () => { }; /** - * @param {any} req + * @param {Request} req * @returns {Promise} */ const accountFromRequest = (req) => new Promise((resolve, reject) => { const authorization = req.headers.authorization; - const location = url.parse(req.url, true); - const accessToken = location.query.access_token || req.headers['sec-websocket-protocol']; + const location = req.url ? url.parse(req.url, true) : undefined; + const accessToken = location?.query.access_token || req.headers['sec-websocket-protocol']; if (!authorization && !accessToken) { reject(new AuthenticationError('Missing access token')); @@ -389,11 +401,12 @@ const startServer = async () => { const token = authorization ? authorization.replace(/^Bearer /, '') : accessToken; + // @ts-expect-error resolve(accountFromToken(token, req)); }); /** - * @param {any} req + * @param {Request} req * @returns {string|undefined} */ const channelNameFromPath = req => { @@ -425,7 +438,7 @@ const startServer = async () => { }; /** - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {import('pino').Logger} logger * @param {string|undefined} channelName * @returns {Promise.} @@ -463,7 +476,7 @@ const startServer = async () => { */ /** - * @param {any} req + * @param {Request} req * @param {SystemMessageHandlers} eventHandlers * @returns {SubscriptionListener} */ @@ -488,7 +501,7 @@ const startServer = async () => { }; /** - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {http.OutgoingMessage} res */ const subscribeHttpToSystemChannel = (req, res) => { @@ -515,8 +528,8 @@ const startServer = async () => { }; /** - * @param {any} req - * @param {any} res + * @param {Request} req + * @param {http.ServerResponse} res * @param {function(Error=): void} next */ const authenticationMiddleware = (req, res, next) => { @@ -545,8 +558,8 @@ const startServer = async () => { /** * @param {Error} err - * @param {any} req - * @param {any} res + * @param {Request} req + * @param {http.ServerResponse} res * @param {function(Error=): void} next */ const errorMiddleware = (err, req, res, next) => { @@ -564,16 +577,15 @@ const startServer = async () => { }; /** - * @param {any[]} arr + * @param {string[]} arr * @param {number=} shift * @returns {string} */ - // @ts-ignore const placeholders = (arr, shift = 0) => arr.map((_, i) => `$${i + 1 + shift}`).join(', '); /** * @param {string} listId - * @param {any} req + * @param {Request} req * @returns {Promise.} */ const authorizeListAccess = async (listId, req) => { @@ -623,7 +635,7 @@ const startServer = async () => { /** * @param {string[]} channelIds - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {import('pino').Logger} log * @param {function(string, string): void} output * @param {undefined | function(string[], SubscriptionListener): void} attachCloseHandler @@ -675,6 +687,7 @@ const startServer = async () => { // The channels that need filtering are determined in the function // `channelNameToIds` defined below: if (!needsFiltering || (event !== 'update' && event !== 'status.update')) { + // @ts-expect-error transmit(event, payload); return; } @@ -689,7 +702,9 @@ const startServer = async () => { } // Filter based on language: + // @ts-expect-error if (Array.isArray(req.chosenLanguages) && req.chosenLanguages.indexOf(payload.language) === -1) { + // @ts-expect-error log.debug(`Message ${payload.id} filtered by language (${payload.language})`); return; } @@ -701,8 +716,9 @@ const startServer = async () => { } // Filter based on domain blocks, blocks, mutes, or custom filters: - // @ts-ignore + // @ts-expect-error const targetAccountIds = [payload.account.id].concat(payload.mentions.map(item => item.id)); + // @ts-expect-error const accountDomain = payload.account.acct.split('@')[1]; // TODO: Move this logic out of the message handling loop @@ -713,7 +729,7 @@ const startServer = async () => { } const queries = [ - // @ts-ignore + // @ts-expect-error client.query(`SELECT 1 FROM blocks WHERE (account_id = $1 AND target_account_id IN (${placeholders(targetAccountIds, 2)})) @@ -722,17 +738,19 @@ const startServer = async () => { SELECT 1 FROM mutes WHERE account_id = $1 - AND target_account_id IN (${placeholders(targetAccountIds, 2)})`, [req.accountId, payload.account.id].concat(targetAccountIds)), + AND target_account_id IN (${placeholders(targetAccountIds, 2)})`, [req.accountId, payload. + // @ts-expect-error + account.id].concat(targetAccountIds)), ]; if (accountDomain) { - // @ts-ignore + // @ts-expect-error queries.push(client.query('SELECT 1 FROM account_domain_blocks WHERE account_id = $1 AND domain = $2', [req.accountId, accountDomain])); } - // @ts-ignore + // @ts-expect-error if (!payload.filtered && !req.cachedFilters) { - // @ts-ignore + // @ts-expect-error queries.push(client.query('SELECT filter.id AS id, filter.phrase AS title, filter.context AS context, filter.expires_at AS expires_at, filter.action AS filter_action, keyword.keyword AS keyword, keyword.whole_word AS whole_word FROM custom_filter_keywords keyword JOIN custom_filters filter ON keyword.custom_filter_id = filter.id WHERE filter.account_id = $1 AND (filter.expires_at IS NULL OR filter.expires_at > NOW())', [req.accountId])); } @@ -741,6 +759,7 @@ const startServer = async () => { // Handling blocks & mutes and domain blocks: If one of those applies, // then we don't transmit the payload of the event to the client + // @ts-expect-error if (values[0].rows.length > 0 || (accountDomain && values[1].rows.length > 0)) { return; } @@ -757,9 +776,9 @@ const startServer = async () => { // TODO: Move this logic out of the message handling lifecycle // @ts-ignore if (!req.cachedFilters) { + // @ts-expect-error const filterRows = values[accountDomain ? 2 : 1].rows; - // @ts-ignore req.cachedFilters = filterRows.reduce((cache, filter) => { if (cache[filter.id]) { cache[filter.id].keywords.push([filter.keyword, filter.whole_word]); @@ -789,9 +808,9 @@ const startServer = async () => { // needs to be done in a separate loop as the database returns one // filterRow per keyword, so we need all the keywords before // constructing the regular expression - // @ts-ignore + // @ts-expect-error Object.keys(req.cachedFilters).forEach((key) => { - // @ts-ignore + // @ts-expect-error req.cachedFilters[key].regexp = new RegExp(req.cachedFilters[key].keywords.map(([keyword, whole_word]) => { let expr = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); @@ -812,16 +831,14 @@ const startServer = async () => { // Apply cachedFilters against the payload, constructing a // `filter_results` array of FilterResult entities - // @ts-ignore if (req.cachedFilters) { const status = payload; // TODO: Calculate searchableContent in Ruby on Rails: - // @ts-ignore + // @ts-expect-error const searchableContent = ([status.spoiler_text || '', status.content].concat((status.poll && status.poll.options) ? status.poll.options.map(option => option.title) : [])).concat(status.media_attachments.map(att => att.description)).join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); const searchableTextContent = JSDOM.fragment(searchableContent).textContent; const now = new Date(); - // @ts-ignore const filter_results = Object.values(req.cachedFilters).reduce((results, cachedFilter) => { // Check the filter hasn't expired before applying: if (cachedFilter.expires_at !== null && cachedFilter.expires_at < now) { @@ -881,8 +898,8 @@ const startServer = async () => { }; /** - * @param {any} req - * @param {any} res + * @param {Request} req + * @param {http.ServerResponse} res * @returns {function(string, string): void} */ const streamToHttp = (req, res) => { @@ -924,7 +941,7 @@ const startServer = async () => { }; /** - * @param {any} req + * @param {Request} req * @param {function(): void} [closeHandler] * @returns {function(string[], SubscriptionListener): void} */ @@ -974,10 +991,13 @@ const startServer = async () => { app.use(api); + // @ts-expect-error api.use(authenticationMiddleware); + // @ts-expect-error api.use(errorMiddleware); api.get('/api/v1/streaming/*', (req, res) => { + // @ts-expect-error const channelName = channelNameFromPath(req); // FIXME: In theory we'd never actually reach here due to @@ -988,8 +1008,11 @@ const startServer = async () => { return; } + // @ts-expect-error channelNameToIds(req, channelName, req.query).then(({ channelIds, options }) => { + // @ts-expect-error const onSend = streamToHttp(req, res); + // @ts-expect-error const onEnd = streamHttpEnd(req, subscriptionHeartbeat(channelIds)); // @ts-ignore @@ -1012,7 +1035,7 @@ const startServer = async () => { */ /** - * @param {any} req + * @param {Request} req * @returns {string[]} */ const channelsForUserStream = req => { @@ -1026,7 +1049,7 @@ const startServer = async () => { }; /** - * @param {any} req + * @param {Request} req * @param {string} name * @param {StreamParams} params * @returns {Promise.<{ channelIds: string[], options: { needsFiltering: boolean, filterLocal?: boolean, filterRemote?: boolean } }>} @@ -1145,7 +1168,7 @@ const startServer = async () => { /** * @typedef WebSocketSession * @property {import('ws').WebSocket & { isAlive: boolean}} websocket - * @property {http.IncomingMessage & ResolvedAccount} request + * @property {Request} request * @property {import('pino').Logger} logger * @property {Object.} subscriptions */ @@ -1271,7 +1294,7 @@ const startServer = async () => { /** * @param {import('ws').WebSocket & { isAlive: boolean }} ws - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {import('pino').Logger} log */ function onConnection(ws, req, log) { @@ -1338,9 +1361,19 @@ const startServer = async () => { const { type, stream, ...params } = json; if (type === 'subscribe') { - subscribeWebsocketToChannel(session, firstParam(stream), params); + subscribeWebsocketToChannel( + session, + // @ts-expect-error + firstParam(stream), + params + ); } else if (type === 'unsubscribe') { - unsubscribeWebsocketFromChannel(session, firstParam(stream), params); + unsubscribeWebsocketFromChannel( + session, + // @ts-expect-error + firstParam(stream), + params + ); } else { // Unknown action type } @@ -1360,13 +1393,13 @@ const startServer = async () => { setInterval(() => { wss.clients.forEach(ws => { - // @ts-ignore + // @ts-expect-error if (ws.isAlive === false) { ws.terminate(); return; } - // @ts-ignore + // @ts-expect-error ws.isAlive = false; ws.ping('', false); }); @@ -1396,14 +1429,16 @@ const startServer = async () => { }; /** - * @param {any} server + * @param {http.Server} server * @param {function(string): void} [onSuccess] */ const attachServerWithConfig = (server, onSuccess) => { if (process.env.SOCKET) { server.listen(process.env.SOCKET, () => { if (onSuccess) { + // @ts-expect-error fs.chmodSync(server.address(), 0o666); + // @ts-expect-error onSuccess(server.address()); } }); @@ -1418,6 +1453,7 @@ const attachServerWithConfig = (server, onSuccess) => { server.listen(port, bind, () => { if (onSuccess) { + // @ts-expect-error onSuccess(`${server.address().address}:${server.address().port}`); } }); diff --git a/streaming/logging.js b/streaming/logging.js index e1c552c22e..61946b622c 100644 --- a/streaming/logging.js +++ b/streaming/logging.js @@ -100,7 +100,7 @@ export function createWebsocketLogger(request, resolvedAccount) { /** * Initializes the log level based on the environment - * @param {Object} env + * @param {Object} env * @param {string} environment */ export function initializeLogLevel(env, environment) { diff --git a/streaming/redis.js b/streaming/redis.js index 040246fda9..e8f28c0f90 100644 --- a/streaming/redis.js +++ b/streaming/redis.js @@ -6,6 +6,7 @@ import { parseIntFromEnvValue } from './utils.js'; * @typedef RedisConfiguration * @property {string|undefined} url * @property {import('ioredis').RedisOptions} options + * @property {string|undefined} namespace */ /** diff --git a/streaming/utils.js b/streaming/utils.js index 47c63dd4ca..dd5e82c67c 100644 --- a/streaming/utils.js +++ b/streaming/utils.js @@ -13,11 +13,15 @@ const FALSE_VALUES = [ ]; /** - * @param {any} value + * @typedef {typeof FALSE_VALUES[number]} FalseValue + */ + +/** + * @param {unknown} value * @returns {boolean} */ export function isTruthy(value) { - return value && !FALSE_VALUES.includes(value); + return !!value && !FALSE_VALUES.includes(/** @type {FalseValue} */ (value)); } /** diff --git a/yarn.lock b/yarn.lock index ec4f2cd622..e74f1029e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2054,16 +2054,16 @@ __metadata: languageName: node linkType: hard -"@es-joy/jsdoccomment@npm:~0.52.0": - version: 0.52.0 - resolution: "@es-joy/jsdoccomment@npm:0.52.0" +"@es-joy/jsdoccomment@npm:~0.71.0": + version: 0.71.0 + resolution: "@es-joy/jsdoccomment@npm:0.71.0" dependencies: "@types/estree": "npm:^1.0.8" - "@typescript-eslint/types": "npm:^8.34.1" + "@typescript-eslint/types": "npm:^8.46.0" comment-parser: "npm:1.4.1" esquery: "npm:^1.6.0" - jsdoc-type-pratt-parser: "npm:~4.1.0" - checksum: 10c0/4def78060ef58859f31757b9d30c4939fc33e7d9ee85637a7f568c1d209c33aa0abd2cf5a3a4f3662ec5b12b85ecff2f2035d809dc93b9382a31a6dfb200d83c + jsdoc-type-pratt-parser: "npm:~6.6.0" + checksum: 10c0/fe64b729c18238c7e83f8fab30eab8ce97da6565adbb963011463f9abedef5393972ac1eeebd04b17b189e94bc389274dcb8f707023e96fd922d12dc608b5409 languageName: node linkType: hard @@ -2857,7 +2857,7 @@ __metadata: eslint-import-resolver-typescript: "npm:^4.2.5" eslint-plugin-formatjs: "npm:^5.3.1" eslint-plugin-import: "npm:~2.32.0" - eslint-plugin-jsdoc: "npm:^54.0.0" + eslint-plugin-jsdoc: "npm:^60.0.0" eslint-plugin-jsx-a11y: "npm:~6.10.2" eslint-plugin-promise: "npm:~7.2.1" eslint-plugin-react: "npm:^7.37.4" @@ -4657,13 +4657,20 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.45.0, @typescript-eslint/types@npm:^8.34.1, @typescript-eslint/types@npm:^8.45.0": +"@typescript-eslint/types@npm:8.45.0, @typescript-eslint/types@npm:^8.45.0": version: 8.45.0 resolution: "@typescript-eslint/types@npm:8.45.0" checksum: 10c0/0213a0573c671d13bc91961a2b2e814ec7f6381ff093bce6704017bd96b2fc7fee25906c815cedb32a0601cf5071ca6c7c5f940d087c3b0d3dd7d4bc03478278 languageName: node linkType: hard +"@typescript-eslint/types@npm:^8.46.0": + version: 8.46.1 + resolution: "@typescript-eslint/types@npm:8.46.1" + checksum: 10c0/90887acaa5b33b45af20cf7f87ec4ae098c0daa88484245473e73903fa6e542f613247c22148132167891ca06af6549a60b9d2fd14a65b22871e016901ce3756 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:8.45.0": version: 8.45.0 resolution: "@typescript-eslint/typescript-estree@npm:8.45.0" @@ -6368,7 +6375,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -7135,23 +7142,25 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsdoc@npm:^54.0.0": - version: 54.0.0 - resolution: "eslint-plugin-jsdoc@npm:54.0.0" +"eslint-plugin-jsdoc@npm:^60.0.0": + version: 60.8.3 + resolution: "eslint-plugin-jsdoc@npm:60.8.3" dependencies: - "@es-joy/jsdoccomment": "npm:~0.52.0" + "@es-joy/jsdoccomment": "npm:~0.71.0" are-docs-informative: "npm:^0.0.2" comment-parser: "npm:1.4.1" - debug: "npm:^4.4.1" + debug: "npm:^4.4.3" escape-string-regexp: "npm:^4.0.0" espree: "npm:^10.4.0" esquery: "npm:^1.6.0" + html-entities: "npm:^2.6.0" + object-deep-merge: "npm:^1.0.5" parse-imports-exports: "npm:^0.2.4" semver: "npm:^7.7.2" spdx-expression-parse: "npm:^4.0.0" peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10c0/cf0a388fc670ababe26f9584c467bc8c1592aa83affcf16118d8181c186a6d8f02a8ea65250766b45168fca5cb879a6af66e8457cdb98f0f923bd927572e2de5 + checksum: 10c0/2c5aa623a3e5f7410b36464df759ae5e7265ba6f9aaf67f7c16f9033c4a699532a3de702afe5bd6132717a61196be44aff170db36b71600278800770a9cd88ab languageName: node linkType: hard @@ -8159,6 +8168,13 @@ __metadata: languageName: node linkType: hard +"html-entities@npm:^2.6.0": + version: 2.6.0 + resolution: "html-entities@npm:2.6.0" + checksum: 10c0/7c8b15d9ea0cd00dc9279f61bab002ba6ca8a7a0f3c36ed2db3530a67a9621c017830d1d2c1c65beb9b8e3436ea663e9cf8b230472e0e413359399413b27c8b7 + languageName: node + linkType: hard + "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -8908,10 +8924,10 @@ __metadata: languageName: node linkType: hard -"jsdoc-type-pratt-parser@npm:~4.1.0": - version: 4.1.0 - resolution: "jsdoc-type-pratt-parser@npm:4.1.0" - checksum: 10c0/7700372d2e733a32f7ea0a1df9cec6752321a5345c11a91b2ab478a031a426e934f16d5c1f15c8566c7b2c10af9f27892a29c2c789039f595470e929a4aa60ea +"jsdoc-type-pratt-parser@npm:~6.6.0": + version: 6.6.0 + resolution: "jsdoc-type-pratt-parser@npm:6.6.0" + checksum: 10c0/3cb9c28a945a66a925ebe40fd752113af01e655a0a0fedc6b1702e23c8f9ed187c45caf6cf94f009bde6cf5c98562524aa7a74ebb4571fca6d3ee5bef0344ec1 languageName: node linkType: hard @@ -9867,6 +9883,15 @@ __metadata: languageName: node linkType: hard +"object-deep-merge@npm:^1.0.5": + version: 1.0.5 + resolution: "object-deep-merge@npm:1.0.5" + dependencies: + type-fest: "npm:4.2.0" + checksum: 10c0/6664ecb43a2519c9b101f1c3b130dfc73e108d86ec06fbe7261505e1522cf8b69b10dd53b8cbb4cde35cca9d44d349667e2404f06fff85cf9f50b825bb6d1839 + languageName: node + linkType: hard + "object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" @@ -13387,6 +13412,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:4.2.0": + version: 4.2.0 + resolution: "type-fest@npm:4.2.0" + checksum: 10c0/75e0c112ae91d3b68c75da9b7563cf393f91ebdfca5d53d0b3f0405690217eadca318f9ddb89d58ee6ed67b8e32d23a4eae2aabc4e351e5ae184d610247bf772 + languageName: node + linkType: hard + "type-fest@npm:^0.16.0": version: 0.16.0 resolution: "type-fest@npm:0.16.0"