Use generated data for plugin list

This commit is contained in:
Niels van Velzen
2023-12-18 19:13:25 +01:00
parent 102ff406b8
commit 8c3adc6d53
10 changed files with 115941 additions and 295 deletions
+3 -256
View File
@@ -39,263 +39,10 @@ All plugins hosted on the repository can be built from source and manually added
## List
### Official Plugins
import { Plugins } from '../../../../src/data/plugins';
import PluginList from '../../../../src/components/plugins/PluginList';
#### Metadata Plugins
Manage your Anime in Jellyfin with several different metadata providers and options for organizing your collection.
##### Anilist
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-anilist.svg)](https://github.com/jellyfin/jellyfin-plugin-anilist)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-anilist.svg)](https://github.com/jellyfin/jellyfin-plugin-anilist)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-anilist.svg)](https://github.com/jellyfin/jellyfin-plugin-anilist)
Provides metadata support from [Anilist](https://anilist.co/).
**Link:**
- [Github](https://github.com/jellyfin/jellyfin-plugin-anilist)
##### Anidb
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-anidb.svg)](https://github.com/jellyfin/jellyfin-plugin-anidb)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-anidb.svg)](https://github.com/jellyfin/jellyfin-plugin-anidb)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-anidb.svg)](https://github.com/jellyfin/jellyfin-plugin-anidb)
Provides metadata support from [Anidb](https://anidb.net/).
**Link:**
- [Github](https://github.com/jellyfin/jellyfin-plugin-anidb)
##### Anisearch
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-anisearch.svg)](https://github.com/jellyfin/jellyfin-plugin-anisearch)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-anisearch.svg)](https://github.com/jellyfin/jellyfin-plugin-anisearch)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-anisearch.svg)](https://github.com/jellyfin/jellyfin-plugin-anisearch)
Provides metadata support from [Anisearch](https://www.anisearch.com/).
**Link:**
- [Github](https://github.com/jellyfin/jellyfin-plugin-anisearch)
##### Bookshelf
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-bookshelf.svg)](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-bookshelf.svg)](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-bookshelf.svg)](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
Supports several different metadata providers and options for organizing your collection.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-bookshelf)
##### Kitsu
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-kitsu.svg)](https://github.com/jellyfin/jellyfin-plugin-kitsu)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-kitsu.svg)](https://github.com/jellyfin/jellyfin-plugin-kitsu)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-kitsu.svg)](https://github.com/jellyfin/jellyfin-plugin-kitsu)
Provides metadata support from [Kitsu](https://kitsu.io/).
- [Github](https://github.com/jellyfin/jellyfin-plugin-kitsu)
#### Fanart
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-fanart.svg)](https://github.com/jellyfin/jellyfin-plugin-fanart)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-fanart.svg)](https://github.com/jellyfin/jellyfin-plugin-fanart)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-fanart.svg)](https://github.com/jellyfin/jellyfin-plugin-fanart)
Scrape poster images for movies, shows, and artists in your library from [fanart.tv](https://fanart.tv).
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-fanart)
#### Kodi Sync Queue
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-kodisyncqueue.svg)](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-kodisyncqueue.svg)](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-kodisyncqueue.svg)](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
Helps keep Jellyfin for Kodi in sync with the library without needing to run periodic full scans.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-kodisyncqueue)
#### LDAP
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-ldapauth.svg)](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-ldapauth.svg)](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-ldapauth.svg)](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
Authenticate your Jellyfin users against an LDAP database, and optionally create users who do not yet exist automatically. Allows the administrator to customize most aspects of the LDAP authentication process, including customizable search attributes, username attribute, and a search filter for administrative users (set on user creation). The user, via the "Manual Login" process, can enter any valid attribute value, which will be mapped back to the specified username attribute automatically as well.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-ldapauth)
#### NextPVR
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-nextpvr.svg)](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-nextpvr.svg)](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-nextpvr.svg)](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
Provides access to Live TV, Program Guide, and Recordings from [NextPVR](https://www.nextpvr.com/).
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-nextpvr)
#### [Open Subtitles](/docs/general/server/plugins/open-subtitles)
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-opensubtitles.svg)](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-opensubtitles.svg)](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-opensubtitles.svg)](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
Download subtitles from the internet to use with your media files from [Open Subtitles](https://www.opensubtitles.org/). You can configure the languages it downloads on a per-library basis.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-opensubtitles)
#### Playback Reporting
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-playbackreporting.svg)](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-playbackreporting.svg)](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-playbackreporting.svg)](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
Collect and show user playback statistics, such as total time watched, media watched, time of day watched, and time of week watched. Can keep information for as long as you want or can cull older information automatically. Also allows you to manually query the data collected so you can generate your own reports.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-playbackreporting)
#### Reports
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-reports.svg)](https://github.com/jellyfin/jellyfin-plugin-reports)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-reports.svg)](https://github.com/jellyfin/jellyfin-plugin-reports)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-reports.svg)](https://github.com/jellyfin/jellyfin-plugin-reports)
Generate reports of your media library.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-reports)
#### TMDb Box Sets
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-tmdbboxsets.svg)](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-tmdbboxsets.svg)](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-tmdbboxsets.svg)](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
Automatically create movie box sets based on TMDb collections. Configurable minimum number of films to be considered a boxset. Boxsets are created as collections and includes a scheduled task to ensure that new media is automatically put into boxsets.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
#### Trakt
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-trakt.svg)](https://github.com/jellyfin/jellyfin-plugin-trakt)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-trakt.svg)](https://github.com/jellyfin/jellyfin-plugin-trakt)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-trakt.svg)](https://github.com/jellyfin/jellyfin-plugin-trakt)
Record your watched media with [Trakt](https://trakt.tv).
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-trakt)
#### TVHeadend
[![Language](https://img.shields.io/github/languages/top/jellyfin/jellyfin-plugin-tvheadend.svg)](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
[![Contributors](https://img.shields.io/github/contributors/jellyfin/jellyfin-plugin-tvheadend.svg)](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
[![License](https://img.shields.io/github/license/jellyfin/jellyfin-plugin-tvheadend.svg)](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
Manage TVHeadEnd from Jellyfin. Click [here](/docs/general/server/plugins/tvheadend) for plugin support.
**Links:**
- [GitHub](https://github.com/jellyfin/jellyfin-plugin-tvheadend)
### 3rd-Party Plugins
#### Ani-Sync
Ani-Sync lets you synchronize/scrobble your Jellyfin Anime watch progress to popular services like MyAnimeList, AniList, Kitsu.
**Links:**
- [GitHub](https://github.com/vosmiic/jellyfin-ani-sync)
#### Intros
Download flashy intros from prerolls.video for your movies.
**Links:**
- [GitHub](https://github.com/dkanada/jellyfin-plugin-intros)
#### Kinopoisk metadata plugin
Fetches metadata from [https://kinopoisk.ru](https://kinopoisk.ru). This site is popular in the Russian-speaking community and contains almost no English-language information. Can provide movies and series rating, description, actors and staff, trailers and so on.
**Links:**
- [GitHub](https://github.com/LinFor/jellyfin-plugin-kinopoisk)
#### Last.FM
Enables audio scrobbling to Last.FM as well as a metadata fetcher source.
**Links:**
- [GitHub](https://github.com/jesseward/jellyfin-plugin-lastfm)
#### Merge Versions
Automatically group every repeated movie.
**Links:**
- [GitHub](https://github.com/danieladov/jellyfin-plugin-mergeversions)
#### Shokofin
A plugin to integrate your Shoko database with the Jellyfin media server.
**Links:**
- [GitHub](https://github.com/ShokoAnime/Shokofin)
#### Skin Manager
Download and manage the most popular skins.
**Links:**
- [GitHub](https://github.com/danieladov/jellyfin-plugin-skin-manager)
#### Themerr
Plugin for Jellyfin that adds theme songs to movies using ThemerrDB.
**Links:**
- [GitHub](https://github.com/LizardByte/themerr-jellyfin)
#### YouTube Metadata
Downloads metadata of YouTube videos with a YouTube API key.
**Links:**
- [GitHub](https://github.com/ankenyr/jellyfin-youtube-metadata-plugin)
<PluginList plugins={Plugins} />
## Repositories
+409 -2
View File
@@ -52,6 +52,7 @@
"eslint-plugin-react-hooks": "4.6.0",
"node-fetch": "3.3.2",
"prettier": "3.1.1",
"tsx": "4.6.2",
"typescript": "5.3.3",
"typescript-plugin-css-modules": "5.0.2"
},
@@ -3270,6 +3271,358 @@
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -7517,6 +7870,43 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/esbuild": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.18.20",
"@esbuild/android-arm64": "0.18.20",
"@esbuild/android-x64": "0.18.20",
"@esbuild/darwin-arm64": "0.18.20",
"@esbuild/darwin-x64": "0.18.20",
"@esbuild/freebsd-arm64": "0.18.20",
"@esbuild/freebsd-x64": "0.18.20",
"@esbuild/linux-arm": "0.18.20",
"@esbuild/linux-arm64": "0.18.20",
"@esbuild/linux-ia32": "0.18.20",
"@esbuild/linux-loong64": "0.18.20",
"@esbuild/linux-mips64el": "0.18.20",
"@esbuild/linux-ppc64": "0.18.20",
"@esbuild/linux-riscv64": "0.18.20",
"@esbuild/linux-s390x": "0.18.20",
"@esbuild/linux-x64": "0.18.20",
"@esbuild/netbsd-x64": "0.18.20",
"@esbuild/openbsd-x64": "0.18.20",
"@esbuild/sunos-x64": "0.18.20",
"@esbuild/win32-arm64": "0.18.20",
"@esbuild/win32-ia32": "0.18.20",
"@esbuild/win32-x64": "0.18.20"
}
},
"node_modules/escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -8997,7 +9387,6 @@
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz",
"integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==",
"dev": true,
"peer": true,
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
@@ -15801,7 +16190,6 @@
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"peer": true,
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
@@ -17203,6 +17591,25 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/tsx": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.6.2.tgz",
"integrity": "sha512-QPpBdJo+ZDtqZgAnq86iY/PD2KYCUPSUGIunHdGwyII99GKH+f3z3FZ8XNFLSGQIA4I365ui8wnQpl8OKLqcsg==",
"dev": true,
"dependencies": {
"esbuild": "~0.18.20",
"get-tsconfig": "^4.7.2"
},
"bin": {
"tsx": "dist/cli.mjs"
},
"engines": {
"node": ">=18.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
}
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+3 -1
View File
@@ -18,7 +18,8 @@
"lint": "eslint --ext .ts,.js,.json,.jsx,.tsx .",
"test:blog-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-blog-urls.json",
"test:docs-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-docs-urls.json",
"test:web-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-web-urls.json"
"test:web-urls": "node ./scripts/check-urls.mjs ./scripts/data/jellyfin-web-urls.json",
"update-plugins": "tsx ./scripts/update-plugins.ts"
},
"dependencies": {
"@docusaurus/core": "3.0.1",
@@ -77,6 +78,7 @@
"eslint-plugin-react-hooks": "4.6.0",
"node-fetch": "3.3.2",
"prettier": "3.1.1",
"tsx": "4.6.2",
"typescript": "5.3.3",
"typescript-plugin-css-modules": "5.0.2"
}
+38
View File
@@ -0,0 +1,38 @@
import { AllPluginRepositories, PluginRepository } from '../src/data/pluginRepositories';
import { Plugin } from '../src/data/plugins';
import { writeFile } from 'node:fs/promises';
const OUTPUT_PATH = new URL('../src/data/plugins.generated.json', import.meta.url);
async function getPluginManifest(repository: PluginRepository) {
try {
const response = await fetch(repository.url);
const json = await response.json();
return json;
} catch (cause) {
console.warn(`Failed to retrieve plugin repository ${repository.name} at ${repository.url}`, { cause });
return [];
}
}
async function getPlugins(repositories: Array<PluginRepository>) {
const plugins: { repository: string; plugin: Plugin }[] = [];
for (const repository of repositories) {
const manifest = await getPluginManifest(repository);
for (const plugin of manifest) {
plugins.push({ repository: repository.id, plugin });
}
}
return plugins;
}
async function updatePlugins(repositories = AllPluginRepositories) {
console.log(`Downloading data for ${repositories.length} repositories`);
const plugins = await getPlugins(AllPluginRepositories);
console.log(`Writing ${plugins.length} plugins to ${OUTPUT_PATH}`);
await writeFile(OUTPUT_PATH, JSON.stringify(plugins, null, '\t'));
}
updatePlugins();
+46
View File
@@ -0,0 +1,46 @@
import React from 'react';
import DetailsCard from '../common/DetailsCard';
import { Plugin, PluginWithRepository } from '../../data/plugins';
import { RepositoryById } from '../../data/pluginRepositories';
function PluginDetails({ plugin }: { plugin: Plugin | PluginWithRepository }) {
const repository = 'repository' in plugin ? RepositoryById(plugin.repository) : null;
// TODO: Add filtering?
if (repository.unstable) return;
const targetAbi = plugin.versions.find((version) => version.targetAbi)?.targetAbi ?? null;
const latestVersion = plugin.versions.find((version) => version.sourceUrl && version.version) ?? null;
return (
<DetailsCard
id={plugin.guid}
title={plugin.name}
badges={
<>
{repository.official ? (
<span className='badge badge--primary margin-right--sm'>Official</span>
) : (
<span className='badge badge--secondary margin-right--sm'>Third Party</span>
)}
{repository.unstable && <span className='badge badge--warning margin-right--sm'>Unstable</span>}
<span className='badge badge--secondary margin-right--sm'>{plugin.category}</span>
{targetAbi && <span className='badge badge--secondary margin-right--sm'>{targetAbi}</span>}
</>
}
description={plugin.description}
primaryButtons={[
latestVersion && (
<a key='download' href={latestVersion.sourceUrl} className='button button--primary'>
Download {latestVersion.version}
</a>
)
]}
// description={<pre>{JSON.stringify(plugin, null, '\t')}</pre>}
// footerDetails={<img src={plugin.imageUrl} />}
/>
);
}
export default PluginDetails;
+14
View File
@@ -0,0 +1,14 @@
import React from 'react';
import { Plugin } from '../../data/plugins';
import PluginDetails from './PluginDetails';
const PluginList = ({ plugins }: { plugins: Array<Plugin> }) => (
<>
{plugins.map((plugin) => (
<PluginDetails key={plugin.guid} plugin={plugin} />
))}
</>
);
export default PluginList;
@@ -2,43 +2,34 @@ import React from 'react';
import DetailsCard from '../common/DetailsCard';
import { PluginRepository } from '../../data/pluginRepositories';
import { PluginsForRepository } from '../../data/plugins';
const PluginRepositoryDetails = ({ repository }: { repository: PluginRepository }) => (
<DetailsCard
id={repository.id}
title={repository.name}
badges={
<>
{repository.official ? (
<span className='badge badge--primary margin-right--sm'>Official</span>
) : (
<span className='badge badge--secondary margin-right--sm'>Third Party</span>
)}
{repository.unstable && <span className='badge badge--warning margin-right--sm'>Unstable</span>}
</>
}
description={
<>
<span>Repository URL</span>
<pre>{repository.url}</pre>
function PluginRepositoryDetails({ repository }: { repository: PluginRepository }) {
const plugins = PluginsForRepository(repository.id);
{Object.entries(repository.includes).length > 0 && (
<>
<h4>Includes</h4>
<ul>
{Object.entries(repository.includes).map(([name, url]) => (
<li key={url}>
<a href={url} target='_blank' rel='noreferrer'>
{name}
</a>
</li>
))}
</ul>
</>
)}
</>
}
/>
);
return (
<DetailsCard
id={repository.id}
title={repository.name}
badges={
<>
{repository.official ? (
<span className='badge badge--primary margin-right--sm'>Official</span>
) : (
<span className='badge badge--secondary margin-right--sm'>Third Party</span>
)}
{repository.unstable && <span className='badge badge--warning margin-right--sm'>Unstable</span>}
</>
}
description={
<>
<span>Repository URL</span>
<pre>{repository.url}</pre>
Included plugins: {plugins.map((plugin) => plugin.name).join(', ')}.
</>
}
/>
);
}
export default PluginRepositoryDetails;
+7
View File
@@ -99,3 +99,10 @@ export const ThirdPartyRepositories: Array<PluginRepository> = [
}
}
];
export const AllPluginRepositories: Array<PluginRepository> = [
...OfficialPluginRepositories,
...ThirdPartyRepositories
];
export const RepositoryById = (id: string) => AllPluginRepositories.find((repository) => repository.id === id) ?? null;
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
import GeneratedPlugins from './plugins.generated.json';
export type PluginManifest = Array<Plugin>;
export type Plugin = {
guid: string;
name: string;
description: string;
overview: string;
category: string;
owner: string;
imageUrl?: string;
versions: Array<PluginVersion>;
};
export type PluginWithRepository = Plugin & { repository: string };
export type PluginVersion = {
changelog?: string;
targetAbi?: string;
sourceUrl?: string;
checksum?: string;
timestamp?: string;
version?: string;
};
type GeneratedPlugin = {
repository: string;
plugin: Plugin;
};
export const Plugins: Array<PluginWithRepository> = (GeneratedPlugins as GeneratedPlugin[]).map(
({ repository, plugin }) => ({ ...plugin, repository })
);
export const PluginsForRepository = (repository: string) =>
(GeneratedPlugins as GeneratedPlugin[])
.filter((plugin) => plugin.repository === repository)
.map(({ plugin }) => plugin);