mirror of
https://github.com/CompeyDev/fxtwitter-docker.git
synced 2025-04-02 00:50:57 +01:00
Change printWidth
to 100
This commit is contained in:
parent
e36b94bb0b
commit
0c2f1b04f9
18 changed files with 52 additions and 160 deletions
|
@ -3,7 +3,7 @@
|
|||
"semi": true,
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"printWidth": 90,
|
||||
"printWidth": 100,
|
||||
"arrowParens": "avoid",
|
||||
"quoteProps": "consistent"
|
||||
}
|
||||
|
|
|
@ -22,9 +22,7 @@ try {
|
|||
.toString()
|
||||
.match(/name ?= ?"(.+?)"/)[1];
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`Error reading wrangler.toml to find worker name, using 'fixtweet' instead.`
|
||||
);
|
||||
console.error(`Error reading wrangler.toml to find worker name, using 'fixtweet' instead.`);
|
||||
}
|
||||
|
||||
const releaseName = `${workerName}-${gitBranch}-${gitCommit}-${new Date()
|
||||
|
|
|
@ -86,8 +86,7 @@ const populateTweetProperties = async (
|
|||
const noteTweetText = tweet.note_tweet?.note_tweet_results?.result?.text;
|
||||
|
||||
if (noteTweetText) {
|
||||
tweet.legacy.entities.urls =
|
||||
tweet.note_tweet?.note_tweet_results?.result?.entity_set.urls;
|
||||
tweet.legacy.entities.urls = tweet.note_tweet?.note_tweet_results?.result?.entity_set.urls;
|
||||
tweet.legacy.entities.hashtags =
|
||||
tweet.note_tweet?.note_tweet_results?.result?.entity_set.hashtags;
|
||||
tweet.legacy.entities.symbols =
|
||||
|
@ -178,17 +177,9 @@ const populateTweetProperties = async (
|
|||
}
|
||||
|
||||
/* If a language is specified in API or by user, let's try translating it! */
|
||||
if (
|
||||
typeof language === 'string' &&
|
||||
language.length === 2 &&
|
||||
language !== tweet.legacy.lang
|
||||
) {
|
||||
if (typeof language === 'string' && language.length === 2 && language !== tweet.legacy.lang) {
|
||||
console.log(`Attempting to translate Tweet to ${language}...`);
|
||||
const translateAPI = await translateTweet(
|
||||
tweet,
|
||||
conversation.guestToken || '',
|
||||
language
|
||||
);
|
||||
const translateAPI = await translateTweet(tweet, conversation.guestToken || '', language);
|
||||
if (translateAPI !== null && translateAPI?.translation) {
|
||||
apiTweet.translation = {
|
||||
text: unescapeText(linkFixer(tweet, translateAPI?.translation || '')),
|
||||
|
@ -287,20 +278,12 @@ export const statusAPI = async (
|
|||
}
|
||||
/* Creating the response objects */
|
||||
const response: TweetAPIResponse = { code: 200, message: 'OK' } as TweetAPIResponse;
|
||||
const apiTweet: APITweet = (await populateTweetProperties(
|
||||
tweet,
|
||||
res,
|
||||
language
|
||||
)) as APITweet;
|
||||
const apiTweet: APITweet = (await populateTweetProperties(tweet, res, language)) as APITweet;
|
||||
|
||||
/* We found a quote tweet, let's process that too */
|
||||
const quoteTweet = tweet.quoted_status_result;
|
||||
if (quoteTweet) {
|
||||
apiTweet.quote = (await populateTweetProperties(
|
||||
quoteTweet,
|
||||
res,
|
||||
language
|
||||
)) as APITweet;
|
||||
apiTweet.quote = (await populateTweetProperties(quoteTweet, res, language)) as APITweet;
|
||||
}
|
||||
|
||||
/* Finally, staple the Tweet to the response and return it */
|
||||
|
|
|
@ -342,18 +342,14 @@ export const handleStatus = async (
|
|||
|
||||
A possible explanation for this weird behavior is due to the Medium template we are forced to use because Telegram IV is not an open platform
|
||||
and we have to pretend to be Medium in order to get working IV, but haven't figured if the template is causing issues. */
|
||||
const text = useIV
|
||||
? sanitizeText(newText).replace(/\n/g, '<br>')
|
||||
: sanitizeText(newText);
|
||||
const text = useIV ? sanitizeText(newText).replace(/\n/g, '<br>') : sanitizeText(newText);
|
||||
|
||||
/* Push basic headers relating to author, Tweet text, and site name */
|
||||
headers.push(
|
||||
`<meta property="og:title" content="${tweet.author.name} (@${tweet.author.screen_name})"/>`,
|
||||
`<meta property="og:description" content="${text}"/>`,
|
||||
`<meta property="og:site_name" content="${siteName}"/>`,
|
||||
`<meta property="twitter:card" content="${
|
||||
tweet.quote?.twitter_card || tweet.twitter_card
|
||||
}"/>`
|
||||
`<meta property="twitter:card" content="${tweet.quote?.twitter_card || tweet.twitter_card}"/>`
|
||||
);
|
||||
|
||||
/* Special reply handling if authorText is not overriden */
|
||||
|
|
|
@ -18,8 +18,7 @@ const Experiments: { [key in Experiment]: ExperimentConfig } = {
|
|||
|
||||
export const experimentCheck = (experiment: Experiment, condition = true) => {
|
||||
console.log(`Checking experiment ${experiment}`);
|
||||
const experimentEnabled =
|
||||
Experiments[experiment].percentage > Math.random() && condition;
|
||||
const experimentEnabled = Experiments[experiment].percentage > Math.random() && condition;
|
||||
console.log(`Experiment ${experiment} enabled: ${experimentEnabled}`);
|
||||
return experimentEnabled;
|
||||
};
|
||||
|
|
41
src/fetch.ts
41
src/fetch.ts
|
@ -41,18 +41,15 @@ export const twitterFetch = async (
|
|||
...Constants.BASE_HEADERS
|
||||
};
|
||||
|
||||
const guestTokenRequest = new Request(
|
||||
`${Constants.TWITTER_API_ROOT}/1.1/guest/activate.json`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: tokenHeaders,
|
||||
cf: {
|
||||
cacheEverything: true,
|
||||
cacheTtl: Constants.GUEST_TOKEN_MAX_AGE
|
||||
},
|
||||
body: ''
|
||||
}
|
||||
);
|
||||
const guestTokenRequest = new Request(`${Constants.TWITTER_API_ROOT}/1.1/guest/activate.json`, {
|
||||
method: 'POST',
|
||||
headers: tokenHeaders,
|
||||
cf: {
|
||||
cacheEverything: true,
|
||||
cacheTtl: Constants.GUEST_TOKEN_MAX_AGE
|
||||
},
|
||||
body: ''
|
||||
});
|
||||
|
||||
/* A dummy version of the request only used for Cloudflare caching purposes.
|
||||
The reason it exists at all is because Cloudflare won't cache POST requests. */
|
||||
|
@ -150,9 +147,7 @@ export const twitterFetch = async (
|
|||
headers: headers
|
||||
});
|
||||
const performanceEnd = performance.now();
|
||||
console.log(
|
||||
`Elongator request successful after ${performanceEnd - performanceStart}ms`
|
||||
);
|
||||
console.log(`Elongator request successful after ${performanceEnd - performanceStart}ms`);
|
||||
} else {
|
||||
const performanceStart = performance.now();
|
||||
apiRequest = await fetch(url, {
|
||||
|
@ -160,9 +155,7 @@ export const twitterFetch = async (
|
|||
headers: headers
|
||||
});
|
||||
const performanceEnd = performance.now();
|
||||
console.log(
|
||||
`Guest API request successful after ${performanceEnd - performanceStart}ms`
|
||||
);
|
||||
console.log(`Guest API request successful after ${performanceEnd - performanceStart}ms`);
|
||||
}
|
||||
|
||||
response = await apiRequest?.json();
|
||||
|
@ -172,9 +165,7 @@ export const twitterFetch = async (
|
|||
console.error('Unknown error while fetching from API', e);
|
||||
!useElongator &&
|
||||
event &&
|
||||
event.waitUntil(
|
||||
cache.delete(guestTokenRequestCacheDummy.clone(), { ignoreMethod: true })
|
||||
);
|
||||
event.waitUntil(cache.delete(guestTokenRequestCacheDummy.clone(), { ignoreMethod: true }));
|
||||
if (useElongator) {
|
||||
console.log('Elongator request failed, trying again without it');
|
||||
wasElongatorDisabled = true;
|
||||
|
@ -199,17 +190,13 @@ export const twitterFetch = async (
|
|||
continue;
|
||||
}
|
||||
|
||||
const remainingRateLimit = parseInt(
|
||||
apiRequest.headers.get('x-rate-limit-remaining') || '0'
|
||||
);
|
||||
const remainingRateLimit = parseInt(apiRequest.headers.get('x-rate-limit-remaining') || '0');
|
||||
console.log(`Remaining rate limit: ${remainingRateLimit} requests`);
|
||||
/* Running out of requests within our rate limit, let's purge the cache */
|
||||
if (!useElongator && remainingRateLimit < 10) {
|
||||
console.log(`Purging token on this edge due to low rate limit remaining`);
|
||||
event &&
|
||||
event.waitUntil(
|
||||
cache.delete(guestTokenRequestCacheDummy.clone(), { ignoreMethod: true })
|
||||
);
|
||||
event.waitUntil(cache.delete(guestTokenRequestCacheDummy.clone(), { ignoreMethod: true }));
|
||||
}
|
||||
|
||||
if (!validateFunction(response)) {
|
||||
|
|
|
@ -8,10 +8,7 @@ export const renderCard = (
|
|||
return {};
|
||||
}
|
||||
|
||||
const binding_values: Record<
|
||||
string,
|
||||
{ string_value?: string; boolean_value?: boolean }
|
||||
> = {};
|
||||
const binding_values: Record<string, { string_value?: string; boolean_value?: boolean }> = {};
|
||||
|
||||
card.legacy.binding_values.forEach(value => {
|
||||
if (value.key && value.value) {
|
||||
|
@ -55,12 +52,8 @@ export const renderCard = (
|
|||
external_media: {
|
||||
type: 'video',
|
||||
url: binding_values.player_url.string_value,
|
||||
width: parseInt(
|
||||
(binding_values.player_width?.string_value || '1280').replace('px', '')
|
||||
), // TODO: Replacing px might not be necessary, it's just there as a precaution
|
||||
height: parseInt(
|
||||
(binding_values.player_height?.string_value || '720').replace('px', '')
|
||||
)
|
||||
width: parseInt((binding_values.player_width?.string_value || '1280').replace('px', '')), // TODO: Replacing px might not be necessary, it's just there as a precaution
|
||||
height: parseInt((binding_values.player_height?.string_value || '720').replace('px', ''))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,10 +16,7 @@ export const colorFromPalette = (palette: MediaPlaceholderColor[]) => {
|
|||
const rgb = palette[i].rgb;
|
||||
|
||||
// We need vibrant colors, grey backgrounds won't do!
|
||||
if (
|
||||
rgb.red + rgb.green + rgb.blue < 120 ||
|
||||
rgb.red + rgb.green + rgb.blue > 240 * 3
|
||||
) {
|
||||
if (rgb.red + rgb.green + rgb.blue < 120 || rgb.red + rgb.green + rgb.blue > 240 * 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,30 +15,18 @@ export const calculateTimeLeft = (date: Date) => {
|
|||
export const calculateTimeLeftString = (date: Date) => {
|
||||
const { days, hours, minutes, seconds } = calculateTimeLeft(date);
|
||||
const daysString =
|
||||
days > 0
|
||||
? `${days} ${days === 1 ? Strings.SINGULAR_DAY_LEFT : Strings.PLURAL_DAYS_LEFT}`
|
||||
: '';
|
||||
days > 0 ? `${days} ${days === 1 ? Strings.SINGULAR_DAY_LEFT : Strings.PLURAL_DAYS_LEFT}` : '';
|
||||
const hoursString =
|
||||
hours > 0
|
||||
? `${hours} ${hours === 1 ? Strings.SINGULAR_HOUR_LEFT : Strings.PLURAL_HOURS_LEFT}`
|
||||
: '';
|
||||
const minutesString =
|
||||
minutes > 0
|
||||
? `${minutes} ${
|
||||
minutes === 1 ? Strings.SINGULAR_MINUTE_LEFT : Strings.PLURAL_MINUTES_LEFT
|
||||
}`
|
||||
? `${minutes} ${minutes === 1 ? Strings.SINGULAR_MINUTE_LEFT : Strings.PLURAL_MINUTES_LEFT}`
|
||||
: '';
|
||||
const secondsString =
|
||||
seconds > 0
|
||||
? `${seconds} ${
|
||||
seconds === 1 ? Strings.SINGULAR_SECOND_LEFT : Strings.PLURAL_SECONDS_LEFT
|
||||
}`
|
||||
? `${seconds} ${seconds === 1 ? Strings.SINGULAR_SECOND_LEFT : Strings.PLURAL_SECONDS_LEFT}`
|
||||
: '';
|
||||
return (
|
||||
daysString ||
|
||||
hoursString ||
|
||||
minutesString ||
|
||||
secondsString ||
|
||||
Strings.FINAL_POLL_RESULTS
|
||||
);
|
||||
return daysString || hoursString || minutesString || secondsString || Strings.FINAL_POLL_RESULTS;
|
||||
};
|
||||
|
|
|
@ -40,10 +40,7 @@ export const generateUserAgent = (): [string, string] => {
|
|||
return [userAgent.format({ platform: platformLinux }), secChUa];
|
||||
case Platforms.Android:
|
||||
userAgent = isEdge ? edgeMobileUA : chromeMobileUA;
|
||||
return [
|
||||
userAgent.format({ platform: platformAndroid, version: String(version) }),
|
||||
secChUa
|
||||
];
|
||||
return [userAgent.format({ platform: platformAndroid, version: String(version) }), secChUa];
|
||||
default:
|
||||
return [userAgent.format({ platform: platformWindows }), secChUa];
|
||||
}
|
||||
|
|
|
@ -132,9 +132,7 @@ const generateTweetFooter = (tweet: APITweet, isQuote = false): string => {
|
|||
{aboutSection}
|
||||
`.format({
|
||||
socialText: getSocialTextIV(tweet) || '',
|
||||
viewOriginal: !isQuote
|
||||
? `<a href="${tweet.url}">View original post</a>`
|
||||
: notApplicableComment,
|
||||
viewOriginal: !isQuote ? `<a href="${tweet.url}">View original post</a>` : notApplicableComment,
|
||||
aboutSection: isQuote
|
||||
? ''
|
||||
: `<h2>About author</h2>
|
||||
|
|
|
@ -8,17 +8,12 @@ export const renderPhoto = (
|
|||
const { tweet, engagementText, authorText, isOverrideMedia, userAgent } = properties;
|
||||
const instructions: ResponseInstructions = { addHeaders: [] };
|
||||
|
||||
if (
|
||||
(tweet.media?.photos?.length || 0) > 1 &&
|
||||
(!tweet.media?.mosaic || isOverrideMedia)
|
||||
) {
|
||||
if ((tweet.media?.photos?.length || 0) > 1 && (!tweet.media?.mosaic || isOverrideMedia)) {
|
||||
photo = photo as APIPhoto;
|
||||
|
||||
const all = tweet.media?.all as APIMedia[];
|
||||
const baseString =
|
||||
all.length === tweet.media?.photos?.length
|
||||
? Strings.PHOTO_COUNT
|
||||
: Strings.MEDIA_COUNT;
|
||||
all.length === tweet.media?.photos?.length ? Strings.PHOTO_COUNT : Strings.MEDIA_COUNT;
|
||||
|
||||
const photoCounter = baseString.format({
|
||||
number: String(all.indexOf(photo) + 1),
|
||||
|
@ -30,9 +25,7 @@ export const renderPhoto = (
|
|||
if (authorText === Strings.DEFAULT_AUTHOR_TEXT || isTelegram) {
|
||||
instructions.authorText = photoCounter;
|
||||
} else {
|
||||
instructions.authorText = `${authorText}${
|
||||
authorText ? ' ― ' : ''
|
||||
}${photoCounter}`;
|
||||
instructions.authorText = `${authorText}${authorText ? ' ― ' : ''}${photoCounter}`;
|
||||
}
|
||||
|
||||
if (engagementText && !isTelegram) {
|
||||
|
|
|
@ -31,9 +31,7 @@ export const renderVideo = (
|
|||
we'll put an indicator if there are more than one video */
|
||||
if (all && all.length > 1 && (userAgent?.indexOf('Telegram') ?? 0) > -1) {
|
||||
const baseString =
|
||||
all.length === tweet.media?.videos?.length
|
||||
? Strings.VIDEO_COUNT
|
||||
: Strings.MEDIA_COUNT;
|
||||
all.length === tweet.media?.videos?.length ? Strings.VIDEO_COUNT : Strings.MEDIA_COUNT;
|
||||
const videoCounter = baseString.format({
|
||||
number: String(all.indexOf(video) + 1),
|
||||
total: String(all.length)
|
||||
|
|
9
src/types/twitterTypes.d.ts
vendored
9
src/types/twitterTypes.d.ts
vendored
|
@ -469,14 +469,9 @@ type GraphQLConversationThread = {
|
|||
sortIndex: string;
|
||||
};
|
||||
|
||||
type GraphQLTimelineEntry =
|
||||
| GraphQLTimelineTweetEntry
|
||||
| GraphQLConversationThread
|
||||
| unknown;
|
||||
type GraphQLTimelineEntry = GraphQLTimelineTweetEntry | GraphQLConversationThread | unknown;
|
||||
|
||||
type V2ThreadInstruction =
|
||||
| TimeLineAddEntriesInstruction
|
||||
| TimeLineTerminateTimelineInstruction;
|
||||
type V2ThreadInstruction = TimeLineAddEntriesInstruction | TimeLineTerminateTimelineInstruction;
|
||||
|
||||
type TimeLineAddEntriesInstruction = {
|
||||
type: 'TimelineAddEntries';
|
||||
|
|
|
@ -17,7 +17,6 @@ export const isGraphQLTweet = (response: unknown): response is GraphQLTweet => {
|
|||
typeof response === 'object' &&
|
||||
response !== null &&
|
||||
'__typename' in response &&
|
||||
(response.__typename === 'Tweet' ||
|
||||
response.__typename === 'TweetWithVisibilityResults')
|
||||
(response.__typename === 'Tweet' || response.__typename === 'TweetWithVisibilityResults')
|
||||
);
|
||||
};
|
||||
|
|
|
@ -36,11 +36,7 @@ const getBaseRedirectUrl = (request: IRequest) => {
|
|||
};
|
||||
|
||||
/* Handler for status (Tweet) request */
|
||||
const statusRequest = async (
|
||||
request: IRequest,
|
||||
event: FetchEvent,
|
||||
flags: InputFlags = {}
|
||||
) => {
|
||||
const statusRequest = async (request: IRequest, event: FetchEvent, flags: InputFlags = {}) => {
|
||||
const { handle, id, mediaNumber, language, prefix } = request.params;
|
||||
const url = new URL(request.url);
|
||||
// eslint-disable-next-line sonarjs/no-duplicate-string
|
||||
|
@ -211,11 +207,7 @@ const statusRequest = async (
|
|||
};
|
||||
|
||||
/* Handler for User Profiles */
|
||||
const profileRequest = async (
|
||||
request: IRequest,
|
||||
event: FetchEvent,
|
||||
flags: InputFlags = {}
|
||||
) => {
|
||||
const profileRequest = async (request: IRequest, event: FetchEvent, flags: InputFlags = {}) => {
|
||||
const { handle } = request.params;
|
||||
const url = new URL(request.url);
|
||||
const userAgent = request.headers.get('User-Agent') || '';
|
||||
|
@ -284,9 +276,7 @@ const profileRequest = async (
|
|||
headers = {
|
||||
...headers,
|
||||
'cache-control':
|
||||
baseUrl !== Constants.TWITTER_ROOT
|
||||
? 'max-age=0'
|
||||
: profileResponse.cacheControl
|
||||
baseUrl !== Constants.TWITTER_ROOT ? 'max-age=0' : profileResponse.cacheControl
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -345,15 +335,11 @@ const versionRequest = async (request: IRequest) => {
|
|||
httpversion: (request.cf?.httpProtocol as string) ?? 'Unknown HTTP Version',
|
||||
tlsversion: (request.cf?.tlsVersion as string) ?? 'Unknown TLS Version',
|
||||
ip:
|
||||
request.headers.get('x-real-ip') ??
|
||||
request.headers.get('cf-connecting-ip') ??
|
||||
'Unknown IP',
|
||||
request.headers.get('x-real-ip') ?? request.headers.get('cf-connecting-ip') ?? 'Unknown IP',
|
||||
city: request.cf?.city ?? 'Unknown City',
|
||||
region: request.cf?.region ?? request.cf?.country ?? 'Unknown Region',
|
||||
country: request.cf?.country ?? 'Unknown Country',
|
||||
asn: `AS${request.cf?.asn ?? '??'} (${
|
||||
request.cf?.asOrganization ?? 'Unknown ASN'
|
||||
})`,
|
||||
asn: `AS${request.cf?.asn ?? '??'} (${request.cf?.asOrganization ?? 'Unknown ASN'})`,
|
||||
ua: sanitizeText(request.headers.get('user-agent') ?? 'Unknown User Agent')
|
||||
}),
|
||||
{
|
||||
|
@ -394,9 +380,7 @@ const setRedirectRequest = async (request: IRequest) => {
|
|||
{
|
||||
headers: {
|
||||
'set-cookie': `base_redirect=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure; HttpOnly`,
|
||||
'content-security-policy': `frame-ancestors ${Constants.STANDARD_DOMAIN_LIST.join(
|
||||
' '
|
||||
)};`,
|
||||
'content-security-policy': `frame-ancestors ${Constants.STANDARD_DOMAIN_LIST.join(' ')};`,
|
||||
...Constants.RESPONSE_HEADERS
|
||||
},
|
||||
status: 200
|
||||
|
@ -443,9 +427,7 @@ const setRedirectRequest = async (request: IRequest) => {
|
|||
{
|
||||
headers: {
|
||||
'set-cookie': `base_redirect=${url}; path=/; max-age=63072000; secure; HttpOnly`,
|
||||
'content-security-policy': `frame-ancestors ${Constants.STANDARD_DOMAIN_LIST.join(
|
||||
' '
|
||||
)};`,
|
||||
'content-security-policy': `frame-ancestors ${Constants.STANDARD_DOMAIN_LIST.join(' ')};`,
|
||||
...Constants.RESPONSE_HEADERS
|
||||
},
|
||||
status: 200
|
||||
|
@ -491,9 +473,7 @@ router.get('/owoembed', async (request: IRequest) => {
|
|||
|
||||
const test = {
|
||||
author_name: text,
|
||||
author_url: `${Constants.TWITTER_ROOT}/${encodeURIComponent(
|
||||
author
|
||||
)}/status/${status}`,
|
||||
author_url: `${Constants.TWITTER_ROOT}/${encodeURIComponent(author)}/status/${status}`,
|
||||
/* Change provider name if tweet is on deprecated domain. */
|
||||
provider_name:
|
||||
searchParams.get('deprecated') === 'true'
|
||||
|
@ -536,10 +516,7 @@ router.get('*', async (request: IRequest) => {
|
|||
});
|
||||
|
||||
/* Wrapper to handle caching, and misc things like catching robots.txt */
|
||||
export const cacheWrapper = async (
|
||||
request: Request,
|
||||
event?: FetchEvent
|
||||
): Promise<Response> => {
|
||||
export const cacheWrapper = async (request: Request, event?: FetchEvent): Promise<Response> => {
|
||||
const startTime = performance.now();
|
||||
const userAgent = request.headers.get('User-Agent') || '';
|
||||
// https://developers.cloudflare.com/workers/examples/cache-api/
|
||||
|
|
|
@ -83,9 +83,7 @@ test('Twitter moment redirect', async () => {
|
|||
)
|
||||
);
|
||||
expect(result.status).toEqual(302);
|
||||
expect(result.headers.get('location')).toEqual(
|
||||
`${twitterBaseUrl}/i/events/1572638642127966214`
|
||||
);
|
||||
expect(result.headers.get('location')).toEqual(`${twitterBaseUrl}/i/events/1572638642127966214`);
|
||||
});
|
||||
|
||||
test('Tweet response robot', async () => {
|
||||
|
|
|
@ -12,11 +12,7 @@
|
|||
"allowJs": true,
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"types": [
|
||||
"@cloudflare/workers-types/2023-07-01",
|
||||
"@types/jest",
|
||||
"@sentry/integrations"
|
||||
]
|
||||
"types": ["@cloudflare/workers-types/2023-07-01", "@types/jest", "@sentry/integrations"]
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist", "test"]
|
||||
|
|
Loading…
Add table
Reference in a new issue