diff --git a/.env.example b/.env.example
index 2b5ae71..c37f8d5 100644
--- a/.env.example
+++ b/.env.example
@@ -5,6 +5,7 @@ TEXT_ONLY_DOMAINS = "t.fxtwitter.com,t.twittpr.com,t.fixupx.com"
INSTANT_VIEW_DOMAINS = "i.fxtwitter.com,i.twittpr.com,i.fixupx.com"
INSTANT_VIEW_THREADS_DOMAINS = "u.fxtwitter.com,u.twittpr.com,u.fixupx.com"
GALLERY_DOMAINS = "g.fxtwitter.com,g.twittpr.com,g.fixupx.com"
+NATIVE_MULTI_IMAGE_DOMAINS = "m.fxtwitter.com,m.twittpr.com,m.fixupx.com"
MOSAIC_DOMAIN_LIST = "mosaic.fxtwitter.com"
API_HOST_LIST = "api.fxtwitter.com,api-canary.fxtwitter.com"
HOST_URL = "https://fxtwitter.com"
@@ -13,4 +14,5 @@ EMBED_URL = "https://github.com/FixTweet/FxTwitter"
SENTRY_DSN = ""
SENTRY_AUTH_TOKEN = ""
SENTRY_ORG = ""
-SENTRY_PROJECT = ""
\ No newline at end of file
+SENTRY_PROJECT = ""
+GIF_TRANSCODE_DOMAIN = "gif.fxtwitter.com"
\ No newline at end of file
diff --git a/.github/readme/directmedia.png b/.github/readme/directmedia.png
new file mode 100644
index 0000000..1dabccb
Binary files /dev/null and b/.github/readme/directmedia.png differ
diff --git a/.github/readme/fixtweet.webp b/.github/readme/fixtweet.webp
new file mode 100644
index 0000000..605aa64
Binary files /dev/null and b/.github/readme/fixtweet.webp differ
diff --git a/.github/readme/gallery.png b/.github/readme/gallery.png
new file mode 100644
index 0000000..e255447
Binary files /dev/null and b/.github/readme/gallery.png differ
diff --git a/.github/readme/poll.png b/.github/readme/poll.png
new file mode 100644
index 0000000..429db1f
Binary files /dev/null and b/.github/readme/poll.png differ
diff --git a/.github/readme/quote.png b/.github/readme/quote.png
new file mode 100644
index 0000000..8ee5a0f
Binary files /dev/null and b/.github/readme/quote.png differ
diff --git a/.github/readme/tco.png b/.github/readme/tco.png
new file mode 100644
index 0000000..1fe31f1
Binary files /dev/null and b/.github/readme/tco.png differ
diff --git a/.github/readme/textonly.png b/.github/readme/textonly.png
new file mode 100644
index 0000000..9813e23
Binary files /dev/null and b/.github/readme/textonly.png differ
diff --git a/.github/readme/translate.png b/.github/readme/translate.png
new file mode 100644
index 0000000..59bd00f
Binary files /dev/null and b/.github/readme/translate.png differ
diff --git a/.github/readme/videos.png b/.github/readme/videos.png
new file mode 100644
index 0000000..631a694
Binary files /dev/null and b/.github/readme/videos.png differ
diff --git a/README.md b/README.md
index cc0bfa0..aa11bb8 100644
--- a/README.md
+++ b/README.md
@@ -29,13 +29,13 @@
### For `twitter.com` links on Discord, send a link and type `s/e/p` to make `twittpr.com`.
-
+
## Embed Videos
We all have videos of memes and other things from Twitter we want to quickly share with friends. With normal Twitter links, embedding videos is often broken on Discord and impossible on Telegram. But using FxTwitter, we embed the raw mp4 file so it's compatible with just about anything supporting video embeds.
-
+
On Discord, we'll also automatically embed videos linked from other platforms, such as YouTube, so they can play without having to open a browser.
@@ -43,13 +43,13 @@ On Discord, we'll also automatically embed videos linked from other platforms, s
If you want to share the results of a Twitter poll, you can do so by just linking the post using FxTwitter.
-
+
## Embed Quotes & Media
Quotes and their media can provide important context to a post. So we'll automatically add said context, and even media if there isn't already media embedded in the quote.
-
+
## Translate Posts
@@ -57,19 +57,25 @@ You can translate a post into any other supported language, with the original an
Just append a post with its 2-letter ISO language code. So for English, add `/en` at the end.
-
+
## Gallery view
Use `g.fxtwitter.com` or `g.fixupx.com` to generate minimal embeds with just the post's media and author information without other distractions. This can be particularly useful for read-only channels dedicated to sharing media.
-
+
+
+## Text-only view
+
+Basically the opposite of gallery view, use `t.fxtwitter.com` / `t.fixupx.com` to exclude photos/videos and only display text.
+
+
## Direct media links
Want to link directly to a post's media without the embed? You can easily do that using FxTwitter.
-
+
There are a few supported ways to do this:
@@ -87,12 +93,12 @@ In the future we plan to do even more with Instant View such as embedding entire
Examples from above:
-- `https://d.fxtwitter.com/dangeredwolf/status/1548119328498728960`
-- `https://fxtwitter.com/dangeredwolf/status/1548117889437208581.jpg`
+- `https://d.fxtwitter.com/example/status/1548119328498728960`
+- `https://fxtwitter.com/example/status/1548117889437208581.jpg`
Posts with multiple images are supported, so you can do something like this and it will pick the correct one:
-`https://d.fxtwitter.com/dangeredwolf/status/1547514042146865153/photo/3`
+`https://d.fxtwitter.com/example/status/1547514042146865153/photo/3`
Otherwise, it will default to the first image.
@@ -100,7 +106,7 @@ Otherwise, it will default to the first image.
The default Twitter embeds include t.co link shorteners, which make it difficult to know where the link is heading. We automatically replace t.co links with their original links to make things clearer.
-
+
## Redirect to Nitter or other custom instances
@@ -124,26 +130,26 @@ On a different note, if the person who posted a FxTwitter link forgot to strip t
In many ways, FxTwitter has richer embeds and does more. Here's a table comparing some of FxTwitter's features compared to Twitter default embeds as well as other embedding services
-| | FxTwitter | Twitter default | vxTwitter (BetterTwitFix) |
-| -------------------------------------- | :------------------------------------------------: | :------------------------------: | :-------------------------------------------------: |
-| Embed Posts / Images | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
-| Embed profile pictures on text posts | :heavy_check_mark: | :x: | :heavy_check_mark: |
-| Embed Twitter Videos | :heavy_check_mark: | :heavy_minus_sign: Discord Only¹ | :heavy_check_mark: |
-| Embed External Videos (YouTube, etc.) | :heavy_check_mark:⁴ | :x: | :x:³ |
-| Embed Poll results | :heavy_check_mark: | :x: | [:heavy_check_mark:][polladd] |
-| Embed Quotes | :heavy_check_mark: | :x: | :ballot_box_with_check: Without Media |
-| Embed Multiple Images | :heavy_check_mark: | :heavy_minus_sign: Discord Only² | :heavy_check_mark: |
-| Translate Posts | :heavy_check_mark: | :x: | :x: |
-| Replace t.co with original links | :heavy_check_mark: | :x: | :heavy_check_mark: |
-| Redirect to media file (without embed) | :heavy_check_mark: | :x: | :ballot_box_with_check: Subdomain broken, no images |
-| Gallery view | :heavy_check_mark: | :x: | :x: |
-| Strip tracking info on redirect | :heavy_check_mark: | :x: | :heavy_check_mark: |
-| Show retweet, like, reply, view counts | :heavy_minus_sign: Discord / Telegram Instant View | :heavy_minus_sign: Discord Only² | :ballot_box_with_check: No replies / views |
-| Discord sed replace (`s/`) friendly | :ballot_box_with_check: twittpr.com | N/A | :x: |
-| Domain for X.com links | :ballot_box_with_check: fixupx.com | N/A | :ballot_box_with_check: fixvx.com |
-| Telegram Instant View | :heavy_check_mark: | :x: | :x: |
-| Status fetch API for Developers | :heavy_check_mark: | N/A | :heavy_check_mark: |
-| Last commit | [![][flc]][fc] | N/A | [![][vlc]][vc] |
+| | FxTwitter | Twitter default | vxTwitter (BetterTwitFix) |
+| -------------------------------------- | :------------------------------------------------: | :----------------: | :-------------------------------------------------: |
+| Embed Posts / Images | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
+| Embed profile pictures on text posts | :heavy_check_mark: | :x: | :heavy_check_mark: |
+| Embed Twitter Videos | :heavy_check_mark: | :x: | :heavy_check_mark: |
+| Embed External Videos (YouTube, etc.) | :heavy_check_mark:⁴ | :x: | :x:³ |
+| Embed Poll results | :heavy_check_mark: | :x: | [:heavy_check_mark:][polladd] |
+| Embed Quotes | :heavy_check_mark: | :x: | :ballot_box_with_check: Without Media |
+| Embed Multiple Images | :heavy_check_mark: | :x: | :heavy_check_mark: |
+| Translate Posts | :heavy_check_mark: | :x: | :x: |
+| Replace t.co with original links | :heavy_check_mark: | :x: | :heavy_check_mark: |
+| Redirect to media file (without embed) | :heavy_check_mark: | :x: | :ballot_box_with_check: Subdomain broken, no images |
+| Gallery view | :heavy_check_mark: | :x: | :x: |
+| Strip tracking info on redirect | :heavy_check_mark: | :x: | :heavy_check_mark: |
+| Show retweet, like, reply, view counts | :heavy_minus_sign: Discord / Telegram Instant View | :x: | :ballot_box_with_check: No replies / views |
+| Discord sed replace (`s/`) friendly | :ballot_box_with_check: twittpr.com | N/A | :x: |
+| Domain for X.com links | :ballot_box_with_check: fixupx.com | N/A | :ballot_box_with_check: fixvx.com |
+| Telegram Instant View | :heavy_check_mark: | :x: | :x: |
+| Status fetch API for Developers | :heavy_check_mark: | N/A | :heavy_check_mark: |
+| Last commit | [![][flc]][fc] | N/A | [![][vlc]][vc] |
[flc]: https://img.shields.io/github/last-commit/FixTweet/FxTwitter?label
[vlc]: https://img.shields.io/github/last-commit/dylanpdx/BetterTwitFix?label
@@ -228,3 +234,7 @@ Feel free to [open an issue](https://github.com/FixTweet/FxTwitter/issues)
[Mosaic](https://github.com/FixTweet/mosaic) Multi-image combiner by [Antonio32A](https://github.com/Antonio32A)
& other contributions by [Antonio32A](https://github.com/Antonio32A), [Burner](https://github.com/YaBoiBurner), [Deer-Spangle](https://github.com/Deer-Spangle), [Eramdam](https://github.com/Eramdam), [SirStendec](https://github.com/SirStendec), [SpeedyFolf](https://github.com/SpeedyFolf), [Wazbat](https://github.com/Wazbat)
+
+## Disclaimer
+
+Twitter, Tweet, and X are trademarks of X Corp. This project is not affiliated in any way with X Corp or Twitter.
diff --git a/esbuild.config.mjs b/esbuild.config.mjs
index 41c4c35..959ca2c 100644
--- a/esbuild.config.mjs
+++ b/esbuild.config.mjs
@@ -39,12 +39,14 @@ let envVariables = [
'INSTANT_VIEW_DOMAINS',
'INSTANT_VIEW_THREADS_DOMAINS',
'GALLERY_DOMAINS',
+ 'NATIVE_MULTI_IMAGE_DOMAINS',
'HOST_URL',
'REDIRECT_URL',
'EMBED_URL',
'MOSAIC_DOMAIN_LIST',
'API_HOST_LIST',
- 'SENTRY_DSN'
+ 'SENTRY_DSN',
+ 'GIF_TRANSCODE_DOMAIN'
];
// Create defines for all environment variables
diff --git a/jestconfig.json b/jestconfig.json
index 8a4d5eb..9132585 100644
--- a/jestconfig.json
+++ b/jestconfig.json
@@ -9,6 +9,7 @@
"INSTANT_VIEW_DOMAINS": "i.fxtwitter.com,i.twittpr.com,i.fixupx.com",
"INSTANT_VIEW_THREADS_DOMAINS": "u.fxtwitter.com,u.twittpr.com,u.fixupx.com",
"GALLERY_DOMAINS": "g.fxtwitter.com,g.twittpr.com,g.fixupx.com",
+ "NATIVE_MULTI_IMAGE_DOMAINS": "m.fxtwitter.com,m.twittpr.com,m.fixupx.com",
"STANDARD_DOMAIN_LIST": "fxtwitter.com,fixupx.com,twittpr.com",
"DIRECT_MEDIA_DOMAINS": "d.fxtwitter.com,dl.fxtwitter.com,d.fixupx.com,dl.fixupx.com",
"MOSAIC_DOMAIN_LIST": "mosaic.fxtwitter.com",
diff --git a/package-lock.json b/package-lock.json
index 237339b..2b0115d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,30 +9,30 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
- "@hono/sentry": "^1.0.0",
- "hono": "^3.12.3"
+ "@hono/sentry": "^1.0.1",
+ "hono": "^3.12.12"
},
"devDependencies": {
- "@cloudflare/workers-types": "^4.20231218.0",
- "@microsoft/eslint-formatter-sarif": "^3.0.0",
- "@sentry/esbuild-plugin": "^2.10.2",
- "@sentry/integrations": "^7.93.0",
- "@types/jest": "^29.5.11",
- "@typescript-eslint/eslint-plugin": "^6.18.1",
- "@typescript-eslint/parser": "^6.18.1",
- "dotenv": "^16.3.1",
- "eslint": "^8.56.0",
+ "@cloudflare/workers-types": "^4.20240423.0",
+ "@microsoft/eslint-formatter-sarif": "^3.1.0",
+ "@sentry/esbuild-plugin": "^2.16.1",
+ "@sentry/integrations": "^7.112.2",
+ "@types/jest": "^29.5.12",
+ "@typescript-eslint/eslint-plugin": "^7.7.1",
+ "@typescript-eslint/parser": "^7.7.1",
+ "dotenv": "^16.4.5",
+ "eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-typescript": "^3.0.0",
"eslint-plugin-optimize-regex": "^1.2.1",
- "eslint-plugin-sonarjs": "^0.23.0",
+ "eslint-plugin-sonarjs": "^0.25.1",
"jest": "^29.7.0",
- "jest-environment-miniflare": "^2.14.1",
- "prettier": "^3.2.2",
- "ts-jest": "^29.1.1",
+ "jest-environment-miniflare": "^2.14.2",
+ "prettier": "^3.2.5",
+ "ts-jest": "^29.1.2",
"ts-loader": "^9.5.1",
- "typescript": "^5.3.3",
- "wrangler": "^3.22.4"
+ "typescript": "^5.4.5",
+ "wrangler": "^3.51.2"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -45,61 +45,61 @@
}
},
"node_modules/@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dev": true,
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/code-frame": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
- "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "version": "7.24.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+ "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
"dev": true,
"dependencies": {
- "@babel/highlight": "^7.23.4",
- "chalk": "^2.4.2"
+ "@babel/highlight": "^7.24.2",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/compat-data": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
- "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz",
+ "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.18.5",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz",
- "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz",
+ "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==",
"dev": true,
"dependencies": {
- "@ampproject/remapping": "^2.1.0",
- "@babel/code-frame": "^7.16.7",
- "@babel/generator": "^7.18.2",
- "@babel/helper-compilation-targets": "^7.18.2",
- "@babel/helper-module-transforms": "^7.18.0",
- "@babel/helpers": "^7.18.2",
- "@babel/parser": "^7.18.5",
- "@babel/template": "^7.16.7",
- "@babel/traverse": "^7.18.5",
- "@babel/types": "^7.18.4",
- "convert-source-map": "^1.7.0",
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.24.2",
+ "@babel/generator": "^7.24.4",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.24.4",
+ "@babel/parser": "^7.24.4",
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.1",
+ "@babel/types": "^7.24.0",
+ "convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
- "json5": "^2.2.1",
- "semver": "^6.3.0"
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
},
"engines": {
"node": ">=6.9.0"
@@ -110,14 +110,14 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
- "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz",
+ "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.23.6",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
+ "@babel/types": "^7.24.0",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
},
"engines": {
@@ -175,12 +175,12 @@
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
- "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "version": "7.24.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz",
+ "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.22.15"
+ "@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -239,9 +239,9 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
- "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+ "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -266,13 +266,13 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz",
- "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz",
+ "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==",
"dev": true,
"dependencies": {
"@babel/template": "^7.24.0",
- "@babel/traverse": "^7.24.0",
+ "@babel/traverse": "^7.24.1",
"@babel/types": "^7.24.0"
},
"engines": {
@@ -280,23 +280,24 @@
}
},
"node_modules/@babel/highlight": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
- "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "version": "7.24.2",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+ "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
- "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
+ "version": "7.24.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
+ "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -366,12 +367,12 @@
}
},
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz",
- "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz",
+ "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -468,12 +469,12 @@
}
},
"node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz",
- "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz",
+ "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -497,18 +498,18 @@
}
},
"node_modules/@babel/traverse": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz",
- "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==",
+ "version": "7.24.1",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz",
+ "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==",
"dev": true,
"dependencies": {
- "@babel/code-frame": "^7.23.5",
- "@babel/generator": "^7.23.6",
+ "@babel/code-frame": "^7.24.1",
+ "@babel/generator": "^7.24.1",
"@babel/helper-environment-visitor": "^7.22.20",
"@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.24.0",
+ "@babel/parser": "^7.24.1",
"@babel/types": "^7.24.0",
"debug": "^4.3.1",
"globals": "^11.1.0"
@@ -547,9 +548,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-64": {
- "version": "1.20240223.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240223.1.tgz",
- "integrity": "sha512-GgHnvkazLFZ7bmR96+dTX0+WS13a+5CHOOP3qNUSR9oEnR4hHzpNIO75MuZsm9RPAXrvtT7nSJmYwiGCZXh6og==",
+ "version": "1.20240405.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240405.0.tgz",
+ "integrity": "sha512-ut8kwpHmlz9dNSjoov6v1b6jS50J46Mj9QcMA0t1Hne36InaQk/qqPSd12fN5p2GesZ9OOBJvBdDsTblVdyJ1w==",
"cpu": [
"x64"
],
@@ -563,9 +564,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-arm64": {
- "version": "1.20240223.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240223.1.tgz",
- "integrity": "sha512-ZF98vUmVlC0EVEd3RRuhMq4HYWFcqmPtMIMPUN2+ivEHR92TE+6E/AvdeE6wcE7fKHQ+fk3dH+ZgB0GcfptfnA==",
+ "version": "1.20240405.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240405.0.tgz",
+ "integrity": "sha512-x3A3Ym+J2DH1uYnw0aedeKOTnUebEo312+Aladv7bFri97pjRJcqVbYhMtOHLkHjwYn7bpKSY2eL5iM+0XT29A==",
"cpu": [
"arm64"
],
@@ -579,9 +580,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-64": {
- "version": "1.20240223.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240223.1.tgz",
- "integrity": "sha512-1kH41ewNTGMmAk2zUX0Xj9VSfidl26GQ0ZrWMdi5kwf6gAHd3oVWNigJN078Jx56SgQxNcqVGX1LunqF949asw==",
+ "version": "1.20240405.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240405.0.tgz",
+ "integrity": "sha512-3tYpfjtxEQ0R30Pna7OF3Bz0CTx30hc0QNtH61KnkvXtaeYMkWutSKQKXIuVlPa/7v1MHp+8ViBXMflmS7HquA==",
"cpu": [
"x64"
],
@@ -595,9 +596,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-arm64": {
- "version": "1.20240223.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240223.1.tgz",
- "integrity": "sha512-Ro8Og5C4evh890JrRm0B8sHyumRtgL+mUqPeNcEsyG45jAQy5xHpapHnmJAMJV6ah+zDc1cZtQq+en39SojXvQ==",
+ "version": "1.20240405.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240405.0.tgz",
+ "integrity": "sha512-NpKZlvmdgcX/m4tP5zM91AfJpZrue2/GRA+Sl3szxAivu2uE5jDVf5SS9dzqzCVfPrdhylqH7yeL4U/cafFNOg==",
"cpu": [
"arm64"
],
@@ -611,9 +612,9 @@
}
},
"node_modules/@cloudflare/workerd-windows-64": {
- "version": "1.20240223.1",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240223.1.tgz",
- "integrity": "sha512-eNP5sfaP6WL07DaoigYou5ASPF7jHsFiNzzD2vGOI7yFd5sPlb7sJ4SpIy+BCX0LdqFnjmlUo5Xr+/I6qJ2Nww==",
+ "version": "1.20240405.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240405.0.tgz",
+ "integrity": "sha512-REBeJMxvUCjwuEVzSSIBtzAyM69QjToab8qBst0S9vdih+9DObym4dw8CevdBQhDbFrHiyL9E6pAZpLPNHVgCw==",
"cpu": [
"x64"
],
@@ -627,9 +628,9 @@
}
},
"node_modules/@cloudflare/workers-types": {
- "version": "4.20240222.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240222.0.tgz",
- "integrity": "sha512-luO0BdK3rLlCv3B240+cTrfqm+XSbHtpk+88aJtGwzyVK9QF/Xz8lBgE/oZZLN8nCTmOvxAZnszyxUuZ8GP8Cg==",
+ "version": "4.20240423.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240423.0.tgz",
+ "integrity": "sha512-ssuccb3j+URp6mP2p0PcQE9vmS3YeKBQnALHF9P3yQfUAFozuhTsDTbqmL+zPrJvUcG7SL2xVQkNDF9QJeKDZw==",
"dev": true
},
"node_modules/@cspotcode/source-map-support": {
@@ -1215,9 +1216,9 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
- "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
"dev": true
},
"node_modules/@iarna/toml": {
@@ -1896,12 +1897,6 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
- "node_modules/@jest/transform/node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true
- },
"node_modules/@jest/transform/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -2011,14 +2006,14 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz",
- "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -2043,14 +2038,14 @@
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
- "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
"peer": true,
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
@@ -2060,9 +2055,9 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.23",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz",
- "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==",
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -2070,9 +2065,9 @@
}
},
"node_modules/@microsoft/eslint-formatter-sarif": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@microsoft/eslint-formatter-sarif/-/eslint-formatter-sarif-3.0.0.tgz",
- "integrity": "sha512-KIKkT44hEqCzqxODYwFMUvYEK0CrdHx/Ll9xiOWgFbBSRuzbxmVy4d/tzfgoucGz72HJZNOMjuyzFTBKntRK5Q==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@microsoft/eslint-formatter-sarif/-/eslint-formatter-sarif-3.1.0.tgz",
+ "integrity": "sha512-/mn4UXziHzGXnKCg+r8HGgPy+w4RzpgdoqFuqaKOqUVBT5x2CygGefIrO4SusaY7t0C4gyIWMNu6YQT6Jw64Cw==",
"dev": true,
"dependencies": {
"eslint": "^8.9.0",
@@ -2363,27 +2358,27 @@
}
},
"node_modules/@sentry/babel-plugin-component-annotate": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.14.2.tgz",
- "integrity": "sha512-mFBVnIZmdMrpxo61rG5yf0WFt5VrRpy8cpIpJtT3mYkX9vDmcUZaZaD1ctv73iZF3QwaieVdn05Na5mWzZ8h/A==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.16.1.tgz",
+ "integrity": "sha512-pJka66URsqQbk6hTs9H1XFpUeI0xxuqLYf9Dy5pRGNHSJMtfv91U+CaYSWt03aRRMGDXMduh62zAAY7Wf0HO+A==",
"dev": true,
"engines": {
"node": ">= 14"
}
},
"node_modules/@sentry/bundler-plugin-core": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.14.2.tgz",
- "integrity": "sha512-HgOFWYdq87lSmeVW1w8K2Vf2DGzRPvKzHTajZYLTPlrZ1jbajq9vwuqhrJ9AnDkjl0mjyzSPEy3ZTeG1Z7uRNA==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.16.1.tgz",
+ "integrity": "sha512-n6z8Ts3T9HROLuY7tVEYpBKvS+P7+b8NdqxP7QBcwp2nuPUlN5Ola1ivFjk1p5a7wRYeN9zM8orGe4l2HeNfYA==",
"dev": true,
"dependencies": {
- "@babel/core": "7.18.5",
- "@sentry/babel-plugin-component-annotate": "2.14.2",
+ "@babel/core": "^7.18.5",
+ "@sentry/babel-plugin-component-annotate": "2.16.1",
"@sentry/cli": "^2.22.3",
"dotenv": "^16.3.1",
- "find-up": "5.0.0",
- "glob": "9.3.2",
- "magic-string": "0.27.0",
+ "find-up": "^5.0.0",
+ "glob": "^9.3.2",
+ "magic-string": "0.30.8",
"unplugin": "1.0.1"
},
"engines": {
@@ -2391,9 +2386,9 @@
}
},
"node_modules/@sentry/cli": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.28.6.tgz",
- "integrity": "sha512-o2Ngz7xXuhwHxMi+4BFgZ4qjkX0tdZeOSIZkFAGnTbRhQe5T8bxq6CcQRLdPhqMgqvDn7XuJ3YlFtD3ZjHvD7g==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.31.0.tgz",
+ "integrity": "sha512-nCESoXAG3kRUO5n3QbDYAqX6RU3z1ORjnd7a3sqijYsCGHfOpcjGdS7JYLVg5if+tXMEF5529BPXFe5Kg/J9tw==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -2410,19 +2405,19 @@
"node": ">= 10"
},
"optionalDependencies": {
- "@sentry/cli-darwin": "2.28.6",
- "@sentry/cli-linux-arm": "2.28.6",
- "@sentry/cli-linux-arm64": "2.28.6",
- "@sentry/cli-linux-i686": "2.28.6",
- "@sentry/cli-linux-x64": "2.28.6",
- "@sentry/cli-win32-i686": "2.28.6",
- "@sentry/cli-win32-x64": "2.28.6"
+ "@sentry/cli-darwin": "2.31.0",
+ "@sentry/cli-linux-arm": "2.31.0",
+ "@sentry/cli-linux-arm64": "2.31.0",
+ "@sentry/cli-linux-i686": "2.31.0",
+ "@sentry/cli-linux-x64": "2.31.0",
+ "@sentry/cli-win32-i686": "2.31.0",
+ "@sentry/cli-win32-x64": "2.31.0"
}
},
"node_modules/@sentry/cli-darwin": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.28.6.tgz",
- "integrity": "sha512-KRf0VvTltHQ5gA7CdbUkaIp222LAk/f1+KqpDzO6nB/jC/tL4sfiy6YyM4uiH6IbVEudB8WpHCECiatmyAqMBA==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.31.0.tgz",
+ "integrity": "sha512-VM5liyxMnm4K2g0WsrRPXRCMLhaT09C7gK5Fz/CxKYh9sbMZB7KA4hV/3klkyuyw1+ECF1J66cefhNkFZepUig==",
"dev": true,
"optional": true,
"os": [
@@ -2433,9 +2428,9 @@
}
},
"node_modules/@sentry/cli-linux-arm": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.28.6.tgz",
- "integrity": "sha512-ANG7U47yEHD1g3JrfhpT4/MclEvmDZhctWgSP5gVw5X4AlcI87E6dTqccnLgvZjiIAQTaJJAZuSHVVF3Jk403w==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.31.0.tgz",
+ "integrity": "sha512-AZoCN3waXEfXGCd3YSrikcX/y63oQe0Tiyapkeoifq/0QhI+2MOOrAQb60gthsXwb0UDK/XeFi3PaxyUCphzxA==",
"cpu": [
"arm"
],
@@ -2450,9 +2445,9 @@
}
},
"node_modules/@sentry/cli-linux-arm64": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.28.6.tgz",
- "integrity": "sha512-caMDt37FI752n4/3pVltDjlrRlPFCOxK4PHvoZGQ3KFMsai0ZhE/0CLBUMQqfZf0M0r8KB2x7wqLm7xSELjefQ==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.31.0.tgz",
+ "integrity": "sha512-eENJTmXoFX3uNr8xRW7Bua2Sw3V1tylQfdtS85pNjZPdbm3U8wYQSWu2VoZkK2ASOoC+17YC8jTQxq62KWnSeQ==",
"cpu": [
"arm64"
],
@@ -2467,9 +2462,9 @@
}
},
"node_modules/@sentry/cli-linux-i686": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.28.6.tgz",
- "integrity": "sha512-Tj1+GMc6lFsDRquOqaGKXFpW9QbmNK4TSfynkWKiJxdTEn5jSMlXXfr0r9OQrxu3dCCqEHkhEyU63NYVpgxIPw==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.31.0.tgz",
+ "integrity": "sha512-cQUFb3brhLaNSIoNzjU/YASnTM1I3TDJP9XXzH0eLK9sSopCcDcc6OrYEYvdjJXZKzFv5sbc9UNMsIDbh4+rYg==",
"cpu": [
"x86",
"ia32"
@@ -2485,9 +2480,9 @@
}
},
"node_modules/@sentry/cli-linux-x64": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.28.6.tgz",
- "integrity": "sha512-Dt/Xz784w/z3tEObfyJEMmRIzn0D5qoK53H9kZ6e0yNvJOSKNCSOq5cQk4n1/qeG0K/6SU9dirmvHwFUiVNyYg==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.31.0.tgz",
+ "integrity": "sha512-z1zTNg91nZJRdcGHC/bCU1KwIaifV0MLJteip9KrFDprzhJk1HtMxFOS0+OZ5/UH21CjAFmg9Pj6IAGqm3BYjA==",
"cpu": [
"x64"
],
@@ -2502,9 +2497,9 @@
}
},
"node_modules/@sentry/cli-win32-i686": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.28.6.tgz",
- "integrity": "sha512-zkpWtvY3kt+ogVaAbfFr2MEkgMMHJNJUnNMO8Ixce9gh38sybIkDkZNFnVPBXMClJV0APa4QH0EwumYBFZUMuQ==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.31.0.tgz",
+ "integrity": "sha512-+K7fdk57aUd4CmYrQfDGYPzVyxsTnVro6IPb5QSSLpP03dL7ko5208epu4m2SyN/MkFvscy9Di3n3DTvIfDU2w==",
"cpu": [
"x86",
"ia32"
@@ -2519,9 +2514,9 @@
}
},
"node_modules/@sentry/cli-win32-x64": {
- "version": "2.28.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.28.6.tgz",
- "integrity": "sha512-TG2YzZ9JMeNFzbicdr5fbtsusVGACbrEfHmPgzWGDeLUP90mZxiMTjkXsE1X/5jQEQjB2+fyfXloba/Ugo51hA==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.31.0.tgz",
+ "integrity": "sha512-w5cvpZ6VVlhlyleY8TYHmrP7g48vKHnoVt5xFccfxT+HqQI/AxodvzgVvBTM2kB/sh/kHwexp6bJGWCdkGftww==",
"cpu": [
"x64"
],
@@ -2535,25 +2530,25 @@
}
},
"node_modules/@sentry/core": {
- "version": "7.103.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.103.0.tgz",
- "integrity": "sha512-LCI+PIDoF/RLqN41fNXum3ilmS6ukni6L7t38vSdibbe2G0804EbPLtOIpv2PkS8E6CFuRW5zOb+8OwEAAtZWw==",
+ "version": "7.112.2",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.112.2.tgz",
+ "integrity": "sha512-gHPCcJobbMkk0VR18J65WYQTt3ED4qC6X9lHKp27Ddt63E+MDGkG6lvYBU1LS8cV7CdyBGC1XXDCfor61GvLsA==",
"dev": true,
"dependencies": {
- "@sentry/types": "7.103.0",
- "@sentry/utils": "7.103.0"
+ "@sentry/types": "7.112.2",
+ "@sentry/utils": "7.112.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/esbuild-plugin": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/@sentry/esbuild-plugin/-/esbuild-plugin-2.14.2.tgz",
- "integrity": "sha512-ciumtibhxguf47xLwQmhzotdQiHFqiifcROnjU2VACub/GD+2cpz6rnKU5BAPTo13UIR0+Nask/xYmZkpMbGog==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/@sentry/esbuild-plugin/-/esbuild-plugin-2.16.1.tgz",
+ "integrity": "sha512-xwkuDKxNfEL8hMjlD/ByjmTeC1QiLULTsmdiYFjlz9HcYUtjU175V+cmOKqWrXAg/j3DmPZM9zNS9sdg3E7oVg==",
"dev": true,
"dependencies": {
- "@sentry/bundler-plugin-core": "2.14.2",
+ "@sentry/bundler-plugin-core": "2.16.1",
"unplugin": "1.0.1",
"uuid": "^9.0.0"
},
@@ -2562,14 +2557,14 @@
}
},
"node_modules/@sentry/integrations": {
- "version": "7.103.0",
- "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.103.0.tgz",
- "integrity": "sha512-jS1vQqBBF776xFpht4xS5cJRztbpskFELeZX57pELzy/J7PNjbO0/oypP1qK7budMxxkazJhkcNwJw9eUFT0pg==",
+ "version": "7.112.2",
+ "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.112.2.tgz",
+ "integrity": "sha512-ioC2yyU6DqtLkdmWnm87oNvdn2+9oKctJeA4t+jkS6JaJ10DcezjCwiLscX4rhB9aWJV3IWF7Op0O6K3w0t2Hg==",
"dev": true,
"dependencies": {
- "@sentry/core": "7.103.0",
- "@sentry/types": "7.103.0",
- "@sentry/utils": "7.103.0",
+ "@sentry/core": "7.112.2",
+ "@sentry/types": "7.112.2",
+ "@sentry/utils": "7.112.2",
"localforage": "^1.8.1"
},
"engines": {
@@ -2577,21 +2572,21 @@
}
},
"node_modules/@sentry/types": {
- "version": "7.103.0",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.103.0.tgz",
- "integrity": "sha512-NCvKyx8d2AGBQKPARrJemZmZ16DiMo688OEikZg4BbvFNDUzK5Egm2BH0vfLDhbNkU19o3maJowrYo42m8r9Zw==",
+ "version": "7.112.2",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.112.2.tgz",
+ "integrity": "sha512-kCMLt7yhY5OkWE9MeowlTNmox9pqDxcpvqguMo4BDNZM5+v9SEb1AauAdR78E1a1V8TyCzjBD7JDfXWhvpYBcQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/utils": {
- "version": "7.103.0",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.103.0.tgz",
- "integrity": "sha512-phkUJt3F0UOkVq+M4GfdAh2ewI3ASrNiJddx9aO7GnT0aDwwVBHZltnqt95qgAB8W+BipTSt1dAh8yUbbq1Ceg==",
+ "version": "7.112.2",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.112.2.tgz",
+ "integrity": "sha512-OjLh0hx0t1EcL4ZIjf+4svlmmP+tHUDGcr5qpFWH78tjmkPW4+cqPuZCZfHSuWcDdeiaXi8TnYoVRqDcJKK/eQ==",
"dev": true,
"dependencies": {
- "@sentry/types": "7.103.0"
+ "@sentry/types": "7.112.2"
},
"engines": {
"node": ">=8"
@@ -2663,18 +2658,18 @@
}
},
"node_modules/@types/better-sqlite3": {
- "version": "7.6.9",
- "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.9.tgz",
- "integrity": "sha512-FvktcujPDj9XKMJQWFcl2vVl7OdRIqsSRX9b0acWwTmwLK9CF2eqo/FRcmMLNpugKoX/avA6pb7TorDLmpgTnQ==",
+ "version": "7.6.10",
+ "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.10.tgz",
+ "integrity": "sha512-TZBjD+yOsyrUJGmcUj6OS3JADk3+UZcNv3NOBqGkM09bZdi28fNZw8ODqbMOLfKCu7RYCO62/ldq1iHbzxqoPw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/eslint": {
- "version": "8.56.5",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz",
- "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==",
+ "version": "8.56.10",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz",
+ "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==",
"dev": true,
"peer": true,
"dependencies": {
@@ -2750,9 +2745,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "20.11.24",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz",
- "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==",
+ "version": "20.12.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
+ "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -2795,33 +2790,33 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
- "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz",
+ "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==",
"dev": true,
"dependencies": {
- "@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/type-utils": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "7.7.1",
+ "@typescript-eslint/type-utils": "7.7.1",
+ "@typescript-eslint/utils": "7.7.1",
+ "@typescript-eslint/visitor-keys": "7.7.1",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
- "ignore": "^5.2.4",
+ "ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
- "eslint": "^7.0.0 || ^8.0.0"
+ "@typescript-eslint/parser": "^7.0.0",
+ "eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -2863,26 +2858,26 @@
"dev": true
},
"node_modules/@typescript-eslint/parser": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
- "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz",
+ "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
+ "@typescript-eslint/scope-manager": "7.7.1",
+ "@typescript-eslint/types": "7.7.1",
+ "@typescript-eslint/typescript-estree": "7.7.1",
+ "@typescript-eslint/visitor-keys": "7.7.1",
"debug": "^4.3.4"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
+ "eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -2891,16 +2886,16 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
- "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz",
+ "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0"
+ "@typescript-eslint/types": "7.7.1",
+ "@typescript-eslint/visitor-keys": "7.7.1"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -2908,25 +2903,25 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
- "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz",
+ "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/typescript-estree": "7.7.1",
+ "@typescript-eslint/utils": "7.7.1",
"debug": "^4.3.4",
- "ts-api-utils": "^1.0.1"
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
+ "eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -2935,12 +2930,12 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
- "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz",
+ "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==",
"dev": true,
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -2948,22 +2943,22 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
- "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz",
+ "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
+ "@typescript-eslint/types": "7.7.1",
+ "@typescript-eslint/visitor-keys": "7.7.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -3009,28 +3004,28 @@
"dev": true
},
"node_modules/@typescript-eslint/utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
- "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz",
+ "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@types/json-schema": "^7.0.12",
- "@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "semver": "^7.5.4"
+ "@types/json-schema": "^7.0.15",
+ "@types/semver": "^7.5.8",
+ "@typescript-eslint/scope-manager": "7.7.1",
+ "@typescript-eslint/types": "7.7.1",
+ "@typescript-eslint/typescript-estree": "7.7.1",
+ "semver": "^7.6.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
+ "eslint": "^8.56.0"
}
},
"node_modules/@typescript-eslint/utils/node_modules/lru-cache": {
@@ -3067,16 +3062,16 @@
"dev": true
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
- "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz",
+ "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "eslint-visitor-keys": "^3.4.1"
+ "@typescript-eslint/types": "7.7.1",
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -3090,9 +3085,9 @@
"dev": true
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
- "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
+ "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
"dev": true,
"peer": true,
"dependencies": {
@@ -3115,9 +3110,9 @@
"peer": true
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
- "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
+ "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
"dev": true,
"peer": true
},
@@ -3141,16 +3136,16 @@
"peer": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
- "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
+ "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6"
+ "@webassemblyjs/wasm-gen": "1.12.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
@@ -3181,30 +3176,30 @@
"peer": true
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
- "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
+ "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/helper-wasm-section": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-opt": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6",
- "@webassemblyjs/wast-printer": "1.11.6"
+ "@webassemblyjs/helper-wasm-section": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-opt": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1",
+ "@webassemblyjs/wast-printer": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
- "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
+ "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
"@webassemblyjs/leb128": "1.11.6",
@@ -3212,26 +3207,26 @@
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
- "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
+ "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6"
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
- "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
+ "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-api-error": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
@@ -3240,13 +3235,13 @@
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
- "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
+ "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@xtuc/long": "4.2.2"
}
},
@@ -3599,12 +3594,15 @@
"dev": true
},
"node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
"engines": {
"node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/blake3-wasm": {
@@ -3694,9 +3692,9 @@
"dev": true
},
"node_modules/builtins": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz",
- "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz",
+ "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==",
"dev": true,
"dependencies": {
"semver": "^7.0.0"
@@ -3766,9 +3764,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001591",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz",
- "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
+ "version": "1.0.30001612",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz",
+ "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==",
"dev": true,
"funding": [
{
@@ -3944,9 +3942,9 @@
"dev": true
},
"node_modules/convert-source-map": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
"node_modules/cookie": {
@@ -4087,9 +4085,9 @@
}
},
"node_modules/dedent": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz",
- "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
+ "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
"dev": true,
"peerDependencies": {
"babel-plugin-macros": "^3.1.0"
@@ -4170,9 +4168,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.688",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.688.tgz",
- "integrity": "sha512-3/tHg2ChPF00eukURIB8cSVt3/9oeS1oTUIEt3ivngBInUaEcBhG2VdyEDejhwQdR6SLqaiEAEc0dHS0V52pOw==",
+ "version": "1.4.746",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.746.tgz",
+ "integrity": "sha512-jeWaIta2rIG2FzHaYIhSuVWqC6KJYo7oSBX4Jv7g+aVujKztfvdpf+n6MGwZdC5hQXbax4nntykLH2juIQrfPg==",
"dev": true
},
"node_modules/emittery": {
@@ -4194,9 +4192,9 @@
"dev": true
},
"node_modules/enhanced-resolve": {
- "version": "5.15.1",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz",
- "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==",
+ "version": "5.16.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
+ "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -4216,9 +4214,9 @@
}
},
"node_modules/es-module-lexer": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
- "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz",
+ "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==",
"dev": true,
"peer": true
},
@@ -4369,12 +4367,12 @@
}
},
"node_modules/eslint-plugin-sonarjs": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.23.0.tgz",
- "integrity": "sha512-z44T3PBf9W7qQ/aR+NmofOTyg6HLhSEZOPD4zhStqBpLoMp8GYhFksuUBnCxbnf1nfISpKBVkQhiBLFI/F4Wlg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.25.1.tgz",
+ "integrity": "sha512-5IOKvj/GMBNqjxBdItfotfRHo7w48496GOu1hxdeXuD0mB1JBlDCViiLHETDTfA8pDAVSBimBEQoetRXYceQEw==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
},
"peerDependencies": {
"eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -4890,13 +4888,13 @@
}
},
"node_modules/glob": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.2.tgz",
- "integrity": "sha512-BTv/JhKXFEHsErMte/AnfiSv8yYOLLiyH2lTg8vn02O21zWFgHPTfxtgn1QRe7NRgggUhC8hacR2Re94svHqeA==",
+ "version": "9.3.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
+ "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
- "minimatch": "^7.4.1",
+ "minimatch": "^8.0.2",
"minipass": "^4.2.4",
"path-scurry": "^1.6.1"
},
@@ -4926,15 +4924,15 @@
"dev": true
},
"node_modules/glob/node_modules/minimatch": {
- "version": "7.4.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
- "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
+ "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -4991,9 +4989,9 @@
}
},
"node_modules/hasown": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
- "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.2"
@@ -5254,51 +5252,6 @@
"node": ">=10"
}
},
- "node_modules/istanbul-lib-instrument/node_modules/@babel/core": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz",
- "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==",
- "dev": true,
- "dependencies": {
- "@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.23.5",
- "@babel/generator": "^7.23.6",
- "@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helpers": "^7.24.0",
- "@babel/parser": "^7.24.0",
- "@babel/template": "^7.24.0",
- "@babel/traverse": "^7.24.0",
- "@babel/types": "^7.24.0",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/istanbul-lib-instrument/node_modules/@babel/core/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/istanbul-lib-instrument/node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true
- },
"node_modules/istanbul-lib-instrument/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -7097,9 +7050,9 @@
}
},
"node_modules/jschardet": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-3.0.0.tgz",
- "integrity": "sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-3.1.2.tgz",
+ "integrity": "sha512-mw3CBZGzW8nUBPYhFU2ztZ/kJ6NClQUQVpyzvFMfznZsoC///ZQ30J2RCUanNsr5yF22LqhgYr/lj807/ZleWA==",
"dev": true,
"engines": {
"node": ">=0.1.90"
@@ -7268,12 +7221,12 @@
}
},
"node_modules/magic-string": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
- "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"dev": true,
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.13"
+ "@jridgewell/sourcemap-codec": "^1.4.15"
},
"engines": {
"node": ">=12"
@@ -7415,9 +7368,9 @@
}
},
"node_modules/miniflare": {
- "version": "3.20240223.0",
- "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240223.0.tgz",
- "integrity": "sha512-8T/36FEfvsL4aMF7SLZ28v+PQL0jsUlVw/u114GYcdobkyPax9E6Ahn0XePOHEqLxQSndwPee+eS1phHANFePA==",
+ "version": "3.20240405.2",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240405.2.tgz",
+ "integrity": "sha512-n/V5m9GVMN37U5gWdrNXKx2d1icLXtcIKcxWtLslH4RTaebZJdSRmp12UHyuQsKlaSpTkNqyzLVtCEgt2bhRSA==",
"dev": true,
"dependencies": {
"@cspotcode/source-map-support": "0.8.1",
@@ -7428,7 +7381,7 @@
"glob-to-regexp": "^0.4.1",
"stoppable": "^1.1.0",
"undici": "^5.28.2",
- "workerd": "1.20240223.1",
+ "workerd": "1.20240405.0",
"ws": "^8.11.0",
"youch": "^3.2.2",
"zod": "^3.20.6"
@@ -7441,9 +7394,9 @@
}
},
"node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -7877,12 +7830,12 @@
"dev": true
},
"node_modules/path-scurry": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
- "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
+ "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
"dev": true,
"dependencies": {
- "lru-cache": "^9.1.1 || ^10.0.0",
+ "lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
@@ -7911,9 +7864,9 @@
}
},
"node_modules/path-to-regexp": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
- "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==",
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz",
+ "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==",
"dev": true
},
"node_modules/path-type": {
@@ -8119,9 +8072,9 @@
}
},
"node_modules/pure-rand": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz",
- "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
+ "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
"dev": true,
"funding": [
{
@@ -8406,6 +8359,15 @@
],
"peer": true
},
+ "node_modules/safe-stable-stringify": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
+ "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
@@ -8690,9 +8652,9 @@
}
},
"node_modules/terser": {
- "version": "5.28.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz",
- "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==",
+ "version": "5.30.4",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.4.tgz",
+ "integrity": "sha512-xRdd0v64a8mFK9bnsKVdoNP9GQIKUAaJPTaqEQDL4w/J8WaW4sWXXoMZ+6SimPkfT5bElreXf8m9HnmPc3E1BQ==",
"dev": true,
"peer": true,
"dependencies": {
@@ -8947,9 +8909,9 @@
"dev": true
},
"node_modules/ts-api-utils": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
- "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
"dev": true,
"engines": {
"node": ">=16"
@@ -9034,6 +8996,67 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "node_modules/ts-json-schema-generator": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ts-json-schema-generator/-/ts-json-schema-generator-1.5.1.tgz",
+ "integrity": "sha512-apX5qG2+NA66j7b4AJm8q/DpdTeOsjfh7A3LpKsUiil0FepkNwtN28zYgjrsiiya2/OPhsr/PSjX5FUYg79rCg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.15",
+ "commander": "^12.0.0",
+ "glob": "^8.0.3",
+ "json5": "^2.2.3",
+ "normalize-path": "^3.0.0",
+ "safe-stable-stringify": "^2.4.3",
+ "typescript": "~5.4.2"
+ },
+ "bin": {
+ "ts-json-schema-generator": "bin/ts-json-schema-generator"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/ts-json-schema-generator/node_modules/commander": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz",
+ "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/ts-json-schema-generator/node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/ts-json-schema-generator/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/ts-loader": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
@@ -9206,9 +9229,9 @@
}
},
"node_modules/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "version": "5.4.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@@ -9326,12 +9349,6 @@
"node": ">=10.12.0"
}
},
- "node_modules/v8-to-istanbul/node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true
- },
"node_modules/validate-npm-package-name": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz",
@@ -9354,9 +9371,9 @@
}
},
"node_modules/watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz",
+ "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==",
"dev": true,
"peer": true,
"dependencies": {
@@ -9374,27 +9391,27 @@
"dev": true
},
"node_modules/webpack": {
- "version": "5.90.3",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz",
- "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==",
+ "version": "5.91.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz",
+ "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==",
"dev": true,
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.5",
- "@webassemblyjs/ast": "^1.11.5",
- "@webassemblyjs/wasm-edit": "^1.11.5",
- "@webassemblyjs/wasm-parser": "^1.11.5",
+ "@webassemblyjs/ast": "^1.12.1",
+ "@webassemblyjs/wasm-edit": "^1.12.1",
+ "@webassemblyjs/wasm-parser": "^1.12.1",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.9.0",
"browserslist": "^4.21.10",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.15.0",
+ "enhanced-resolve": "^5.16.0",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.2.9",
+ "graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
@@ -9402,7 +9419,7 @@
"schema-utils": "^3.2.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.10",
- "watchpack": "^2.4.0",
+ "watchpack": "^2.4.1",
"webpack-sources": "^3.2.3"
},
"bin": {
@@ -9486,9 +9503,9 @@
}
},
"node_modules/workerd": {
- "version": "1.20240223.1",
- "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240223.1.tgz",
- "integrity": "sha512-Mo1fwdp6DLva4/fWdL09ZdYllkO45I4YpWG5PbF/YUGFlu2aMk24fmU6Pd6fo5/cWek4F+n3LmYEKKHfqjiJIA==",
+ "version": "1.20240405.0",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240405.0.tgz",
+ "integrity": "sha512-AWrOSBh4Ll7sBWHuh0aywm8hDkKqsZmcwnDB0PVGszWZM5mndNBI5iJ/8haXVpdoyqkJQEVdhET9JDi4yU8tRg==",
"dev": true,
"hasInstallScript": true,
"bin": {
@@ -9498,17 +9515,17 @@
"node": ">=16"
},
"optionalDependencies": {
- "@cloudflare/workerd-darwin-64": "1.20240223.1",
- "@cloudflare/workerd-darwin-arm64": "1.20240223.1",
- "@cloudflare/workerd-linux-64": "1.20240223.1",
- "@cloudflare/workerd-linux-arm64": "1.20240223.1",
- "@cloudflare/workerd-windows-64": "1.20240223.1"
+ "@cloudflare/workerd-darwin-64": "1.20240405.0",
+ "@cloudflare/workerd-darwin-arm64": "1.20240405.0",
+ "@cloudflare/workerd-linux-64": "1.20240405.0",
+ "@cloudflare/workerd-linux-arm64": "1.20240405.0",
+ "@cloudflare/workerd-windows-64": "1.20240405.0"
}
},
"node_modules/wrangler": {
- "version": "3.30.1",
- "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.30.1.tgz",
- "integrity": "sha512-cT6Ezx8h2v5QiI0HWhnHVy32ng4omdMVdhaMQLuMnyMIHmyDoRg7pmrbhtZfj0663gExLdVtE4ucK//yncVTwg==",
+ "version": "3.51.2",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.51.2.tgz",
+ "integrity": "sha512-8TRUwzPHj6+uPDzY0hBJ9/YwniEF9pqMGe5qbqLP/XsHTCWxIFib5go374zyCkmuVh23AwV7NuTA6gUtSqZ8pQ==",
"dev": true,
"dependencies": {
"@cloudflare/kv-asset-handler": "0.3.1",
@@ -9517,13 +9534,14 @@
"blake3-wasm": "^2.1.5",
"chokidar": "^3.5.3",
"esbuild": "0.17.19",
- "miniflare": "3.20240223.0",
+ "miniflare": "3.20240405.2",
"nanoid": "^3.3.3",
"path-to-regexp": "^6.2.0",
"resolve": "^1.22.8",
"resolve.exports": "^2.0.2",
"selfsigned": "^2.0.1",
"source-map": "0.6.1",
+ "ts-json-schema-generator": "^1.5.0",
"xxhash-wasm": "^1.0.1"
},
"bin": {
@@ -9537,7 +9555,7 @@
"fsevents": "~2.3.2"
},
"peerDependencies": {
- "@cloudflare/workers-types": "^4.20230914.0"
+ "@cloudflare/workers-types": "^4.20240405.0"
},
"peerDependenciesMeta": {
"@cloudflare/workers-types": {
@@ -9707,9 +9725,9 @@
}
},
"node_modules/zod": {
- "version": "3.22.4",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz",
- "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==",
+ "version": "3.23.3",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.3.tgz",
+ "integrity": "sha512-tPvq1B/2Yu/dh2uAIH2/BhUlUeLIUvAjr6dpL/75I0pCYefHgjhXk1o1Kob3kTU8C7yU1j396jFHlsVWFi9ogg==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
diff --git a/package.json b/package.json
index f5bc423..2004b33 100644
--- a/package.json
+++ b/package.json
@@ -16,29 +16,29 @@
"author": "dangered wolf",
"license": "MIT",
"devDependencies": {
- "@cloudflare/workers-types": "^4.20231218.0",
- "@microsoft/eslint-formatter-sarif": "^3.0.0",
- "@sentry/esbuild-plugin": "^2.10.2",
- "@sentry/integrations": "^7.93.0",
- "@types/jest": "^29.5.11",
- "@typescript-eslint/eslint-plugin": "^6.18.1",
- "@typescript-eslint/parser": "^6.18.1",
- "dotenv": "^16.3.1",
- "eslint": "^8.56.0",
+ "@cloudflare/workers-types": "^4.20240423.0",
+ "@microsoft/eslint-formatter-sarif": "^3.1.0",
+ "@sentry/esbuild-plugin": "^2.16.1",
+ "@sentry/integrations": "^7.112.2",
+ "@types/jest": "^29.5.12",
+ "@typescript-eslint/eslint-plugin": "^7.7.1",
+ "@typescript-eslint/parser": "^7.7.1",
+ "dotenv": "^16.4.5",
+ "eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-typescript": "^3.0.0",
"eslint-plugin-optimize-regex": "^1.2.1",
- "eslint-plugin-sonarjs": "^0.23.0",
+ "eslint-plugin-sonarjs": "^0.25.1",
"jest": "^29.7.0",
- "jest-environment-miniflare": "^2.14.1",
- "prettier": "^3.2.2",
- "ts-jest": "^29.1.1",
+ "jest-environment-miniflare": "^2.14.2",
+ "prettier": "^3.2.5",
+ "ts-jest": "^29.1.2",
"ts-loader": "^9.5.1",
- "typescript": "^5.3.3",
- "wrangler": "^3.22.4"
+ "typescript": "^5.4.5",
+ "wrangler": "^3.51.2"
},
"dependencies": {
- "@hono/sentry": "^1.0.0",
- "hono": "^3.12.3"
+ "@hono/sentry": "^1.0.1",
+ "hono": "^3.12.12"
}
}
diff --git a/src/caches.ts b/src/caches.ts
index 6b94213..a9c1229 100644
--- a/src/caches.ts
+++ b/src/caches.ts
@@ -20,6 +20,13 @@ export const cacheMiddleware = (): MiddlewareHandler => async (c, next) => {
console.log('cacheUrl', cacheUrl);
let cacheKey: Request;
+ const returnAsJson = Constants.API_HOST_LIST.includes(cacheUrl.hostname);
+
+ /* If caching unavailable, ignore the rest of the cache middleware */
+ if (typeof caches === 'undefined') {
+ await next();
+ return c.res.clone();
+ }
try {
cacheKey = new Request(cacheUrl.toString(), request);
@@ -74,17 +81,20 @@ export const cacheMiddleware = (): MiddlewareHandler => async (c, next) => {
case 'DELETE':
console.log('Purging cache as requested');
await cache.delete(cacheKey);
- return c.text('');
+ if (returnAsJson) return c.json('');
+ return c.html('');
/* yes, we do give HEAD */
case 'HEAD':
- return c.text('');
+ if (returnAsJson) return c.json('');
+ return c.html('');
/* We properly state our OPTIONS when asked */
case 'OPTIONS':
c.header('allow', Constants.RESPONSE_HEADERS.allow);
c.status(204);
- return c.text('');
+ return;
default:
c.status(405);
- return c.text('');
+ if (returnAsJson) return c.json('');
+ return c.html('');
}
};
diff --git a/src/constants.ts b/src/constants.ts
index 84447c6..2426cab 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -7,18 +7,21 @@ export const Constants = {
INSTANT_VIEW_DOMAINS: INSTANT_VIEW_DOMAINS.split(','),
INSTANT_VIEW_THREADS_DOMAINS: INSTANT_VIEW_THREADS_DOMAINS.split(','),
GALLERY_DOMAINS: GALLERY_DOMAINS.split(','),
+ NATIVE_MULTI_IMAGE_DOMAINS: NATIVE_MULTI_IMAGE_DOMAINS.split(','),
MOSAIC_DOMAIN_LIST: MOSAIC_DOMAIN_LIST.split(','),
API_HOST_LIST: API_HOST_LIST.split(','),
HOST_URL: HOST_URL,
EMBED_URL: EMBED_URL,
REDIRECT_URL: REDIRECT_URL,
RELEASE_NAME: RELEASE_NAME,
+ GIF_TRANSCODE_DOMAIN: GIF_TRANSCODE_DOMAIN,
API_DOCS_URL: `https://github.com/dangeredwolf/FixTweet/wiki/API-Home`,
TWITTER_ROOT: 'https://twitter.com',
TWITTER_GLOBAL_NAME_ROOT: 'twitter.com',
TWITTER_API_ROOT: 'https://api.twitter.com',
+ TWITTER_VIDEO_BASE: 'https://video.twimg.com',
BOT_UA_REGEX:
- /bot|facebook|embed|got|firefox\/92|firefox\/38|curl|wget|go-http|yahoo|generator|whatsapp|revoltchat|preview|link|proxy|vkshare|images|analyzer|index|crawl|spider|python|cfnetwork|node|mastodon|http\.rb|ruby|bun\/|fiddler/gi,
+ /bot|facebook|embed|got|firefox\/92|firefox\/38|curl|wget|go-http|yahoo|generator|whatsapp|revoltchat|preview|link|proxy|vkshare|images|analyzer|index|crawl|spider|python|cfnetwork|node|mastodon|http\.rb|ruby|bun\/|fiddler|iframely/gi,
/* 3 hours */
GUEST_TOKEN_MAX_AGE: 3 * 60 * 60,
GUEST_BEARER_TOKEN: `Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA`,
diff --git a/src/embed/status.ts b/src/embed/status.ts
index 883df3b..6f2a793 100644
--- a/src/embed/status.ts
+++ b/src/embed/status.ts
@@ -8,6 +8,7 @@ import { renderPhoto } from '../render/photo';
import { renderVideo } from '../render/video';
import { renderInstantView } from '../render/instantview';
import { constructTwitterThread } from '../providers/twitter/conversation';
+import { Experiment, experimentCheck } from '../experiments';
export const returnError = (c: Context, error: string): Response => {
return c.html(
@@ -97,6 +98,7 @@ export const handleStatus = async (
}
const isTelegram = (userAgent || '').indexOf('Telegram') > -1;
+ const isDiscord = (userAgent || '').indexOf('Discord') > -1;
/* Should sensitive statuses be allowed Instant View? */
let useIV =
isTelegram /*&& !status.possibly_sensitive*/ &&
@@ -277,7 +279,7 @@ export const handleStatus = async (
/* This status has a video to render. */
break;
}
- } else if (media?.videos) {
+ } else if (media?.videos && !flags.nativeMultiImage) {
const instructions = renderVideo(
{ status: status, userAgent: userAgent, text: newText },
media.videos[0]
@@ -290,16 +292,40 @@ export const handleStatus = async (
siteName = instructions.siteName;
}
} else if (media?.mosaic) {
- const instructions = renderPhoto(
- {
- status: status,
- authorText: authorText,
- engagementText: engagementText,
- userAgent: userAgent
- },
- media.mosaic
- );
- headers.push(...instructions.addHeaders);
+ if (
+ experimentCheck(Experiment.DISCORD_NATIVE_MULTI_IMAGE, isDiscord) &&
+ flags.nativeMultiImage
+ ) {
+ const photos = status.media?.photos || [];
+
+ photos.forEach(photo => {
+ /* Override the card type */
+ status.embed_card = 'summary_large_image';
+ console.log('set embed_card to summary_large_image');
+
+ const instructions = renderPhoto(
+ {
+ status: status,
+ authorText: authorText,
+ engagementText: engagementText,
+ userAgent: userAgent
+ },
+ photo
+ );
+ headers.push(...instructions.addHeaders);
+ });
+ } else {
+ const instructions = renderPhoto(
+ {
+ status: status,
+ authorText: authorText,
+ engagementText: engagementText,
+ userAgent: userAgent
+ },
+ media.mosaic
+ );
+ headers.push(...instructions.addHeaders);
+ }
} else if (media?.photos) {
const instructions = renderPhoto(
{
@@ -312,7 +338,7 @@ export const handleStatus = async (
);
headers.push(...instructions.addHeaders);
}
- if (status.media?.external && !status.media.videos?.length) {
+ if (status.media?.external && !status.media.videos?.length && !flags.nativeMultiImage) {
const { external } = status.media;
authorText = newText || '';
headers.push(
@@ -444,6 +470,20 @@ export const handleStatus = async (
providerEngagementText = Strings.DEFAULT_AUTHOR_TEXT;
}
+ let provider = '';
+ const mediaType = overrideMedia ?? status.media.videos?.[0]?.type;
+
+ if (mediaType === 'gif') {
+ provider = `GIF - ${Constants.BRANDING_NAME}`;
+ } else if (
+ status.embed_card === 'player' &&
+ providerEngagementText !== Strings.DEFAULT_AUTHOR_TEXT
+ ) {
+ provider = providerEngagementText;
+ }
+
+ // Now you can use the 'provider' variable
+
headers.push(
``.format(
{
@@ -454,10 +494,7 @@ export const handleStatus = async (
status: encodeURIComponent(statusId),
author: encodeURIComponent(status.author.screen_name || ''),
name: status.author.name || '',
- provider:
- status.embed_card === 'player' && providerEngagementText !== Strings.DEFAULT_AUTHOR_TEXT
- ? `&provider=${encodeURIComponent(providerEngagementText)}`
- : ''
+ provider: provider ? `&provider=${encodeURIComponent(provider)}` : ''
}
)
);
diff --git a/src/experiments.ts b/src/experiments.ts
index 83127c1..0b16983 100644
--- a/src/experiments.ts
+++ b/src/experiments.ts
@@ -2,7 +2,9 @@ export enum Experiment {
IV_FORCE_THREAD_UNROLL = 'IV_FORCE_THREAD_UNROLL',
ELONGATOR_BY_DEFAULT = 'ELONGATOR_BY_DEFAULT',
ELONGATOR_PROFILE_API = 'ELONGATOR_PROFILE_API',
- TWEET_DETAIL_API = 'TWEET_DETAIL_API'
+ TWEET_DETAIL_API = 'TWEET_DETAIL_API',
+ DISCORD_NATIVE_MULTI_IMAGE = 'DISCORD_NATIVE_MULTI_IMAGE',
+ TRANSCODE_GIFS = 'TRANSCODE_GIFS'
}
type ExperimentConfig = {
@@ -31,6 +33,16 @@ const Experiments: { [key in Experiment]: ExperimentConfig } = {
name: 'Tweet detail API',
description: 'Use Tweet Detail API (where available with elongator)',
percentage: 0.75
+ },
+ [Experiment.DISCORD_NATIVE_MULTI_IMAGE]: {
+ name: 'Discord native multi-image',
+ description: 'Use Discord native multi-image',
+ percentage: 1
+ },
+ [Experiment.TRANSCODE_GIFS]: {
+ name: 'Transcode GIFs',
+ description: 'Transcode GIFs for Discord, etc.',
+ percentage: 1
}
};
diff --git a/src/fetch.ts b/src/fetch.ts
index 0581362..26462ac 100644
--- a/src/fetch.ts
+++ b/src/fetch.ts
@@ -59,11 +59,11 @@ export const twitterFetch = async (
}
);
- const cache = caches.default;
+ const cache = typeof caches !== 'undefined' ? caches.default : null;
while (apiAttempts < API_ATTEMPTS) {
/* Generate a random CSRF token, Twitter just cares that header and cookie match,
- REST can use shorter csrf tokens (32 bytes) but graphql prefers 160 bytes */
+ REST can use shorter csrf tokens (32 bytes) but graphql uses a 160 byte one. */
const csrfToken = crypto.randomUUID().replace(/-/g, '');
const headers: Record = {
@@ -75,7 +75,12 @@ export const twitterFetch = async (
let activate: Response | null = null;
- if (!newTokenGenerated && !useElongator) {
+ if (cache === null) {
+ console.log('Caching unavailable, requesting new token');
+ newTokenGenerated = true;
+ }
+
+ if (!newTokenGenerated && !useElongator && cache) {
const timeBefore = performance.now();
const cachedResponse = await cache.match(guestTokenRequestCacheDummy.clone());
const timeAfter = performance.now();
@@ -138,13 +143,12 @@ export const twitterFetch = async (
if (useElongator && typeof c.env?.TwitterProxy !== 'undefined') {
console.log('Fetching using elongator');
const performanceStart = performance.now();
- apiRequest = await withTimeout(
- (signal: AbortSignal) =>
- c.env?.TwitterProxy.fetch(url, {
- method: 'GET',
- headers: headers,
- signal: signal
- })
+ apiRequest = await withTimeout((signal: AbortSignal) =>
+ c.env?.TwitterProxy.fetch(url, {
+ method: 'GET',
+ headers: headers,
+ signal: signal
+ })
);
const performanceEnd = performance.now();
console.log(`Elongator request successful after ${performanceEnd - performanceStart}ms`);
@@ -173,6 +177,7 @@ export const twitterFetch = async (
}
try {
!useElongator &&
+ cache &&
c.executionCtx &&
c.executionCtx.waitUntil(
cache.delete(guestTokenRequestCacheDummy.clone(), { ignoreMethod: true })
@@ -208,6 +213,7 @@ export const twitterFetch = async (
console.log(`Purging token on this edge due to low rate limit remaining`);
try {
c.executionCtx &&
+ cache &&
c.executionCtx.waitUntil(
cache.delete(guestTokenRequestCacheDummy.clone(), { ignoreMethod: true })
);
@@ -232,7 +238,7 @@ export const twitterFetch = async (
}
try {
/* If we've generated a new token, we'll cache it */
- if (c.executionCtx && newTokenGenerated && activate) {
+ if (c.executionCtx && newTokenGenerated && activate && cache) {
const cachingResponse = new Response(await activate.clone().text(), {
headers: {
...tokenHeaders,
diff --git a/src/helpers/card.ts b/src/helpers/card.ts
index 8df5c89..973ae58 100644
--- a/src/helpers/card.ts
+++ b/src/helpers/card.ts
@@ -3,7 +3,11 @@ import { calculateTimeLeftString } from './pollTime';
/* Renders card for polls and non-Twitter video embeds (i.e. YouTube) */
export const renderCard = (
card: GraphQLTwitterStatus['card']
-): { poll?: APIPoll; external_media?: APIExternalMedia } => {
+): {
+ poll?: APIPoll;
+ external_media?: APIExternalMedia;
+ media?: { videos: TweetMedia[]; photos: TweetMedia[] };
+} => {
if (!Array.isArray(card.legacy?.binding_values)) {
return {};
}
@@ -58,5 +62,37 @@ export const renderCard = (
};
}
+ if (binding_values.unified_card?.string_value) {
+ try {
+ const card = JSON.parse(binding_values.unified_card.string_value);
+ const mediaEntities = card?.media_entities as Record;
+
+ if (mediaEntities) {
+ const media = {
+ videos: [] as TweetMedia[],
+ photos: [] as TweetMedia[]
+ };
+ Object.keys(mediaEntities).forEach(key => {
+ const mediaItem = mediaEntities[key];
+ switch (mediaItem.type) {
+ case 'photo':
+ media.photos.push(mediaItem);
+ break;
+ case 'animated_gif':
+ case 'video':
+ media.videos.push(mediaItem);
+ break;
+ }
+ });
+
+ console.log('media', media);
+
+ return { media: media };
+ }
+ } catch (e) {
+ console.error('Failed to parse unified card JSON', e);
+ }
+ }
+
return {};
};
diff --git a/src/helpers/media.ts b/src/helpers/media.ts
index b1e4b84..8dd78c7 100644
--- a/src/helpers/media.ts
+++ b/src/helpers/media.ts
@@ -1,5 +1,7 @@
+import { Context } from 'hono';
+
/* Help populate API response for media */
-export const processMedia = (media: TweetMedia): APIPhoto | APIVideo | null => {
+export const processMedia = (c: Context, media: TweetMedia): APIPhoto | APIVideo | null => {
if (media.type === 'photo') {
return {
type: 'photo',
@@ -10,9 +12,27 @@ export const processMedia = (media: TweetMedia): APIPhoto | APIVideo | null => {
};
} else if (media.type === 'video' || media.type === 'animated_gif') {
/* Find the variant with the highest bitrate */
- const bestVariant = media.video_info?.variants?.reduce?.((a, b) =>
- (a.bitrate ?? 0) > (b.bitrate ?? 0) ? a : b
- );
+ const bestVariant = media.video_info?.variants
+ ?.filter?.(format => {
+ if (c.req.header('user-agent')?.includes('Telegram') && format.bitrate) {
+ /* Telegram doesn't support videos over 20 MB, so we need to filter them out */
+ const bitrate = format.bitrate || 0;
+ const length = (media.video_info?.duration_millis || 0) / 1000;
+ /* Calculate file size in bytes */
+ const fileSizeBytes: number = (bitrate * length) / 8;
+ /* Convert file size to megabytes (MB) */
+ const fileSizeMB: number = fileSizeBytes / (1024 * 1024);
+
+ console.log(
+ `Estimated file size: ${fileSizeMB.toFixed(2)} MB for bitrate ${bitrate / 1000} kbps`
+ );
+ return (
+ fileSizeMB < 30
+ ); /* Currently this calculation is off, so we'll just do it if it's way over */
+ }
+ return !format.url.includes('hevc');
+ })
+ .reduce?.((a, b) => ((a.bitrate ?? 0) > (b.bitrate ?? 0) ? a : b));
return {
url: bestVariant?.url || '',
thumbnail_url: media.media_url_https,
@@ -20,7 +40,8 @@ export const processMedia = (media: TweetMedia): APIPhoto | APIVideo | null => {
width: media.original_info?.width,
height: media.original_info?.height,
format: bestVariant?.content_type || '',
- type: media.type === 'animated_gif' ? 'gif' : 'video'
+ type: media.type === 'animated_gif' ? 'gif' : 'video',
+ variants: media.video_info?.variants ?? []
};
}
return null;
diff --git a/src/helpers/translate.ts b/src/helpers/translate.ts
index 687bf83..38110fc 100644
--- a/src/helpers/translate.ts
+++ b/src/helpers/translate.ts
@@ -64,13 +64,12 @@ export const translateStatus = async (
tweet.rest_id ?? tweet.legacy?.id_str
},destinationLanguage=None,translationSource=Some(Google),feature=None,timeout=None,onlyCached=None/translation/service/translateTweet`;
console.log(url, headers);
- translationApiResponse = (await withTimeout(
- (signal: AbortSignal) =>
- c.env?.TwitterProxy.fetch(url, {
- method: 'GET',
- headers: headers,
- signal: signal
- })
+ translationApiResponse = (await withTimeout((signal: AbortSignal) =>
+ c.env?.TwitterProxy.fetch(url, {
+ method: 'GET',
+ headers: headers,
+ signal: signal
+ })
)) as Response;
translationResults = (await translationApiResponse.json()) as TranslationPartial;
diff --git a/src/helpers/useragent.ts b/src/helpers/useragent.ts
index 2315d7e..78619ed 100644
--- a/src/helpers/useragent.ts
+++ b/src/helpers/useragent.ts
@@ -1,6 +1,6 @@
/* We keep this value up-to-date for making our requests to Twitter as
indistinguishable from normal user traffic as possible. */
-const fakeChromeVersion = 120;
+const fakeChromeVersion = 124;
const platformWindows = 'Windows NT 10.0; Win64; x64';
const platformMac = 'Macintosh; Intel Mac OS X 10_15_7';
const platformLinux = 'X11; Linux x86_64';
diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts
index 7827bbf..1505cbe 100644
--- a/src/helpers/utils.ts
+++ b/src/helpers/utils.ts
@@ -58,11 +58,11 @@ export async function withTimeout(
}
export const formatNumber = (num: number) => {
- if (num >= 1e6) {
- return (num / 1e6).toFixed(2) + 'M';
- } else if (num >= 1e3) {
- return (num / 1e3).toFixed(1) + 'K';
- } else {
- return num.toString();
- }
-};
\ No newline at end of file
+ if (num >= 1e6) {
+ return (num / 1e6).toFixed(2) + 'M';
+ } else if (num >= 1e3) {
+ return (num / 1e3).toFixed(1) + 'K';
+ } else {
+ return num.toString();
+ }
+};
diff --git a/src/providers/twitter/conversation.ts b/src/providers/twitter/conversation.ts
index c7bfe43..3119b44 100644
--- a/src/providers/twitter/conversation.ts
+++ b/src/providers/twitter/conversation.ts
@@ -5,6 +5,36 @@ import { Experiment, experimentCheck } from '../../experiments';
import { isGraphQLTwitterStatus } from '../../helpers/graphql';
import { Context } from 'hono';
+const writeDataPoint = (
+ c: Context,
+ language: string | undefined,
+ nsfw: boolean | null,
+ returnCode: string,
+ flags?: InputFlags
+) => {
+ console.log('Writing data point...');
+ if (typeof c.env?.AnalyticsEngine !== 'undefined') {
+ const flagString =
+ Object.keys(flags || {})
+ // @ts-expect-error - TypeScript doesn't like iterating over the keys, but that's OK
+ .filter(flag => flags?.[flag])[0] || 'standard';
+
+ console.log(flagString);
+
+ c.env?.AnalyticsEngine.writeDataPoint({
+ blobs: [
+ c.req.raw.cf?.colo as string /* Datacenter location */,
+ c.req.raw.cf?.country as string /* Country code */,
+ c.req.header('user-agent') ?? '' /* User agent (for aggregating bots calling) */,
+ returnCode /* Return code */,
+ flagString /* Type of request */,
+ language ?? '' /* For translate feature */
+ ],
+ doubles: [nsfw ? 1 : 0 /* NSFW media = 1, No NSFW Media = 0 */]
+ });
+ }
+};
+
export const fetchTweetDetail = async (
c: Context,
status: string,
@@ -304,6 +334,7 @@ export const constructTwitterThread = async (
console.log('response', response);
if (!response?.data) {
+ writeDataPoint(c, language, null, '404');
return { status: null, thread: null, author: null, code: 404 };
}
}
@@ -316,19 +347,23 @@ export const constructTwitterThread = async (
const result = response?.data?.tweetResult?.result as GraphQLTwitterStatus;
if (typeof result === 'undefined') {
+ writeDataPoint(c, language, null, '404');
return { status: null, thread: null, author: null, code: 404 };
}
const buildStatus = await buildAPITwitterStatus(c, result, language, null, legacyAPI);
if ((buildStatus as FetchResults)?.status === 401) {
+ writeDataPoint(c, language, null, '401');
return { status: null, thread: null, author: null, code: 401 };
} else if (buildStatus === null || (buildStatus as FetchResults)?.status === 404) {
+ writeDataPoint(c, language, null, '404');
return { status: null, thread: null, author: null, code: 404 };
}
status = buildStatus as APITwitterStatus;
+ writeDataPoint(c, language, status.possibly_sensitive, '200');
return { status: status, thread: null, author: status.author, code: 200 };
}
@@ -339,6 +374,7 @@ export const constructTwitterThread = async (
/* Don't bother processing thread on a null tweet */
if (originalStatus === null) {
+ writeDataPoint(c, language, null, '404');
return { status: null, thread: null, author: null, code: 404 };
}
@@ -351,6 +387,7 @@ export const constructTwitterThread = async (
)) as APITwitterStatus;
if (status === null) {
+ writeDataPoint(c, language, null, '404');
return { status: null, thread: null, author: null, code: 404 };
}
@@ -358,6 +395,7 @@ export const constructTwitterThread = async (
/* If we're not processing threads, let's be done here */
if (!processThread) {
+ writeDataPoint(c, language, status.possibly_sensitive, '200');
return { status: status, thread: null, author: author, code: 200 };
}
diff --git a/src/providers/twitter/processor.ts b/src/providers/twitter/processor.ts
index 20bfb88..fefe4f7 100644
--- a/src/providers/twitter/processor.ts
+++ b/src/providers/twitter/processor.ts
@@ -183,7 +183,7 @@ export const buildAPITwitterStatus = async (
/* Populate status media */
mediaList.forEach(media => {
- const mediaObject = processMedia(media);
+ const mediaObject = processMedia(c, media);
if (mediaObject) {
apiStatus.media.all = apiStatus.media?.all ?? [];
apiStatus.media?.all?.push(mediaObject);
@@ -242,6 +242,31 @@ export const buildAPITwitterStatus = async (
if (card.poll) {
apiStatus.poll = card.poll;
}
+ /* TODO: Right now, we push them after native photos and videos but should we prepend them instead? */
+ if (card.media) {
+ if (card.media.videos) {
+ card.media.videos.forEach(video => {
+ const mediaObject = processMedia(c, video) as APIVideo;
+ if (mediaObject) {
+ apiStatus.media.all = apiStatus.media?.all ?? [];
+ apiStatus.media?.all?.push(mediaObject);
+ apiStatus.media.videos = apiStatus.media?.videos ?? [];
+ apiStatus.media.videos?.push(mediaObject);
+ }
+ });
+ }
+ if (card.media.photos) {
+ card.media.photos.forEach(photo => {
+ const mediaObject = processMedia(c, photo) as APIPhoto;
+ if (mediaObject) {
+ apiStatus.media.all = apiStatus.media?.all ?? [];
+ apiStatus.media?.all?.push(mediaObject);
+ apiStatus.media.photos = apiStatus.media?.photos ?? [];
+ apiStatus.media.photos?.push(mediaObject);
+ }
+ });
+ }
+ }
} else {
/* Determine if the status contains a YouTube link (either youtube.com or youtu.be) so we can include it */
const youtubeIdRegex = /(https?:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([^\s&]+)/;
diff --git a/src/realms/api/hit.ts b/src/realms/api/hit.ts
new file mode 100644
index 0000000..4d8db8e
--- /dev/null
+++ b/src/realms/api/hit.ts
@@ -0,0 +1,15 @@
+import { Context } from 'hono';
+
+export const linkHitRequest = async (c: Context) => {
+ // eslint-disable-next-line sonarjs/no-duplicate-string
+ const userAgent = c.req.header('User-Agent') || '';
+
+ if (userAgent.includes('Telegram')) {
+ c.status(403);
+ }
+ // If param `url` exists, 302 redirect to it
+ if (typeof c.req.query('url') === 'string') {
+ const url = new URL(c.req.query('url') as string);
+ return c.redirect(url.href, 302);
+ }
+};
diff --git a/src/realms/api/router.ts b/src/realms/api/router.ts
index 6816dc5..da08d56 100644
--- a/src/realms/api/router.ts
+++ b/src/realms/api/router.ts
@@ -3,6 +3,7 @@ import { statusRequest } from '../twitter/routes/status';
import { profileRequest } from '../twitter/routes/profile';
import { Strings } from '../../strings';
import { Constants } from '../../constants';
+import { linkHitRequest } from './hit';
export const api = new Hono();
@@ -16,6 +17,9 @@ api.use('*', async (c, next) => {
}
await next();
});
+
+api.get('/2/hit', linkHitRequest);
+
/* Current v1 API endpoints. Currently, these still go through the Twitter embed requests. API v2+ won't do this. */
api.get('/status/:id', statusRequest);
api.get('/status/:id/', statusRequest);
diff --git a/src/realms/twitter/router.ts b/src/realms/twitter/router.ts
index 3f79666..0d50a59 100644
--- a/src/realms/twitter/router.ts
+++ b/src/realms/twitter/router.ts
@@ -98,9 +98,13 @@ twitter.get('/owoembed', oembed);
twitter.get('/robots.txt', async c => c.text(Strings.ROBOTS_TXT));
twitter.get('/i/events/:id', genericTwitterRedirect);
+twitter.get('/i/trending/:id', genericTwitterRedirect);
twitter.get('/hashtag/:hashtag', genericTwitterRedirect);
twitter.get('/:handle/', _profileRequest);
twitter.get('/:handle', _profileRequest);
+/* Redirect profile subpages in case someone links them for some reason (https://github.com/FixTweet/FxTwitter/issues/603) */
+twitter.get('/:handle/:subpage', genericTwitterRedirect);
+twitter.get('/:handle/:subpage/', genericTwitterRedirect);
twitter.all('*', async c => c.redirect(Constants.REDIRECT_URL, 302));
diff --git a/src/realms/twitter/routes/status.ts b/src/realms/twitter/routes/status.ts
index 4138e70..e70b32f 100644
--- a/src/realms/twitter/routes/status.ts
+++ b/src/realms/twitter/routes/status.ts
@@ -44,7 +44,7 @@ export const statusRequest = async (c: Context) => {
Also note that all we're doing here is setting the direct flag. If someone
links a video and ends it with .jpg, it will still redirect to a .mp4! */
- if (url.pathname.match(/\/status(es)?\/\d{2,20}\.(mp4|png|jpe?g)/g)) {
+ if (url.pathname.match(/\/status(es)?\/\d{2,20}\.(mp4|png|jpe?g|gifv?)/g)) {
console.log('Direct media request by extension');
flags.direct = true;
} else if (Constants.DIRECT_MEDIA_DOMAINS.includes(url.hostname)) {
@@ -63,6 +63,9 @@ export const statusRequest = async (c: Context) => {
} else if (Constants.GALLERY_DOMAINS.includes(url.hostname)) {
console.log('Gallery embed request');
flags.gallery = true;
+ } else if (Constants.NATIVE_MULTI_IMAGE_DOMAINS.includes(url.hostname)) {
+ console.log('Force native multi-image');
+ flags.nativeMultiImage = true;
} else if (prefix === 'dl' || prefix === 'dir') {
console.log('Direct media request by path prefix');
flags.direct = true;
diff --git a/src/render/instantview.ts b/src/render/instantview.ts
index 5725519..d11b8be 100644
--- a/src/render/instantview.ts
+++ b/src/render/instantview.ts
@@ -64,9 +64,9 @@ const formatDate = (date: Date): string => {
};
const htmlifyLinks = (input: string): string => {
- const urlPattern = /\bhttps?:\/\/\S+/g;
+ const urlPattern = /\bhttps?:\/\/[\w.-]+\.\w+[/\w.-]*\w/g;
return input.replace(urlPattern, url => {
- return `${url}`;
+ return `${url}`;
});
};
@@ -129,6 +129,23 @@ const generateInlineAuthorHeader = (status: APIStatus, author: APIUser, authorAc
});
}
+const wrapForeignLinks = (url: string) => {
+ let unwrap = false;
+ const whitelistedDomains = ['twitter.com', 'x.com', 't.me', 'telegram.me'];
+ try {
+ const urlObj = new URL(url);
+
+ if (!whitelistedDomains.includes(urlObj.hostname)) {
+ unwrap = true;
+ }
+ } catch (error) {
+ unwrap = true;
+ }
+
+ return unwrap
+ ? `https://${Constants.API_HOST_LIST[0]}/2/hit?url=${encodeURIComponent(url)}`
+ : url;
+};
const generateStatusFooter = (status: APIStatus, isQuote = false, author: APIUser): string => {
let description = author.description;
@@ -164,7 +181,7 @@ const generateStatusFooter = (status: APIStatus, isQuote = false, author: APIUse
}'s profile picture" />`,
location: author.location ? `📌 ${author.location}` : '',
website: author.website
- ? `🔗 ${author.website.display_url}`
+ ? `🔗 ${author.website.display_url}`
: '',
joined: author.joined ? `📆 ${formatDate(new Date(author.joined))}` : '',
following: truncateSocialCount(author.following),
diff --git a/src/render/video.ts b/src/render/video.ts
index 065cc87..a07a867 100644
--- a/src/render/video.ts
+++ b/src/render/video.ts
@@ -1,4 +1,5 @@
import { Constants } from '../constants';
+import { Experiment, experimentCheck } from '../experiments';
import { handleQuote } from '../helpers/quote';
import { Strings } from '../strings';
@@ -47,14 +48,28 @@ export const renderVideo = (
instructions.authorText += `\n${handleQuote(status.quote)}`;
}
+ let url = video.url;
+
+ if (
+ experimentCheck(Experiment.TRANSCODE_GIFS, !!Constants.GIF_TRANSCODE_DOMAIN) &&
+ !userAgent?.includes('Telegram') &&
+ video.type === 'gif'
+ ) {
+ url = video.url.replace(
+ Constants.TWITTER_VIDEO_BASE,
+ `https://${Constants.GIF_TRANSCODE_DOMAIN}`
+ );
+ console.log('We passed checks for transcoding GIFs, feeding embed url', url);
+ }
+
/* Push the raw video-related headers */
instructions.addHeaders = [
``,
``,
- ``,
+ ``,
``,
- ``,
- ``,
+ ``,
+ ``,
``,
``,
``,
diff --git a/src/types/env.d.ts b/src/types/env.d.ts
index 111de5f..7a02d4a 100644
--- a/src/types/env.d.ts
+++ b/src/types/env.d.ts
@@ -5,11 +5,13 @@ declare const TEXT_ONLY_DOMAINS: string;
declare const INSTANT_VIEW_DOMAINS: string;
declare const INSTANT_VIEW_THREADS_DOMAINS: string;
declare const GALLERY_DOMAINS: string;
+declare const NATIVE_MULTI_IMAGE_DOMAINS: string;
declare const HOST_URL: string;
declare const EMBED_URL: string;
declare const REDIRECT_URL: string;
declare const MOSAIC_DOMAIN_LIST: string;
declare const API_HOST_LIST: string;
+declare const GIF_TRANSCODE_DOMAIN: string;
declare const SENTRY_DSN: string;
declare const RELEASE_NAME: string;
diff --git a/src/types/types.d.ts b/src/types/types.d.ts
index 6a9c2d4..cc1e635 100644
--- a/src/types/types.d.ts
+++ b/src/types/types.d.ts
@@ -11,6 +11,7 @@ type InputFlags = {
instantViewUnrollThreads?: boolean;
archive?: boolean;
gallery?: boolean;
+ nativeMultiImage?: boolean;
};
interface StatusResponse {
@@ -102,6 +103,7 @@ interface APIVideo extends APIMedia {
thumbnail_url: string;
format: string;
duration: number;
+ variants: TweetMediaFormat[];
}
interface APIMosaicPhoto extends APIMedia {
diff --git a/src/types/vendor/twitter.d.ts b/src/types/vendor/twitter.d.ts
index 6d3cbee..3a589f5 100644
--- a/src/types/vendor/twitter.d.ts
+++ b/src/types/vendor/twitter.d.ts
@@ -440,7 +440,8 @@ type GraphQLTwitterStatus = {
| 'last_updated_datetime_utc'
| 'duration_minutes'
| 'api'
- | 'card_url';
+ | 'card_url'
+ | 'unified_card';
value:
| {
string_value: string; // "Option text"
diff --git a/src/worker.ts b/src/worker.ts
index e20dbf4..3d5ab74 100644
--- a/src/worker.ts
+++ b/src/worker.ts
@@ -10,7 +10,8 @@ import { twitter } from './realms/twitter/router';
import { cacheMiddleware } from './caches';
const noCache = 'max-age=0, no-cache, no-store, must-revalidate';
-const embeddingClientRegex = /(discordbot|telegrambot|facebook|whatsapp|firefox\/92|vkshare|revoltchat|preview)/gi;
+const embeddingClientRegex =
+ /(discordbot|telegrambot|facebook|whatsapp|firefox\/92|vkshare|revoltchat|preview|iframely)/gi;
/* This is the root app which contains route trees for multiple "realms".