feat(streamystats): add Jellyfin-only Streamystats integration#2923
Merged
Conversation
Settings tab gated to Jellyfin, "View on Streamystats" link plus an inline per-user stats panel in the media modal. Auth reuses the existing jellyfin_api_key. Refactors ExternalServiceSettingsPage to a declarative fields prop (Seerr/Tautulli/Streamystats all migrated) so the shared component no longer carries service-specific branching.
Pairs with the existing error header so the actual diagnosis (timeout, ECONNREFUSED, 404, etc.) is visible in DEBUG logs without changing the user-facing alert text.
After a media-server switch the system enters a brief window where media_server_type is set but credentials aren't yet saved. Background jobs (rule executor → notification cascade) hitting MediaServerFactory in this state threw a generic Error, which NotificationService logged at ERROR level. Detect this transition state explicitly in getService() and throw a typed ServiceUnavailableException. NotificationService treats this exception as transient and logs at DEBUG, keeping the user-facing log quiet while the user finishes configuring the new server.
- Item link format is /servers/<serverId>/library/<itemId>, not
/library/<itemId>. Resolve serverId via /api/servers and cache.
- Add GET /api/streamystats/info endpoint exposing { url, serverId }
so the UI can build correct links from a single source.
- Replace ad-hoc Tailwind tones with Maintainerr brand tokens:
bg-zinc-900/70 card, text-white title, text-error-400, BrandLink
for the panel link.
- Vendor upstream favicon.svg as the badge image (replaces the text
fallback and the temporary PNG).
- Helper text on the settings page now splits example URLs onto
separate lines under the input.
- Drop dead streamystats_url field from the UI ISettings interface;
modal reads /streamystats/info instead.
Verified against upstream apps/nextjs-app/lib/db/items.ts: several
aggregation fields in /api/get-item-details are returned as PostgreSQL
COUNT/EXTRACT strings on the wire, even though Streamystats's
TypeScript interface declares them as number. Confirmed cases:
watchCountByMonth[].{month,year,watchCount,uniqueUsers} (items.ts:675-678)
totalViews (items.ts:232)
usersWatched[].watchCount (items.ts:530)
Only fields explicitly wrapped in Number(...) (totalWatchTime,
completionRate) arrive as numbers. The user's ZodError ("expected
number, received string" on month/year/uniqueUsers) maps directly to
the un-coerced columns.
Switch the affected schema fields to z.coerce.number() so the shared
schema stays robust without depending on upstream patching every
aggregation. The change is a no-op for fields that already arrive as
numbers.
… enforcement Three review findings from the previous round, all addressed: HIGH — Streamystats client lifecycle - StreamystatsApiService.init() now always clears `api` and `resolvedServerId` before the early-return guard, so removing the Streamystats URL actually deactivates /api/streamystats endpoints in-process (controller's `if (!api)` check now matches). - SettingsService.saveJellyfinSettings/removeJellyfinSettings now re-init Streamystats so rotating Jellyfin credentials or wiping Jellyfin propagates to the Streamystats client cache. - removeJellyfinSettings also nulls streamystats_url, since Streamystats can't authenticate without Jellyfin. MEDIUM — Jellyfin-only enforcement is now real, not cosmetic - Settings controller's four Streamystats endpoints (GET/POST/DELETE/ test) and the Streamystats info/items endpoints all assert media_server_type === JELLYFIN; otherwise 403 Forbidden. - Streamystats settings page redirects to /settings/main when the active media server isn't Jellyfin. MEDIUM — Server resolution prefers URL over name - resolveServerId now matches by URL first (trailing-slash-normalised) and falls back to name only when no URL match exists. Avoids the ambiguity where two Streamystats-registered servers share a display name but point at different Jellyfin URLs. Adds four focused tests: - init() clears cached api when settings are removed - URL-first matching beats name-only when both candidates share a name - saveJellyfinSettings re-initialises Streamystats - removeJellyfinSettings clears streamystats_url and re-inits Streamystats
…TS errors - streamystats-api.service.ts: simplify the serverId resolver to compare jellyfin_url against Streamystats's stored url directly. jellyfin_url is already canonicalised by serviceUrlSchema, so the per-service strip was unnecessary scope for this PR. A unified URL-normalization pass across all server-side services can land separately. - MediaModal/index.spec.tsx + EmbyLoginButton.tsx: drive-by fixes for two TypeScript errors the upstream Emby PR left behind (isEmby missing from the useMediaServerType mock, name missing on two InputGroup calls).
Adds Settings/Streamystats/index.spec.tsx with four cases that exercise the Jellyfin-only redirect on direct navigation to /settings/streamystats: - returns null while settings are still loading (no API call fires) - redirects to /settings/main when Plex is active (no API call fires) - redirects to /settings/main when Emby is active (no API call fires) - mounts the form and loads its defaults only when Jellyfin is active The third case directly covers the reviewer-flagged path: a Plex/Emby user typing /settings/streamystats does not leak a 403-backed GET, save or test request — ExternalServiceSettingsPage never mounts. Also restores the trailing-slash strip on the Streamystats serverId resolver so URL matching stays reliable when /api/servers reports a slash-suffixed URL. A broader manual-string-ops refactor of URL trims across the server can land separately.
The Streamystats settings page rendered <div> children inside
ExternalServiceSettingsPage's <p id="url-help">, triggering a React
hydration warning ("<div> cannot be a descendant of <p>"). Replaced
the inner <div>s with text + <br /> + <span> wrappers so the markup
stays phrasing-content only. Visual layout is unchanged.
Verified end-to-end against a live dev server:
- 0 console errors after the fix on /settings/streamystats
- form mounts, GET /api/settings/streamystats returns 200
- test/save/delete flows all behave as expected
maintainerr-automation Bot
added a commit
that referenced
this pull request
May 20, 2026
* build(deps): bump the nestjs group with 5 updates (#2899) Bumps the nestjs group with 5 updates: | Package | From | To | | --- | --- | --- | | [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) | `11.1.20` | `11.1.21` | | [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) | `11.1.20` | `11.1.21` | | [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) | `11.1.20` | `11.1.21` | | [@nestjs/swagger](https://github.com/nestjs/swagger) | `11.4.2` | `11.4.3` | | [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) | `11.1.20` | `11.1.21` | Updates `@nestjs/common` from 11.1.20 to 11.1.21 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/common) Updates `@nestjs/core` from 11.1.20 to 11.1.21 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/core) Updates `@nestjs/platform-express` from 11.1.20 to 11.1.21 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/platform-express) Updates `@nestjs/swagger` from 11.4.2 to 11.4.3 - [Release notes](https://github.com/nestjs/swagger/releases) - [Commits](nestjs/swagger@11.4.2...11.4.3) Updates `@nestjs/testing` from 11.1.20 to 11.1.21 - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.21/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/common" dependency-version: 11.1.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/core" dependency-version: 11.1.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/platform-express" dependency-version: 11.1.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/swagger" dependency-version: 11.4.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nestjs - dependency-name: "@nestjs/testing" dependency-version: 11.1.21 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: nestjs ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump typescript-eslint from 8.59.2 to 8.59.3 (#2900) Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.59.2 to 8.59.3. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/typescript-eslint) --- updated-dependencies: - dependency-name: typescript-eslint dependency-version: 8.59.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump turbo from 2.9.6 to 2.9.12 (#2901) Bumps [turbo](https://github.com/vercel/turborepo) from 2.9.6 to 2.9.12. - [Release notes](https://github.com/vercel/turborepo/releases) - [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md) - [Commits](vercel/turborepo@v2.9.6...v2.9.12) --- updated-dependencies: - dependency-name: turbo dependency-version: 2.9.12 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @typescript-eslint/parser from 8.59.2 to 8.59.3 (#2902) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.59.2 to 8.59.3. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.59.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci(docs-drift): broaden fix scanner and surface documentation-labeled items Replace the behavioral-fix path allowlist with a denylist so every UI and server-module fix is flagged except internal-only events/logging. Add a section listing merged PRs and open issues carrying the `documentation` label, and pass GH_TOKEN to the report step so it can query them. * Revert PR 2879 (#2904) * Initial plan * fix(ci): revert PR 2879 Agent-Logs-Url: https://github.com/Maintainerr/Maintainerr/sessions/49aef6e5-0ff3-477b-aa59-e6d25d283693 Co-authored-by: enoch85 <4511254+enoch85@users.noreply.github.com> * fix(ci): add missing yaml newline Agent-Logs-Url: https://github.com/Maintainerr/Maintainerr/sessions/bdecdc93-4aa4-467f-89bd-080b8a9e67f0 Co-authored-by: enoch85 <4511254+enoch85@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: enoch85 <4511254+enoch85@users.noreply.github.com> * build(deps): bump better-sqlite3 from 12.9.0 to 12.10.0 (#2908) Bumps [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) from 12.9.0 to 12.10.0. - [Release notes](https://github.com/WiseLibs/better-sqlite3/releases) - [Commits](WiseLibs/better-sqlite3@v12.9.0...v12.10.0) --- updated-dependencies: - dependency-name: better-sqlite3 dependency-version: 12.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @suites/di.nestjs from 3.0.1 to 3.1.0 (#2907) Bumps [@suites/di.nestjs](https://github.com/suites-dev/suites/tree/HEAD/packages/di/nestjs) from 3.0.1 to 3.1.0. - [Release notes](https://github.com/suites-dev/suites/releases) - [Changelog](https://github.com/suites-dev/suites/blob/master/packages/di/nestjs/CHANGELOG.md) - [Commits](https://github.com/suites-dev/suites/commits/@suites/di.nestjs@3.1.0/packages/di/nestjs) --- updated-dependencies: - dependency-name: "@suites/di.nestjs" dependency-version: 3.1.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump axios from 1.16.0 to 1.16.1 (#2910) Bumps [axios](https://github.com/axios/axios) from 1.16.0 to 1.16.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v1.16.0...v1.16.1) --- updated-dependencies: - dependency-name: axios dependency-version: 1.16.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @types/node from 22.19.17 to 22.19.19 (#2909) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.19.17 to 22.19.19. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.19.19 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Document GitHub CI workflow commands (#2912) * Document CI workflow commands * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Clarify CI workflow commands --------- Co-authored-by: enoch85 <mailto@danielhansson.nu> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * build(deps): bump react-hook-form from 7.75.0 to 7.76.0 (#2916) Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.75.0 to 7.76.0. - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](react-hook-form/react-hook-form@v7.75.0...v7.76.0) --- updated-dependencies: - dependency-name: react-hook-form dependency-version: 7.76.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump knip from 6.13.1 to 6.14.1 (#2915) Bumps [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) from 6.13.1 to 6.14.1. - [Release notes](https://github.com/webpro-nl/knip/releases) - [Commits](https://github.com/webpro-nl/knip/commits/knip@6.14.1/packages/knip) --- updated-dependencies: - dependency-name: knip dependency-version: 6.14.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @typescript-eslint/eslint-plugin (#2917) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.59.3 to 8.59.4. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.59.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump vite from 8.0.12 to 8.0.13 (#2918) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.12 to 8.0.13. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.0.13/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.13 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump nestjs-zod from 5.3.0 to 5.4.0 (#2920) Bumps [nestjs-zod](https://github.com/BenLorantfy/nestjs-zod/tree/HEAD/packages/nestjs-zod) from 5.3.0 to 5.4.0. - [Release notes](https://github.com/BenLorantfy/nestjs-zod/releases) - [Commits](https://github.com/BenLorantfy/nestjs-zod/commits/v5.4.0/packages/nestjs-zod) --- updated-dependencies: - dependency-name: nestjs-zod dependency-version: 5.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump rolldown from 1.0.0-rc.18 to 1.0.1 (#2919) Bumps [rolldown](https://github.com/rolldown/rolldown/tree/HEAD/packages/rolldown) from 1.0.0-rc.18 to 1.0.1. - [Release notes](https://github.com/rolldown/rolldown/releases) - [Changelog](https://github.com/rolldown/rolldown/blob/main/CHANGELOG.md) - [Commits](https://github.com/rolldown/rolldown/commits/v1.0.1/packages/rolldown) --- updated-dependencies: - dependency-name: rolldown dependency-version: 1.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump date-fns from 4.1.0 to 4.2.1 (#2921) Bumps [date-fns](https://github.com/date-fns/date-fns) from 4.1.0 to 4.2.1. - [Release notes](https://github.com/date-fns/date-fns/releases) - [Changelog](https://github.com/date-fns/date-fns/blob/main/CHANGELOG.md) - [Commits](date-fns/date-fns@v4.1.0...v4.2.1) --- updated-dependencies: - dependency-name: date-fns dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Replace partial-cast query mocks in CollectionDetailPage spec (#2914) * Use typed query helpers in CollectionDetailPage spec * Format CollectionDetailPage spec --------- * feat(media-server): add Emby as a third supported media server (#2911) * fix(ci): make docs drift PR request resilient * feat(streamystats): add Jellyfin-only Streamystats integration (#2923) * fix: tighten emby storage and icon handling * chore: format emby followup changes * fix: tighten emby storage and icon handling (#2924) * fix: tighten emby storage and icon handling * chore: format emby followup changes * fix(streamystats): don't send stored Jellyfin API key on connection test (#2925) * fix: align emby login error styling * fix(emby): request MediaSources field when computing library sizes computeLibraryStorageSizes queried /Items without a Fields parameter, so Emby returned items with no MediaSources (and no top-level Size). Every item summed to 0, so no library was ever added to the result map and the storage-metrics endpoint reported sizeBytesByLibrary: {}. #2924 added pagination and an item.Size ?? MediaSources fallback but dropped the original `Fields: 'MediaSources'`, and its test mocked responses that already contained the size fields — so the regression passed CI while real Emby servers returned empty sizes. Request `Fields: 'MediaSources'` on the paginated query and add a regression test asserting the field is present. * build(deps-dev): bump @types/react in the react group (#2926) Bumps the react group with 1 update: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). Updates `@types/react` from 19.2.14 to 19.2.15 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: "@types/react" dependency-version: 19.2.15 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: react ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump postcss from 8.5.14 to 8.5.15 (#2927) Bumps [postcss](https://github.com/postcss/postcss) from 8.5.14 to 8.5.15. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](postcss/postcss@8.5.14...8.5.15) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.15 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @typescript-eslint/parser from 8.59.3 to 8.59.4 (#2928) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.59.3 to 8.59.4. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.4/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.59.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @tanstack/eslint-plugin-query (#2929) Bumps [@tanstack/eslint-plugin-query](https://github.com/TanStack/query/tree/HEAD/packages/eslint-plugin-query) from 5.100.10 to 5.100.11. - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/eslint-plugin-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/eslint-plugin-query@5.100.11/packages/eslint-plugin-query) --- updated-dependencies: - dependency-name: "@tanstack/eslint-plugin-query" dependency-version: 5.100.11 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump turbo from 2.9.12 to 2.9.14 (#2930) Bumps [turbo](https://github.com/vercel/turborepo) from 2.9.12 to 2.9.14. - [Release notes](https://github.com/vercel/turborepo/releases) - [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md) - [Commits](vercel/turborepo@v2.9.12...v2.9.14) --- updated-dependencies: - dependency-name: turbo dependency-version: 2.9.14 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump glob from 7.2.3 to 13.0.6 Bumps [glob](https://github.com/isaacs/node-glob) from 7.2.3 to 13.0.6. - [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md) - [Commits](isaacs/node-glob@v7.2.3...v13.0.6) --- updated-dependencies: - dependency-name: glob dependency-version: 13.0.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump undici from 5.29.0 to 7.25.0 Bumps [undici](https://github.com/nodejs/undici) from 5.29.0 to 7.25.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](nodejs/undici@v5.29.0...v7.25.0) --- updated-dependencies: - dependency-name: undici dependency-version: 7.25.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump ajv from 6.15.0 to 8.20.0 Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.15.0 to 8.20.0. - [Release notes](https://github.com/ajv-validator/ajv/releases) - [Commits](ajv-validator/ajv@v6.15.0...v8.20.0) --- updated-dependencies: - dependency-name: ajv dependency-version: 8.20.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump tar from 6.2.1 to 7.5.15 Bumps [tar](https://github.com/isaacs/node-tar) from 6.2.1 to 7.5.15. - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](isaacs/node-tar@v6.2.1...v7.5.15) --- updated-dependencies: - dependency-name: tar dependency-version: 7.5.15 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump minimatch from 3.1.5 to 10.2.5 Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.1.5 to 10.2.5. - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](isaacs/minimatch@v3.1.5...v10.2.5) --- updated-dependencies: - dependency-name: minimatch dependency-version: 10.2.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * fix(overlays): keep ellipse anchored on drag and resize (#2938) * fix(deps): resolve transitive security advisories Force patched versions of transitive-only dependencies flagged by Dependabot. All direct runtime deps were already patched; these overrides clear the nested copies pulled by build/dev tooling. - node-gyp 11.2.0: replaces tar 6.2.1 with patched 7.5.15 (GHSA-r6q2-hw4h-h46w, -8qq5-rm4j-mr97, -34x7-hfp2-rc4v, -83g3-92jg-28cx, -qffp-2rhf-9h96, -9ppj-qmqm-q256) - minimatch 9.0.9: ReDoS fixes (GHSA-7r86-cg39-jmmj and related) - yaml 1.10.3: stack overflow (GHSA-48c2-rrv3-qjmp) - ajv 8.20.0: $data ReDoS (GHSA-2g4f-4pwh-qvx6) - undici 6.25.0: WebSocket/smuggling/decompression fixes via cheerio (GHSA-f269-vfmq-vjvj, -2mjp-6q6p-2qxm, -vrm6-8vpv-qv8q, -v9p9-hfj2-hcw8, -4992-7rv2-5pvq, -g9mf-h72j-4rw9) * chore(deps): dedupe @typescript-eslint to clear TypeScript peer warning eslint-plugin-jest pulled a stale @typescript-eslint/utils@8.46.4 (peer typescript <6.0.0) alongside the toolchain's 8.59.4 (peer <6.1.0), so the intersected range excluded the project's TS 6.0.3 and emitted YN0060/YN0086 on install. Deduping aligns all @typescript-eslint/* copies on 8.59.4. Dev-tooling only. * chore: apply staged updates * build(deps): bump react-router-dom from 7.15.0 to 7.15.1 Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 7.15.0 to 7.15.1. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.15.1/packages/react-router-dom) --- updated-dependencies: - dependency-name: react-router-dom dependency-version: 7.15.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps-dev): bump vitest from 4.1.6 to 4.1.7 Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.6 to 4.1.7. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.7/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 4.1.7 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps-dev): bump @vitejs/plugin-react from 6.0.1 to 6.0.2 Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 6.0.1 to 6.0.2. - [Release notes](https://github.com/vitejs/vite-plugin-react/releases) - [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.2/packages/plugin-react) --- updated-dependencies: - dependency-name: "@vitejs/plugin-react" dependency-version: 6.0.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix(ui): sync settings forms via react-hook-form values to stop render loop The Emby, Jellyfin and Servarr settings forms reset the form from loaded settings inside a useEffect keyed on the query result. When that data reference is unstable, the effect re-fires every render and loops until the vitest worker exhausts memory and is SIGTERM'd — which is what was failing the test job. Use react-hook-form's `values` option instead: it deep-compares and keeps the form in sync without an effect. Also stop ts-jest from re-transforming the prebuilt @maintainerr/contracts dist output, removing the compiler warning flood on every server test run. * build(deps): bump @tanstack/react-query from 5.100.10 to 5.100.11 (#2945) Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.100.10 to 5.100.11. - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.100.11/packages/react-query) --- updated-dependencies: - dependency-name: "@tanstack/react-query" dependency-version: 5.100.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * test(ui): wait for Run Now to enable before clicking in overlay pass test The "Run Now" button stays disabled until the server's enabled state finishes loading. The test clicked as soon as the button rendered, so under CI load the click could land while it was still disabled (a no-op), leaving processAllOverlays uncalled and failing intermittently. Wait for the button to enable before clicking. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: maintainerr-automation[bot] <261505141+maintainerr-automation[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: enoch85 <mailto@danielhansson.nu> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: enoch85 <4511254+enoch85@users.noreply.github.com> Co-authored-by: Kristian Matthews-Kennington <kristian@matthews-kennington.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Contributor
|
🎉 This PR is included in version 3.12.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
doonga
pushed a commit
to greyrock-labs/home-ops
that referenced
this pull request
May 21, 2026
…12.0 ) (#101) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/maintainerr/maintainerr](https://github.com/Maintainerr/Maintainerr) | minor | `3.11.2` → `3.12.0` | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/34) for more information. --- ### Release Notes <details> <summary>Maintainerr/Maintainerr (ghcr.io/maintainerr/maintainerr)</summary> ### [`v3.12.0`](https://github.com/Maintainerr/Maintainerr/releases/tag/v3.12.0) [Compare Source](Maintainerr/Maintainerr@v3.11.2...v3.12.0) ##### Highlights - Added Emby as a third supported media server alongside Plex and Jellyfin ([#​2911](Maintainerr/Maintainerr#2911)). - Introduced Jellyfin-only Streamystats integration, including a new settings tab and per-user stats panel ([#​2923](Maintainerr/Maintainerr#2923)). - Fixed Emby library size computation and metadata updates to align with documented API behavior ([#​2924](Maintainerr/Maintainerr#2924)). ##### Breaking Changes - None. ##### Features - Added Emby as a third supported media server ([#​2911](Maintainerr/Maintainerr#2911)). - Introduced Jellyfin-only Streamystats integration, including a new settings tab and per-user stats panel ([#​2923](Maintainerr/Maintainerr#2923)). ##### Fixes - Fixed Emby library size computation and metadata updates to align with documented API behavior ([#​2924](Maintainerr/Maintainerr#2924)). - Resolved transitive security advisories by forcing patched versions of dependencies. - Fixed issue with Emby login error styling. - Prevented Jellyfin API key from being sent during Streamystats connection tests ([#​2925](Maintainerr/Maintainerr#2925)). - Fixed overlay ellipse anchoring during drag and resize ([#​2938](Maintainerr/Maintainerr#2938)). - Synced settings forms via react-hook-form values to stop render loops. ##### Performance - None. ##### Database migrations - Added support for Emby by introducing new columns: `emby_url`, `emby_api_key`, `emby_user_id`, and `emby_server_name` to the `settings` table. - Added support for Streamystats by introducing a new column: `streamystats_url` to the `settings` table. ##### Internal - Updated test for overlay "Run Now" button to wait for enabled state before clicking. - Replaced partial query mocks in `CollectionDetailPage` spec with typed helpers ([#​2914](Maintainerr/Maintainerr#2914)). - Documented GitHub CI workflow commands ([#​2912](Maintainerr/Maintainerr#2912)). - Improved CI docs drift scanner to surface documentation-labeled items. ##### Dependencies - Updated 29 dependencies, including [@​tanstack/react-query](https://github.com/tanstack/react-query), [@​vitejs/plugin-react](https://github.com/vitejs/plugin-react), vitest, react-router-dom, and tar. </details> --- ### Configuration 📅 **Schedule**: (in timezone America/New_York) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xODIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE4Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19--> Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/101
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/api/get-item-details/[itemId](per-user table, completion %, last watched, series episode coverage).jellyfin_api_key— no separate credential field.Bundled refactor
ExternalServiceSettingsPagenow takes a declarativefieldsprop; Seerr, Tautulli, Streamystats all migrated. Removes service-specific branching from the shared component.Out-of-scope fixes bundled in this PR
These weren't part of the Streamystats integration plan, but were either triggered by it or noticed during development and small enough not to warrant a separate PR:
f2e0f27b):MediaServerFactory.getService()now throwsServiceUnavailableExceptionwhen the configured server type has no credentials yet (the brief window between a switch and saving new credentials).NotificationService.transformMessageContentcatches this specific exception at DEBUG instead of ERROR, eliminating the scary log cascade users saw mid-switch. Same behavior existed ondevelopmentbefore this branch — flagged by a real user log.50cd8c75): one-line fixes toMediaModal/index.spec.tsx(missingisEmbyon theuseMediaServerTypemock) andEmbyLoginButton.tsx(missingnameon twoInputGroupcalls). Both exist ondevelopmentwithout this branch.Verification
Quality gate green: lint clean, 1332 server + 52 UI test files (206 tests) pass.
End-to-end verified against a live dev server (Playwright + curl):
/settings/streamystatsunder Plex/Emby → redirects to/settings/main, zero leaked API callsstreamystats_urlis nulled when the active server switches away from JellyfinMedia-modal badge link + per-user stats panel were verified manually by the maintainer against a live Jellyfin + Streamystats instance earlier in development.
Upstream blockers (tracked separately)
authenticateMediaBrowser— unblocks future rule sources (recommendations / watchlists).