From 95ace0991774042f32c21a26a8fc5f85eb124646 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 16:39:01 +0800 Subject: [PATCH 01/25] refactor(twitter): web-api -> mobile-api --- lib/routes/twitter/keyword.ts | 2 +- lib/routes/twitter/media.ts | 2 +- .../{web-api => mobile-api}/constants.ts | 0 .../twitter/{web-api => mobile-api}/login.ts | 56 +++++++++---------- .../twitter/{web-api => mobile-api}/media.ts | 0 .../twitter/{web-api => mobile-api}/search.ts | 0 .../twitter/{web-api => mobile-api}/token.ts | 0 .../twitter/{web-api => mobile-api}/tweet.ts | 0 .../{web-api => mobile-api}/twitter-api.ts | 0 .../twitter/{web-api => mobile-api}/user.ts | 0 lib/routes/twitter/tweet.ts | 2 +- lib/routes/twitter/user.ts | 2 +- package.json | 2 +- 13 files changed, 32 insertions(+), 34 deletions(-) rename lib/routes/twitter/{web-api => mobile-api}/constants.ts (100%) rename lib/routes/twitter/{web-api => mobile-api}/login.ts (80%) rename lib/routes/twitter/{web-api => mobile-api}/media.ts (100%) rename lib/routes/twitter/{web-api => mobile-api}/search.ts (100%) rename lib/routes/twitter/{web-api => mobile-api}/token.ts (100%) rename lib/routes/twitter/{web-api => mobile-api}/tweet.ts (100%) rename lib/routes/twitter/{web-api => mobile-api}/twitter-api.ts (100%) rename lib/routes/twitter/{web-api => mobile-api}/user.ts (100%) diff --git a/lib/routes/twitter/keyword.ts b/lib/routes/twitter/keyword.ts index d9c35ecf73e4a3..9d4e000764e4aa 100644 --- a/lib/routes/twitter/keyword.ts +++ b/lib/routes/twitter/keyword.ts @@ -1,5 +1,5 @@ import { Route } from '@/types'; -import webApiImpl from './web-api/search'; +import webApiImpl from './mobile-api/search'; export const route: Route = { path: '/keyword/:keyword/:routeParams?', diff --git a/lib/routes/twitter/media.ts b/lib/routes/twitter/media.ts index a52451677cd503..486237cd18b1db 100644 --- a/lib/routes/twitter/media.ts +++ b/lib/routes/twitter/media.ts @@ -1,5 +1,5 @@ import { Route } from '@/types'; -import webApiImpl from './web-api/media'; +import webApiImpl from './mobile-api/media'; export const route: Route = { path: '/media/:id/:routeParams?', diff --git a/lib/routes/twitter/web-api/constants.ts b/lib/routes/twitter/mobile-api/constants.ts similarity index 100% rename from lib/routes/twitter/web-api/constants.ts rename to lib/routes/twitter/mobile-api/constants.ts diff --git a/lib/routes/twitter/web-api/login.ts b/lib/routes/twitter/mobile-api/login.ts similarity index 80% rename from lib/routes/twitter/web-api/login.ts rename to lib/routes/twitter/mobile-api/login.ts index 3518ea79739f8d..3fc4defe8ee3c9 100644 --- a/lib/routes/twitter/web-api/login.ts +++ b/lib/routes/twitter/mobile-api/login.ts @@ -5,14 +5,12 @@ import got from '@/utils/got'; import crypto from 'crypto'; import { config } from '@/config'; import { v5 as uuidv5 } from 'uuid'; -import { authenticator } from 'otplib'; import logger from '@/utils/logger'; import cache from '@/utils/cache'; const NAMESPACE = 'd41d092b-b007-48f7-9129-e9538d2d8fe9'; const username = config.twitter.username; const password = config.twitter.password; -const authenticationSecret = config.twitter.authenticationSecret; let authentication = null; @@ -138,33 +136,33 @@ async function login() { authentication = subtask.open_account; break; } else if (subtask.subtask_id === 'LoginTwoFactorAuthChallenge') { - const token = authenticator.generate(authenticationSecret); - - // eslint-disable-next-line no-await-in-loop - const task5 = await got.post('https://api.twitter.com/1.1/onboarding/task.json', { - headers, - json: { - flow_token: task4.data.flow_token, - subtask_inputs: [ - { - enter_text: { - suggestion_id: null, - text: token, - link: 'next_link', - }, - subtask_id: 'LoginTwoFactorAuthChallenge', - }, - ], - }, - }); - logger.debug('Twitter login 6 finished: LoginTwoFactorAuthChallenge.'); - - for (const subtask of task5.data?.subtasks || []) { - if (subtask.open_account) { - authentication = subtask.open_account; - break; - } - } + // const token = authenticator.generate(authenticationSecret); + + // // eslint-disable-next-line no-await-in-loop + // const task5 = await got.post('https://api.twitter.com/1.1/onboarding/task.json', { + // headers, + // json: { + // flow_token: task4.data.flow_token, + // subtask_inputs: [ + // { + // enter_text: { + // suggestion_id: null, + // text: token, + // link: 'next_link', + // }, + // subtask_id: 'LoginTwoFactorAuthChallenge', + // }, + // ], + // }, + // }); + // logger.debug('Twitter login 6 finished: LoginTwoFactorAuthChallenge.'); + + // for (const subtask of task5.data?.subtasks || []) { + // if (subtask.open_account) { + // authentication = subtask.open_account; + // break; + // } + // } break; } } diff --git a/lib/routes/twitter/web-api/media.ts b/lib/routes/twitter/mobile-api/media.ts similarity index 100% rename from lib/routes/twitter/web-api/media.ts rename to lib/routes/twitter/mobile-api/media.ts diff --git a/lib/routes/twitter/web-api/search.ts b/lib/routes/twitter/mobile-api/search.ts similarity index 100% rename from lib/routes/twitter/web-api/search.ts rename to lib/routes/twitter/mobile-api/search.ts diff --git a/lib/routes/twitter/web-api/token.ts b/lib/routes/twitter/mobile-api/token.ts similarity index 100% rename from lib/routes/twitter/web-api/token.ts rename to lib/routes/twitter/mobile-api/token.ts diff --git a/lib/routes/twitter/web-api/tweet.ts b/lib/routes/twitter/mobile-api/tweet.ts similarity index 100% rename from lib/routes/twitter/web-api/tweet.ts rename to lib/routes/twitter/mobile-api/tweet.ts diff --git a/lib/routes/twitter/web-api/twitter-api.ts b/lib/routes/twitter/mobile-api/twitter-api.ts similarity index 100% rename from lib/routes/twitter/web-api/twitter-api.ts rename to lib/routes/twitter/mobile-api/twitter-api.ts diff --git a/lib/routes/twitter/web-api/user.ts b/lib/routes/twitter/mobile-api/user.ts similarity index 100% rename from lib/routes/twitter/web-api/user.ts rename to lib/routes/twitter/mobile-api/user.ts diff --git a/lib/routes/twitter/tweet.ts b/lib/routes/twitter/tweet.ts index bdd4e14c9f1faf..85ba8a5db7a508 100644 --- a/lib/routes/twitter/tweet.ts +++ b/lib/routes/twitter/tweet.ts @@ -1,5 +1,5 @@ import { Route } from '@/types'; -import webApiImpl from './web-api/tweet'; +import webApiImpl from './mobile-api/tweet'; export const route: Route = { path: '/tweet/:id/status/:status/:original?', diff --git a/lib/routes/twitter/user.ts b/lib/routes/twitter/user.ts index 9c255d584589a4..fcfaebaab20f46 100644 --- a/lib/routes/twitter/user.ts +++ b/lib/routes/twitter/user.ts @@ -1,5 +1,5 @@ import { Route } from '@/types'; -import webApiImpl from './web-api/user'; +import webApiImpl from './mobile-api/user'; export const route: Route = { path: '/user/:id/:routeParams?', diff --git a/package.json b/package.json index 4d41de705a1d82..fd68cafc4a4604 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ }, "license": "MIT", "author": "DIYgod", - "main": "lib/pkg.js", + "main": "lib/pkg.ts", "files": [ "lib" ], From 4a7c00f27484c39dbee69806079a714887448183 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 20:57:19 +0800 Subject: [PATCH 02/25] feat(twitter): api structure and web user --- lib/config.ts | 3 +- .../twitter/{ => api}/developer-api/search.ts | 2 +- .../twitter/{ => api}/developer-api/user.ts | 2 +- lib/routes/twitter/api/index.ts | 37 ++++++ .../twitter-api.ts => api/mobile-api/api.ts} | 5 +- .../twitter/{ => api}/mobile-api/constants.ts | 0 .../twitter/{ => api}/mobile-api/login.ts | 0 .../twitter/{ => api}/mobile-api/token.ts | 0 lib/routes/twitter/api/web-api/api.ts | 121 ++++++++++++++++++ lib/routes/twitter/api/web-api/constants.ts | 93 ++++++++++++++ lib/routes/twitter/api/web-api/utils.ts | 120 +++++++++++++++++ lib/routes/twitter/keyword.ts | 16 ++- lib/routes/twitter/media.ts | 22 +++- lib/routes/twitter/mobile-api/media.ts | 25 ---- lib/routes/twitter/mobile-api/search.ts | 18 --- lib/routes/twitter/mobile-api/tweet.ts | 27 ---- lib/routes/twitter/mobile-api/user.ts | 30 ----- lib/routes/twitter/tweet.ts | 23 +++- lib/routes/twitter/user.ts | 28 +++- lib/routes/twitter/utils.ts | 13 +- 20 files changed, 471 insertions(+), 114 deletions(-) rename lib/routes/twitter/{ => api}/developer-api/search.ts (94%) rename lib/routes/twitter/{ => api}/developer-api/user.ts (97%) create mode 100644 lib/routes/twitter/api/index.ts rename lib/routes/twitter/{mobile-api/twitter-api.ts => api/mobile-api/api.ts} (99%) rename lib/routes/twitter/{ => api}/mobile-api/constants.ts (100%) rename lib/routes/twitter/{ => api}/mobile-api/login.ts (100%) rename lib/routes/twitter/{ => api}/mobile-api/token.ts (100%) create mode 100644 lib/routes/twitter/api/web-api/api.ts create mode 100644 lib/routes/twitter/api/web-api/constants.ts create mode 100644 lib/routes/twitter/api/web-api/utils.ts delete mode 100644 lib/routes/twitter/mobile-api/media.ts delete mode 100644 lib/routes/twitter/mobile-api/search.ts delete mode 100644 lib/routes/twitter/mobile-api/tweet.ts delete mode 100644 lib/routes/twitter/mobile-api/user.ts diff --git a/lib/config.ts b/lib/config.ts index c915144c4a4003..d99935c457cc54 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -252,6 +252,7 @@ export type Config = { oauthTokenSecrets?: string[]; username?: string; password?: string; + cookie?: string; }; weibo: { app_key?: string; @@ -591,7 +592,7 @@ const calculateValue = () => { oauthTokenSecrets: envs.TWITTER_OAUTH_TOKEN_SECRET?.split(','), username: envs.TWITTER_USERNAME, password: envs.TWITTER_PASSWORD, - authenticationSecret: envs.TWITTER_AUTHENTICATION_SECRET, + cookie: envs.TWITTER_COOKIE, }, weibo: { app_key: envs.WEIBO_APP_KEY, diff --git a/lib/routes/twitter/developer-api/search.ts b/lib/routes/twitter/api/developer-api/search.ts similarity index 94% rename from lib/routes/twitter/developer-api/search.ts rename to lib/routes/twitter/api/developer-api/search.ts index 3afb40b4af7388..f3162e2fdf7eb8 100644 --- a/lib/routes/twitter/developer-api/search.ts +++ b/lib/routes/twitter/api/developer-api/search.ts @@ -1,4 +1,4 @@ -import utils from '../utils'; +import utils from '../../utils'; export default async (ctx) => { const keyword = ctx.req.param('keyword'); diff --git a/lib/routes/twitter/developer-api/user.ts b/lib/routes/twitter/api/developer-api/user.ts similarity index 97% rename from lib/routes/twitter/developer-api/user.ts rename to lib/routes/twitter/api/developer-api/user.ts index 9153336afc7585..a5c94712fddbce 100644 --- a/lib/routes/twitter/developer-api/user.ts +++ b/lib/routes/twitter/api/developer-api/user.ts @@ -1,4 +1,4 @@ -import utils from '../utils'; +import utils from '../../utils'; export default async (ctx) => { const id = ctx.req.param('id'); diff --git a/lib/routes/twitter/api/index.ts b/lib/routes/twitter/api/index.ts new file mode 100644 index 00000000000000..209013c79b2764 --- /dev/null +++ b/lib/routes/twitter/api/index.ts @@ -0,0 +1,37 @@ +import mobileApi from './mobile-api/api'; +import webApi from './web-api/api'; +import { config } from '@/config'; + +const enableMobileApi = config.twitter.username && config.twitter.password; +const enableWebApi = config.twitter.cookie; + +type ApiItem = (id: string, params?: Record) => Promise> | Record | null; +let api: { + init: () => void; + getUser: ApiItem; + getUserTweets: ApiItem; + getUserTweetsAndReplies: ApiItem; + getUserMedia: ApiItem; + getUserLikes: ApiItem; + getUserTweet: ApiItem; + getSearch: ApiItem; +} = { + init: () => { + throw new Error('Twitter API is not configured'); + }, + getUser: () => null, + getUserTweets: () => null, + getUserTweetsAndReplies: () => null, + getUserMedia: () => null, + getUserLikes: () => null, + getUserTweet: () => null, + getSearch: () => null, +}; + +if (enableWebApi) { + api = webApi; +} else if (enableMobileApi) { + api = mobileApi; +} + +export default api; diff --git a/lib/routes/twitter/mobile-api/twitter-api.ts b/lib/routes/twitter/api/mobile-api/api.ts similarity index 99% rename from lib/routes/twitter/mobile-api/twitter-api.ts rename to lib/routes/twitter/api/mobile-api/api.ts index a33d861d008520..aa8bc978326087 100644 --- a/lib/routes/twitter/mobile-api/twitter-api.ts +++ b/lib/routes/twitter/api/mobile-api/api.ts @@ -5,7 +5,7 @@ import got from '@/utils/got'; import OAuth from 'oauth-1.0a'; import CryptoJS from 'crypto-js'; import queryString from 'query-string'; -import { getToken } from './token'; +import { initToken, getToken } from './token'; import cache from '@/utils/cache'; const twitterGot = async (url, params) => { @@ -269,7 +269,7 @@ const getUserTweet = (id, params) => cacheTryGet(id, params, getUserTweetByStatu const getSearch = async (keywords, params = {}) => gatherLegacyFromData(await timelineKeywords(keywords, params)); -export { +export default { getUser, getUserTweets, getUserTweetsAndReplies, @@ -278,4 +278,5 @@ export { excludeRetweet, getSearch, getUserTweet, + init: initToken, }; diff --git a/lib/routes/twitter/mobile-api/constants.ts b/lib/routes/twitter/api/mobile-api/constants.ts similarity index 100% rename from lib/routes/twitter/mobile-api/constants.ts rename to lib/routes/twitter/api/mobile-api/constants.ts diff --git a/lib/routes/twitter/mobile-api/login.ts b/lib/routes/twitter/api/mobile-api/login.ts similarity index 100% rename from lib/routes/twitter/mobile-api/login.ts rename to lib/routes/twitter/api/mobile-api/login.ts diff --git a/lib/routes/twitter/mobile-api/token.ts b/lib/routes/twitter/api/mobile-api/token.ts similarity index 100% rename from lib/routes/twitter/mobile-api/token.ts rename to lib/routes/twitter/api/mobile-api/token.ts diff --git a/lib/routes/twitter/api/web-api/api.ts b/lib/routes/twitter/api/web-api/api.ts new file mode 100644 index 00000000000000..8c81c873819ca0 --- /dev/null +++ b/lib/routes/twitter/api/web-api/api.ts @@ -0,0 +1,121 @@ +import { baseUrl, gqlMap, gqlFeatures, gqlFieldToggles } from './constants'; +import { config } from '@/config'; +import cache from '@/utils/cache'; +import { twitterGot, paginationTweets, gatherLegacyFromData } from './utils'; + +const getUserData = (id) => + cache.tryGet(`twitter-userdata-${id}`, () => { + if (id.startsWith('+')) { + return twitterGot(`${baseUrl}${gqlMap.UserByRestId}`, { + variables: JSON.stringify({ + userId: id.slice(1), + withSafetyModeUserFields: true, + }), + features: JSON.stringify(gqlFeatures.UserByRestId), + fieldToggles: JSON.stringify(gqlFieldToggles.UserByScreenName), + }); + } + return twitterGot(`${baseUrl}${gqlMap.UserByScreenName}`, { + variables: JSON.stringify({ + screen_name: id, + withSafetyModeUserFields: true, + }), + features: JSON.stringify(gqlFeatures.UserByScreenName), + fieldToggles: JSON.stringify(gqlFieldToggles.UserByScreenName), + }); + }); + +const cacheTryGet = async (_id, params, func) => { + const userData: any = await getUserData(_id); + const id = (userData.data?.user || userData.data?.user_result)?.result?.rest_id; + if (id === undefined) { + throw new Error('User not found'); + } + const funcName = func.name; + const paramsString = JSON.stringify(params); + return cache.tryGet(`twitter:${id}:${funcName}:${paramsString}`, () => func(id, params), config.cache.routeExpire, false); +}; + +const getUserTweets = (id: string, params?: Record) => + cacheTryGet(id, params, async (id, params = {}) => + gatherLegacyFromData( + await paginationTweets('UserTweets', id, { + ...params, + withQuickPromoteEligibilityTweetFields: true, + }) + ) + ); + +const getUserTweetsAndReplies = (id: string, params?: Record) => + cacheTryGet(id, params, async (id, params = {}) => + gatherLegacyFromData( + await paginationTweets('UserTweetsAndReplies', id, { + ...params, + count: 20, + includePromotedContent: true, + withCommunity: true, + withVoice: true, + withV2Timeline: true, + }), + ['profile-conversation-'], + id + ) + ); + +const getUserMedia = (id: string, params?: Record) => cacheTryGet(id, params, async (id, params = {}) => gatherLegacyFromData(await paginationTweets('MediaTimeline', id, params))); + +const getUserLikes = (id: string, params?: Record) => cacheTryGet(id, params, async (id, params = {}) => gatherLegacyFromData(await paginationTweets('Likes', id, params))); + +const getUserTweet = (id: string, params?: Record) => + cacheTryGet(id, params, async (id, params = {}) => + gatherLegacyFromData( + await paginationTweets( + 'TweetDetail', + id, + { + ...params, + includeHasBirdwatchNotes: false, + includePromotedContent: false, + withBirdwatchNotes: false, + withVoice: false, + withV2Timeline: true, + }, + ['threaded_conversation_with_injections_v2'] + ), + ['homeConversation-', 'conversationthread-'] + ) + ); + +const getSearch = async (keywords: string, params?: Record) => + gatherLegacyFromData( + await paginationTweets( + 'SearchTimeline', + undefined, + { + ...params, + rawQuery: keywords, + count: 20, + product: 'Latest', + withDownvotePerspective: false, + withReactionsMetadata: false, + withReactionsPerspective: false, + }, + ['search_by_raw_query', 'search_timeline', 'timeline'] + ) + ); + +const getUser = async (id: string) => { + const userData: any = await getUserData(id); + return (userData.data?.user || userData.data?.user_result)?.result?.legacy; +}; + +export default { + getUser, + getUserTweets, + getUserTweetsAndReplies, + getUserMedia, + getUserLikes, + getUserTweet, + getSearch, + init: () => {}, +}; diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts new file mode 100644 index 00000000000000..01df27da1b38be --- /dev/null +++ b/lib/routes/twitter/api/web-api/constants.ts @@ -0,0 +1,93 @@ +const baseUrl = 'https://twitter.com/i/api'; + +const graphQLEndpointsPlain = [ + '/graphql/eS7LO5Jy3xgmd3dbL044EA/UserTweets', + '/graphql/k5XapwcSikNsEsILW5FvgA/UserByScreenName', + '/graphql/k3YiLNE_MAy5J-NANLERdg/HomeTimeline', + '/graphql/3GeIaLmNhTm1YsUmxR57tg/UserTweetsAndReplies', + '/graphql/TOU4gQw8wXIqpSzA4TYKgg/UserMedia', + '/graphql/B8I_QCljDBVfin21TTWMqA/Likes', + '/graphql/tD8zKvQzwY3kdx5yz6YmOw/UserByRestId', +]; + +const gqlMap = Object.fromEntries(graphQLEndpointsPlain.map((endpoint) => [endpoint.split('/')[3].replace(/V2$|Query$|QueryV2$/, ''), endpoint])); + +const gqlFeatures = { + UserByScreenName: { + hidden_profile_likes_enabled: true, + hidden_profile_subscriptions_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + subscriptions_verification_info_is_identity_verified_enabled: true, + subscriptions_verification_info_verified_since_enabled: true, + highlights_tweets_tab_ui_enabled: true, + responsive_web_twitter_article_notes_tab_enabled: true, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + responsive_web_graphql_timeline_navigation_enabled: true, + }, + UserByRestId: { + hidden_profile_likes_enabled: true, + hidden_profile_subscriptions_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + subscriptions_verification_info_is_identity_verified_enabled: true, + subscriptions_verification_info_verified_since_enabled: true, + highlights_tweets_tab_ui_enabled: true, + responsive_web_twitter_article_notes_tab_enabled: true, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + responsive_web_graphql_timeline_navigation_enabled: true, + }, + UserTweetsAndReplies: { + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: true, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, + }, +}; + +const gqlFieldToggles = { + UserByScreenName: { + withAuxiliaryUserLabels: false, + }, + UserByRestId: { + withAuxiliaryUserLabels: false, + }, +}; + +const timelineParams = { + include_can_media_tag: 1, + include_cards: 1, + include_entities: 1, + include_profile_interstitial_type: 0, + include_quote_count: 0, + include_reply_count: 0, + include_user_entities: 0, + include_ext_reply_count: 0, + include_ext_media_color: 0, + cards_platform: 'Web-13', + tweet_mode: 'extended', + send_error_codes: 1, + simple_quoted_tweet: 1, +}; + +const bearerToken = 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA'; + +export { baseUrl, gqlMap, gqlFeatures, gqlFieldToggles, timelineParams, bearerToken }; diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts new file mode 100644 index 00000000000000..5f89ede024e965 --- /dev/null +++ b/lib/routes/twitter/api/web-api/utils.ts @@ -0,0 +1,120 @@ +import { baseUrl, gqlFeatures, bearerToken, gqlMap } from './constants'; +import { config } from '@/config'; +import got from '@/utils/got'; +import queryString from 'query-string'; +import { Cookie } from 'tough-cookie'; + +export const twitterGot = async (url, params) => { + if (!config.twitter.cookie) { + throw new Error('Twitter cookie is not configured'); + } + const jsonCookie = Object.fromEntries( + config.twitter.cookie + .split(';') + .map((c) => Cookie.parse(c)?.toJSON()) + .map((c) => [c.key, c.value]) + ); + if (!jsonCookie || !jsonCookie.auth_token || !jsonCookie.ct0) { + throw new Error('Twitter cookie is not valid'); + } + + const requestData = { + url: `${url}?${queryString.stringify(params)}`, + method: 'GET', + headers: { + authority: 'twitter.com', + accept: '*/*', + 'accept-language': 'en-US,en;q=0.9', + authorization: bearerToken, + 'cache-control': 'no-cache', + 'content-type': 'application/json', + cookie: config.twitter.cookie, + dnt: '1', + pragma: 'no-cache', + referer: 'https://twitter.com/narendramodi', + 'x-csrf-token': jsonCookie.ct0, + 'x-twitter-active-user': 'yes', + 'x-twitter-auth-type': 'OAuth2Session', + 'x-twitter-client-language': 'en', + }, + }; + + const response = await got(requestData.url, { + headers: requestData.headers, + }); + + return response.data; +}; + +export const paginationTweets = async (endpoint: string, userId: number | undefined, variables: Record, path?: string[]) => { + const { data } = await twitterGot(baseUrl + gqlMap[endpoint], { + variables: JSON.stringify({ + ...variables, + userId, + }), + features: JSON.stringify(gqlFeatures[endpoint]), + }); + + let instructions; + if (path) { + instructions = data; + for (const p of path) { + instructions = instructions[p]; + } + instructions = instructions.instructions; + } else { + instructions = data.user.result.timeline_v2.timeline.instructions; + } + + return instructions.find((i) => i.__typename === 'TimelineAddEntries' || i.type === 'TimelineAddEntries').entries; +}; + +export function gatherLegacyFromData(entries, filterNested?: string[], userId?: number | string) { + const tweets = []; + const filteredEntries = []; + for (const entry of entries) { + const entryId = entry.entryId; + if (entryId) { + if (entryId.startsWith('tweet-')) { + filteredEntries.push(entry); + } + if (filterNested && filterNested.some((f) => entryId.startsWith(f))) { + filteredEntries.push(...entry.content.items); + } + } + } + for (const entry of filteredEntries) { + if (entry.entryId) { + const content = entry.content || entry.item; + let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; + if (tweet && tweet.tweet) { + tweet = tweet.tweet; + } + if (tweet) { + const retweet = tweet.legacy?.retweeted_status_result?.result; + for (const t of [tweet, retweet]) { + if (!t?.legacy) { + continue; + } + t.legacy.user = t.core?.user_result?.result?.legacy || t.core?.user_results?.result?.legacy; + t.legacy.id_str = t.rest_id; // avoid falling back to conversation_id_str elsewhere + const quote = t.quoted_status_result?.result; + if (quote) { + t.legacy.quoted_status = quote.legacy; + t.legacy.quoted_status.user = quote.core.user_result?.result?.legacy || quote.core.user_results?.result?.legacy; + } + } + const legacy = tweet.legacy; + if (legacy) { + if (retweet) { + legacy.retweeted_status = retweet.legacy; + } + if (userId === undefined || legacy.user_id_str === userId + '') { + tweets.push(legacy); + } + } + } + } + } + return tweets; +} diff --git a/lib/routes/twitter/keyword.ts b/lib/routes/twitter/keyword.ts index 9d4e000764e4aa..1538d8329eb611 100644 --- a/lib/routes/twitter/keyword.ts +++ b/lib/routes/twitter/keyword.ts @@ -1,5 +1,6 @@ import { Route } from '@/types'; -import webApiImpl from './mobile-api/search'; +import api from './api'; +import utils from './utils'; export const route: Route = { path: '/keyword/:keyword/:routeParams?', @@ -34,5 +35,16 @@ export const route: Route = { }; async function handler(ctx) { - return await webApiImpl(ctx); + const keyword = ctx.req.param('keyword'); + await api.init(); + const data = await api.getSearch(keyword); + + return { + title: `Twitter Keyword - ${keyword}`, + link: `https://twitter.com/search?q=${encodeURIComponent(keyword)}`, + item: utils.ProcessFeed(ctx, { + data, + }), + allowEmpty: true, + }; } diff --git a/lib/routes/twitter/media.ts b/lib/routes/twitter/media.ts index 486237cd18b1db..3a184f3483f5df 100644 --- a/lib/routes/twitter/media.ts +++ b/lib/routes/twitter/media.ts @@ -1,5 +1,6 @@ import { Route } from '@/types'; -import webApiImpl from './mobile-api/media'; +import api from './api'; +import utils from './utils'; export const route: Route = { path: '/media/:id/:routeParams?', @@ -35,5 +36,22 @@ export const route: Route = { }; async function handler(ctx) { - return await webApiImpl(ctx); + const id = ctx.req.param('id'); + const { count } = utils.parseRouteParams(ctx.req.param('routeParams')); + const params = count ? { count } : {}; + + await api.init(); + const userInfo = await api.getUser(id); + const data = await api.getUserMedia(id, params); + const profileImageUrl = userInfo.profile_image_url || userInfo.profile_image_url_https; + + return { + title: `Twitter @${userInfo.name}`, + link: `https://twitter.com/${userInfo.screen_name}/media`, + image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'), + description: userInfo.description, + item: utils.ProcessFeed(ctx, { + data, + }), + }; } diff --git a/lib/routes/twitter/mobile-api/media.ts b/lib/routes/twitter/mobile-api/media.ts deleted file mode 100644 index 9aa8c472a3c776..00000000000000 --- a/lib/routes/twitter/mobile-api/media.ts +++ /dev/null @@ -1,25 +0,0 @@ -import utils from '../utils'; -// import { config } from '@/config'; -import { getUser, getUserMedia } from './twitter-api'; -import { initToken } from './token'; - -export default async (ctx) => { - const id = ctx.req.param('id'); - const { count } = utils.parseRouteParams(ctx.req.param('routeParams')); - const params = count ? { count } : {}; - - await initToken(); - const userInfo = await getUser(id); - const data = await getUserMedia(id, params); - const profileImageUrl = userInfo.profile_image_url || userInfo.profile_image_url_https; - - return { - title: `Twitter @${userInfo.name}`, - link: `https://twitter.com/${userInfo.screen_name}/media`, - image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'), - description: userInfo.description, - item: utils.ProcessFeed(ctx, { - data, - }), - }; -}; diff --git a/lib/routes/twitter/mobile-api/search.ts b/lib/routes/twitter/mobile-api/search.ts deleted file mode 100644 index 2544e6ed9eee40..00000000000000 --- a/lib/routes/twitter/mobile-api/search.ts +++ /dev/null @@ -1,18 +0,0 @@ -import utils from '../utils'; -import { getSearch } from './twitter-api'; -import { initToken } from './token'; - -export default async (ctx) => { - const keyword = ctx.req.param('keyword'); - await initToken(); - const data = await getSearch(keyword); - - return { - title: `Twitter Keyword - ${keyword}`, - link: `https://twitter.com/search?q=${encodeURIComponent(keyword)}`, - item: utils.ProcessFeed(ctx, { - data, - }), - allowEmpty: true, - }; -}; diff --git a/lib/routes/twitter/mobile-api/tweet.ts b/lib/routes/twitter/mobile-api/tweet.ts deleted file mode 100644 index b0bcb3f3de0330..00000000000000 --- a/lib/routes/twitter/mobile-api/tweet.ts +++ /dev/null @@ -1,27 +0,0 @@ -// import { config } from '@/config'; -import { getUser, getUserTweet } from './twitter-api'; -import utils from '../utils'; -import { fallback, queryToBoolean } from '@/utils/readable-social'; -import { config } from '@/config'; -import { initToken } from './token'; - -export default async (ctx) => { - const id = ctx.req.param('id'); - const status = ctx.req.param('status'); - const routeParams = new URLSearchParams(ctx.req.param('original')); - const original = fallback(undefined, queryToBoolean(routeParams.get('original')), false); - const params = { focalTweetId: status }; - await initToken(); - const userInfo = await getUser(id); - const data = await getUserTweet(id, params); - const profileImageUrl = userInfo.profile_image_url || userInfo.profile_image_url_https; - const item = original && config.isPackage ? data : utils.ProcessFeed(ctx, { data }); - - return { - title: `Twitter @${userInfo.name}`, - link: `https://twitter.com/${userInfo.screen_name}/status/${status}`, - image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'), - description: userInfo.description, - item, - }; -}; diff --git a/lib/routes/twitter/mobile-api/user.ts b/lib/routes/twitter/mobile-api/user.ts deleted file mode 100644 index 7ee0d88ccfac7d..00000000000000 --- a/lib/routes/twitter/mobile-api/user.ts +++ /dev/null @@ -1,30 +0,0 @@ -import utils from '../utils'; -import { getUser, getUserTweets, getUserTweetsAndReplies, excludeRetweet } from './twitter-api'; -import { initToken } from './token'; - -export default async (ctx) => { - const id = ctx.req.param('id'); - - // For compatibility - const { count, exclude_replies, include_rts } = utils.parseRouteParams(ctx.req.param('routeParams')); - const params = count ? { count } : {}; - - await initToken(); - const userInfo = await getUser(id); - let data = await (exclude_replies ? getUserTweets(id, params) : getUserTweetsAndReplies(id, params)); - if (!include_rts) { - data = excludeRetweet(data); - } - - const profileImageUrl = userInfo.profile_image_url || userInfo.profile_image_url_https; - - return { - title: `Twitter @${userInfo.name}`, - link: `https://twitter.com/${userInfo.screen_name}`, - image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'), - description: userInfo.description, - item: utils.ProcessFeed(ctx, { - data, - }), - }; -}; diff --git a/lib/routes/twitter/tweet.ts b/lib/routes/twitter/tweet.ts index 85ba8a5db7a508..02620021d78625 100644 --- a/lib/routes/twitter/tweet.ts +++ b/lib/routes/twitter/tweet.ts @@ -1,5 +1,7 @@ import { Route } from '@/types'; -import webApiImpl from './mobile-api/tweet'; +import api from './api'; +import utils from './utils'; +import { fallback, queryToBoolean } from '@/utils/readable-social'; export const route: Route = { path: '/tweet/:id/status/:status/:original?', @@ -33,5 +35,22 @@ export const route: Route = { }; async function handler(ctx) { - return await webApiImpl(ctx); + const id = ctx.req.param('id'); + const status = ctx.req.param('status'); + const routeParams = new URLSearchParams(ctx.req.param('original')); + const original = fallback(undefined, queryToBoolean(routeParams.get('original')), false); + const params = { focalTweetId: status }; + await api.init(); + const userInfo = await api.getUser(id); + const data = await api.getUserTweet(id, params); + const profileImageUrl = userInfo.profile_image_url || userInfo.profile_image_url_https; + const item = original && config.isPackage ? data : utils.ProcessFeed(ctx, { data }); + + return { + title: `Twitter @${userInfo.name}`, + link: `https://twitter.com/${userInfo.screen_name}/status/${status}`, + image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'), + description: userInfo.description, + item, + }; } diff --git a/lib/routes/twitter/user.ts b/lib/routes/twitter/user.ts index fcfaebaab20f46..75f548e44837c5 100644 --- a/lib/routes/twitter/user.ts +++ b/lib/routes/twitter/user.ts @@ -1,5 +1,6 @@ import { Route } from '@/types'; -import webApiImpl from './mobile-api/user'; +import utils from './utils'; +import api from './api'; export const route: Route = { path: '/user/:id/:routeParams?', @@ -39,5 +40,28 @@ export const route: Route = { }; async function handler(ctx) { - return await webApiImpl(ctx); + const id = ctx.req.param('id'); + + // For compatibility + const { count, exclude_replies, include_rts } = utils.parseRouteParams(ctx.req.param('routeParams')); + const params = count ? { count } : {}; + + await api.init(); + const userInfo = await api.getUser(id); + let data = await (exclude_replies ? api.getUserTweets(id, params) : api.getUserTweetsAndReplies(id, params)); + if (!include_rts) { + data = utils.excludeRetweet(data); + } + + const profileImageUrl = userInfo?.profile_image_url || userInfo?.profile_image_url_https; + + return { + title: `Twitter @${userInfo?.name}`, + link: `https://twitter.com/${userInfo?.screen_name}`, + image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'), + description: userInfo?.description, + item: utils.ProcessFeed(ctx, { + data, + }), + }; } diff --git a/lib/routes/twitter/utils.ts b/lib/routes/twitter/utils.ts index 175800e6b36f66..d6a8e3815d6ab8 100644 --- a/lib/routes/twitter/utils.ts +++ b/lib/routes/twitter/utils.ts @@ -474,4 +474,15 @@ const parseRouteParams = (routeParams) => { return { count, exclude_replies, include_rts, force_web_api }; }; -export default { ProcessFeed, getAppClient, parseRouteParams }; +export const excludeRetweet = function (tweets) { + const excluded = []; + for (const t of tweets) { + if (t.retweeted_status) { + continue; + } + excluded.push(t); + } + return excluded; +}; + +export default { ProcessFeed, getAppClient, parseRouteParams, excludeRetweet }; From 52edc7e393438631d09f77e8f55960f261d266bb Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 21:41:39 +0800 Subject: [PATCH 03/25] feat(twitter): media for webapi --- lib/routes/twitter/api/web-api/api.ts | 36 ++++++++++++++++++--- lib/routes/twitter/api/web-api/constants.ts | 31 ++++++++++++------ lib/routes/twitter/api/web-api/utils.ts | 16 +++++---- lib/routes/twitter/media.ts | 4 +++ lib/routes/twitter/user.ts | 4 +++ 5 files changed, 72 insertions(+), 19 deletions(-) diff --git a/lib/routes/twitter/api/web-api/api.ts b/lib/routes/twitter/api/web-api/api.ts index 8c81c873819ca0..709031a05ae40b 100644 --- a/lib/routes/twitter/api/web-api/api.ts +++ b/lib/routes/twitter/api/web-api/api.ts @@ -1,4 +1,4 @@ -import { baseUrl, gqlMap, gqlFeatures, gqlFieldToggles } from './constants'; +import { baseUrl, gqlMap, gqlFeatures } from './constants'; import { config } from '@/config'; import cache from '@/utils/cache'; import { twitterGot, paginationTweets, gatherLegacyFromData } from './utils'; @@ -12,7 +12,9 @@ const getUserData = (id) => withSafetyModeUserFields: true, }), features: JSON.stringify(gqlFeatures.UserByRestId), - fieldToggles: JSON.stringify(gqlFieldToggles.UserByScreenName), + fieldToggles: JSON.stringify({ + withAuxiliaryUserLabels: false, + }), }); } return twitterGot(`${baseUrl}${gqlMap.UserByScreenName}`, { @@ -21,7 +23,9 @@ const getUserData = (id) => withSafetyModeUserFields: true, }), features: JSON.stringify(gqlFeatures.UserByScreenName), - fieldToggles: JSON.stringify(gqlFieldToggles.UserByScreenName), + fieldToggles: JSON.stringify({ + withAuxiliaryUserLabels: false, + }), }); }); @@ -62,7 +66,31 @@ const getUserTweetsAndReplies = (id: string, params?: Record) => ) ); -const getUserMedia = (id: string, params?: Record) => cacheTryGet(id, params, async (id, params = {}) => gatherLegacyFromData(await paginationTweets('MediaTimeline', id, params))); +const getUserMedia = (id: string, params?: Record) => + cacheTryGet(id, params, async (id, params = {}) => { + const cursorSource = await paginationTweets('UserMedia', id, { + ...params, + count: 20, + includePromotedContent: false, + withClientEventToken: false, + withBirdwatchNotes: false, + withVoice: true, + withV2Timeline: true, + }); + const cursor = cursorSource.find((i) => i.content?.cursorType === 'Top').content.value; + return gatherLegacyFromData( + await paginationTweets('UserMedia', id, { + ...params, + cursor, + count: 20, + includePromotedContent: false, + withClientEventToken: false, + withBirdwatchNotes: false, + withVoice: true, + withV2Timeline: true, + }) + ); + }); const getUserLikes = (id: string, params?: Record) => cacheTryGet(id, params, async (id, params = {}) => gatherLegacyFromData(await paginationTweets('Likes', id, params))); diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts index 01df27da1b38be..f6fa059c2e6b52 100644 --- a/lib/routes/twitter/api/web-api/constants.ts +++ b/lib/routes/twitter/api/web-api/constants.ts @@ -61,14 +61,27 @@ const gqlFeatures = { longform_notetweets_inline_media_enabled: true, responsive_web_enhance_cards_enabled: false, }, -}; - -const gqlFieldToggles = { - UserByScreenName: { - withAuxiliaryUserLabels: false, - }, - UserByRestId: { - withAuxiliaryUserLabels: false, + UserMedia: { + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: true, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, }, }; @@ -90,4 +103,4 @@ const timelineParams = { const bearerToken = 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA'; -export { baseUrl, gqlMap, gqlFeatures, gqlFieldToggles, timelineParams, bearerToken }; +export { baseUrl, gqlMap, gqlFeatures, timelineParams, bearerToken }; diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts index 5f89ede024e965..dce2192370ed38 100644 --- a/lib/routes/twitter/api/web-api/utils.ts +++ b/lib/routes/twitter/api/web-api/utils.ts @@ -12,7 +12,7 @@ export const twitterGot = async (url, params) => { config.twitter.cookie .split(';') .map((c) => Cookie.parse(c)?.toJSON()) - .map((c) => [c.key, c.value]) + .map((c) => [c?.key, c?.value]) ); if (!jsonCookie || !jsonCookie.auth_token || !jsonCookie.ct0) { throw new Error('Twitter cookie is not valid'); @@ -66,17 +66,21 @@ export const paginationTweets = async (endpoint: string, userId: number | undefi instructions = data.user.result.timeline_v2.timeline.instructions; } - return instructions.find((i) => i.__typename === 'TimelineAddEntries' || i.type === 'TimelineAddEntries').entries; + const entries1 = instructions.find((i) => i.type === 'TimelineAddToModule')?.moduleItems; // Media + const entries2 = instructions.find((i) => i.type === 'TimelineAddEntries').entries; + return entries1 || entries2; }; -export function gatherLegacyFromData(entries, filterNested?: string[], userId?: number | string) { - const tweets = []; - const filteredEntries = []; +export function gatherLegacyFromData(entries: any[], filterNested?: string[], userId?: number | string) { + const tweets: any[] = []; + const filteredEntries: any[] = []; for (const entry of entries) { const entryId = entry.entryId; if (entryId) { if (entryId.startsWith('tweet-')) { filteredEntries.push(entry); + } else if (entryId.startsWith('profile-grid-0-tweet-')) { + filteredEntries.push(entry); } if (filterNested && filterNested.some((f) => entryId.startsWith(f))) { filteredEntries.push(...entry.content.items); @@ -98,7 +102,7 @@ export function gatherLegacyFromData(entries, filterNested?: string[], userId?: } t.legacy.user = t.core?.user_result?.result?.legacy || t.core?.user_results?.result?.legacy; t.legacy.id_str = t.rest_id; // avoid falling back to conversation_id_str elsewhere - const quote = t.quoted_status_result?.result; + const quote = t.quoted_status_result?.result?.tweet || t.quoted_status_result?.result; if (quote) { t.legacy.quoted_status = quote.legacy; t.legacy.quoted_status.user = quote.core.user_result?.result?.legacy || quote.core.user_results?.result?.legacy; diff --git a/lib/routes/twitter/media.ts b/lib/routes/twitter/media.ts index 3a184f3483f5df..4e5d797206c3a3 100644 --- a/lib/routes/twitter/media.ts +++ b/lib/routes/twitter/media.ts @@ -17,6 +17,10 @@ export const route: Route = { name: 'TWITTER_PASSWORD', description: '', }, + { + name: 'TWITTER_COOKIE', + description: '', + }, ], requirePuppeteer: false, antiCrawler: false, diff --git a/lib/routes/twitter/user.ts b/lib/routes/twitter/user.ts index 75f548e44837c5..e2aac02b954b1a 100644 --- a/lib/routes/twitter/user.ts +++ b/lib/routes/twitter/user.ts @@ -21,6 +21,10 @@ export const route: Route = { name: 'TWITTER_PASSWORD', description: '', }, + { + name: 'TWITTER_COOKIE', + description: '', + }, ], requirePuppeteer: false, antiCrawler: false, From 85733f3186a16d108af6f94d917dad9fa1a4d0a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 21:45:50 +0800 Subject: [PATCH 04/25] chore(deps-dev): bump @typescript-eslint/eslint-plugin from 7.3.0 to 7.3.1 (#14851) * chore(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.3.0 to 7.3.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.3.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 77 +++++++++++--------------------------------------- 2 files changed, 18 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 19ee3913e2faa5..fb970fd0602d5e 100644 --- a/package.json +++ b/package.json @@ -142,7 +142,7 @@ "@types/supertest": "6.0.2", "@types/tiny-async-pool": "2.0.3", "@types/tough-cookie": "4.0.5", - "@typescript-eslint/eslint-plugin": "7.3.0", + "@typescript-eslint/eslint-plugin": "7.3.1", "@typescript-eslint/parser": "7.3.1", "@vercel/nft": "0.26.4", "@vitest/coverage-v8": "1.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a25d198642345..32c14ac8b4b142 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -287,8 +287,8 @@ devDependencies: specifier: 4.0.5 version: 4.0.5 '@typescript-eslint/eslint-plugin': - specifier: 7.3.0 - version: 7.3.0(@typescript-eslint/parser@7.3.1)(eslint@8.57.0)(typescript@5.4.2) + specifier: 7.3.1 + version: 7.3.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/parser': specifier: 7.3.1 version: 7.3.1(eslint@8.57.0)(typescript@5.4.2) @@ -2669,8 +2669,8 @@ packages: dev: false optional: true - /@typescript-eslint/eslint-plugin@7.3.0(@typescript-eslint/parser@7.3.1)(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-e65ii0Y/jkqX3GXSBM7v9qt9ufxd4omcWyPVVC/msq/hP+hYC6CddLRvlvclni+u7UcaNYT/QhBYlaMHaR2ixw==} + /@typescript-eslint/eslint-plugin@7.3.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-STEDMVQGww5lhCuNXVSQfbfuNII5E08QWkvAw5Qwf+bj2WT+JkG1uc+5/vXA3AOYMDHVOSpL+9rcbEUiHIm2dw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -2682,10 +2682,10 @@ packages: dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.3.1(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/scope-manager': 7.3.0 - '@typescript-eslint/type-utils': 7.3.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/utils': 7.3.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/visitor-keys': 7.3.0 + '@typescript-eslint/scope-manager': 7.3.1 + '@typescript-eslint/type-utils': 7.3.1(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/utils': 7.3.1(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/visitor-keys': 7.3.1 debug: 4.3.4 eslint: 8.57.0 graphemer: 1.4.0 @@ -2727,14 +2727,6 @@ packages: '@typescript-eslint/visitor-keys': 6.21.0 dev: true - /@typescript-eslint/scope-manager@7.3.0: - resolution: {integrity: sha512-KlG7xH3J/+nHpZRcYeskO5QVJCnnssxYKBlrj3MoyMONihn3P4xu5jIelrS5YWvBjbytgHmFkzjDApranoYkNA==} - engines: {node: ^18.18.0 || >=20.0.0} - dependencies: - '@typescript-eslint/types': 7.3.0 - '@typescript-eslint/visitor-keys': 7.3.0 - dev: true - /@typescript-eslint/scope-manager@7.3.1: resolution: {integrity: sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2743,8 +2735,8 @@ packages: '@typescript-eslint/visitor-keys': 7.3.1 dev: true - /@typescript-eslint/type-utils@7.3.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-TyQ19ydo248eFjTfHFSvZbxalFUOxU9o2M6SUk3wOA0yRF1ZiB2VP5iaoLrGKcg7TyUxS4knYIHnE55ih82Cfg==} + /@typescript-eslint/type-utils@7.3.1(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-iFhaysxFsMDQlzJn+vr3OrxN8NmdQkHks4WaqD4QBnt5hsq234wcYdyQ9uquzJJIDAj5W4wQne3yEsYA6OmXGw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -2753,8 +2745,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.3.0(typescript@5.4.2) - '@typescript-eslint/utils': 7.3.0(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/typescript-estree': 7.3.1(typescript@5.4.2) + '@typescript-eslint/utils': 7.3.1(eslint@8.57.0)(typescript@5.4.2) debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.2.1(typescript@5.4.2) @@ -2768,11 +2760,6 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/types@7.3.0: - resolution: {integrity: sha512-oYCBkD0xVxzmZZmYiIWVewyy/q/ugq7PPm4pHhE1IgcT062i96G0Ww3gd8BvUYpk2yvg95q00Hj2CHRLjAuZBA==} - engines: {node: ^18.18.0 || >=20.0.0} - dev: true - /@typescript-eslint/types@7.3.1: resolution: {integrity: sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2800,28 +2787,6 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree@7.3.0(typescript@5.4.2): - resolution: {integrity: sha512-UF85+bInQZ3olhI/zxv0c2b2SMuymn3t6/lkRkSB239HHxFmPSlmcggOKAjYzqRCdtqhPDftpsV1LlDH66AXrA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 7.3.0 - '@typescript-eslint/visitor-keys': 7.3.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.6.0 - ts-api-utils: 1.2.1(typescript@5.4.2) - typescript: 5.4.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree@7.3.1(typescript@5.4.2): resolution: {integrity: sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2863,8 +2828,8 @@ packages: - typescript dev: true - /@typescript-eslint/utils@7.3.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-7PKIDoe2ppR1SK56TLv7WQXrdHqEiueVwLVIjdSR4ROY2LprmJenf4+tT8iJIfxrsPzjSJGNeQ7GVmfoYbqrhw==} + /@typescript-eslint/utils@7.3.1(eslint@8.57.0)(typescript@5.4.2): + resolution: {integrity: sha512-jIERm/6bYQ9HkynYlNZvXpzmXWZGhMbrOvq3jJzOSOlKXsVjrrolzWBjDW6/TvT5Q3WqaN4EkmcfdQwi9tDjBQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -2872,9 +2837,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.3.0 - '@typescript-eslint/types': 7.3.0 - '@typescript-eslint/typescript-estree': 7.3.0(typescript@5.4.2) + '@typescript-eslint/scope-manager': 7.3.1 + '@typescript-eslint/types': 7.3.1 + '@typescript-eslint/typescript-estree': 7.3.1(typescript@5.4.2) eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: @@ -2890,14 +2855,6 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@7.3.0: - resolution: {integrity: sha512-Gz8Su+QjOI5qP8UQ74VqKaTt/BLy23IhCCHLbYxhmNzHCGFHrvfgq4hISZvuqQ690ubkD0746qLcWC647nScuQ==} - engines: {node: ^18.18.0 || >=20.0.0} - dependencies: - '@typescript-eslint/types': 7.3.0 - eslint-visitor-keys: 3.4.3 - dev: true - /@typescript-eslint/visitor-keys@7.3.1: resolution: {integrity: sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==} engines: {node: ^18.18.0 || >=20.0.0} From 2b6c84c829f63cfcc2f8009494e114a1c2cb4a62 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 21:51:01 +0800 Subject: [PATCH 05/25] feat(twitter): keyword for webapi --- lib/routes/twitter/api/web-api/api.ts | 4 +--- lib/routes/twitter/api/web-api/constants.ts | 23 +++++++++++++++++++++ lib/routes/twitter/keyword.ts | 4 ++++ lib/routes/twitter/media.ts | 8 +++---- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/lib/routes/twitter/api/web-api/api.ts b/lib/routes/twitter/api/web-api/api.ts index 709031a05ae40b..2a280d7896cfca 100644 --- a/lib/routes/twitter/api/web-api/api.ts +++ b/lib/routes/twitter/api/web-api/api.ts @@ -123,10 +123,8 @@ const getSearch = async (keywords: string, params?: Record) => ...params, rawQuery: keywords, count: 20, + querySource: 'typed_query', product: 'Latest', - withDownvotePerspective: false, - withReactionsMetadata: false, - withReactionsPerspective: false, }, ['search_by_raw_query', 'search_timeline', 'timeline'] ) diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts index f6fa059c2e6b52..436f2d3fb6c921 100644 --- a/lib/routes/twitter/api/web-api/constants.ts +++ b/lib/routes/twitter/api/web-api/constants.ts @@ -8,6 +8,7 @@ const graphQLEndpointsPlain = [ '/graphql/TOU4gQw8wXIqpSzA4TYKgg/UserMedia', '/graphql/B8I_QCljDBVfin21TTWMqA/Likes', '/graphql/tD8zKvQzwY3kdx5yz6YmOw/UserByRestId', + '/graphql/flaR-PUMshxFWZWPNpq4zA/SearchTimeline', ]; const gqlMap = Object.fromEntries(graphQLEndpointsPlain.map((endpoint) => [endpoint.split('/')[3].replace(/V2$|Query$|QueryV2$/, ''), endpoint])); @@ -83,6 +84,28 @@ const gqlFeatures = { longform_notetweets_inline_media_enabled: true, responsive_web_enhance_cards_enabled: false, }, + SearchTimeline: { + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: true, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, + }, }; const timelineParams = { diff --git a/lib/routes/twitter/keyword.ts b/lib/routes/twitter/keyword.ts index 1538d8329eb611..93544c9f6294ee 100644 --- a/lib/routes/twitter/keyword.ts +++ b/lib/routes/twitter/keyword.ts @@ -17,6 +17,10 @@ export const route: Route = { name: 'TWITTER_PASSWORD', description: '', }, + { + name: 'TWITTER_COOKIE', + description: '', + }, ], requirePuppeteer: false, antiCrawler: false, diff --git a/lib/routes/twitter/media.ts b/lib/routes/twitter/media.ts index 4e5d797206c3a3..f88762451c118b 100644 --- a/lib/routes/twitter/media.ts +++ b/lib/routes/twitter/media.ts @@ -47,13 +47,13 @@ async function handler(ctx) { await api.init(); const userInfo = await api.getUser(id); const data = await api.getUserMedia(id, params); - const profileImageUrl = userInfo.profile_image_url || userInfo.profile_image_url_https; + const profileImageUrl = userInfo?.profile_image_url || userInfo?.profile_image_url_https; return { - title: `Twitter @${userInfo.name}`, - link: `https://twitter.com/${userInfo.screen_name}/media`, + title: `Twitter @${userInfo?.name}`, + link: `https://twitter.com/${userInfo?.screen_name}/media`, image: profileImageUrl.replace(/_normal.jpg$/, '.jpg'), - description: userInfo.description, + description: userInfo?.description, item: utils.ProcessFeed(ctx, { data, }), From 1bc24075c75a546b7fe2c2944da0b02023ca1b0f Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 22:11:20 +0800 Subject: [PATCH 06/25] feat(twitter): list for webapi --- lib/routes/twitter/api-fallback-common.ts | 17 ---- lib/routes/twitter/api/index.ts | 2 + lib/routes/twitter/api/web-api/api.ts | 15 ++++ lib/routes/twitter/api/web-api/constants.ts | 23 ++++++ lib/routes/twitter/collection.ts | 86 --------------------- lib/routes/twitter/list.ts | 55 ++++++------- lib/routes/twitter/media.ts | 2 +- 7 files changed, 65 insertions(+), 135 deletions(-) delete mode 100644 lib/routes/twitter/api-fallback-common.ts delete mode 100644 lib/routes/twitter/collection.ts diff --git a/lib/routes/twitter/api-fallback-common.ts b/lib/routes/twitter/api-fallback-common.ts deleted file mode 100644 index e08e04cf868eee..00000000000000 --- a/lib/routes/twitter/api-fallback-common.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { config } from '@/config'; -import logger from '@/utils/logger'; -import utils from './utils'; - -export default async (ctx, devApiImpl, webApiImpl) => { - const { force_web_api } = utils.parseRouteParams(ctx.req.param('routeParams')); - - if (!force_web_api && config.twitter && config.twitter.consumer_key && config.twitter.consumer_secret) { - try { - await devApiImpl(ctx); - return; - } catch (error) { - logger.error(`Fallback to Twitter web API due to developer API error:\n${error.stack}`); - } - } - await webApiImpl(ctx); -}; diff --git a/lib/routes/twitter/api/index.ts b/lib/routes/twitter/api/index.ts index 209013c79b2764..a7d885f9cc28de 100644 --- a/lib/routes/twitter/api/index.ts +++ b/lib/routes/twitter/api/index.ts @@ -15,6 +15,7 @@ let api: { getUserLikes: ApiItem; getUserTweet: ApiItem; getSearch: ApiItem; + getList: ApiItem; } = { init: () => { throw new Error('Twitter API is not configured'); @@ -26,6 +27,7 @@ let api: { getUserLikes: () => null, getUserTweet: () => null, getSearch: () => null, + getList: () => null, }; if (enableWebApi) { diff --git a/lib/routes/twitter/api/web-api/api.ts b/lib/routes/twitter/api/web-api/api.ts index 2a280d7896cfca..6063b1cc4d28cd 100644 --- a/lib/routes/twitter/api/web-api/api.ts +++ b/lib/routes/twitter/api/web-api/api.ts @@ -130,6 +130,20 @@ const getSearch = async (keywords: string, params?: Record) => ) ); +const getList = async (id: string, params?: Record) => + gatherLegacyFromData( + await paginationTweets( + 'ListLatestTweetsTimeline', + undefined, + { + ...params, + listId: id, + count: 20, + }, + ['list', 'tweets_timeline', 'timeline'] + ) + ); + const getUser = async (id: string) => { const userData: any = await getUserData(id); return (userData.data?.user || userData.data?.user_result)?.result?.legacy; @@ -143,5 +157,6 @@ export default { getUserLikes, getUserTweet, getSearch, + getList, init: () => {}, }; diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts index 436f2d3fb6c921..0982fc6a2628b6 100644 --- a/lib/routes/twitter/api/web-api/constants.ts +++ b/lib/routes/twitter/api/web-api/constants.ts @@ -9,6 +9,7 @@ const graphQLEndpointsPlain = [ '/graphql/B8I_QCljDBVfin21TTWMqA/Likes', '/graphql/tD8zKvQzwY3kdx5yz6YmOw/UserByRestId', '/graphql/flaR-PUMshxFWZWPNpq4zA/SearchTimeline', + '/graphql/TOTgqavWmxywKv5IbMMK1w/ListLatestTweetsTimeline', ]; const gqlMap = Object.fromEntries(graphQLEndpointsPlain.map((endpoint) => [endpoint.split('/')[3].replace(/V2$|Query$|QueryV2$/, ''), endpoint])); @@ -106,6 +107,28 @@ const gqlFeatures = { longform_notetweets_inline_media_enabled: true, responsive_web_enhance_cards_enabled: false, }, + ListLatestTweetsTimeline: { + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: true, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, + }, }; const timelineParams = { diff --git a/lib/routes/twitter/collection.ts b/lib/routes/twitter/collection.ts deleted file mode 100644 index 9d2ea78d0d0304..00000000000000 --- a/lib/routes/twitter/collection.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Route } from '@/types'; -import utils from './utils'; -import { config } from '@/config'; -const T = {}; -import { TwitterApi } from 'twitter-api-v2'; -import { fallback, queryToBoolean } from '@/utils/readable-social'; - -export const route: Route = { - path: '/collection/:uid/:collectionId/:routeParams?', - categories: ['social-media'], - example: '/twitter/collection/DIYgod/1527857429467172864', - parameters: { uid: 'username, should match the generated token', collectionId: 'collection ID, can be found in URL', routeParams: 'extra parameters, see the table above' }, - features: { - requireConfig: [ - { - name: 'TWITTER_USERNAME', - description: '', - }, - { - name: 'TWITTER_PASSWORD', - description: '', - }, - ], - requirePuppeteer: false, - antiCrawler: false, - supportBT: false, - supportPodcast: false, - supportScihub: false, - }, - name: 'Collection', - maintainers: ['TonyRL'], - handler, - description: `:::warning - This route requires Twitter token's corresponding id, therefore it's only available when self-hosting, refer to the [Deploy Guide](/install/#route-specific-configurations) for route-specific configurations. - :::`, -}; - -async function handler(ctx) { - const uid = ctx.req.param('uid'); - const collectionId = ctx.req.param('collectionId'); - const cookie = config.twitter.tokens[uid]; - if (!cookie) { - throw new Error(`lacking twitter token for user ${uid}`); - } else if (!T[uid]) { - const token = cookie.split(','); - T[uid] = new TwitterApi({ - appKey: token[0], - appSecret: token[1], - accessToken: token[2], - accessSecret: token[3], - }).readOnly; - } - - const id = `custom-${collectionId}`; - - const data = await T[uid].v1.get('collections/entries.json', { - id, - count: ctx.req.query('limit') ? (Number(ctx.req.query('limit')) > 200 ? 200 : Number(ctx.req.query('limit'))) : 200, - }); - - const routeParams = new URLSearchParams(ctx.req.param('routeParams')); - - // fix user without screen_name - for (const tweet of Object.values(data.objects.tweets)) { - tweet.user = data.objects.users[tweet.user.id_str]; - if (tweet.quoted_status) { - tweet.quoted_status.user = data.objects.users[tweet.quoted_status.user.id_str]; - } - } - - return { - title: data.objects.timelines[id].name, - description: data.objects.timelines[id].description, - link: data.objects.timelines[id].collection_url, - item: utils.ProcessFeed( - ctx, - { - data: Object.values(data.objects.tweets), - }, - { - showAuthorInTitle: fallback(undefined, queryToBoolean(routeParams.get('showAuthorInTitle')), true), - showAuthorInDesc: fallback(undefined, queryToBoolean(routeParams.get('showAuthorInDesc')), true), - } - ), - }; -} diff --git a/lib/routes/twitter/list.ts b/lib/routes/twitter/list.ts index 2abbb1372e24c7..79cdea76ebced5 100644 --- a/lib/routes/twitter/list.ts +++ b/lib/routes/twitter/list.ts @@ -1,15 +1,27 @@ import { Route } from '@/types'; -import cache from '@/utils/cache'; +import api from './api'; import utils from './utils'; -import { config } from '@/config'; export const route: Route = { - path: '/list/:id/:name/:routeParams?', + path: '/list/:id/:routeParams?', categories: ['social-media'], example: '/twitter/list/ladyleet/javascript', parameters: { id: 'username', name: 'list name', routeParams: 'extra parameters, see the table above' }, features: { - requireConfig: false, + requireConfig: [ + { + name: 'TWITTER_USERNAME', + description: '', + }, + { + name: 'TWITTER_PASSWORD', + description: '', + }, + { + name: 'TWITTER_COOKIE', + description: '', + }, + ], requirePuppeteer: false, antiCrawler: false, supportBT: false, @@ -17,40 +29,21 @@ export const route: Route = { supportScihub: false, }, name: 'List timeline', - maintainers: ['xyqfer'], + maintainers: ['DIYgod', 'xyqfer'], handler, }; async function handler(ctx) { - if (!config.twitter || !config.twitter.consumer_key || !config.twitter.consumer_secret) { - throw new Error('Twitter RSS is disabled due to the lack of relevant config'); - } - const { id, name } = ctx.req.param(); - const client = await utils.getAppClient(); + const id = ctx.req.param('id'); + const { count } = utils.parseRouteParams(ctx.req.param('routeParams')); + const params = count ? { count } : {}; - const list_data = await cache.tryGet(`twitter_lists_list_screen_name:${id}`, async () => { - const data = await client.v1.get('lists/list.json', { - screen_name: id, - }); - - const cached_lists = {}; - for (const e of data) { - cached_lists[e.name] = { id: e.id_str, slug: e.slug }; - } - - return cached_lists; - }); - const cur_list = list_data[name]; - - const data = await client.v1.get('lists/statuses.json', { - list_id: cur_list.id, - slug: cur_list.slug, - tweet_mode: 'extended', - }); + await api.init(); + const data = await api.getList(id, params); return { - title: `Twitter List - ${id}/${name}`, - link: `https://twitter.com/${id}/lists/${name}`, + title: `Twitter List - ${id}`, + link: `https://twitter.com/i/lists/${id}`, item: utils.ProcessFeed(ctx, { data, }), diff --git a/lib/routes/twitter/media.ts b/lib/routes/twitter/media.ts index f88762451c118b..160c747e482bdf 100644 --- a/lib/routes/twitter/media.ts +++ b/lib/routes/twitter/media.ts @@ -29,7 +29,7 @@ export const route: Route = { supportScihub: false, }, name: 'User media', - maintainers: ['yindaheng98', 'Rongronggg9'], + maintainers: ['DIYgod', 'yindaheng98', 'Rongronggg9'], handler, radar: [ { From c5ea105fab0e96f987a19f34d7f07f1eb8b922ba Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 22:36:56 +0800 Subject: [PATCH 07/25] feat(twitter): following for webapi --- lib/routes/twitter/api/index.ts | 2 + lib/routes/twitter/api/web-api/api.ts | 18 ++++++ lib/routes/twitter/api/web-api/constants.ts | 22 ++++++++ lib/routes/twitter/followings.ts | 62 +++++++-------------- 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/lib/routes/twitter/api/index.ts b/lib/routes/twitter/api/index.ts index a7d885f9cc28de..10d721d092197d 100644 --- a/lib/routes/twitter/api/index.ts +++ b/lib/routes/twitter/api/index.ts @@ -16,6 +16,7 @@ let api: { getUserTweet: ApiItem; getSearch: ApiItem; getList: ApiItem; + getHomeTimeline: ApiItem; } = { init: () => { throw new Error('Twitter API is not configured'); @@ -28,6 +29,7 @@ let api: { getUserTweet: () => null, getSearch: () => null, getList: () => null, + getHomeTimeline: () => null, }; if (enableWebApi) { diff --git a/lib/routes/twitter/api/web-api/api.ts b/lib/routes/twitter/api/web-api/api.ts index 6063b1cc4d28cd..870c569e7fb245 100644 --- a/lib/routes/twitter/api/web-api/api.ts +++ b/lib/routes/twitter/api/web-api/api.ts @@ -149,6 +149,23 @@ const getUser = async (id: string) => { return (userData.data?.user || userData.data?.user_result)?.result?.legacy; }; +const getHomeTimeline = async (id: string, params?: Record) => + gatherLegacyFromData( + await paginationTweets( + 'HomeTimeline', + undefined, + { + ...params, + count: 20, + includePromotedContent: true, + latestControlAvailable: true, + requestContext: 'launch', + withCommunity: true, + }, + ['home', 'home_timeline_urt'] + ) + ); + export default { getUser, getUserTweets, @@ -158,5 +175,6 @@ export default { getUserTweet, getSearch, getList, + getHomeTimeline, init: () => {}, }; diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts index 0982fc6a2628b6..bfd1c904f81d8b 100644 --- a/lib/routes/twitter/api/web-api/constants.ts +++ b/lib/routes/twitter/api/web-api/constants.ts @@ -129,6 +129,28 @@ const gqlFeatures = { longform_notetweets_inline_media_enabled: true, responsive_web_enhance_cards_enabled: false, }, + HomeTimeline: { + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: true, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, + }, }; const timelineParams = { diff --git a/lib/routes/twitter/followings.ts b/lib/routes/twitter/followings.ts index b01a8080ed6e72..a12d93c80a6497 100644 --- a/lib/routes/twitter/followings.ts +++ b/lib/routes/twitter/followings.ts @@ -1,14 +1,11 @@ import { Route } from '@/types'; import utils from './utils'; -import { config } from '@/config'; -const T = {}; -import { TwitterApi } from 'twitter-api-v2'; -import { fallback, queryToBoolean } from '@/utils/readable-social'; +import api from './api'; export const route: Route = { - path: '/followings/:id/:routeParams?', + path: '/followings/:routeParams?', categories: ['social-media'], - example: '/twitter/followings/DIYgod', + example: '/twitter/followings', parameters: { id: 'username', routeParams: 'extra parameters, see the table above' }, features: { requireConfig: [ @@ -20,6 +17,10 @@ export const route: Route = { name: 'TWITTER_PASSWORD', description: '', }, + { + name: 'TWITTER_COOKIE', + description: '', + }, ], requirePuppeteer: false, antiCrawler: false, @@ -30,46 +31,25 @@ export const route: Route = { name: 'User following timeline', maintainers: ['DIYgod'], handler, - description: `:::warning - This route requires Twitter token's corresponding id, therefore it's only available when self-hosting, refer to the [Deploy Guide](/install/#route-specific-configurations) for route-specific configurations. - :::`, }; async function handler(ctx) { - const id = ctx.req.param('id'); - const cookie = config.twitter.tokens[id]; - if (!cookie) { - throw new Error(`lacking twitter token for user ${id}`); - } else if (!T[id]) { - const token = cookie.split(','); - T[id] = new TwitterApi({ - appKey: token[0], - appSecret: token[1], - accessToken: token[2], - accessSecret: token[3], - }).readOnly; - } - - const data = await T[id].v1.get('statuses/home_timeline.json', { - tweet_mode: 'extended', - count: 100, - }); + // For compatibility + const { count, include_rts } = utils.parseRouteParams(ctx.req.param('routeParams')); + const params = count ? { count } : {}; - // undefined and strings like "exclude_rts_replies" is also safely parsed, so no if branch is needed - const routeParams = new URLSearchParams(ctx.req.param('routeParams')); + await api.init(); + let data = await api.getHomeTimeline('', params); + if (!include_rts) { + data = utils.excludeRetweet(data); + } return { - title: `${id} 的 Twitter 关注时间线`, - link: `https://twitter.com/${id}/`, - item: utils.ProcessFeed( - ctx, - { - data, - }, - { - showAuthorInTitle: fallback(undefined, queryToBoolean(routeParams.get('showAuthorInTitle')), true), - showAuthorInDesc: fallback(undefined, queryToBoolean(routeParams.get('showAuthorInDesc')), true), - } - ), + title: `Twitter following timeline`, + link: `https://twitter.com/home`, + // description: userInfo?.description, + item: utils.ProcessFeed(ctx, { + data, + }), }; } From ebbaf45c3bdc8f0ade0e3fb27f34f6f08750defd Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 22:39:34 +0800 Subject: [PATCH 08/25] feat(twitter): update title --- lib/routes/twitter/{followings.ts => home.ts} | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename lib/routes/twitter/{followings.ts => home.ts} (86%) diff --git a/lib/routes/twitter/followings.ts b/lib/routes/twitter/home.ts similarity index 86% rename from lib/routes/twitter/followings.ts rename to lib/routes/twitter/home.ts index a12d93c80a6497..8075f77759c58e 100644 --- a/lib/routes/twitter/followings.ts +++ b/lib/routes/twitter/home.ts @@ -3,10 +3,9 @@ import utils from './utils'; import api from './api'; export const route: Route = { - path: '/followings/:routeParams?', + path: '/home/:routeParams?', categories: ['social-media'], - example: '/twitter/followings', - parameters: { id: 'username', routeParams: 'extra parameters, see the table above' }, + example: '/twitter/home', features: { requireConfig: [ { @@ -28,7 +27,7 @@ export const route: Route = { supportPodcast: false, supportScihub: false, }, - name: 'User following timeline', + name: 'Home timeline', maintainers: ['DIYgod'], handler, }; From 75354f7620223fb463663cea027faac372f4b74e Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 22:42:08 +0800 Subject: [PATCH 09/25] feat(twitter): radar --- lib/routes/twitter/home.ts | 6 ++++++ lib/routes/twitter/list.ts | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/lib/routes/twitter/home.ts b/lib/routes/twitter/home.ts index 8075f77759c58e..5a55812dac3624 100644 --- a/lib/routes/twitter/home.ts +++ b/lib/routes/twitter/home.ts @@ -30,6 +30,12 @@ export const route: Route = { name: 'Home timeline', maintainers: ['DIYgod'], handler, + radar: [ + { + source: ['twitter.com/home'], + target: '/home', + }, + ], }; async function handler(ctx) { diff --git a/lib/routes/twitter/list.ts b/lib/routes/twitter/list.ts index 79cdea76ebced5..9a501f09b2c3f2 100644 --- a/lib/routes/twitter/list.ts +++ b/lib/routes/twitter/list.ts @@ -31,6 +31,12 @@ export const route: Route = { name: 'List timeline', maintainers: ['DIYgod', 'xyqfer'], handler, + radar: [ + { + source: ['twitter.com/i/lists/:id'], + target: '/list/:id', + }, + ], }; async function handler(ctx) { From d3064e2491e3a9a0a05aa75927623477f6fb0a03 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Tue, 19 Mar 2024 22:53:11 +0800 Subject: [PATCH 10/25] feat(twitter): docs --- lib/routes/twitter/home.ts | 6 +++--- lib/routes/twitter/keyword.ts | 6 +++--- lib/routes/twitter/list.ts | 6 +++--- lib/routes/twitter/media.ts | 6 +++--- lib/routes/twitter/namespace.ts | 9 ++++++++- lib/routes/twitter/tweet.ts | 4 ++-- lib/routes/twitter/user.ts | 6 +++--- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/routes/twitter/home.ts b/lib/routes/twitter/home.ts index 5a55812dac3624..4b8b1254c9c7b9 100644 --- a/lib/routes/twitter/home.ts +++ b/lib/routes/twitter/home.ts @@ -10,15 +10,15 @@ export const route: Route = { requireConfig: [ { name: 'TWITTER_USERNAME', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_PASSWORD', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_COOKIE', - description: '', + description: 'Please see above for details.', }, ], requirePuppeteer: false, diff --git a/lib/routes/twitter/keyword.ts b/lib/routes/twitter/keyword.ts index 93544c9f6294ee..2954a0ab6b5cdb 100644 --- a/lib/routes/twitter/keyword.ts +++ b/lib/routes/twitter/keyword.ts @@ -11,15 +11,15 @@ export const route: Route = { requireConfig: [ { name: 'TWITTER_USERNAME', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_PASSWORD', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_COOKIE', - description: '', + description: 'Please see above for details.', }, ], requirePuppeteer: false, diff --git a/lib/routes/twitter/list.ts b/lib/routes/twitter/list.ts index 9a501f09b2c3f2..645c17c0cc8018 100644 --- a/lib/routes/twitter/list.ts +++ b/lib/routes/twitter/list.ts @@ -11,15 +11,15 @@ export const route: Route = { requireConfig: [ { name: 'TWITTER_USERNAME', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_PASSWORD', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_COOKIE', - description: '', + description: 'Please see above for details.', }, ], requirePuppeteer: false, diff --git a/lib/routes/twitter/media.ts b/lib/routes/twitter/media.ts index 160c747e482bdf..c43ad10c289f7d 100644 --- a/lib/routes/twitter/media.ts +++ b/lib/routes/twitter/media.ts @@ -11,15 +11,15 @@ export const route: Route = { requireConfig: [ { name: 'TWITTER_USERNAME', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_PASSWORD', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_COOKIE', - description: '', + description: 'Please see above for details.', }, ], requirePuppeteer: false, diff --git a/lib/routes/twitter/namespace.ts b/lib/routes/twitter/namespace.ts index abf6886182f7ab..ace8355e707afb 100644 --- a/lib/routes/twitter/namespace.ts +++ b/lib/routes/twitter/namespace.ts @@ -36,5 +36,12 @@ https://rsshub.app/twitter/user/durov/readable=1&authorNameBold=1&showAuthorInTi generates -Readable Twitter RSS of Durov`, +Readable Twitter RSS of Durov + +Currently supports two authentication methods: + +- Using TWITTER_COOKIE (recommended): Configure the cookies of logged-in Twitter Web, at least including the fields auth_token and ct0. RSSHub will use this information to directly access Twitter's web API to obtain data. + +- Using TWITTER_USERNAME TWITTER_PASSWORD: Configure the Twitter username and password. RSSHub will use this information to log in to Twitter and obtain data using the mobile API. Please note that if you have not logged in with the current IP address before, it is easy to trigger Twitter's risk control mechanism. +`, }; diff --git a/lib/routes/twitter/tweet.ts b/lib/routes/twitter/tweet.ts index 02620021d78625..c5404b75175ffc 100644 --- a/lib/routes/twitter/tweet.ts +++ b/lib/routes/twitter/tweet.ts @@ -16,11 +16,11 @@ export const route: Route = { requireConfig: [ { name: 'TWITTER_USERNAME', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_PASSWORD', - description: '', + description: 'Please see above for details.', }, ], requirePuppeteer: false, diff --git a/lib/routes/twitter/user.ts b/lib/routes/twitter/user.ts index e2aac02b954b1a..c53469392d6b18 100644 --- a/lib/routes/twitter/user.ts +++ b/lib/routes/twitter/user.ts @@ -15,15 +15,15 @@ export const route: Route = { requireConfig: [ { name: 'TWITTER_USERNAME', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_PASSWORD', - description: '', + description: 'Please see above for details.', }, { name: 'TWITTER_COOKIE', - description: '', + description: 'Please see above for details.', }, ], requirePuppeteer: false, From c0b3348c9219e593de9e3669a3b3a244c24b14f9 Mon Sep 17 00:00:00 2001 From: cnkmmk <22782790+cnkmmk@users.noreply.github.com> Date: Tue, 19 Mar 2024 22:54:46 +0800 Subject: [PATCH 11/25] fix(route): Fix howtoforge (#14852) --- lib/routes/howtoforge/rss.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/routes/howtoforge/rss.ts b/lib/routes/howtoforge/rss.ts index f7b9674f67d92b..853f26718898cf 100644 --- a/lib/routes/howtoforge/rss.ts +++ b/lib/routes/howtoforge/rss.ts @@ -4,13 +4,14 @@ import { load } from 'cheerio'; export const route: Route = { path: '/', + categories: ['study'], + example: '/howtoforge', radar: [ { source: ['howtoforge.com/'], - target: '', }, ], - name: 'Unknown', + name: 'Tutorials', maintainers: ['cnkmmk'], handler, url: 'howtoforge.com/', From 9399fb32667c0fa897ba783f9bbf7a5f3c61e1ba Mon Sep 17 00:00:00 2001 From: Mg Pig Date: Tue, 19 Mar 2024 23:38:30 +0800 Subject: [PATCH 12/25] fix(route): 18comic add cover image (#14858) --- lib/routes/18comic/templates/description.art | 3 +++ lib/routes/18comic/utils.ts | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/routes/18comic/templates/description.art b/lib/routes/18comic/templates/description.art index d434d8f998413c..ffe0935976d0a0 100644 --- a/lib/routes/18comic/templates/description.art +++ b/lib/routes/18comic/templates/description.art @@ -1,3 +1,6 @@ +{{ if cover }} + +{{ /if }}

{{ introduction }}

{{ each images image }} diff --git a/lib/routes/18comic/utils.ts b/lib/routes/18comic/utils.ts index 5d657d86c45821..e90e55077c9e42 100644 --- a/lib/routes/18comic/utils.ts +++ b/lib/routes/18comic/utils.ts @@ -49,6 +49,7 @@ const ProcessItems = async (ctx, currentUrl, rootUrl) => { const content = load(detailResponse.data); item.pubDate = parseDate(content('div[itemprop="datePublished"]').first().attr('content')); + item.updated = parseDate(content('div[itemprop="datePublished"]').last().attr('content')); item.category = content('span[data-type="tags"]') .first() .find('a') @@ -65,6 +66,7 @@ const ProcessItems = async (ctx, currentUrl, rootUrl) => { images: content('.img_zoom_img img') .toArray() .map((image) => content(image).attr('data-original')), + cover: content('.thumb-overlay img').first().attr('src'), }); return item; From c91e008143932b759cc414ce35062ec5edd4c6d5 Mon Sep 17 00:00:00 2001 From: Zero Date: Wed, 20 Mar 2024 00:02:19 +0800 Subject: [PATCH 13/25] =?UTF-8?q?feat(route):=20Add=20=E6=B5=99=E6=B1=9F?= =?UTF-8?q?=E5=B7=A5=E4=B8=9A=E5=A4=A7=E5=AD=A6=E8=AE=BE=E8=AE=A1=E4=B8=8E?= =?UTF-8?q?=E5=BB=BA=E7=AD=91=E5=AD=A6=E9=99=A2=E9=80=9A=E7=9F=A5=20(#1485?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(route): Add 浙江工业大学设计与建筑学院通知 * perf: 优化浙工大设建学院通知相关代码 --- lib/routes/zjut/da/index.ts | 91 ++++++++++++++++++++++++++++++++++++ lib/routes/zjut/namespace.ts | 6 +++ 2 files changed, 97 insertions(+) create mode 100644 lib/routes/zjut/da/index.ts create mode 100644 lib/routes/zjut/namespace.ts diff --git a/lib/routes/zjut/da/index.ts b/lib/routes/zjut/da/index.ts new file mode 100644 index 00000000000000..ae52a1bbfef0f7 --- /dev/null +++ b/lib/routes/zjut/da/index.ts @@ -0,0 +1,91 @@ +import { Route } from '@/types'; +import got from '@/utils/got'; +import cache from '@/utils/cache'; +import { parseDate } from '@/utils/parse-date'; +import { load } from 'cheerio'; +import iconv from 'iconv-lite'; + +const rootUrl = 'http://www.design.zjut.edu.cn/'; +const host = 'http://www.design.zjut.edu.cn/BigClass.jsp?'; + +const map = new Map([ + [1, { id: 'bigclassid=16', title: '学院新闻 - 浙工大设建学院' }], + [2, { id: 'bigclassid=18', title: '公告通知 - 浙工大设建学院' }], + [3, { id: 'bigclassid=5&sid=25', title: '科研申报 - 浙工大设建学院' }], + [4, { id: 'bigclassid=5&sid=26', title: '科研成果 - 浙工大设建学院' }], + [5, { id: 'bigclassid=5&sid=27', title: '文件与资源 - 浙工大设建学院' }], + [6, { id: 'bigclassid=20', title: '学术交流 - 浙工大设建学院' }], +]); + +export const route: Route = { + path: '/da/:type', + categories: ['university'], + example: '/zjut/da/1', + parameters: { type: '分类,见下表' }, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + name: '设计与建筑学院', + maintainers: ['yikZero'], + handler, + description: `| 学院新闻 | 公告通知 | 科研申报 | 科研成果 | 文件与资源 | 学术交流 | +| -------- | -------- | -------- | -------- | -------- | -------- | +| 1 | 2 | 3 | 4 | 5 | 6 |`, +}; + +async function handler(ctx) { + const type = Number.parseInt(ctx.req.param('type')); + const id = map.get(type)?.id; + const listResponse = await got(`${host}${id}`, { + responseType: 'buffer', + }); + listResponse.data = iconv.decode(listResponse.data, 'gbk'); + const $ = load(listResponse.data); + + const list = $("td[class='newstd'] .news2") + .map((index, item) => { + item = $(item); + const title = item.find('a').text(); + + let link = item.find('a').attr('href'); + if (!link) { + return null; + } + if (!link.startsWith('http')) { + link = rootUrl + link; + } + + const date = item.next().text().replace('[', '').replace(']', ''); + + return { + title, + description: '', + pubDate: parseDate(date), + link, + }; + }) + .get(); + + const items = await Promise.all( + list.map((item) => + cache.tryGet(item.link, async () => { + const itemsResponse = await got(item.link); + const $ = load(itemsResponse.data); + item.description = $('div[style="line-height:27px;"]').html(); + + return item; + }) + ) + ); + + return { + title: map.get(type)?.title, + link: `${host}${id}`, + item: items, + }; +} diff --git a/lib/routes/zjut/namespace.ts b/lib/routes/zjut/namespace.ts new file mode 100644 index 00000000000000..4c5f1fcd3b16b0 --- /dev/null +++ b/lib/routes/zjut/namespace.ts @@ -0,0 +1,6 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: '浙江工业大学', + url: 'zjut.edu.cn', +}; From a33502b716e7faeab190045e4e227e134d8726f4 Mon Sep 17 00:00:00 2001 From: cnkmmk <22782790+cnkmmk@users.noreply.github.com> Date: Wed, 20 Mar 2024 00:14:30 +0800 Subject: [PATCH 14/25] =?UTF-8?q?fix(route):=20Fix=20=E5=9B=BD=E5=A4=96?= =?UTF-8?q?=E4=B8=BB=E6=9C=BA=E6=B5=8B=E8=AF=84=20(#14860)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/zhujiceping/rss.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/routes/zhujiceping/rss.ts b/lib/routes/zhujiceping/rss.ts index 3a6515881e9ff6..1c28d10d5c4187 100644 --- a/lib/routes/zhujiceping/rss.ts +++ b/lib/routes/zhujiceping/rss.ts @@ -5,13 +5,14 @@ import { load } from 'cheerio'; export const route: Route = { path: '/', + categories: ['blog'], + example: '/zhujiceping', radar: [ { source: ['zhujiceping.com/'], - target: '', }, ], - name: 'Unknown', + name: '最新发布', maintainers: ['cnkmmk'], handler, url: 'zhujiceping.com/', From 906f95e2e871b0a3d403fbdf412c90bd9cf58297 Mon Sep 17 00:00:00 2001 From: LMark <40017222+ladeng07@users.noreply.github.com> Date: Wed, 20 Mar 2024 00:32:41 +0800 Subject: [PATCH 15/25] =?UTF-8?q?feat(route):=20=20=E4=B8=AD=E5=9B=BD?= =?UTF-8?q?=E6=B5=B7=E6=B4=8B=E5=A4=A7=E5=AD=A6=E5=90=8E=E5=8B=A4=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=20(#14854)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add 中国海洋大学后勤通知 * Update lib/routes/ouc/hqsz.ts * Update lib/routes/ouc/hqsz.ts --------- --- lib/routes/ouc/hqsz.ts | 89 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 lib/routes/ouc/hqsz.ts diff --git a/lib/routes/ouc/hqsz.ts b/lib/routes/ouc/hqsz.ts new file mode 100644 index 00000000000000..33dd96832fb465 --- /dev/null +++ b/lib/routes/ouc/hqsz.ts @@ -0,0 +1,89 @@ +import { parseDate } from '@/utils/parse-date'; +import got from '@/utils/got'; +import cache from '@/utils/cache'; +import CryptoJS from 'crypto-js/crypto-js'; + +export const route: Route = { + path: '/hqsz', + categories: ['university'], + example: '/ouc/hqsz', + parameters: {}, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: true, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + radar: [ + { + source: ['hqsz.ouc.edu.cn/news.html'], + }, + ], + name: '后勤公告通知', + maintainers: ['ladeng07'], + handler, + url: 'hqsz.ouc.edu.cn/news.html?typeId=02', +}; + +function Decrypt(word, keyStr = '1974051005060708', ivStr = '1974051005060708') { + const key = CryptoJS.enc.Utf8.parse(keyStr); // ""中与后台一样 密码 + const iv = CryptoJS.enc.Utf8.parse(ivStr); // ""中与后台一样 + const base64 = CryptoJS.enc.Base64.parse(word); + const src = CryptoJS.enc.Base64.stringify(base64); + + const decrypt = CryptoJS.AES.decrypt(src, key, { + iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7, + }); + + const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); + return decryptedStr; +} + +async function handler() { + const base = 'http://hqsz.ouc.edu.cn/'; + const link = base + 'api/website/frontendWebsite/lists'; + const { data } = await got.post(link, { + form: { + schoolCode: '10423', + website: '89e97da117d547128283cf9d12891fa9', + code: '0202', + pageSize: '10', + pageIndex: '1', + }, + }); + const list = JSON.parse(Decrypt(data)).data.list.map((item) => ({ + title: item.title, + id: item.id, + author: item.author, + link: base + 'news_detail.html?id=' + item.id, + pubDate: parseDate(item.publishTime), + })); + + const out = await Promise.all( + list.map((item) => + cache.tryGet(item.link, async () => { + const { data } = await got.post(base + 'api/website/frontendWebsite/info', { + form: { + schoolCode: '10423', + website: '89e97da117d547128283cf9d12891fa9', + id: item.id, + }, + }); + item.description = Decrypt(JSON.parse(Decrypt(data)).data.content); + delete item.id; + return item; + }) + ) + ); + + return { + title: '中国海洋大学后勤公告通知', + link, + description: '中国海洋大学后勤公告通知', + item: out, + }; +} From fc1b99f1c15911820534149199d122877c65e6ff Mon Sep 17 00:00:00 2001 From: Jia Chen Date: Wed, 20 Mar 2024 01:04:31 +0800 Subject: [PATCH 16/25] feat(route): recover kaopu.news route (#14818) * feat(route): recover kaopu.news route * feat(route): recover kaopu.new from deprecated * feat(route): update param & desc info --- lib/router.js | 3 -- lib/routes-deprecated/kaopunews/index.js | 28 ------------- lib/routes/kaopu/namespace.ts | 6 +++ lib/routes/kaopu/news.ts | 51 ++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 31 deletions(-) delete mode 100644 lib/routes-deprecated/kaopunews/index.js create mode 100644 lib/routes/kaopu/namespace.ts create mode 100644 lib/routes/kaopu/news.ts diff --git a/lib/router.js b/lib/router.js index fef63a38078d22..ccc3a1bf365839 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1262,9 +1262,6 @@ router.get('/missevan/drama/:id', lazyloadRouteHandler('./routes/missevan/drama' // AMD router.get('/amd/graphicsdrivers/:id/:rid?', lazyloadRouteHandler('./routes/amd/graphicsdrivers')); -// 靠谱新闻 -router.get('/kaopunews/:language?', lazyloadRouteHandler('./routes/kaopunews')); - // 光谷社区 router.get('/guanggoo/:category?', lazyloadRouteHandler('./routes/guanggoo/index')); diff --git a/lib/routes-deprecated/kaopunews/index.js b/lib/routes-deprecated/kaopunews/index.js deleted file mode 100644 index e848e9c55d53fb..00000000000000 --- a/lib/routes-deprecated/kaopunews/index.js +++ /dev/null @@ -1,28 +0,0 @@ -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const language = ctx.params.language || ''; - - const rootUrl = 'https://kaopu.news'; - const currentUrl = `${rootUrl}/${language === 'zh-hant' ? 'zh-hant' : 'index'}.html`; - const apiUrl = `https://kaopucdn.azureedge.net/jsondata/news_han${language === 'zh-hant' ? 't' : 's'}_0.json`; - - const response = await got({ - method: 'get', - url: apiUrl, - }); - - const items = response.data.map((item) => ({ - link: item.link, - title: item.title, - author: item.publisher, - pubDate: new Date(item.first_seen * 1000), - description: `

${item.story_summary}

`, - })); - - ctx.state.data = { - title: language === 'zh-hant' ? '靠譜新聞' : '靠谱新闻', - link: currentUrl, - item: items, - }; -}; diff --git a/lib/routes/kaopu/namespace.ts b/lib/routes/kaopu/namespace.ts new file mode 100644 index 00000000000000..cfc43a76a33529 --- /dev/null +++ b/lib/routes/kaopu/namespace.ts @@ -0,0 +1,6 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: '靠谱新闻', + url: 'kaopu.news', +}; diff --git a/lib/routes/kaopu/news.ts b/lib/routes/kaopu/news.ts new file mode 100644 index 00000000000000..c81b69bf52a69d --- /dev/null +++ b/lib/routes/kaopu/news.ts @@ -0,0 +1,51 @@ +import { Route } from '@/types'; +import got from '@/utils/got'; +import { parseDate } from '@/utils/parse-date'; + +export const route: Route = { + path: '/news/:language?', + categories: ['new-media'], + example: '/news/zh-hans, /news/zh-hant', + parameters: { + language: '语言', + }, + radar: [ + { + source: ['kaopu.news/'], + }, + ], + name: '全部', + maintainers: ['fashioncj'], + description: `| 简体中文 | 繁体中文 | + | ------- | -------- | + | zh-hans | zh-hant | `, + handler, +}; + +async function handler(ctx) { + const { language } = ctx.req.param(); + + const rootUrl = 'https://kaopu.news'; + const currentUrl = `${rootUrl}/${language === 'zh-hant' ? 'zh-hant' : 'index'}.html`; + // API PATH: https://kaopucdn.azureedge.net/jsondata/news_list_beta_hans_0.json + const apiUrl = `https://kaopucdn.azureedge.net/jsondata/news_list_beta_han${language === 'zh-hant' ? 't' : 's'}_0.json`; + + const response = await got({ + method: 'get', + url: apiUrl, + }); + + const items = response.data.map((item) => ({ + link: item.link, + title: item.title, + author: item.publisher, + pubDate: parseDate(item.pubDate), + description: `

${item.description}

`, + })); + + return { + title: language === 'zh-hant' ? '靠譜新聞' : '靠谱新闻', + link: currentUrl, + item: items, + }; +} From 2e9935d6b220cfaffe06bb0c2f20ed54c78e0f72 Mon Sep 17 00:00:00 2001 From: cnkmmk <22782790+cnkmmk@users.noreply.github.com> Date: Wed, 20 Mar 2024 01:17:38 +0800 Subject: [PATCH 17/25] =?UTF-8?q?fix(route):=20Fix=20=E7=94=B5=E8=84=91?= =?UTF-8?q?=E7=8E=A9=E7=89=A9=20(#14861)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/playpcesor/rss.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/routes/playpcesor/rss.ts b/lib/routes/playpcesor/rss.ts index e0e9778e8b3f0f..4880747310a3da 100644 --- a/lib/routes/playpcesor/rss.ts +++ b/lib/routes/playpcesor/rss.ts @@ -5,13 +5,14 @@ import { load } from 'cheerio'; export const route: Route = { path: '/', + categories: ['blog'], + example: '/playpcesor', radar: [ { source: ['playpcesor.com/'], - target: '', }, ], - name: 'Unknown', + name: '每日精选文章', maintainers: ['cnkmmk'], handler, url: 'playpcesor.com/', From 49eb6ab086227daebf1fdd8e3f031210589a5314 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 22:29:15 +0000 Subject: [PATCH 18/25] chore(deps-dev): bump @types/eslint from 8.56.5 to 8.56.6 (#14864) * chore(deps-dev): bump @types/eslint from 8.56.5 to 8.56.6 Bumps [@types/eslint](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/eslint) from 8.56.5 to 8.56.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/eslint) --- updated-dependencies: - dependency-name: "@types/eslint" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index e1276ec5227c16..913df1c7c80e5a 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "@stylistic/eslint-plugin": "1.7.0", "@types/aes-js": "3.1.4", "@types/crypto-js": "4.2.2", - "@types/eslint": "8.56.5", + "@types/eslint": "8.56.6", "@types/eslint-config-prettier": "6.11.3", "@types/etag": "1.8.3", "@types/fs-extra": "11.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32c14ac8b4b142..338fc21f653fb4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -233,8 +233,8 @@ devDependencies: specifier: 4.2.2 version: 4.2.2 '@types/eslint': - specifier: 8.56.5 - version: 8.56.5 + specifier: 8.56.6 + version: 8.56.6 '@types/eslint-config-prettier': specifier: 6.11.3 version: 6.11.3 @@ -315,7 +315,7 @@ devDependencies: version: 16.6.2(eslint@8.57.0) eslint-plugin-prettier: specifier: 5.1.3 - version: 5.1.3(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) + version: 5.1.3(@types/eslint@8.56.6)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) eslint-plugin-unicorn: specifier: 51.0.1 version: 51.0.1(eslint@8.57.0) @@ -2333,7 +2333,7 @@ packages: peerDependencies: eslint: '>=8.40.0' dependencies: - '@types/eslint': 8.56.5 + '@types/eslint': 8.56.6 acorn: 8.11.3 escape-string-regexp: 4.0.0 eslint: 8.57.0 @@ -2348,7 +2348,7 @@ packages: eslint: '>=8.40.0' dependencies: '@stylistic/eslint-plugin-js': 1.7.0(eslint@8.57.0) - '@types/eslint': 8.56.5 + '@types/eslint': 8.56.6 eslint: 8.57.0 estraverse: 5.3.0 picomatch: 4.0.1 @@ -2359,7 +2359,7 @@ packages: peerDependencies: eslint: '*' dependencies: - '@types/eslint': 8.56.5 + '@types/eslint': 8.56.6 '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.4.2) eslint: 8.57.0 transitivePeerDependencies: @@ -2374,7 +2374,7 @@ packages: eslint: '>=8.40.0' dependencies: '@stylistic/eslint-plugin-js': 1.7.0(eslint@8.57.0) - '@types/eslint': 8.56.5 + '@types/eslint': 8.56.6 '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.4.2) eslint: 8.57.0 transitivePeerDependencies: @@ -2392,7 +2392,7 @@ packages: '@stylistic/eslint-plugin-jsx': 1.7.0(eslint@8.57.0) '@stylistic/eslint-plugin-plus': 1.7.0(eslint@8.57.0)(typescript@5.4.2) '@stylistic/eslint-plugin-ts': 1.7.0(eslint@8.57.0)(typescript@5.4.2) - '@types/eslint': 8.56.5 + '@types/eslint': 8.56.6 eslint: 8.57.0 transitivePeerDependencies: - supports-color @@ -2463,8 +2463,8 @@ packages: resolution: {integrity: sha512-3wXCiM8croUnhg9LdtZUJQwNcQYGWxxdOWDjPe1ykCqJFPVpzAKfs/2dgSoCtAvdPeaponcWPI7mPcGGp9dkKQ==} dev: true - /@types/eslint@8.56.5: - resolution: {integrity: sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==} + /@types/eslint@8.56.6: + resolution: {integrity: sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==} dependencies: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 @@ -4478,7 +4478,7 @@ packages: semver: 7.6.0 dev: true - /eslint-plugin-prettier@5.1.3(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5): + /eslint-plugin-prettier@5.1.3(@types/eslint@8.56.6)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5): resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -4492,7 +4492,7 @@ packages: eslint-config-prettier: optional: true dependencies: - '@types/eslint': 8.56.5 + '@types/eslint': 8.56.6 eslint: 8.57.0 eslint-config-prettier: 9.1.0(eslint@8.57.0) prettier: 3.2.5 From b51a3957345d7c3dda097c6412d2c88fb9cba88a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 22:47:12 +0000 Subject: [PATCH 19/25] chore(deps-dev): bump @babel/preset-env from 7.24.0 to 7.24.1 (#14865) * chore(deps-dev): bump @babel/preset-env from 7.24.0 to 7.24.1 Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.24.0 to 7.24.1. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.1/packages/babel-preset-env) --- updated-dependencies: - dependency-name: "@babel/preset-env" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 450 ++++++++++++++++++++++++++++--------------------- 2 files changed, 263 insertions(+), 189 deletions(-) diff --git a/package.json b/package.json index 913df1c7c80e5a..72f2249c23e60c 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "zod": "3.22.4" }, "devDependencies": { - "@babel/preset-env": "7.24.0", + "@babel/preset-env": "7.24.1", "@babel/preset-typescript": "7.23.3", "@microsoft/eslint-formatter-sarif": "3.0.0", "@stylistic/eslint-plugin": "1.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 338fc21f653fb4..947bf7e6ec0cee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -215,8 +215,8 @@ dependencies: devDependencies: '@babel/preset-env': - specifier: 7.24.0 - version: 7.24.0(@babel/core@7.23.9) + specifier: 7.24.1 + version: 7.24.1(@babel/core@7.23.9) '@babel/preset-typescript': specifier: 7.23.3 version: 7.23.3(@babel/core@7.23.9) @@ -399,8 +399,8 @@ packages: '@babel/highlight': 7.23.4 chalk: 2.4.2 - /@babel/compat-data@7.23.5: - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + /@babel/compat-data@7.24.1: + resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==} engines: {node: '>=6.9.0'} dev: true @@ -455,7 +455,7 @@ packages: resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.23.5 + '@babel/compat-data': 7.24.1 '@babel/helper-validator-option': 7.23.5 browserslist: 4.23.0 lru-cache: 5.1.1 @@ -480,6 +480,24 @@ packages: semver: 6.3.1 dev: true + /@babel/helper-create-class-features-plugin@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.23.9) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.9): resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} engines: {node: '>=6.9.0'} @@ -492,8 +510,8 @@ packages: semver: 6.3.1 dev: true - /@babel/helper-define-polyfill-provider@0.5.0(@babel/core@7.23.9): - resolution: {integrity: sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==} + /@babel/helper-define-polyfill-provider@0.6.1(@babel/core@7.23.9): + resolution: {integrity: sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: @@ -541,6 +559,13 @@ packages: '@babel/types': 7.23.9 dev: true + /@babel/helper-module-imports@7.24.1: + resolution: {integrity: sha512-HfEWzysMyOa7xI5uQHc/OcZf67/jc+xe/RZlznWQHhbb8Pg1SkRdbK4yEi61aY8wxQA7PkSfoojtLQP/Kpe3og==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.0 + dev: true + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.9): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} @@ -596,6 +621,18 @@ packages: '@babel/helper-optimise-call-expression': 7.22.5 dev: true + /@babel/helper-replace-supers@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.9 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: true + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} @@ -667,8 +704,16 @@ packages: '@babel/types': 7.23.9 dev: true - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} + /@babel/parser@7.24.1: + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.0 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -677,8 +722,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==} + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 @@ -686,11 +731,11 @@ packages: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.9) + '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.23.9) dev: true - /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7(@babel/core@7.23.9): - resolution: {integrity: sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==} + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -755,8 +800,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==} + /@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -765,8 +810,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + /@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -898,8 +943,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==} + /@babel/plugin-transform-arrow-functions@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -908,8 +953,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-async-generator-functions@7.23.9(@babel/core@7.23.9): - resolution: {integrity: sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==} + /@babel/plugin-transform-async-generator-functions@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-OTkLJM0OtmzcpOgF7MREERUCdCnCBtBsq3vVFbuq/RKMK0/jdYqdMexWi3zNs7Nzd95ase65MbTGrpFJflOb6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -921,20 +966,20 @@ packages: '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==} + /@babel/plugin-transform-async-to-generator@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-module-imports': 7.22.15 + '@babel/helper-module-imports': 7.24.1 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==} + /@babel/plugin-transform-block-scoped-functions@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -943,8 +988,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==} + /@babel/plugin-transform-block-scoping@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -953,31 +998,31 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==} + /@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.9) + '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.23.9) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} + /@babel/plugin-transform-class-static-block@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.9) + '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.23.9) '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-classes@7.23.8(@babel/core@7.23.9): - resolution: {integrity: sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==} + /@babel/plugin-transform-classes@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -988,24 +1033,24 @@ packages: '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-plugin-utils': 7.24.0 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.9) + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.23.9) '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 dev: true - /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==} + /@babel/plugin-transform-computed-properties@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.24.0 - '@babel/template': 7.23.9 + '@babel/template': 7.24.0 dev: true - /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==} + /@babel/plugin-transform-destructuring@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1014,8 +1059,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==} + /@babel/plugin-transform-dotall-regex@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1025,8 +1070,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==} + /@babel/plugin-transform-duplicate-keys@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1035,8 +1080,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==} + /@babel/plugin-transform-dynamic-import@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1046,8 +1091,8 @@ packages: '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==} + /@babel/plugin-transform-exponentiation-operator@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1057,8 +1102,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==} + /@babel/plugin-transform-export-namespace-from@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1068,8 +1113,8 @@ packages: '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.23.9): - resolution: {integrity: sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==} + /@babel/plugin-transform-for-of@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1079,8 +1124,8 @@ packages: '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==} + /@babel/plugin-transform-function-name@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1091,8 +1136,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==} + /@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1102,8 +1147,8 @@ packages: '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-literals@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==} + /@babel/plugin-transform-literals@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1112,8 +1157,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==} + /@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1123,8 +1168,8 @@ packages: '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==} + /@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1133,8 +1178,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==} + /@babel/plugin-transform-modules-amd@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1156,8 +1201,20 @@ packages: '@babel/helper-simple-access': 7.22.5 dev: true - /@babel/plugin-transform-modules-systemjs@7.23.9(@babel/core@7.23.9): - resolution: {integrity: sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==} + /@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.9 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) + '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-simple-access': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-systemjs@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1169,8 +1226,8 @@ packages: '@babel/helper-validator-identifier': 7.22.20 dev: true - /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==} + /@babel/plugin-transform-modules-umd@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1191,8 +1248,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==} + /@babel/plugin-transform-new-target@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1201,8 +1258,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==} + /@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1212,8 +1269,8 @@ packages: '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} + /@babel/plugin-transform-numeric-separator@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1223,33 +1280,32 @@ packages: '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-object-rest-spread@7.24.0(@babel/core@7.23.9): - resolution: {integrity: sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==} + /@babel/plugin-transform-object-rest-spread@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.23.5 '@babel/core': 7.23.9 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.9) + '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==} + /@babel/plugin-transform-object-super@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.24.0 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.9) + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==} + /@babel/plugin-transform-optional-catch-binding@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1259,8 +1315,8 @@ packages: '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==} + /@babel/plugin-transform-optional-chaining@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1271,8 +1327,8 @@ packages: '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} + /@babel/plugin-transform-parameters@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1281,32 +1337,32 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==} + /@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.9) + '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.23.9) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.23.9): - resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} + /@babel/plugin-transform-private-property-in-object@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.9) + '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.23.9) '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==} + /@babel/plugin-transform-property-literals@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1315,8 +1371,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==} + /@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1326,8 +1382,8 @@ packages: regenerator-transform: 0.15.2 dev: true - /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==} + /@babel/plugin-transform-reserved-words@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1336,8 +1392,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==} + /@babel/plugin-transform-shorthand-properties@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1346,8 +1402,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-spread@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==} + /@babel/plugin-transform-spread@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1357,8 +1413,8 @@ packages: '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==} + /@babel/plugin-transform-sticky-regex@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1367,8 +1423,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==} + /@babel/plugin-transform-template-literals@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1377,8 +1433,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==} + /@babel/plugin-transform-typeof-symbol@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1400,8 +1456,8 @@ packages: '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.9) dev: true - /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==} + /@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1410,8 +1466,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==} + /@babel/plugin-transform-unicode-property-regex@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1421,8 +1477,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==} + /@babel/plugin-transform-unicode-regex@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1432,8 +1488,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==} + /@babel/plugin-transform-unicode-sets-regex@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1443,28 +1499,28 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/preset-env@7.24.0(@babel/core@7.23.9): - resolution: {integrity: sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==} + /@babel/preset-env@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-CwCMz1Z28UHLI2iE+cbnWT2epPMV9bzzoBGM6A3mOS22VQd/1TPoWItV7S7iL9TkPmPEf5L/QzurmztyyDN9FA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.23.5 + '@babel/compat-data': 7.24.1 '@babel/core': 7.23.9 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.7(@babel/core@7.23.9) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.1(@babel/core@7.23.9) '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.9) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.9) '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.9) '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.9) '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.9) '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.9) - '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.9) + '@babel/plugin-syntax-import-assertions': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-syntax-import-attributes': 7.24.1(@babel/core@7.23.9) '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.9) '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.9) '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.9) @@ -1476,58 +1532,58 @@ packages: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.9) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.9) '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.9) - '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-async-generator-functions': 7.23.9(@babel/core@7.23.9) - '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-classes': 7.23.8(@babel/core@7.23.9) - '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.23.9) - '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-systemjs': 7.23.9(@babel/core@7.23.9) - '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.23.9) + '@babel/plugin-transform-arrow-functions': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-async-generator-functions': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-async-to-generator': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-block-scoped-functions': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-block-scoping': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-class-properties': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-class-static-block': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-classes': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-computed-properties': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-destructuring': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-dotall-regex': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-duplicate-keys': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-dynamic-import': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-exponentiation-operator': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-export-namespace-from': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-for-of': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-function-name': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-json-strings': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-literals': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-logical-assignment-operators': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-member-expression-literals': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-modules-amd': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-modules-systemjs': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-modules-umd': 7.24.1(@babel/core@7.23.9) '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.9) - '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-object-rest-spread': 7.24.0(@babel/core@7.23.9) - '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.23.9) - '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.23.9) + '@babel/plugin-transform-new-target': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-numeric-separator': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-object-rest-spread': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-object-super': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-optional-catch-binding': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-private-property-in-object': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-property-literals': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-regenerator': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-reserved-words': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-shorthand-properties': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-spread': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-sticky-regex': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-template-literals': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-typeof-symbol': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-unicode-escapes': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-unicode-property-regex': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-unicode-regex': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-unicode-sets-regex': 7.24.1(@babel/core@7.23.9) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.9) - babel-plugin-polyfill-corejs2: 0.4.8(@babel/core@7.23.9) - babel-plugin-polyfill-corejs3: 0.9.0(@babel/core@7.23.9) - babel-plugin-polyfill-regenerator: 0.5.5(@babel/core@7.23.9) + babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.23.9) + babel-plugin-polyfill-corejs3: 0.10.1(@babel/core@7.23.9) + babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.23.9) core-js-compat: 3.36.0 semver: 6.3.1 transitivePeerDependencies: @@ -1587,6 +1643,15 @@ packages: '@babel/types': 7.23.9 dev: true + /@babel/template@7.24.0: + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + dev: true + /@babel/traverse@7.23.9: resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==} engines: {node: '>=6.9.0'} @@ -1614,6 +1679,15 @@ packages: to-fast-properties: 2.0.0 dev: true + /@babel/types@7.24.0: + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -3192,38 +3266,38 @@ packages: resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==} dev: false - /babel-plugin-polyfill-corejs2@0.4.8(@babel/core@7.23.9): - resolution: {integrity: sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==} + /babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.23.9): + resolution: {integrity: sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/compat-data': 7.23.5 + '@babel/compat-data': 7.24.1 '@babel/core': 7.23.9 - '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.23.9) + '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.23.9) semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3@0.9.0(@babel/core@7.23.9): - resolution: {integrity: sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==} + /babel-plugin-polyfill-corejs3@0.10.1(@babel/core@7.23.9): + resolution: {integrity: sha512-XiFei6VGwM4ii6nKC1VCenGD8Z4bjiNYcrdkM8oqM3pbuemmyb8biMgrDX1ZHSbIuMLXatM6JJ/StPYIuTl6MQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.23.9) + '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.23.9) core-js-compat: 3.36.0 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator@0.5.5(@babel/core@7.23.9): - resolution: {integrity: sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==} + /babel-plugin-polyfill-regenerator@0.6.1(@babel/core@7.23.9): + resolution: {integrity: sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.23.9) + '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.23.9) transitivePeerDependencies: - supports-color dev: true From 82273c0df62204d7bc4102edd82ca378475e716f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 07:03:40 +0800 Subject: [PATCH 20/25] chore(deps): bump imapflow from 1.0.156 to 1.0.158 (#14866) * chore(deps): bump imapflow from 1.0.156 to 1.0.158 Bumps [imapflow](https://github.com/postalsys/imapflow) from 1.0.156 to 1.0.158. - [Release notes](https://github.com/postalsys/imapflow/releases) - [Changelog](https://github.com/postalsys/imapflow/blob/master/CHANGELOG.md) - [Commits](https://github.com/postalsys/imapflow/compare/v1.0.156...v1.0.158) --- updated-dependencies: - dependency-name: imapflow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 60 +++++++++++++++++++++++--------------------------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 72f2249c23e60c..835344e2580c67 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "html-to-text": "9.0.5", "https-proxy-agent": "7.0.4", "iconv-lite": "0.6.3", - "imapflow": "1.0.156", + "imapflow": "1.0.158", "instagram-private-api": "1.46.1", "ioredis": "5.3.2", "ip-regex": "5.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 947bf7e6ec0cee..ffe991bddc4a4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,8 +90,8 @@ dependencies: specifier: 0.6.3 version: 0.6.3 imapflow: - specifier: 1.0.156 - version: 1.0.156 + specifier: 1.0.158 + version: 1.0.158 instagram-private-api: specifier: 1.46.1 version: 1.46.1 @@ -414,10 +414,10 @@ packages: '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) '@babel/helpers': 7.23.9 - '@babel/parser': 7.23.9 - '@babel/template': 7.23.9 + '@babel/parser': 7.24.1 + '@babel/template': 7.24.0 '@babel/traverse': 7.23.9 - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 convert-source-map: 2.0.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -431,7 +431,7 @@ packages: resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 @@ -448,7 +448,7 @@ packages: resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-compilation-targets@7.23.6: @@ -534,15 +534,15 @@ packages: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.23.9 - '@babel/types': 7.23.9 + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-member-expression-to-functions@7.23.0: @@ -644,14 +644,14 @@ packages: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-string-parser@7.23.4: @@ -673,17 +673,17 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-function-name': 7.23.0 - '@babel/template': 7.23.9 - '@babel/types': 7.23.9 + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 dev: true /@babel/helpers@7.23.9: resolution: {integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.23.9 + '@babel/template': 7.24.0 '@babel/traverse': 7.23.9 - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color dev: true @@ -929,7 +929,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: true /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.9): @@ -1597,7 +1597,7 @@ packages: dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.24.0 - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 esutils: 2.0.3 dev: true @@ -1634,15 +1634,6 @@ packages: regenerator-runtime: 0.14.1 dev: true - /@babel/template@7.23.9: - resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.9 - '@babel/types': 7.23.9 - dev: true - /@babel/template@7.24.0: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} @@ -1662,8 +1653,8 @@ packages: '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.9 - '@babel/types': 7.23.9 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -5605,8 +5596,8 @@ packages: hasBin: true dev: false - /imapflow@1.0.156: - resolution: {integrity: sha512-HzPBJ25omt2uL8p4VpkWYcL7ILVXuAAJplswpPuLtryy9eW0AvBtPxKeVbxU1QLQMdsZmEr0p4skHVO4jY3k8A==} + /imapflow@1.0.158: + resolution: {integrity: sha512-8ysCZm3Eb80I5/AM3w0Chd+pi9HfUer9QRWE/Ca3MZbu/q97Xve3G4n40V7P+KJ3SXc0GM0tiotIaCcXqIccHw==} dependencies: encoding-japanese: 2.0.0 iconv-lite: 0.6.3 @@ -5614,7 +5605,7 @@ packages: libmime: 5.3.4 libqp: 2.1.0 mailsplit: 5.4.0 - nodemailer: 6.9.11 + nodemailer: 6.9.12 pino: 8.19.0 socks: 2.8.1 dev: false @@ -6908,6 +6899,11 @@ packages: engines: {node: '>=6.0.0'} dev: false + /nodemailer@6.9.12: + resolution: {integrity: sha512-pnLo7g37Br3jXbF0bl5DekBJihm2q+3bB3l2o/B060sWmb5l+VqeScAQCBqaQ+5ezRZFzW5SciZNGdRDEbq89w==} + engines: {node: '>=6.0.0'} + dev: false + /nopt@5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} From fde2be236b793cb82c1615a7d807e6aaa6c892e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 23:10:59 +0000 Subject: [PATCH 21/25] chore(deps-dev): bump @babel/preset-typescript from 7.23.3 to 7.24.1 (#14868) * chore(deps-dev): bump @babel/preset-typescript from 7.23.3 to 7.24.1 Bumps [@babel/preset-typescript](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-typescript) from 7.23.3 to 7.24.1. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.1/packages/babel-preset-typescript) --- updated-dependencies: - dependency-name: "@babel/preset-typescript" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 91 ++++++++++++-------------------------------------- 2 files changed, 23 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index 835344e2580c67..b7560cedbec664 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ }, "devDependencies": { "@babel/preset-env": "7.24.1", - "@babel/preset-typescript": "7.23.3", + "@babel/preset-typescript": "7.24.1", "@microsoft/eslint-formatter-sarif": "3.0.0", "@stylistic/eslint-plugin": "1.7.0", "@types/aes-js": "3.1.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ffe991bddc4a4a..ce15e86c95e24f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -218,8 +218,8 @@ devDependencies: specifier: 7.24.1 version: 7.24.1(@babel/core@7.23.9) '@babel/preset-typescript': - specifier: 7.23.3 - version: 7.23.3(@babel/core@7.23.9) + specifier: 7.24.1 + version: 7.24.1(@babel/core@7.23.9) '@microsoft/eslint-formatter-sarif': specifier: 3.0.0 version: 3.0.0 @@ -441,7 +441,7 @@ packages: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: @@ -462,24 +462,6 @@ packages: semver: 6.3.1 dev: true - /@babel/helper-create-class-features-plugin@7.24.0(@babel/core@7.23.9): - resolution: {integrity: sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.9) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - semver: 6.3.1 - dev: true - /@babel/helper-create-class-features-plugin@7.24.1(@babel/core@7.23.9): resolution: {integrity: sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==} engines: {node: '>=6.9.0'} @@ -549,14 +531,14 @@ packages: resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-module-imports@7.24.1: @@ -584,12 +566,7 @@ packages: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 - dev: true - - /@babel/helper-plugin-utils@7.22.5: - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} + '@babel/types': 7.24.0 dev: true /@babel/helper-plugin-utils@7.24.0: @@ -609,18 +586,6 @@ packages: '@babel/helper-wrap-function': 7.22.20 dev: true - /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.9): - resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - dev: true - /@babel/helper-replace-supers@7.24.1(@babel/core@7.23.9): resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} engines: {node: '>=6.9.0'} @@ -838,14 +803,14 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} + /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 dev: true /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.9): @@ -922,8 +887,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + /@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1189,18 +1154,6 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.9 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - dev: true - /@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.23.9): resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} engines: {node: '>=6.9.0'} @@ -1443,17 +1396,17 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.23.9): - resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==} + /@babel/plugin-transform-typescript@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.23.9) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.9) + '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.23.9) + '@babel/helper-plugin-utils': 7.24.0 + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.23.9) dev: true /@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.23.9): @@ -1601,18 +1554,18 @@ packages: esutils: 2.0.3 dev: true - /@babel/preset-typescript@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==} + /@babel/preset-typescript@7.24.1(@babel/core@7.23.9): + resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.9 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.9) - '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.23.9) + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.23.9) + '@babel/plugin-transform-typescript': 7.24.1(@babel/core@7.23.9) dev: true /@babel/regjsgen@0.8.0: From 6c8bb2ff9bfae578b5598c9bd4f982f81dd2ec29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 07:41:43 +0800 Subject: [PATCH 22/25] chore(deps-dev): bump @types/node from 20.11.29 to 20.11.30 (#14867) * chore(deps-dev): bump @types/node from 20.11.29 to 20.11.30 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.29 to 20.11.30. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 67 ++++++++++++++++++++++---------------------------- 2 files changed, 31 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index b7560cedbec664..5ea9c87d8ff3fb 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "@types/mailparser": "3.4.4", "@types/markdown-it": "13.0.7", "@types/module-alias": "2.0.4", - "@types/node": "20.11.29", + "@types/node": "20.11.30", "@types/request-promise-native": "1.0.21", "@types/supertest": "6.0.2", "@types/tiny-async-pool": "2.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce15e86c95e24f..ec9aa2c43f6adc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -272,8 +272,8 @@ devDependencies: specifier: 2.0.4 version: 2.0.4 '@types/node': - specifier: 20.11.29 - version: 20.11.29 + specifier: 20.11.30 + version: 20.11.30 '@types/request-promise-native': specifier: 1.0.21 version: 1.0.21 @@ -360,7 +360,7 @@ devDependencies: version: 4.3.2(typescript@5.4.2) vitest: specifier: 1.4.0 - version: 1.4.0(@types/node@20.11.29)(jsdom@24.0.0) + version: 1.4.0(@types/node@20.11.30)(jsdom@24.0.0) packages: @@ -534,13 +534,6 @@ packages: '@babel/types': 7.24.0 dev: true - /@babel/helper-module-imports@7.22.15: - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.0 - dev: true - /@babel/helper-module-imports@7.24.1: resolution: {integrity: sha512-HfEWzysMyOa7xI5uQHc/OcZf67/jc+xe/RZlznWQHhbb8Pg1SkRdbK4yEi61aY8wxQA7PkSfoojtLQP/Kpe3og==} engines: {node: '>=6.9.0'} @@ -556,7 +549,7 @@ packages: dependencies: '@babel/core': 7.23.9 '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.22.15 + '@babel/helper-module-imports': 7.24.1 '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 @@ -602,7 +595,7 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/helper-skip-transparent-expression-wrappers@7.22.5: @@ -666,7 +659,7 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.9 + '@babel/types': 7.24.0 dev: true /@babel/parser@7.24.1: @@ -2453,7 +2446,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.11.29 + '@types/node': 20.11.30 '@types/responselike': 1.0.3 dev: false @@ -2495,14 +2488,14 @@ packages: /@types/etag@1.8.3: resolution: {integrity: sha512-QYHv9Yeh1ZYSMPQOoxY4XC4F1r+xRUiAriB303F4G6uBsT3KKX60DjiogvVv+2VISVDuJhcIzMdbjT+Bm938QQ==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: true /@types/fs-extra@11.0.4: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: true /@types/git-rev-sync@2.0.2: @@ -2520,7 +2513,7 @@ packages: /@types/imapflow@1.0.18: resolution: {integrity: sha512-BoWZUoMktji2YJmkRY8z0KsjvyDNpBzeC/rLVMFKcHkPxaKp+SHBFfx/kj7ltKh3l010Lc9RZqnJs8KUMNhf6Q==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: true /@types/istanbul-lib-coverage@2.0.6: @@ -2530,7 +2523,7 @@ packages: /@types/jsdom@21.1.6: resolution: {integrity: sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 '@types/tough-cookie': 4.0.5 parse5: 7.1.2 dev: true @@ -2546,13 +2539,13 @@ packages: /@types/jsonfile@6.1.4: resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: true /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: false /@types/linkify-it@3.0.5: @@ -2566,7 +2559,7 @@ packages: /@types/mailparser@3.4.4: resolution: {integrity: sha512-C6Znp2QVS25JqtuPyxj38Qh+QoFcLycdxsvcc6IZCGekhaMBzbdTXzwGzhGoYb3TfKu8IRCNV0sV1o3Od97cEQ==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 iconv-lite: 0.6.3 dev: true @@ -2601,12 +2594,12 @@ packages: /@types/node-fetch@2.6.11: resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 form-data: 4.0.0 dev: false - /@types/node@20.11.29: - resolution: {integrity: sha512-P99thMkD/1YkCvAtOd6/zGedKNA0p2fj4ZpjCzcNiSCBWgm3cNRTBfa/qjFnsKkkojxu4vVLtWpesnZ9+ap+gA==} + /@types/node@20.11.30: + resolution: {integrity: sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==} dependencies: undici-types: 5.26.5 @@ -2631,14 +2624,14 @@ packages: resolution: {integrity: sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==} dependencies: '@types/caseless': 0.12.5 - '@types/node': 20.11.29 + '@types/node': 20.11.30 '@types/tough-cookie': 4.0.5 form-data: 2.5.1 /@types/responselike@1.0.3: resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: false /@types/semver@7.5.8: @@ -2650,7 +2643,7 @@ packages: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: true /@types/supertest@6.0.2: @@ -2683,7 +2676,7 @@ packages: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 dev: false optional: true @@ -2926,7 +2919,7 @@ packages: strip-literal: 2.0.0 test-exclude: 6.0.0 v8-to-istanbul: 9.2.0 - vitest: 1.4.0(@types/node@20.11.29)(jsdom@24.0.0) + vitest: 1.4.0(@types/node@20.11.30)(jsdom@24.0.0) transitivePeerDependencies: - supports-color dev: true @@ -9026,7 +9019,7 @@ packages: vfile-message: 4.0.2 dev: true - /vite-node@1.4.0(@types/node@20.11.29): + /vite-node@1.4.0(@types/node@20.11.30): resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -9035,7 +9028,7 @@ packages: debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.1.5(@types/node@20.11.29) + vite: 5.1.5(@types/node@20.11.30) transitivePeerDependencies: - '@types/node' - less @@ -9063,7 +9056,7 @@ packages: - typescript dev: true - /vite@5.1.5(@types/node@20.11.29): + /vite@5.1.5(@types/node@20.11.30): resolution: {integrity: sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -9091,7 +9084,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 esbuild: 0.19.12 postcss: 8.4.35 rollup: 4.12.0 @@ -9099,7 +9092,7 @@ packages: fsevents: 2.3.3 dev: true - /vitest@1.4.0(@types/node@20.11.29)(jsdom@24.0.0): + /vitest@1.4.0(@types/node@20.11.30)(jsdom@24.0.0): resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -9124,7 +9117,7 @@ packages: jsdom: optional: true dependencies: - '@types/node': 20.11.29 + '@types/node': 20.11.30 '@vitest/expect': 1.4.0 '@vitest/runner': 1.4.0 '@vitest/snapshot': 1.4.0 @@ -9143,8 +9136,8 @@ packages: strip-literal: 2.0.0 tinybench: 2.6.0 tinypool: 0.8.2 - vite: 5.1.5(@types/node@20.11.29) - vite-node: 1.4.0(@types/node@20.11.29) + vite: 5.1.5(@types/node@20.11.30) + vite-node: 1.4.0(@types/node@20.11.30) why-is-node-running: 2.2.2 transitivePeerDependencies: - less From e0beaad6872d56ff1b6e5145ec0bbd9f29e90e25 Mon Sep 17 00:00:00 2001 From: Ethan Shen <42264778+nczitzk@users.noreply.github.com> Date: Wed, 20 Mar 2024 09:08:16 +0800 Subject: [PATCH 23/25] =?UTF-8?q?fix(route):=204k=E4=B8=96=E7=95=8C=20(#14?= =?UTF-8?q?859)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * style: auto format * fix(route): 4k世界 --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/routes/4ksj/forum.ts | 205 ++++++++++++++-------- lib/routes/4ksj/templates/description.art | 95 +++++----- 2 files changed, 178 insertions(+), 122 deletions(-) diff --git a/lib/routes/4ksj/forum.ts b/lib/routes/4ksj/forum.ts index c10c8b0e807ae5..94d9d33fbb355a 100644 --- a/lib/routes/4ksj/forum.ts +++ b/lib/routes/4ksj/forum.ts @@ -12,42 +12,36 @@ import * as path from 'node:path'; import iconv from 'iconv-lite'; export const route: Route = { - path: '/forum/:id?', - categories: ['multimedia'], - example: '/4ksj/forum', - parameters: { id: '分类 id,默认为最新4K电影' }, - features: { - requireConfig: false, - requirePuppeteer: false, - antiCrawler: false, - supportBT: false, - supportPodcast: false, - supportScihub: false, - }, + path: '/:id?', name: '分类', + url: '4ksj.com', maintainers: ['nczitzk'], handler, + example: '/4ksj/4k-uhd-1', + parameters: { id: '分类 id,默认为最新4K电影' }, description: `:::tip - 若订阅 [最新 4K 电影](https://www.4ksj.com/forum-2-1.html),网址为 \`https://www.4ksj.com/forum-2-1.html\`。截取 \`https://www.4ksj.com/forum-\` 到末尾 \`.html\` 的部分 \`2-1\` 作为参数,此时路由为 [\`/4ksj/forum/2-1\`](https://rsshub.app/4ksj/forum/2-1)。 + 若订阅 [最新 4K 电影](https://www.4ksj.com/4k-uhd-1.html),网址为 \`https://www.4ksj.com/4k-uhd-1.html\`。截取 \`https://www.4ksj.com/\` 到末尾 \`.html\` 的部分 \`4k-uhd-1\` 作为参数,此时路由为 [\`/4ksj/4k-uhd-1\`](https://rsshub.app/4ksj/4k-uhd-1)。 - 若订阅子分类 [Dolby Vision 纪录片 4K 电影](https://www.4ksj.com/forum-4kdianying-s7-dianyingbiaozhun-3-dytypes-9-1.html),网址为 \`https://www.4ksj.com/forum-4kdianying-s7-dianyingbiaozhun-3-dytypes-9-1.html\`。截取 \`https://www.4ksj.com/forum-\` 到末尾 \`.html\` 的部分 \`4kdianying-s7-dianyingbiaozhun-3-dytypes-9-1\` 作为参数,此时路由为 [\`/4ksj/forum/4kdianying-s7-dianyingbiaozhun-3-dytypes-9-1\`](https://rsshub.app/4ksj/forum/4kdianying-s7-dianyingbiaozhun-3-dytypes-9-1)。 + 若订阅子分类 [Dolby Vision 动作 4K 电影](https://www.4ksj.com/4k-uhd-s7-display-3-dytypes-1-1.html),网址为 \`https://www.4ksj.com/4k-uhd-s7-display-3-dytypes-1-1.html\`。截取 \`https://www.4ksj.com/forum-\` 到末尾 \`.html\` 的部分 \`4kdianying-s7-dianyingbiaozhun-3-dytypes-9-1\` 作为参数,此时路由为 [\`/4ksj/4k-uhd-s7-display-3-dytypes-1-1\`](https://rsshub.app/4ksj/4k-uhd-s7-display-3-dytypes-1-1)。 :::`, + categories: ['multimedia'], }; async function handler(ctx) { - const id = ctx.req.param('id') ?? '2-1'; + const { id = '4k-uhd-1' } = ctx.req.param(); const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25; const rootUrl = 'https://www.4ksj.com'; - const currentUrl = `${rootUrl}/forum-${id}.html`; + const currentUrl = new URL(`${id}.html`, rootUrl).href; - const response = await got({ - method: 'get', - url: currentUrl, + const { data: response } = await got(currentUrl, { responseType: 'buffer', }); - const $ = load(iconv.decode(response.data, 'gbk')); + const $ = load(iconv.decode(response, 'gbk')); + + const language = 'zh'; + const image = $('div.nexlogo img').prop('src'); let items = $('div.nex_cmo_piv a') .slice(0, limit) @@ -56,76 +50,128 @@ async function handler(ctx) { item = $(item); return { - link: new URL(item.attr('href'), rootUrl).href, + link: new URL(item.prop('href'), rootUrl).href, }; }); items = await Promise.all( items.map((item) => cache.tryGet(item.link, async () => { - const detailResponse = await got({ - method: 'get', - url: item.link, + const { data: detailResponse } = await got(item.link, { responseType: 'buffer', }); - const content = load(iconv.decode(detailResponse.data, 'gbk')); - - const details = {}; - const links = {}; + const $$ = load(iconv.decode(detailResponse, 'gbk')); - content('.nex_drama_Details') - .find('em') - .each(function () { - const detail = content(this).parent(); - const key = content(this).text(); - const value = detail.text().replace(key, '').replaceAll(' ', '').trim(); - if (value) { - details[key.replaceAll(/:|\s/g, '')] = value; - } - }); + $$('div.nex_drama_intros em').first().remove(); + $$('strong font').each((_, el) => { + el = $$(el); - content('.nex_netdrivelink, .nex_xunleilink').each(function () { - links[content(this).text()] = content(this).next().html(); + el.parent().remove(); }); - content('.nex_drama_intros em').first().remove(); - content('.nex_thread_author_name em').first().remove(); - content('.xg1 a').remove(); - - const matches = content('.nex_drama_Top em') - .text() - .match(/(.*?)(豆瓣:(.*?))/); + const title = $$('div.nex_drama_Top h5').text(); + const description = $$('div.nex_drama_intros').html(); + const picture = + $$('div.nex_drama_pic') + .html() + .match(/background:url\((.*?)\)/)?.[1] ?? ''; - item.title = content('.nex_drama_Top h5').text(); - item.author = content('.nex_thread_author_name').text(); - item.pubDate = timezone(parseDate(content('.nex_ifpost em').text().replaceAll('发表于', '').trim(), 'YYYY-M-D HH:mm'), +8); - item.category = Object.values(details).map((d) => d.replaceAll(' ', '').trim()); + const details = $$('li.nex_drama_Detail_li, li.nex_drama_Detail_lis dd') + .toArray() + .map((li) => { + li = $$(li); + + const key = li.find('em').text().replaceAll(/:|\s/g, ''); + const value = li.find('span').length === 0 ? li.contents().last().text().trim() : li.find('span').text().trim(); + + return { [key]: value }; + }) + .reduce( + (obj, item) => ({ + ...obj, + ...item, + }), + {} + ); + + const links = + $$('td.t_f ignore_js_op').length === 0 + ? $$('td.t_f strong') + .toArray() + .map((l) => { + l = $$(l); + + const title = l.contents().first().text(); + const link = l.next().prop('href') ?? l.nextUntil('a').next().prop('href'); + + item.enclosure_url = item.enclosure_url ?? link; + item.enclosure_type = item.enclosure_type ?? 'application/x-bittorrent'; + item.enclosure_title = item.enclosure_title ?? title; + + return { + title, + tags: l + .contents() + .last() + .text() + .match(/【(.*?)】/g), + link, + }; + }) + : $$('div.newfujian') + .toArray() + .map((l) => { + l = $$(l); + + return { + title: l.find('p.filename').prop('title') || l.find('p.filename').text(), + tags: l + .find('div.fileaq') + .text() + .match(/【(.*?)】/g), + link: l.find('div.down_2 a').prop('href'), + }; + }); + + const pubDateEl = $$('table.boxtable em').first(); + const pubDate = + pubDateEl.find('span[title]').length === 0 + ? pubDateEl + .first() + .text() + .replace(/发表于\s/, '') + : pubDateEl.find('span[title]').prop('title'); + + item.title = title; item.description = art(path.join(__dirname, 'templates/description.art'), { - picture: content('.nex_drama_pic') - .html() - .match(/background:url\((.*?)\)/)[1], - name: item.title, - time: matches[1], - score: matches[2], + images: picture + ? [ + { + src: picture, + alt: title, + }, + ] + : undefined, + title, + keys: Object.keys(details), details, - detailKeys: Object.keys(details), - intro: content('.nex_drama_intros').html(), + description, + info: $$('div.nex_drama_sums').html(), links, - linkKeys: Object.keys(links), - bt: content('.t_f').html(), - info: content('.nex_drama_sums').html(), }); - - const magnets = content('.t_f a') - .toArray() - .filter((a) => content(a).attr('href').startsWith('magnet')) - .map((a) => content(a).attr('href')); - - if (magnets.length > 0) { - item.enclosure_url = magnets[0]; - item.enclosure_type = 'application/x-bittorrent'; - } + item.pubDate = timezone(parseDate(pubDate, 'YYYY-M-D HH:mm:ss'), +8); + item.category = Object.values(details) + .flatMap((c) => c.split(/\s/)) + .filter(Boolean); + item.author = details['导演']; + item.content = { + html: description, + text: $$('div.nex_drama_intros').text(), + }; + item.image = picture; + item.banner = picture; + item.language = language; return item; }) @@ -133,11 +179,18 @@ async function handler(ctx) { ); return { - title: `4k世界 - ${$('#fontsearch ul.cl li.a') - .toArray() - .map((a) => $(a).text()) - .join('+')}`, + title: `4k世界 - ${ + $('#fontsearch ul.cl li.a') + .toArray() + .map((a) => $(a).text()) + .join('+') || '不限' + }`, + description: $('meta[name="description"]').prop('content'), link: currentUrl, item: items, + allowEmpty: true, + image, + author: $('meta[name="application-name"]').prop('content'), + language, }; } diff --git a/lib/routes/4ksj/templates/description.art b/lib/routes/4ksj/templates/description.art index 8b4f8f609ee61c..160b5fb5cc2595 100644 --- a/lib/routes/4ksj/templates/description.art +++ b/lib/routes/4ksj/templates/description.art @@ -1,56 +1,59 @@ -{{ if picture }} - +{{ if images }} + {{ each images image }} + {{ if !videos?.[0]?.src && image?.src }} +
+ {{ image.alt }} +
+ {{ /if }} + {{ /each }} {{ /if }} -{{ if details }} - - - - - - - - - - - - - - - {{ each detailKeys detail }} - - - - - {{ /each }} - -
片名{{ name }}
时间{{ time }}
豆瓣评分{{ score }}
{{ detail }}{{@ details[detail] }}
+{{ if title }} +

{{ title }}

{{ /if }} -

简介

-  {{@ intro }} -
- -

网盘下载

-{{ if links }} - - - {{ each linkKeys link }} - - - - - {{ /each }} +{{ if keys && details }} +
{{ link }}{{@ links[link] }}
+ + {{ each keys key }} + + + + + {{ /each }} -
+ {{ key }} + + {{ details[key] }} +
+ {{ /if }} -
-

BT种子 / 磁力链下载

-{{@ bt }} -
+{{ if description }} +

{{ description }}

+{{ /if }} -

影片信息

{{ if info }} -{{@ info }} +
{{@ info }}
+{{ /if }} + +{{ if links }} + + + {{ each links link }} + + + + + {{ /each }} + +
+ {{ link.title }} + + {{ link.tags?.join('') ?? '' }} +
{{ /if }} \ No newline at end of file From 39f1f61bf563c120a53758bbff3b34a602333441 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Wed, 20 Mar 2024 12:42:12 +0800 Subject: [PATCH 24/25] fix: twitter cookie getUserTweets --- lib/routes/twitter/api/web-api/api.ts | 4 ++++ lib/routes/twitter/api/web-api/constants.ts | 22 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/routes/twitter/api/web-api/api.ts b/lib/routes/twitter/api/web-api/api.ts index 870c569e7fb245..2b684806195ab7 100644 --- a/lib/routes/twitter/api/web-api/api.ts +++ b/lib/routes/twitter/api/web-api/api.ts @@ -45,7 +45,11 @@ const getUserTweets = (id: string, params?: Record) => gatherLegacyFromData( await paginationTweets('UserTweets', id, { ...params, + count: 20, + includePromotedContent: true, withQuickPromoteEligibilityTweetFields: true, + withVoice: true, + withV2Timeline: true, }) ) ); diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts index bfd1c904f81d8b..44d550c7aef504 100644 --- a/lib/routes/twitter/api/web-api/constants.ts +++ b/lib/routes/twitter/api/web-api/constants.ts @@ -41,6 +41,28 @@ const gqlFeatures = { responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, responsive_web_graphql_timeline_navigation_enabled: true, }, + UserTweets: { + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: true, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, + }, UserTweetsAndReplies: { responsive_web_graphql_exclude_directive_enabled: true, verified_phone_label_enabled: false, From c8e4273843edd98855659b26c262ec6ce0c2b387 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Wed, 20 Mar 2024 12:44:41 +0800 Subject: [PATCH 25/25] refactor(twitter): merge common params --- lib/routes/twitter/api/web-api/constants.ts | 201 +++++--------------- 1 file changed, 43 insertions(+), 158 deletions(-) diff --git a/lib/routes/twitter/api/web-api/constants.ts b/lib/routes/twitter/api/web-api/constants.ts index 44d550c7aef504..5dab4c0ae4e86b 100644 --- a/lib/routes/twitter/api/web-api/constants.ts +++ b/lib/routes/twitter/api/web-api/constants.ts @@ -14,165 +14,50 @@ const graphQLEndpointsPlain = [ const gqlMap = Object.fromEntries(graphQLEndpointsPlain.map((endpoint) => [endpoint.split('/')[3].replace(/V2$|Query$|QueryV2$/, ''), endpoint])); +const gqlFeatureUser = { + hidden_profile_likes_enabled: true, + hidden_profile_subscriptions_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + subscriptions_verification_info_is_identity_verified_enabled: true, + subscriptions_verification_info_verified_since_enabled: true, + highlights_tweets_tab_ui_enabled: true, + responsive_web_twitter_article_notes_tab_enabled: true, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + responsive_web_graphql_timeline_navigation_enabled: true, +}; +const gqlFeatureFeed = { + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: true, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, +}; const gqlFeatures = { - UserByScreenName: { - hidden_profile_likes_enabled: true, - hidden_profile_subscriptions_enabled: true, - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - subscriptions_verification_info_is_identity_verified_enabled: true, - subscriptions_verification_info_verified_since_enabled: true, - highlights_tweets_tab_ui_enabled: true, - responsive_web_twitter_article_notes_tab_enabled: true, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - responsive_web_graphql_timeline_navigation_enabled: true, - }, - UserByRestId: { - hidden_profile_likes_enabled: true, - hidden_profile_subscriptions_enabled: true, - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - subscriptions_verification_info_is_identity_verified_enabled: true, - subscriptions_verification_info_verified_since_enabled: true, - highlights_tweets_tab_ui_enabled: true, - responsive_web_twitter_article_notes_tab_enabled: true, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - responsive_web_graphql_timeline_navigation_enabled: true, - }, - UserTweets: { - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_timeline_navigation_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - c9s_tweet_anatomy_moderator_badge_enabled: true, - tweetypie_unmention_optimization_enabled: true, - responsive_web_edit_tweet_api_enabled: true, - graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, - view_counts_everywhere_api_enabled: true, - longform_notetweets_consumption_enabled: true, - responsive_web_twitter_article_tweet_consumption_enabled: true, - tweet_awards_web_tipping_enabled: false, - freedom_of_speech_not_reach_fetch_enabled: true, - standardized_nudges_misinfo: true, - tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, - rweb_video_timestamps_enabled: true, - longform_notetweets_rich_text_read_enabled: true, - longform_notetweets_inline_media_enabled: true, - responsive_web_enhance_cards_enabled: false, - }, - UserTweetsAndReplies: { - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_timeline_navigation_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - c9s_tweet_anatomy_moderator_badge_enabled: true, - tweetypie_unmention_optimization_enabled: true, - responsive_web_edit_tweet_api_enabled: true, - graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, - view_counts_everywhere_api_enabled: true, - longform_notetweets_consumption_enabled: true, - responsive_web_twitter_article_tweet_consumption_enabled: true, - tweet_awards_web_tipping_enabled: false, - freedom_of_speech_not_reach_fetch_enabled: true, - standardized_nudges_misinfo: true, - tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, - rweb_video_timestamps_enabled: true, - longform_notetweets_rich_text_read_enabled: true, - longform_notetweets_inline_media_enabled: true, - responsive_web_enhance_cards_enabled: false, - }, - UserMedia: { - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_timeline_navigation_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - c9s_tweet_anatomy_moderator_badge_enabled: true, - tweetypie_unmention_optimization_enabled: true, - responsive_web_edit_tweet_api_enabled: true, - graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, - view_counts_everywhere_api_enabled: true, - longform_notetweets_consumption_enabled: true, - responsive_web_twitter_article_tweet_consumption_enabled: true, - tweet_awards_web_tipping_enabled: false, - freedom_of_speech_not_reach_fetch_enabled: true, - standardized_nudges_misinfo: true, - tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, - rweb_video_timestamps_enabled: true, - longform_notetweets_rich_text_read_enabled: true, - longform_notetweets_inline_media_enabled: true, - responsive_web_enhance_cards_enabled: false, - }, - SearchTimeline: { - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_timeline_navigation_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - c9s_tweet_anatomy_moderator_badge_enabled: true, - tweetypie_unmention_optimization_enabled: true, - responsive_web_edit_tweet_api_enabled: true, - graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, - view_counts_everywhere_api_enabled: true, - longform_notetweets_consumption_enabled: true, - responsive_web_twitter_article_tweet_consumption_enabled: true, - tweet_awards_web_tipping_enabled: false, - freedom_of_speech_not_reach_fetch_enabled: true, - standardized_nudges_misinfo: true, - tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, - rweb_video_timestamps_enabled: true, - longform_notetweets_rich_text_read_enabled: true, - longform_notetweets_inline_media_enabled: true, - responsive_web_enhance_cards_enabled: false, - }, - ListLatestTweetsTimeline: { - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_timeline_navigation_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - c9s_tweet_anatomy_moderator_badge_enabled: true, - tweetypie_unmention_optimization_enabled: true, - responsive_web_edit_tweet_api_enabled: true, - graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, - view_counts_everywhere_api_enabled: true, - longform_notetweets_consumption_enabled: true, - responsive_web_twitter_article_tweet_consumption_enabled: true, - tweet_awards_web_tipping_enabled: false, - freedom_of_speech_not_reach_fetch_enabled: true, - standardized_nudges_misinfo: true, - tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, - rweb_video_timestamps_enabled: true, - longform_notetweets_rich_text_read_enabled: true, - longform_notetweets_inline_media_enabled: true, - responsive_web_enhance_cards_enabled: false, - }, - HomeTimeline: { - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - creator_subscriptions_tweet_preview_api_enabled: true, - responsive_web_graphql_timeline_navigation_enabled: true, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - c9s_tweet_anatomy_moderator_badge_enabled: true, - tweetypie_unmention_optimization_enabled: true, - responsive_web_edit_tweet_api_enabled: true, - graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, - view_counts_everywhere_api_enabled: true, - longform_notetweets_consumption_enabled: true, - responsive_web_twitter_article_tweet_consumption_enabled: true, - tweet_awards_web_tipping_enabled: false, - freedom_of_speech_not_reach_fetch_enabled: true, - standardized_nudges_misinfo: true, - tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, - rweb_video_timestamps_enabled: true, - longform_notetweets_rich_text_read_enabled: true, - longform_notetweets_inline_media_enabled: true, - responsive_web_enhance_cards_enabled: false, - }, + UserByScreenName: gqlFeatureUser, + UserByRestId: gqlFeatureUser, + UserTweets: gqlFeatureFeed, + UserTweetsAndReplies: gqlFeatureFeed, + UserMedia: gqlFeatureFeed, + SearchTimeline: gqlFeatureFeed, + ListLatestTweetsTimeline: gqlFeatureFeed, + HomeTimeline: gqlFeatureFeed, }; const timelineParams = {