Prettier and tweaks

This commit is contained in:
dangered wolf 2023-09-10 19:15:48 -04:00
parent e880cc7c37
commit e36b94bb0b
No known key found for this signature in database
GPG key ID: 41E4D37680ED8B58
9 changed files with 100 additions and 85 deletions

View file

@ -12,5 +12,8 @@
},
"env": {
"es6": true
},
"parserOptions": {
"sourceType": "module"
}
}

View file

@ -1,24 +1,16 @@
import { sentryEsbuildPlugin } from "@sentry/esbuild-plugin";
import { sentryEsbuildPlugin } from '@sentry/esbuild-plugin';
import { config } from 'dotenv';
import { execSync } from 'child_process';
import * as esbuild from 'esbuild'
import * as esbuild from 'esbuild';
import fs from 'fs';
config();
const gitCommit = execSync('git rev-parse --short HEAD')
.toString()
.trim();
const gitCommitFull = execSync('git rev-parse HEAD')
.toString()
.trim();
const gitUrl = execSync('git remote get-url origin')
.toString()
.trim();
const gitBranch = execSync('git rev-parse --abbrev-ref HEAD')
.toString()
.trim();
const gitCommit = execSync('git rev-parse --short HEAD').toString().trim();
const gitCommitFull = execSync('git rev-parse HEAD').toString().trim();
const gitUrl = execSync('git remote get-url origin').toString().trim();
const gitBranch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
let workerName = 'fixtweet';
@ -26,16 +18,18 @@ let workerName = 'fixtweet';
try {
workerName = fs
.readFileSync('wrangler.toml')
.toString()
.match(/name ?= ?"(.+?)"/)[1];
} catch(e) {
console.error(`Error reading wrangler.toml to find worker name, using 'fixtweet' instead.`)
.readFileSync('wrangler.toml')
.toString()
.match(/name ?= ?"(.+?)"/)[1];
} catch (e) {
console.error(
`Error reading wrangler.toml to find worker name, using 'fixtweet' instead.`
);
}
const releaseName = `${workerName}-${gitBranch}-${gitCommit}-${new Date()
.toISOString()
.substring(0, 19)}`;
.toISOString()
.substring(0, 19)}`;
let envVariables = [
'BRANDING_NAME',
@ -53,7 +47,6 @@ let envVariables = [
'DEPRECATED_DOMAIN_EPOCH'
];
// Create defines for all environment variables
let defines = {};
for (let envVar of envVariables) {
@ -63,7 +56,7 @@ for (let envVar of envVariables) {
defines['RELEASE_NAME'] = `"${releaseName}"`;
await esbuild.build({
entryPoints: ["src/worker.ts"],
entryPoints: ['src/worker.ts'],
sourcemap: 'external',
outdir: 'dist',
minify: true,
@ -87,9 +80,9 @@ await esbuild.build({
// Auth tokens can be obtained from
// https://sentry.io/orgredirect/organizations/:orgslug/settings/auth-tokens/
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
authToken: process.env.SENTRY_AUTH_TOKEN
})
],
define: defines
});
});

View file

@ -84,7 +84,7 @@ const populateTweetProperties = async (
}
console.log('note_tweet', JSON.stringify(tweet.note_tweet));
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;
@ -173,7 +173,7 @@ const populateTweetProperties = async (
/* Workaround: Force player card by default for videos */
// @ts-expect-error Inexplicably, twitter_card becomes type of 'tweet' instead of 'tweet' | 'summary' | 'summary_large_image' | 'player'
if (apiTweet.media?.videos && apiTweet.twitter_card !== 'player') {
if (apiTweet.media?.videos && apiTweet.twitter_card !== 'player') {
apiTweet.twitter_card = 'player';
}

View file

@ -45,7 +45,7 @@ export const handleStatus = async (
case 500:
console.log(api);
return returnError(Strings.ERROR_API_FAIL);
}
}
const isTelegram = (userAgent || '').indexOf('Telegram') > -1;
/* Should sensitive posts be allowed Instant View? */
@ -330,10 +330,6 @@ export const handleStatus = async (
}
}
if (!flags?.isXDomain) {
siteName = Strings.X_DOMAIN_NOTICE;
}
/* Notice that user is using deprecated domain */
if (flags?.deprecated) {
siteName = Strings.DEPRECATED_DOMAIN_NOTICE;
@ -357,7 +353,7 @@ export const handleStatus = async (
`<meta property="og:site_name" content="${siteName}"/>`,
`<meta property="twitter:card" content="${
tweet.quote?.twitter_card || tweet.twitter_card
}"/>`,
}"/>`
);
/* Special reply handling if authorText is not overriden */
@ -374,15 +370,17 @@ export const handleStatus = async (
/* The additional oembed is pulled by Discord to enable improved embeds.
Telegram does not use this. */
headers.push(
`<link rel="alternate" href="{base}/owoembed?text={text}{deprecatedFlag}&status={status}&author={author}&useXbranding={useXBranding}" type="application/json+oembed" title="{name}">`.format({
base: Constants.HOST_URL,
text: encodeURIComponent(truncateWithEllipsis(authorText, 250)),
deprecatedFlag: flags?.deprecated ? '&deprecated=true' : '',
status: encodeURIComponent(status),
author: encodeURIComponent(tweet.author?.screen_name || ''),
useXBranding: flags?.isXDomain ? 'true' : 'false',
name: tweet.author.name || ''
})
`<link rel="alternate" href="{base}/owoembed?text={text}{deprecatedFlag}&status={status}&author={author}&useXbranding={useXBranding}" type="application/json+oembed" title="{name}">`.format(
{
base: Constants.HOST_URL,
text: encodeURIComponent(truncateWithEllipsis(authorText, 250)),
deprecatedFlag: flags?.deprecated ? '&deprecated=true' : '',
status: encodeURIComponent(status),
author: encodeURIComponent(tweet.author?.screen_name || ''),
useXBranding: flags?.isXDomain ? 'true' : 'false',
name: tweet.author.name || ''
}
)
);
/* When dealing with a Tweet of unknown lang, fall back to en */

View file

@ -300,7 +300,11 @@ export const fetchConversation = async (
return true;
}
console.log('invalid graphql tweet');
if (!tweet && typeof conversation.data?.tweetResult === 'object' && Object.keys(conversation.data?.tweetResult || {}).length === 0) {
if (
!tweet &&
typeof conversation.data?.tweetResult === 'object' &&
Object.keys(conversation.data?.tweetResult || {}).length === 0
) {
console.log('tweet was not found');
return true;
}

View file

@ -15,7 +15,8 @@ export const unescapeText = (text: string) => {
.replace(/&amp;/g, '&');
};
export const truncateWithEllipsis = (str: string, maxLength: number): string => str.length > maxLength ? str.substring(0, maxLength - 1) + '…' : str;
export const truncateWithEllipsis = (str: string, maxLength: number): string =>
str.length > maxLength ? str.substring(0, maxLength - 1) + '…' : str;
const numberFormat = new Intl.NumberFormat('en-US');

View file

@ -1,6 +1,6 @@
/* eslint-disable no-case-declarations */
import { Toucan } from 'toucan-js';
import { RewriteFrames } from "@sentry/integrations";
import { RewriteFrames } from '@sentry/integrations';
import { IRequest, Router } from 'itty-router';
import { Constants } from './constants';
@ -162,11 +162,11 @@ const statusRequest = async (
const cacheControl = baseUrl !== Constants.TWITTER_ROOT ? 'max-age=0' : undefined;
return new Response(null, {
status: 302,
headers: {
'Location': `${baseUrl}/${handle || 'i'}/status/${id}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
status: 302,
headers: {
Location: `${baseUrl}/${handle || 'i'}/status/${id}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
});
}
@ -201,13 +201,12 @@ const statusRequest = async (
const cacheControl = baseUrl !== Constants.TWITTER_ROOT ? 'max-age=0' : undefined;
return new Response(null, {
status: 302,
headers: {
'Location': `${baseUrl}/${handle || 'i'}/status/${id?.match(/\d{2,20}/)?.[0]}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
status: 302,
headers: {
Location: `${baseUrl}/${handle || 'i'}/status/${id?.match(/\d{2,20}/)?.[0]}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
});
}
};
@ -271,11 +270,11 @@ const profileRequest = async (
const cacheControl = baseUrl !== Constants.TWITTER_ROOT ? 'max-age=0' : undefined;
return new Response(null, {
status: 302,
headers: {
'Location': `${baseUrl}/${handle}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
status: 302,
headers: {
Location: `${baseUrl}/${handle}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
});
}
@ -313,11 +312,11 @@ const profileRequest = async (
const cacheControl = baseUrl !== Constants.TWITTER_ROOT ? 'max-age=0' : undefined;
return new Response(null, {
status: 302,
headers: {
'Location': `${baseUrl}/${handle}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
status: 302,
headers: {
Location: `${baseUrl}/${handle}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
});
}
};
@ -329,11 +328,11 @@ const genericTwitterRedirect = async (request: IRequest) => {
const cacheControl = baseUrl !== Constants.TWITTER_ROOT ? 'max-age=0' : undefined;
return new Response(null, {
status: 302,
headers: {
'Location': `${baseUrl}${url.pathname}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
status: 302,
headers: {
Location: `${baseUrl}${url.pathname}`,
...(cacheControl ? { 'cache-control': cacheControl } : {})
}
});
};
@ -342,9 +341,9 @@ const versionRequest = async (request: IRequest) => {
return new Response(
Strings.VERSION_HTML.format({
rtt: request.cf?.clientTcpRtt ? `🏓 ${request.cf.clientTcpRtt} ms RTT` : '',
colo: request.cf?.colo as string ?? '??',
httpversion: request.cf?.httpProtocol as string ?? 'Unknown HTTP Version',
tlsversion: request.cf?.tlsVersion as string ?? 'Unknown TLS Version',
colo: (request.cf?.colo as string) ?? '??',
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') ??
@ -360,7 +359,7 @@ const versionRequest = async (request: IRequest) => {
{
headers: {
...Constants.RESPONSE_HEADERS,
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate',
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate'
},
status: 200
}
@ -395,7 +394,9 @@ 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
@ -419,7 +420,9 @@ 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
@ -440,7 +443,9 @@ 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
@ -654,7 +659,7 @@ const sentryWrapper = async (event: FetchEvent, test = false): Promise<void> =>
request: event.request,
requestDataOptions: {
allowedHeaders: /(.*)/,
allowedSearchParams: /(.*)/,
allowedSearchParams: /(.*)/
},
/* TODO: Figure out what changed between @sentry/integration 7.65.0 and 7.66.0

View file

@ -8,17 +8,21 @@ const humanHeaders = {
const githubUrl = 'https://github.com/FixTweet/FixTweet';
const twitterBaseUrl = 'https://twitter.com';
// @ts-expect-error - Performance not included in jest environment
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - Performance not included in miniflare environment
if (!globalThis.performance) {
// @ts-expect-error - Performance not included in jest environment
globalThis.performance = {};
}
// @ts-expect-error - Performance not included in jest environment
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - Performance not included in miniflare environment
if (!globalThis.performance.now) {
// eslint-disable-next-line no-var
var start = Date.now();
// @ts-expect-error - Performance not included in jest environment
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - Performance not included in miniflare environment
globalThis.performance.now = function () {
return Date.now() - start;
};
@ -58,7 +62,10 @@ test('Tweet redirect human custom base redirect', async () => {
const result = await cacheWrapper(
new Request('https://fxtwitter.com/jack/status/20', {
method: 'GET',
headers: { ...humanHeaders, 'Cookie': 'cf_clearance=a; base_redirect=https://nitter.net' }
headers: {
...humanHeaders,
Cookie: 'cf_clearance=a; base_redirect=https://nitter.net'
}
})
);
expect(result.status).toEqual(302);

View file

@ -12,7 +12,11 @@
"allowJs": true,
"sourceMap": true,
"esModuleInterop": true,
"types": ["@cloudflare/workers-types/2022-11-30", "@types/jest", "@sentry/integrations"]
"types": [
"@cloudflare/workers-types/2023-07-01",
"@types/jest",
"@sentry/integrations"
]
},
"include": ["src"],
"exclude": ["node_modules", "dist", "test"]