diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 99645263d..d9fab953f 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -17,7 +17,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x - name: Install Swashbuckle CLI shell: powershell diff --git a/.github/workflows/canary-workflow.yml b/.github/workflows/canary-workflow.yml index f8e1ddc74..af4a45dec 100644 --- a/.github/workflows/canary-workflow.yml +++ b/.github/workflows/canary-workflow.yml @@ -33,7 +33,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x - name: Bump versions uses: SiqiLu/dotnet-bump-version@2.0.0 @@ -98,7 +98,7 @@ jobs: - name: Compile dotnet app uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x - name: Install Swashbuckle CLI run: dotnet tool install -g --version 6.5.0 Swashbuckle.AspNetCore.Cli diff --git a/.github/workflows/develop-workflow.yml b/.github/workflows/develop-workflow.yml index 9280ef8b4..dff82c01e 100644 --- a/.github/workflows/develop-workflow.yml +++ b/.github/workflows/develop-workflow.yml @@ -46,7 +46,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x - name: Bump versions uses: majora2007/dotnet-bump-version@v0.0.10 @@ -131,7 +131,7 @@ jobs: - name: Compile dotnet app uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x - name: Install Swashbuckle CLI run: dotnet tool install -g --version 6.5.0 Swashbuckle.AspNetCore.Cli diff --git a/.github/workflows/release-workflow.yml b/.github/workflows/release-workflow.yml index 9cd9a73bc..dca370460 100644 --- a/.github/workflows/release-workflow.yml +++ b/.github/workflows/release-workflow.yml @@ -119,7 +119,7 @@ jobs: - name: Compile dotnet app uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x - name: Install Swashbuckle CLI run: dotnet tool install -g --version 6.5.0 Swashbuckle.AspNetCore.Cli diff --git a/API.Benchmark/API.Benchmark.csproj b/API.Benchmark/API.Benchmark.csproj index 29f16495d..cbfd1d715 100644 --- a/API.Benchmark/API.Benchmark.csproj +++ b/API.Benchmark/API.Benchmark.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 Exe @@ -10,8 +10,8 @@ - - + + diff --git a/API.Tests/API.Tests.csproj b/API.Tests/API.Tests.csproj index 0f9c82178..f6ceb75d3 100644 --- a/API.Tests/API.Tests.csproj +++ b/API.Tests/API.Tests.csproj @@ -1,18 +1,18 @@ - net7.0 + net8.0 false - + - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/API/API.csproj b/API/API.csproj index 34ba35da8..a9463ea32 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -2,7 +2,7 @@ Default - net7.0 + net8.0 true Linux true @@ -53,7 +53,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -72,38 +72,37 @@ - - - - - - - + + + + + + - - + + - - + + - - + + - + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/API/Controllers/LibraryController.cs b/API/Controllers/LibraryController.cs index 9d44f629e..d043188d8 100644 --- a/API/Controllers/LibraryController.cs +++ b/API/Controllers/LibraryController.cs @@ -40,15 +40,13 @@ public class LibraryController : BaseApiController private readonly IEventHub _eventHub; private readonly ILibraryWatcher _libraryWatcher; private readonly ILocalizationService _localizationService; - private readonly IStreamService _streamService; private readonly IEasyCachingProvider _libraryCacheProvider; private const string CacheKey = "library_"; public LibraryController(IDirectoryService directoryService, ILogger logger, IMapper mapper, ITaskScheduler taskScheduler, IUnitOfWork unitOfWork, IEventHub eventHub, ILibraryWatcher libraryWatcher, - IEasyCachingProviderFactory cachingProviderFactory, ILocalizationService localizationService, - IStreamService streamService) + IEasyCachingProviderFactory cachingProviderFactory, ILocalizationService localizationService) { _directoryService = directoryService; _logger = logger; @@ -58,7 +56,6 @@ public class LibraryController : BaseApiController _eventHub = eventHub; _libraryWatcher = libraryWatcher; _localizationService = localizationService; - _streamService = streamService; _libraryCacheProvider = cachingProviderFactory.GetCachingProvider(EasyCacheProfiles.Library); } @@ -157,7 +154,7 @@ public class LibraryController : BaseApiController })); } - if (!Directory.Exists(path)) return Ok(_directoryService.ListDirectory(Path.GetDirectoryName(path))); + if (!Directory.Exists(path)) return Ok(_directoryService.ListDirectory(Path.GetDirectoryName(path)!)); return Ok(_directoryService.ListDirectory(path)); } diff --git a/API/Controllers/OPDSController.cs b/API/Controllers/OPDSController.cs index 38922aad9..a29daa165 100644 --- a/API/Controllers/OPDSController.cs +++ b/API/Controllers/OPDSController.cs @@ -99,7 +99,7 @@ public class OpdsController : BaseApiController if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds) return BadRequest(await _localizationService.Translate(userId, "opds-disabled")); - var (baseUrl, prefix) = await GetPrefix(); + var (_, prefix) = await GetPrefix(); var feed = CreateFeed("Kavita", string.Empty, apiKey, prefix); SetFeedId(feed, "root"); @@ -141,10 +141,37 @@ public class OpdsController : BaseApiController }); break; case DashboardStreamType.RecentlyUpdated: - // TODO: See if we can implement this and use (count) on series name for number of updates + feed.Entries.Add(new FeedEntry() + { + Id = "recentlyUpdated", + Title = await _localizationService.Translate(userId, "recently-updated"), + Content = new FeedEntryContent() + { + Text = await _localizationService.Translate(userId, "browse-recently-updated") + }, + Links = new List() + { + CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation, $"{prefix}{apiKey}/recently-updated"), + } + }); break; case DashboardStreamType.MoreInGenre: - // TODO: See if we can implement this + var randomGenre = await _unitOfWork.GenreRepository.GetRandomGenre(); + if (randomGenre == null) break; + + feed.Entries.Add(new FeedEntry() + { + Id = "moreInGenre", + Title = await _localizationService.Translate(userId, "more-in-genre", randomGenre.Title), + Content = new FeedEntryContent() + { + Text = await _localizationService.Translate(userId, "browse-more-in-genre", randomGenre.Title) + }, + Links = new List() + { + CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation, $"{prefix}{apiKey}/more-in-genre?genreId={randomGenre.Id}"), + } + }); break; case DashboardStreamType.SmartFilter: @@ -632,6 +659,61 @@ public class OpdsController : BaseApiController return CreateXmlResult(SerializeXml(feed)); } + [HttpGet("{apiKey}/more-in-genre")] + [Produces("application/xml")] + public async Task GetMoreInGenre(string apiKey, [FromQuery] int genreId, [FromQuery] int pageNumber = 1) + { + var userId = await GetUser(apiKey); + if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds) + return BadRequest(await _localizationService.Translate(userId, "opds-disabled")); + var (baseUrl, prefix) = await GetPrefix(); + var genre = await _unitOfWork.GenreRepository.GetGenreById(genreId); + var seriesDtos = await _unitOfWork.SeriesRepository.GetMoreIn(userId, 0, genreId, GetUserParams(pageNumber)); + var seriesMetadatas = await _unitOfWork.SeriesRepository.GetSeriesMetadataForIds(seriesDtos.Select(s => s.Id)); + + var feed = CreateFeed(await _localizationService.Translate(userId, "more-in-genre", genre.Title), $"{prefix}{apiKey}/more-in-genre", apiKey, prefix); + SetFeedId(feed, "more-in-genre"); + AddPagination(feed, seriesDtos, $"{prefix}{apiKey}/more-in-genre"); + + foreach (var seriesDto in seriesDtos) + { + feed.Entries.Add(CreateSeries(seriesDto, seriesMetadatas.First(s => s.SeriesId == seriesDto.Id), apiKey, prefix, baseUrl)); + } + + return CreateXmlResult(SerializeXml(feed)); + } + + [HttpGet("{apiKey}/recently-updated")] + [Produces("application/xml")] + public async Task GetRecentlyUpdated(string apiKey, [FromQuery] int pageNumber = 1) + { + var userId = await GetUser(apiKey); + if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds) + return BadRequest(await _localizationService.Translate(userId, "opds-disabled")); + var (baseUrl, prefix) = await GetPrefix(); + var seriesDtos = (await _unitOfWork.SeriesRepository.GetRecentlyUpdatedSeries(userId, PageSize)).ToList(); + var seriesMetadatas = await _unitOfWork.SeriesRepository.GetSeriesMetadataForIds(seriesDtos.Select(s => s.SeriesId)); + + var feed = CreateFeed(await _localizationService.Translate(userId, "recently-updated"), $"{prefix}{apiKey}/recently-updated", apiKey, prefix); + SetFeedId(feed, "recently-updated"); + //AddPagination(feed, seriesDtos, $"{prefix}{apiKey}/recently-updated"); + + foreach (var groupedSeries in seriesDtos) + { + var seriesDto = new SeriesDto() + { + Name = $"{groupedSeries.SeriesName} ({groupedSeries.Count})", + Id = groupedSeries.SeriesId, + Format = groupedSeries.Format, + LibraryId = groupedSeries.LibraryId, + }; + var metadata = seriesMetadatas.First(s => s.SeriesId == seriesDto.Id); + feed.Entries.Add(CreateSeries(seriesDto, metadata, apiKey, prefix, baseUrl)); + } + + return CreateXmlResult(SerializeXml(feed)); + } + [HttpGet("{apiKey}/on-deck")] [Produces("application/xml")] public async Task GetOnDeck(string apiKey, [FromQuery] int pageNumber = 1) @@ -1161,7 +1243,7 @@ public class OpdsController : BaseApiController var userId = await GetUser(apiKey); var progress = await _unitOfWork.AppUserProgressRepository.GetUserProgressDtoAsync(chapterId, userId); - // TODO: Type could be wrong + // NOTE: Type could be wrong, there is nothing I can do in the spec var link = CreateLink(FeedLinkRelation.Stream, "image/jpeg", $"{prefix}{apiKey}/image?libraryId={libraryId}&seriesId={seriesId}&volumeId={volumeId}&chapterId={chapterId}&pageNumber=" + "{pageNumber}"); link.TotalPages = mangaFile.Pages; diff --git a/API/Controllers/StreamController.cs b/API/Controllers/StreamController.cs index 49ee1ed90..a694d5b34 100644 --- a/API/Controllers/StreamController.cs +++ b/API/Controllers/StreamController.cs @@ -19,13 +19,11 @@ public class StreamController : BaseApiController { private readonly IStreamService _streamService; private readonly IUnitOfWork _unitOfWork; - private readonly ILogger _logger; - public StreamController(IStreamService streamService, IUnitOfWork unitOfWork, ILogger logger) + public StreamController(IStreamService streamService, IUnitOfWork unitOfWork) { _streamService = streamService; _unitOfWork = unitOfWork; - _logger = logger; } /// diff --git a/API/Controllers/ThemeController.cs b/API/Controllers/ThemeController.cs index 814278bdd..7fa722624 100644 --- a/API/Controllers/ThemeController.cs +++ b/API/Controllers/ThemeController.cs @@ -53,7 +53,7 @@ public class ThemeController : BaseApiController { await _themeService.UpdateDefault(dto.ThemeId); } - catch (KavitaException ex) + catch (KavitaException) { return BadRequest(await _localizationService.Translate(User.GetUserId(), "theme-doesnt-exist")); } diff --git a/API/DTOs/Account/LoginDto.cs b/API/DTOs/Account/LoginDto.cs index a5376e1fc..fe8fce088 100644 --- a/API/DTOs/Account/LoginDto.cs +++ b/API/DTOs/Account/LoginDto.cs @@ -1,4 +1,5 @@ namespace API.DTOs.Account; +#nullable enable public class LoginDto { diff --git a/API/DTOs/Filtering/FilterDto.cs b/API/DTOs/Filtering/FilterDto.cs index 1b8cffc9e..9205a7bba 100644 --- a/API/DTOs/Filtering/FilterDto.cs +++ b/API/DTOs/Filtering/FilterDto.cs @@ -3,6 +3,7 @@ using API.Entities; using API.Entities.Enums; namespace API.DTOs.Filtering; +#nullable enable public class FilterDto { diff --git a/API/DTOs/Filtering/Range.cs b/API/DTOs/Filtering/Range.cs index b9e9a5e49..a75164fa3 100644 --- a/API/DTOs/Filtering/Range.cs +++ b/API/DTOs/Filtering/Range.cs @@ -1,4 +1,6 @@ namespace API.DTOs.Filtering; +#nullable enable + /// /// Represents a range between two int/float/double /// diff --git a/API/DTOs/Filtering/v2/FilterV2Dto.cs b/API/DTOs/Filtering/v2/FilterV2Dto.cs index e25f1e21d..08757f98d 100644 --- a/API/DTOs/Filtering/v2/FilterV2Dto.cs +++ b/API/DTOs/Filtering/v2/FilterV2Dto.cs @@ -1,9 +1,7 @@ using System.Collections.Generic; - namespace API.DTOs.Filtering.v2; - - +#nullable enable /// /// Metadata filtering for v2 API only diff --git a/API/DTOs/LibraryDto.cs b/API/DTOs/LibraryDto.cs index 3da232c47..c8c85063e 100644 --- a/API/DTOs/LibraryDto.cs +++ b/API/DTOs/LibraryDto.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using API.Entities.Enums; namespace API.DTOs; +#nullable enable public class LibraryDto { diff --git a/API/DTOs/MemberDto.cs b/API/DTOs/MemberDto.cs index 226d47eae..7b750b32f 100644 --- a/API/DTOs/MemberDto.cs +++ b/API/DTOs/MemberDto.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using API.DTOs.Account; namespace API.DTOs; +#nullable enable /// /// Represents a member of a Kavita server. diff --git a/API/DTOs/Metadata/ChapterMetadataDto.cs b/API/DTOs/Metadata/ChapterMetadataDto.cs index b9b04cfac..903c327dc 100644 --- a/API/DTOs/Metadata/ChapterMetadataDto.cs +++ b/API/DTOs/Metadata/ChapterMetadataDto.cs @@ -2,6 +2,7 @@ using API.Entities.Enums; namespace API.DTOs.Metadata; +#nullable enable /// /// Exclusively metadata about a given chapter diff --git a/API/DTOs/RatingDto.cs b/API/DTOs/RatingDto.cs index 89f4aebe5..e2cd9d342 100644 --- a/API/DTOs/RatingDto.cs +++ b/API/DTOs/RatingDto.cs @@ -1,6 +1,7 @@ using API.Services.Plus; namespace API.DTOs; +#nullable enable public class RatingDto { diff --git a/API/DTOs/Reader/BookmarkDto.cs b/API/DTOs/Reader/BookmarkDto.cs index a6b185683..ef4cf3d6d 100644 --- a/API/DTOs/Reader/BookmarkDto.cs +++ b/API/DTOs/Reader/BookmarkDto.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; namespace API.DTOs.Reader; +#nullable enable public class BookmarkDto { diff --git a/API/DTOs/Reader/BookmarkInfoDto.cs b/API/DTOs/Reader/BookmarkInfoDto.cs index 7583ee76d..c75c3d8bf 100644 --- a/API/DTOs/Reader/BookmarkInfoDto.cs +++ b/API/DTOs/Reader/BookmarkInfoDto.cs @@ -2,6 +2,7 @@ using API.Entities.Enums; namespace API.DTOs.Reader; +#nullable enable public class BookmarkInfoDto { diff --git a/API/DTOs/Reader/ChapterInfoDto.cs b/API/DTOs/Reader/ChapterInfoDto.cs index bb3a8d3ee..4584a5830 100644 --- a/API/DTOs/Reader/ChapterInfoDto.cs +++ b/API/DTOs/Reader/ChapterInfoDto.cs @@ -2,6 +2,7 @@ using API.Entities.Enums; namespace API.DTOs.Reader; +#nullable enable /// /// Information about the Chapter for the Reader to render diff --git a/API/DTOs/Reader/PersonalToCDto.cs b/API/DTOs/Reader/PersonalToCDto.cs index 6763a157a..144ed561f 100644 --- a/API/DTOs/Reader/PersonalToCDto.cs +++ b/API/DTOs/Reader/PersonalToCDto.cs @@ -1,5 +1,7 @@ namespace API.DTOs.Reader; +#nullable enable + public class PersonalToCDto { public required int ChapterId { get; set; } diff --git a/API/DTOs/Recommendation/ExternalSeriesDetailDto.cs b/API/DTOs/Recommendation/ExternalSeriesDetailDto.cs index b01f1369c..a1341b358 100644 --- a/API/DTOs/Recommendation/ExternalSeriesDetailDto.cs +++ b/API/DTOs/Recommendation/ExternalSeriesDetailDto.cs @@ -2,6 +2,7 @@ using API.DTOs.Scrobbling; namespace API.DTOs.Recommendation; +#nullable enable public class ExternalSeriesDetailDto { diff --git a/API/DTOs/Recommendation/SeriesStaffDto.cs b/API/DTOs/Recommendation/SeriesStaffDto.cs index ae57249f2..0c1e9759d 100644 --- a/API/DTOs/Recommendation/SeriesStaffDto.cs +++ b/API/DTOs/Recommendation/SeriesStaffDto.cs @@ -1,4 +1,5 @@ namespace API.DTOs.Recommendation; +#nullable enable public class SeriesStaffDto { diff --git a/API/DTOs/Scrobbling/ScrobbleResponseDto.cs b/API/DTOs/Scrobbling/ScrobbleResponseDto.cs index f714d1eda..a63e955d7 100644 --- a/API/DTOs/Scrobbling/ScrobbleResponseDto.cs +++ b/API/DTOs/Scrobbling/ScrobbleResponseDto.cs @@ -1,4 +1,5 @@ namespace API.DTOs.Scrobbling; +#nullable enable /// /// Response from Kavita+ Scrobble API diff --git a/API/DTOs/SeriesDetail/UpdateUserReviewDto.cs b/API/DTOs/SeriesDetail/UpdateUserReviewDto.cs index 550969787..cb4039368 100644 --- a/API/DTOs/SeriesDetail/UpdateUserReviewDto.cs +++ b/API/DTOs/SeriesDetail/UpdateUserReviewDto.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; namespace API.DTOs.SeriesDetail; +#nullable enable public class UpdateUserReviewDto { diff --git a/API/DTOs/SeriesDetail/UserReviewDto.cs b/API/DTOs/SeriesDetail/UserReviewDto.cs index 4f74dadbb..6692c6bd5 100644 --- a/API/DTOs/SeriesDetail/UserReviewDto.cs +++ b/API/DTOs/SeriesDetail/UserReviewDto.cs @@ -1,6 +1,7 @@ using API.Services.Plus; namespace API.DTOs.SeriesDetail; +#nullable enable /// /// Represents a User Review for a given Series diff --git a/API/DTOs/Statistics/FileExtensionBreakdownDto.cs b/API/DTOs/Statistics/FileExtensionBreakdownDto.cs index c0d65fe7f..1f122d992 100644 --- a/API/DTOs/Statistics/FileExtensionBreakdownDto.cs +++ b/API/DTOs/Statistics/FileExtensionBreakdownDto.cs @@ -2,6 +2,7 @@ using API.Entities.Enums; namespace API.DTOs.Statistics; +#nullable enable public class FileExtensionDto { diff --git a/API/DTOs/Statistics/TopReadsDto.cs b/API/DTOs/Statistics/TopReadsDto.cs index 819e55ad5..d8e3b1eb0 100644 --- a/API/DTOs/Statistics/TopReadsDto.cs +++ b/API/DTOs/Statistics/TopReadsDto.cs @@ -1,4 +1,5 @@ namespace API.DTOs.Statistics; +#nullable enable public class TopReadDto { diff --git a/API/DTOs/Stats/ServerInfoDto.cs b/API/DTOs/Stats/ServerInfoDto.cs index b7b9ef526..41c4c8264 100644 --- a/API/DTOs/Stats/ServerInfoDto.cs +++ b/API/DTOs/Stats/ServerInfoDto.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using API.Entities.Enums; namespace API.DTOs.Stats; +#nullable enable /// /// Represents information about a Kavita Installation diff --git a/API/DTOs/UpdateRBSDto.cs b/API/DTOs/UpdateRBSDto.cs index 6fdce251c..a7e0c3fc9 100644 --- a/API/DTOs/UpdateRBSDto.cs +++ b/API/DTOs/UpdateRBSDto.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; namespace API.DTOs; +#nullable enable public class UpdateRbsDto { diff --git a/API/DTOs/UserDto.cs b/API/DTOs/UserDto.cs index f63a021f1..7d54102da 100644 --- a/API/DTOs/UserDto.cs +++ b/API/DTOs/UserDto.cs @@ -2,6 +2,7 @@ using API.DTOs.Account; namespace API.DTOs; +#nullable enable public class UserDto { diff --git a/API/Data/Metadata/ComicInfo.cs b/API/Data/Metadata/ComicInfo.cs index 49fb24474..81e10e771 100644 --- a/API/Data/Metadata/ComicInfo.cs +++ b/API/Data/Metadata/ComicInfo.cs @@ -9,6 +9,7 @@ using Kavita.Common.Extensions; using Nager.ArticleNumber; namespace API.Data.Metadata; +#nullable enable /// /// A representation of a ComicInfo.xml file diff --git a/API/Data/Repositories/GenreRepository.cs b/API/Data/Repositories/GenreRepository.cs index dedafeb9a..94e3c8e7f 100644 --- a/API/Data/Repositories/GenreRepository.cs +++ b/API/Data/Repositories/GenreRepository.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using API.DTOs.Metadata; @@ -22,6 +23,8 @@ public interface IGenreRepository Task RemoveAllGenreNoLongerAssociated(bool removeExternal = false); Task> GetAllGenreDtosForLibrariesAsync(IList libraryIds, int userId); Task GetCountAsync(); + Task GetRandomGenre(); + Task GetGenreById(int id); } public class GenreRepository : IGenreRepository @@ -92,6 +95,27 @@ public class GenreRepository : IGenreRepository return await _context.Genre.CountAsync(); } + public async Task GetRandomGenre() + { + var genreCount = await GetCountAsync(); + if (genreCount == 0) return null; + + var randomIndex = new Random().Next(0, genreCount); + return await _context.Genre + .Skip(randomIndex) + .Take(1) + .ProjectTo(_mapper.ConfigurationProvider) + .FirstOrDefaultAsync(); + } + + public async Task GetGenreById(int id) + { + return await _context.Genre + .Where(g => g.Id == id) + .ProjectTo(_mapper.ConfigurationProvider) + .FirstOrDefaultAsync(); + } + public async Task> GetAllGenresAsync() { return await _context.Genre.ToListAsync(); diff --git a/API/Extensions/FileTypeGroupExtensions.cs b/API/Extensions/FileTypeGroupExtensions.cs index 6e533fc4f..24073f642 100644 --- a/API/Extensions/FileTypeGroupExtensions.cs +++ b/API/Extensions/FileTypeGroupExtensions.cs @@ -17,7 +17,7 @@ public static class FileTypeGroupExtensions case FileTypeGroup.Pdf: return Parser.PdfFileExtension; case FileTypeGroup.Images: - return Parser.ImageFileExtensions;; + return Parser.ImageFileExtensions; default: throw new ArgumentOutOfRangeException(nameof(fileTypeGroup), fileTypeGroup, null); } diff --git a/API/Extensions/HttpExtensions.cs b/API/Extensions/HttpExtensions.cs index 12e491a34..fbf828104 100644 --- a/API/Extensions/HttpExtensions.cs +++ b/API/Extensions/HttpExtensions.cs @@ -21,8 +21,8 @@ public static class HttpExtensions PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; - response.Headers.Add("Pagination", JsonSerializer.Serialize(paginationHeader, options)); - response.Headers.Add("Access-Control-Expose-Headers", "Pagination"); + response.Headers.Append("Pagination", JsonSerializer.Serialize(paginationHeader, options)); + response.Headers.Append("Access-Control-Expose-Headers", "Pagination"); } /// @@ -33,7 +33,7 @@ public static class HttpExtensions public static void AddCacheHeader(this HttpResponse response, byte[] content) { if (content is not {Length: > 0}) return; - response.Headers.Add(HeaderNames.ETag, string.Concat(SHA256.HashData(content).Select(x => x.ToString("X2")))); + response.Headers.Append(HeaderNames.ETag, string.Concat(SHA256.HashData(content).Select(x => x.ToString("X2")))); response.Headers.CacheControl = $"private,max-age=100"; } @@ -47,7 +47,7 @@ public static class HttpExtensions { if (filename is not {Length: > 0}) return; var hashContent = filename + File.GetLastWriteTimeUtc(filename); - response.Headers.Add("ETag", string.Concat(SHA256.HashData(Encoding.UTF8.GetBytes(hashContent)).Select(x => x.ToString("X2")))); + response.Headers.Append("ETag", string.Concat(SHA256.HashData(Encoding.UTF8.GetBytes(hashContent)).Select(x => x.ToString("X2")))); if (maxAge != 10) { response.Headers.CacheControl = $"max-age={maxAge}"; diff --git a/API/Extensions/QueryExtensions/Filtering/SeriesFilter.cs b/API/Extensions/QueryExtensions/Filtering/SeriesFilter.cs index 0f013b5a5..5ac6dc302 100644 --- a/API/Extensions/QueryExtensions/Filtering/SeriesFilter.cs +++ b/API/Extensions/QueryExtensions/Filtering/SeriesFilter.cs @@ -22,7 +22,7 @@ public static class SeriesFilter switch (comparison) { case FilterComparison.Equal: - return queryable.Where(s => s.Metadata.Language.Equals(languages.First())); + return queryable.Where(s => s.Metadata.Language.Equals(languages[0])); case FilterComparison.Contains: return queryable.Where(s => languages.Contains(s.Metadata.Language)); case FilterComparison.MustContains: @@ -30,9 +30,9 @@ public static class SeriesFilter case FilterComparison.NotContains: return queryable.Where(s => !languages.Contains(s.Metadata.Language)); case FilterComparison.NotEqual: - return queryable.Where(s => !s.Metadata.Language.Equals(languages.First())); + return queryable.Where(s => !s.Metadata.Language.Equals(languages[0])); case FilterComparison.Matches: - return queryable.Where(s => EF.Functions.Like(s.Metadata.Language, $"{languages.First()}%")); + return queryable.Where(s => EF.Functions.Like(s.Metadata.Language, $"{languages[0]}%")); case FilterComparison.GreaterThan: case FilterComparison.GreaterThanEqual: case FilterComparison.LessThan: diff --git a/API/Extensions/StringExtensions.cs b/API/Extensions/StringExtensions.cs index ee205dbb3..802c4bca4 100644 --- a/API/Extensions/StringExtensions.cs +++ b/API/Extensions/StringExtensions.cs @@ -6,8 +6,9 @@ namespace API.Extensions; public static class StringExtensions { - private static readonly Regex SentenceCaseRegex = new Regex(@"(^[a-z])|\.\s+(.)", - RegexOptions.ExplicitCapture | RegexOptions.Compiled, Services.Tasks.Scanner.Parser.Parser.RegexTimeout); + private static readonly Regex SentenceCaseRegex = new(@"(^[a-z])|\.\s+(.)", + RegexOptions.ExplicitCapture | RegexOptions.Compiled, + Services.Tasks.Scanner.Parser.Parser.RegexTimeout); public static string SentenceCase(this string value) { @@ -21,17 +22,16 @@ public static class StringExtensions /// public static string ToNormalized(this string? value) { - if (string.IsNullOrEmpty(value)) return string.Empty; - return Services.Tasks.Scanner.Parser.Parser.Normalize(value); + return string.IsNullOrEmpty(value) ? string.Empty : Services.Tasks.Scanner.Parser.Parser.Normalize(value); } - public static float AsFloat(this string value) + public static float AsFloat(this string? value, float defaultValue = 0.0f) { - return float.Parse(value, CultureInfo.InvariantCulture); + return string.IsNullOrEmpty(value) ? defaultValue : float.Parse(value, CultureInfo.InvariantCulture); } - public static double AsDouble(this string value) + public static double AsDouble(this string? value, double defaultValue = 0.0f) { - return double.Parse(value, CultureInfo.InvariantCulture); + return string.IsNullOrEmpty(value) ? defaultValue : double.Parse(value, CultureInfo.InvariantCulture); } } diff --git a/API/Helpers/Builders/AppUserBuilder.cs b/API/Helpers/Builders/AppUserBuilder.cs index 790071d0a..bc044c301 100644 --- a/API/Helpers/Builders/AppUserBuilder.cs +++ b/API/Helpers/Builders/AppUserBuilder.cs @@ -5,6 +5,7 @@ using API.Entities; using Kavita.Common; namespace API.Helpers.Builders; +#nullable enable public class AppUserBuilder : IEntityBuilder { diff --git a/API/Helpers/Builders/ChapterBuilder.cs b/API/Helpers/Builders/ChapterBuilder.cs index 80de027c3..b95fa21f0 100644 --- a/API/Helpers/Builders/ChapterBuilder.cs +++ b/API/Helpers/Builders/ChapterBuilder.cs @@ -6,6 +6,7 @@ using API.Entities.Enums; using API.Services.Tasks.Scanner.Parser; namespace API.Helpers.Builders; +#nullable enable public class ChapterBuilder : IEntityBuilder { diff --git a/API/Helpers/Builders/ScrobbleHoldBuilder.cs b/API/Helpers/Builders/ScrobbleHoldBuilder.cs index c09859f3c..cd03a08f0 100644 --- a/API/Helpers/Builders/ScrobbleHoldBuilder.cs +++ b/API/Helpers/Builders/ScrobbleHoldBuilder.cs @@ -1,6 +1,7 @@ using API.Entities.Scrobble; namespace API.Helpers.Builders; +#nullable enable public class ScrobbleHoldBuilder : IEntityBuilder { diff --git a/API/Helpers/ParserInfoHelpers.cs b/API/Helpers/ParserInfoHelpers.cs index 18d2a8f82..fc8d7227a 100644 --- a/API/Helpers/ParserInfoHelpers.cs +++ b/API/Helpers/ParserInfoHelpers.cs @@ -40,7 +40,7 @@ public static class ParserInfoHelpers } } - if (series.Format == MangaFormat.Unknown && format != MangaFormat.Unknown) + if (series.Format == MangaFormat.Unknown) { return true; } diff --git a/API/Helpers/SmartFilterHelper.cs b/API/Helpers/SmartFilterHelper.cs index 4b8e0c8f6..8f61fde21 100644 --- a/API/Helpers/SmartFilterHelper.cs +++ b/API/Helpers/SmartFilterHelper.cs @@ -130,8 +130,9 @@ public static class SmartFilterHelper private static SortOptions DecodeSortOptions(string encodedSortOptions) { var parts = Uri.UnescapeDataString(encodedSortOptions).Split(InnerStatementSeparator); - var sortFieldPart = parts.FirstOrDefault(part => part.StartsWith(SortFieldKey)); - var isAscendingPart = parts.FirstOrDefault(part => part.StartsWith(IsAscendingKey)); + + var sortFieldPart = Array.Find(parts, part => part.StartsWith(SortFieldKey)); + var isAscendingPart = Array.Find(parts, part => part.StartsWith(IsAscendingKey)); var isAscending = isAscendingPart?.Trim().Replace(IsAscendingKey, string.Empty).Equals("true", StringComparison.OrdinalIgnoreCase) ?? false; if (sortFieldPart == null) diff --git a/API/I18N/en.json b/API/I18N/en.json index 2f3dd6fb5..4c1c5b8c4 100644 --- a/API/I18N/en.json +++ b/API/I18N/en.json @@ -151,6 +151,10 @@ "browse-libraries": "Browse by Libraries", "collections": "All Collections", "browse-collections": "Browse by Collections", + "more-in-genre": "More in Genre {0}", + "browse-more-in-genre": "Browse more in {0}", + "recently-updated": "Recently Updated", + "browse-recently-updated": "Browse Recently Updated", "smart-filters": "Smart Filters", "external-sources": "External Sources", "browse-external-sources": "Browse External Sources", diff --git a/API/Middleware/RateLimit/AuthenticationRateLimiterPolicy.cs b/API/Middleware/RateLimit/AuthenticationRateLimiterPolicy.cs index f7732b7bd..c2119bb13 100644 --- a/API/Middleware/RateLimit/AuthenticationRateLimiterPolicy.cs +++ b/API/Middleware/RateLimit/AuthenticationRateLimiterPolicy.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.RateLimiting; namespace API.Middleware.RateLimit; +#nullable enable public class AuthenticationRateLimiterPolicy : IRateLimiterPolicy { diff --git a/API/Program.cs b/API/Program.cs index 09c1707af..c6666075b 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -25,6 +25,7 @@ using Serilog.Events; using Serilog.Sinks.AspNetCore.SignalR.Extensions; namespace API; +#nullable enable public class Program { diff --git a/API/Services/BookService.cs b/API/Services/BookService.cs index 857088d50..7b0ecbbbb 100644 --- a/API/Services/BookService.cs +++ b/API/Services/BookService.cs @@ -199,7 +199,6 @@ public class BookService : IBookService } if (!book.Content.AllFiles.TryGetLocalFileRefByKey(key, out var bookFile)) continue; - //var bookFile = book.Content.AllFiles.Local[key]; var content = await bookFile.ReadContentAsBytesAsync(); importBuilder.Append(Encoding.UTF8.GetString(content)); } @@ -555,7 +554,6 @@ public class BookService : IBookService // If this is a single book and not a collection, set publication status to Completed if (string.IsNullOrEmpty(info.Volume) && Parser.ParseVolume(filePath).Equals(Parser.DefaultVolume)) { - //info.Number = "1"; info.Count = 1; } @@ -938,8 +936,9 @@ public class BookService : IBookService /// /// /// - private static string CoalesceKey(EpubBookRef book, IReadOnlyDictionary mappings, string key) + private static string? CoalesceKey(EpubBookRef book, IReadOnlyDictionary mappings, string? key) { + if (string.IsNullOrEmpty(key)) return key; if (mappings.ContainsKey(CleanContentKeys(key))) return key; // Fallback to searching for key (bad epub metadata) @@ -949,7 +948,7 @@ public class BookService : IBookService key = correctedKey; } - var stepsBack = CountParentDirectory(book.Content.NavigationHtmlFile?.FilePath); // FileName -> FilePath + var stepsBack = CountParentDirectory(book.Content.NavigationHtmlFile?.FilePath); if (mappings.TryGetValue(key, out _)) { return key; diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index 67464bad3..15afddf95 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -644,10 +644,10 @@ public class DirectoryService : IDirectoryService /// Scans a directory by utilizing a recursive folder search. If a .kavitaignore file is found, will ignore matching patterns /// /// - /// + /// /// /// - public IList ScanFiles(string folderPath, string supportedExtensions, GlobMatcher? matcher = null) + public IList ScanFiles(string folderPath, string fileTypes, GlobMatcher? matcher = null) { _logger.LogDebug("[ScanFiles] called on {Path}", folderPath); var files = new List(); @@ -668,19 +668,19 @@ public class DirectoryService : IDirectoryService foreach (var directory in directories) { - files.AddRange(ScanFiles(directory, supportedExtensions, matcher)); + files.AddRange(ScanFiles(directory, fileTypes, matcher)); } // Get the matcher from either ignore or global (default setup) if (matcher == null) { - files.AddRange(GetFilesWithCertainExtensions(folderPath, supportedExtensions)); + files.AddRange(GetFilesWithCertainExtensions(folderPath, fileTypes)); } else { var foundFiles = GetFilesWithCertainExtensions(folderPath, - supportedExtensions) + fileTypes) .Where(file => !matcher.ExcludeMatches(FileSystem.FileInfo.New(file).Name)); files.AddRange(foundFiles); } diff --git a/API/Services/EmailService.cs b/API/Services/EmailService.cs index e6f9c1684..3086abb25 100644 --- a/API/Services/EmailService.cs +++ b/API/Services/EmailService.cs @@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace API.Services; +#nullable enable public interface IEmailService { diff --git a/API/Services/MetadataService.cs b/API/Services/MetadataService.cs index 3a65f4e57..f7ba8a4d7 100644 --- a/API/Services/MetadataService.cs +++ b/API/Services/MetadataService.cs @@ -14,6 +14,7 @@ using Hangfire; using Microsoft.Extensions.Logging; namespace API.Services; +#nullable enable public interface IMetadataService { diff --git a/API/Services/Plus/ExternalMetadataService.cs b/API/Services/Plus/ExternalMetadataService.cs index 48103ef53..cda7fe76e 100644 --- a/API/Services/Plus/ExternalMetadataService.cs +++ b/API/Services/Plus/ExternalMetadataService.cs @@ -31,7 +31,7 @@ internal class ExternalMetadataIdsDto public interface IExternalMetadataService { - Task GetExternalSeriesDetail(int? aniListId, long? malId, int? seriesId); + Task GetExternalSeriesDetail(int? aniListId, long? malId, int? seriesId); } public class ExternalMetadataService : IExternalMetadataService diff --git a/API/Services/ReaderService.cs b/API/Services/ReaderService.cs index 052bf87f2..be46fc90b 100644 --- a/API/Services/ReaderService.cs +++ b/API/Services/ReaderService.cs @@ -22,6 +22,7 @@ using Kavita.Common; using Microsoft.Extensions.Logging; namespace API.Services; +#nullable enable public interface IReaderService { diff --git a/API/Services/ReadingListService.cs b/API/Services/ReadingListService.cs index 66dc01431..d5d5d3152 100644 --- a/API/Services/ReadingListService.cs +++ b/API/Services/ReadingListService.cs @@ -21,6 +21,7 @@ using Kavita.Common; using Microsoft.Extensions.Logging; namespace API.Services; +#nullable enable public interface IReadingListService { diff --git a/API/Services/Tasks/Scanner/ParseScannedFiles.cs b/API/Services/Tasks/Scanner/ParseScannedFiles.cs index 585a60073..6c1852846 100644 --- a/API/Services/Tasks/Scanner/ParseScannedFiles.cs +++ b/API/Services/Tasks/Scanner/ParseScannedFiles.cs @@ -399,7 +399,7 @@ public class ParseScannedFiles /// World of Acceleration v02.cbz having Series "Accel World" and Localized Series of "World of Acceleration" /// /// A collection of ParserInfos - private void MergeLocalizedSeriesWithSeries(IReadOnlyCollection infos) + private void MergeLocalizedSeriesWithSeries(IReadOnlyCollection infos) { var hasLocalizedSeries = infos.Any(i => !string.IsNullOrEmpty(i.LocalizedSeries)); if (!hasLocalizedSeries) return; diff --git a/API/Services/Tasks/Scanner/Parser/DefaultParser.cs b/API/Services/Tasks/Scanner/Parser/DefaultParser.cs index d54404c22..742ed50d1 100644 --- a/API/Services/Tasks/Scanner/Parser/DefaultParser.cs +++ b/API/Services/Tasks/Scanner/Parser/DefaultParser.cs @@ -34,7 +34,7 @@ public class DefaultParser : IDefaultParser public ParserInfo? Parse(string filePath, string rootPath, LibraryType type = LibraryType.Manga) { var fileName = _directoryService.FileSystem.Path.GetFileNameWithoutExtension(filePath); - // TODO: Potential Bug: This will return null, but on Image libraries, if all images, we would want to include this. (we can probably remove this and have users use kavitaignore) + // TODO: Potential Bug: This will return null, but on Image libraries, if all images, we would want to include this. if (type != LibraryType.Image && Parser.IsCoverImage(_directoryService.FileSystem.Path.GetFileName(filePath))) return null; var ret = new ParserInfo() diff --git a/API/Services/Tasks/ScannerService.cs b/API/Services/Tasks/ScannerService.cs index c59cb4cef..48cec71ff 100644 --- a/API/Services/Tasks/ScannerService.cs +++ b/API/Services/Tasks/ScannerService.cs @@ -501,7 +501,6 @@ public class ScannerService : IScannerService // { // await task(); // } - // TODO: We might be able to do Task.WhenAll await _eventHub.SendMessageAsync(MessageFactory.NotificationProgress, MessageFactory.FileScanProgressEvent(string.Empty, library.Name, ProgressEventType.Ended)); diff --git a/API/Services/Tasks/StatsService.cs b/API/Services/Tasks/StatsService.cs index f635ff9af..affe1300a 100644 --- a/API/Services/Tasks/StatsService.cs +++ b/API/Services/Tasks/StatsService.cs @@ -37,7 +37,7 @@ public class StatsService : IStatsService private readonly IUnitOfWork _unitOfWork; private readonly DataContext _context; private readonly IStatisticService _statisticService; - private const string ApiUrl = "https://stats.kavitareader.com"; // "" + private const string ApiUrl = "https://stats.kavitareader.com"; public StatsService(ILogger logger, IUnitOfWork unitOfWork, DataContext context, IStatisticService statisticService) { diff --git a/API/Services/Tasks/VersionUpdaterService.cs b/API/Services/Tasks/VersionUpdaterService.cs index d13461fee..5dbcd1d15 100644 --- a/API/Services/Tasks/VersionUpdaterService.cs +++ b/API/Services/Tasks/VersionUpdaterService.cs @@ -13,7 +13,6 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace API.Services.Tasks; - #nullable enable internal class GithubReleaseMetadata @@ -76,7 +75,7 @@ public class VersionUpdaterService : IVersionUpdaterService /// Fetches the latest release from Github /// /// Latest update - public async Task CheckForUpdate() + public async Task CheckForUpdate() { var update = await GetGithubRelease(); return CreateDto(update); diff --git a/API/Services/TokenService.cs b/API/Services/TokenService.cs index b6b0ade47..bc69c0ff2 100644 --- a/API/Services/TokenService.cs +++ b/API/Services/TokenService.cs @@ -17,6 +17,7 @@ using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegiste namespace API.Services; +#nullable enable public interface ITokenService { diff --git a/API/SignalR/EventHub.cs b/API/SignalR/EventHub.cs index fcdc17b14..25bf5a819 100644 --- a/API/SignalR/EventHub.cs +++ b/API/SignalR/EventHub.cs @@ -21,13 +21,11 @@ public class EventHub : IEventHub { private readonly IHubContext _messageHub; private readonly IPresenceTracker _presenceTracker; - private readonly IUnitOfWork _unitOfWork; - public EventHub(IHubContext messageHub, IPresenceTracker presenceTracker, IUnitOfWork unitOfWork) + public EventHub(IHubContext messageHub, IPresenceTracker presenceTracker) { _messageHub = messageHub; _presenceTracker = presenceTracker; - _unitOfWork = unitOfWork; // TODO: When sending a message, queue the message up and on re-connect, reply the queued messages. Queue messages expire on a rolling basis (rolling array) } diff --git a/API/SignalR/LogHub.cs b/API/SignalR/LogHub.cs index 975711dfd..c52121b7d 100644 --- a/API/SignalR/LogHub.cs +++ b/API/SignalR/LogHub.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; namespace API.SignalR; +#nullable enable public interface ILogHub : Serilog.Sinks.AspNetCore.SignalR.Interfaces.IHub { diff --git a/API/SignalR/MessageHub.cs b/API/SignalR/MessageHub.cs index 85c1467fb..d06d27832 100644 --- a/API/SignalR/MessageHub.cs +++ b/API/SignalR/MessageHub.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; namespace API.SignalR; +#nullable enable /// /// Generic hub for sending messages to UI diff --git a/API/SignalR/Presence/PresenceTracker.cs b/API/SignalR/Presence/PresenceTracker.cs index 87d748841..600a4197a 100644 --- a/API/SignalR/Presence/PresenceTracker.cs +++ b/API/SignalR/Presence/PresenceTracker.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using API.Data; namespace API.SignalR.Presence; +#nullable enable public interface IPresenceTracker { @@ -22,7 +23,6 @@ internal class ConnectionDetail public bool IsAdmin { get; set; } } -// TODO: This can respond to UserRoleUpdate events to handle online users /// /// This is a singleton service for tracking what users have a SignalR connection and their difference connectionIds /// diff --git a/API/SignalR/SignalRMessage.cs b/API/SignalR/SignalRMessage.cs index d3f250293..f00a677b9 100644 --- a/API/SignalR/SignalRMessage.cs +++ b/API/SignalR/SignalRMessage.cs @@ -1,6 +1,7 @@ using System; namespace API.SignalR; +#nullable enable /// /// Payload for SignalR messages to Frontend diff --git a/API/Startup.cs b/API/Startup.cs index 8cf120789..939bfb586 100644 --- a/API/Startup.cs +++ b/API/Startup.cs @@ -232,7 +232,6 @@ public class Startup Task.Run(async () => { // Apply all migrations on startup - var userManager = serviceProvider.GetRequiredService>(); var dataContext = serviceProvider.GetRequiredService(); diff --git a/Kavita.Common/Kavita.Common.csproj b/Kavita.Common/Kavita.Common.csproj index 93143bf29..9e8ecaa91 100644 --- a/Kavita.Common/Kavita.Common.csproj +++ b/Kavita.Common/Kavita.Common.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 kavitareader.com Kavita 0.7.11.2 @@ -12,9 +12,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/README.md b/README.md index 5380a52bf..484331e7e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ install methods and platforms. **Note: Kavita is under heavy development and is being updated all the time, so the tag for bleeding edge builds is `:nightly`. The `:latest` tag will be the latest stable release.** ## Feature Requests -Got a great idea? Throw it up on our [Feature Request site](https://feats.kavitareader.com/) or vote on another idea. Please check the [Project Board](https://github.com/Kareadita/Kavita/projects?type=classic) first for a list of planned features before you submit an idea. +Got a great idea? Throw it up on our [Feature Request site](https://feats.kavitareader.com/), [Feature Discord Channel](https://discord.com/channels/821879810934439936/1164375153493422122) or vote on another idea. Please check the [Project Board](https://github.com/Kareadita/Kavita/projects?type=classic) first for a list of planned features before you submit an idea. ## Notice Kavita is being actively developed and should be considered beta software until the 1.0 release. @@ -107,7 +107,7 @@ Thank you to [ JetBrains](http: Thank you to [Weblate](https://hosted.weblate.org/engage/kavita/) who hosts our localization infrastructure pro-bono. If you want to see Kavita in your language, please help us localize. - Translation status +Translation status ## PikaPods diff --git a/UI/Web/package-lock.json b/UI/Web/package-lock.json index 9202c54f8..fdaa38ef8 100644 --- a/UI/Web/package-lock.json +++ b/UI/Web/package-lock.json @@ -8,26 +8,26 @@ "name": "kavita-webui", "version": "0.4.2", "dependencies": { - "@angular/animations": "^17.0.4", - "@angular/cdk": "^17.0.1", - "@angular/common": "^17.0.4", - "@angular/compiler": "^17.0.4", - "@angular/core": "^17.0.4", - "@angular/forms": "^17.0.4", - "@angular/localize": "^17.0.4", - "@angular/platform-browser": "^17.0.4", - "@angular/platform-browser-dynamic": "^17.0.4", - "@angular/router": "^17.0.4", + "@angular/animations": "^17.0.6", + "@angular/cdk": "^17.0.4", + "@angular/common": "^17.0.6", + "@angular/compiler": "^17.0.6", + "@angular/core": "^17.0.6", + "@angular/forms": "^17.0.6", + "@angular/localize": "^17.0.6", + "@angular/platform-browser": "^17.0.6", + "@angular/platform-browser-dynamic": "^17.0.6", + "@angular/router": "^17.0.6", "@fortawesome/fontawesome-free": "^6.4.2", "@iharbeck/ngx-virtual-scroller": "^17.0.0", "@iplab/ngx-file-upload": "^17.0.0", - "@microsoft/signalr": "^7.0.12", + "@microsoft/signalr": "^8.0.0", "@ng-bootstrap/ng-bootstrap": "^16.0.0", - "@ngneat/transloco": "^6.0.0", + "@ngneat/transloco": "^6.0.4", "@ngneat/transloco-locale": "^5.1.1", "@ngneat/transloco-persist-lang": "^5.0.0", "@ngneat/transloco-persist-translations": "^5.0.0", - "@ngneat/transloco-preload-langs": "^5.0.0", + "@ngneat/transloco-preload-langs": "^5.0.1", "@popperjs/core": "^2.11.7", "@swimlane/ngx-charts": "^20.5.0", "@tweenjs/tween.js": "^21.0.0", @@ -53,17 +53,17 @@ "zone.js": "^0.14.2" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.0.3", - "@angular-eslint/builder": "^17.1.0", - "@angular-eslint/eslint-plugin": "^17.1.0", - "@angular-eslint/eslint-plugin-template": "^17.1.0", - "@angular-eslint/schematics": "^17.1.0", - "@angular-eslint/template-parser": "^17.1.0", - "@angular/cli": "^17.0.3", - "@angular/compiler-cli": "^17.0.4", + "@angular-devkit/build-angular": "^17.0.7", + "@angular-eslint/builder": "^17.1.1", + "@angular-eslint/eslint-plugin": "^17.1.1", + "@angular-eslint/eslint-plugin-template": "^17.1.1", + "@angular-eslint/schematics": "^17.1.1", + "@angular-eslint/template-parser": "^17.1.1", + "@angular/cli": "^17.0.7", + "@angular/compiler-cli": "^17.0.6", "@types/d3": "^7.4.3", "@types/file-saver": "^2.0.7", - "@types/luxon": "^3.3.5", + "@types/luxon": "^3.3.7", "@types/node": "^20.10.0", "@typescript-eslint/eslint-plugin": "^6.13.0", "@typescript-eslint/parser": "^6.13.0", @@ -97,12 +97,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1700.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.3.tgz", - "integrity": "sha512-HUjx7vD16paWXHKHYc2LsSn/kaYbFr2YNnlzuSr9C0kauKS1e7sRpRvtGwQzXfohzgyKi81AAU5uA2KLRGq83w==", + "version": "0.1700.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.7.tgz", + "integrity": "sha512-32uitQKsYLGXAKoXBsmOnPsTt9pS+b9cnFI9ZvBFVhJ31I2EOM7vGcMFalhTxdB/DkVHk4TyO78efV0V26DwCA==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.3", + "@angular-devkit/core": "17.0.7", "rxjs": "7.8.1" }, "engines": { @@ -112,15 +112,15 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.0.3.tgz", - "integrity": "sha512-1lx0mERC1eTHX4vf8q7kUHZNHS0jwZxbwYHAISOplwHjkzRociX0W6rx04yMXn2NCSNhK+w3xbWyAIgyYbP9nA==", + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.0.7.tgz", + "integrity": "sha512-AtEzLk6n6BXqQzk0Bsupe6GV0IgUe7RbpBfqROi+NZqMA7OUAHCX3xA6M68Qu+5KxBtW7T5lHeZZ7iP/y39wtQ==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.1", - "@angular-devkit/architect": "0.1700.3", - "@angular-devkit/build-webpack": "0.1700.3", - "@angular-devkit/core": "17.0.3", + "@angular-devkit/architect": "0.1700.7", + "@angular-devkit/build-webpack": "0.1700.7", + "@angular-devkit/core": "17.0.7", "@babel/core": "7.23.2", "@babel/generator": "7.23.0", "@babel/helper-annotate-as-pure": "7.22.5", @@ -131,7 +131,7 @@ "@babel/preset-env": "7.23.2", "@babel/runtime": "7.23.2", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "17.0.3", + "@ngtools/webpack": "17.0.7", "@vitejs/plugin-basic-ssl": "1.0.1", "ansi-colors": "4.1.3", "autoprefixer": "10.4.16", @@ -176,7 +176,7 @@ "tree-kill": "1.2.2", "tslib": "2.6.2", "undici": "5.27.2", - "vite": "4.5.0", + "vite": "4.5.1", "webpack": "5.89.0", "webpack-dev-middleware": "6.1.1", "webpack-dev-server": "4.15.1", @@ -670,12 +670,12 @@ "dev": true }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1700.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1700.3.tgz", - "integrity": "sha512-r8nVakAnwV5Yy2AjWDpdcGUjHRQBcPljZDhX5tX2H7M3bxD6zG5owXDy8XmG64A7U1jd6D7dQv7zoW/tZwpYvw==", + "version": "0.1700.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1700.7.tgz", + "integrity": "sha512-B9Mg/qYDpE5my8PJ3VPQyRSUV0Oq1bFUzU8s0ZpqEZl1URKc04pm0LtLmebrMIcUZgDiGk0RHaD+O1E9IV/bdQ==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1700.3", + "@angular-devkit/architect": "0.1700.7", "rxjs": "7.8.1" }, "engines": { @@ -689,9 +689,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.3.tgz", - "integrity": "sha512-SOngD3rKnwZWhhUV68AYlH8M3LRGvF69jnDrYKwtRy1ESqSH7tt+1vexGC290gKvqH7bNMgYv8f5BS1AASRfzw==", + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.7.tgz", + "integrity": "sha512-vATobHo5O5tJba424hJfQWLb40GzvZPNsI74dcgSUTgrDph8ksmk5xB9OvEvf0INorQZ2IMphj/VIWj4/+JqSA==", "dev": true, "dependencies": { "ajv": "8.12.0", @@ -728,12 +728,12 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.0.3.tgz", - "integrity": "sha512-gNocyYuNJRd24+JSM5kpO7g9Vg4THcoH5It8nJmS3muelLHDzegvDzXB7iPBjVR8Lxts6sbifYdIkKencUc4vg==", + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.0.7.tgz", + "integrity": "sha512-BY11OkJkM3xyXcvyD7x5kGY/c8Ufd4AfPvI0D9imhVxbns45Q48b1DlvCQvSnCJ/s+OwnkrYb/Efa70ZiaGu8A==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.3", + "@angular-devkit/core": "17.0.7", "jsonc-parser": "3.2.0", "magic-string": "0.30.5", "ora": "5.4.1", @@ -746,13 +746,13 @@ } }, "node_modules/@angular-eslint/builder": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-17.1.0.tgz", - "integrity": "sha512-rLIInxx9q82DDrfcg5gzjNftxhkqdLILUgjlA9XtA9LayU3rz4CS81we+vAOAPbbnGxoMsEeBg5nVecbKN3dVQ==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-17.1.1.tgz", + "integrity": "sha512-QGnIaypNP1osDObTIRJ5JF1KdMBn2oghZXMZAFN+qc+4+EX0SLfrSVw0YTZRH1Sg8ns3/Q+E6jYrswrhV1JmKQ==", "dev": true, "dependencies": { - "@nx/devkit": "17.1.2", - "nx": "17.1.2" + "@nx/devkit": "17.1.3", + "nx": "17.1.3" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", @@ -760,19 +760,19 @@ } }, "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.1.0.tgz", - "integrity": "sha512-Y+CN/8nQZaYjsb2b2sXbkQr0LrgBWhCzyLZ+rLfnLE60B9k4GeDt5b7z/OdSObi1xozXfqiaAZ1eXo0iQMN3JA==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.1.1.tgz", + "integrity": "sha512-xRlSh9qjdUdUKAy/0UQsxX7wf1tHApAsHsfismebPriqfmVAPyEg4HBrM8ImWaZxiqaTGC1AyHsUBQD5FK8o6w==", "dev": true }, "node_modules/@angular-eslint/eslint-plugin": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-17.1.0.tgz", - "integrity": "sha512-pQac5h+XwsquDzaasK/xs9tjdQ/f9eLq8e5An9eXJGHWy4KcrMmQ1XrpaMMMg503LF3rRG/dHKBskGsYgSN9oQ==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-17.1.1.tgz", + "integrity": "sha512-fFOBlCOVObVu3gjLj+0BypqO1ZR/0bfJnDElqMdYwJG7zRaFT8NNQbrOo/q/GQoqOFoNna6mw3teTGsd5JnL2A==", "dev": true, "dependencies": { - "@angular-eslint/utils": "17.1.0", - "@typescript-eslint/utils": "6.11.0" + "@angular-eslint/utils": "17.1.1", + "@typescript-eslint/utils": "6.13.1" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", @@ -780,15 +780,15 @@ } }, "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.1.0.tgz", - "integrity": "sha512-nL9VhChwFQLIRQM4xbTY8Vo095Q4/D77hPtqt3ShYIrORjYTwaWa8+neexToAqXVMapce7oFmFa/OqtxvEerLg==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.1.1.tgz", + "integrity": "sha512-unZ6QNwtxuB8Eni7UPdw7uK6iZipZUXIsH+ZuLMOxwFgGMqeRnpv8SW0212rto3d/Ec0jESzVHKcwZ9pT+jxgw==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.1.0", - "@angular-eslint/utils": "17.1.0", - "@typescript-eslint/type-utils": "6.11.0", - "@typescript-eslint/utils": "6.11.0", + "@angular-eslint/bundled-angular-compiler": "17.1.1", + "@angular-eslint/utils": "17.1.1", + "@typescript-eslint/type-utils": "6.13.1", + "@typescript-eslint/utils": "6.13.1", "aria-query": "5.3.0", "axobject-query": "4.0.0" }, @@ -798,16 +798,16 @@ } }, "node_modules/@angular-eslint/schematics": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-17.1.0.tgz", - "integrity": "sha512-74gW1E5P4z3PvxNXOTXGaF6li/MLcSeJO8z7XtcP7wcXWu0fihOKlMJGgqB3rIcBa8lRcTDLekQERF+kRZ15aQ==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-17.1.1.tgz", + "integrity": "sha512-Bkt8iOXWRQGSrcLRGzdyJLvSPcIChW5+dh5lXa5GhdLmVAF7jpjxqGwW0rNb5JhLa/phyH0XQIpLBaOPtacSMA==", "dev": true, "dependencies": { - "@angular-eslint/eslint-plugin": "17.1.0", - "@angular-eslint/eslint-plugin-template": "17.1.0", - "@nx/devkit": "17.1.2", - "ignore": "5.2.4", - "nx": "17.1.2", + "@angular-eslint/eslint-plugin": "17.1.1", + "@angular-eslint/eslint-plugin-template": "17.1.1", + "@nx/devkit": "17.1.3", + "ignore": "5.3.0", + "nx": "17.1.3", "strip-json-comments": "3.1.1", "tmp": "0.2.1" }, @@ -816,12 +816,12 @@ } }, "node_modules/@angular-eslint/template-parser": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-17.1.0.tgz", - "integrity": "sha512-CTxzB3stjynngTabdO8xTkiPc6Jvo15C2fxb1pYIlDIH2LgPJJxxCHi+IAt9oJpJOPa8QjLVF9VAXE3fLKAcpg==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-17.1.1.tgz", + "integrity": "sha512-ofL46rNhRVeSxrSQF0vwhKMco+vJuo+ZGjSOzFmT9N3KAMB0j+WXTbpyGGMy0gQSBc4W6p+j+zxGa2CR2xb6wA==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.1.0", + "@angular-eslint/bundled-angular-compiler": "17.1.1", "eslint-scope": "^7.0.0" }, "peerDependencies": { @@ -830,13 +830,13 @@ } }, "node_modules/@angular-eslint/utils": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-17.1.0.tgz", - "integrity": "sha512-AmG0xpRtnBQwrbHObonSilmD3hiFEtZHwFY3LT28VWxznB6WIAHFE7SrKWrRsRsXlib8LaRo4uobR5+MO8aLpw==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-17.1.1.tgz", + "integrity": "sha512-CTNPOb05S/DII/Fm8JYUvKo+B4u/ctHjGJ0X1YXUR0q31oaGqTE3KePGq76+Y6swRDf9NjUIcfcnZp3u3j4CBQ==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.1.0", - "@typescript-eslint/utils": "6.11.0" + "@angular-eslint/bundled-angular-compiler": "17.1.1", + "@typescript-eslint/utils": "6.13.1" }, "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", @@ -844,9 +844,9 @@ } }, "node_modules/@angular/animations": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-17.0.4.tgz", - "integrity": "sha512-XHkTBZAoYf1t4Hb06RkYa6cgtjEA5JGq1ArXu/DckOS6G/ZuY+dwWULEmaf9ejJem8O78ol223ZQ5d7sXqpixQ==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-17.0.6.tgz", + "integrity": "sha512-fic61LjLHry79c5H9UGM8Ff311MJnf9an7EukLj2aLJ3J0uadL/H9de7dDp8PaIT10DX9g+aRTIKOmF3PmmXIQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -854,13 +854,13 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.0.4" + "@angular/core": "17.0.6" } }, "node_modules/@angular/cdk": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.0.1.tgz", - "integrity": "sha512-0hrXm2D0s0/vUtDoLFRWTs75k5WY/hQmfnsaJXHeqinbE3eKOxmQxL1i7ymnMSQthEWzgRAhzS3Nfs7Alw3dQA==", + "version": "17.0.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.0.4.tgz", + "integrity": "sha512-mh/EuIR0NPfpNqAXBSZWuJeBMXUvUDYdKhiFWZet5NLO1bDgFe1MGLBjtW4us95k4BZsMLbCKNxJgc+4JqwUvg==", "dependencies": { "tslib": "^2.3.0" }, @@ -874,15 +874,15 @@ } }, "node_modules/@angular/cli": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.0.3.tgz", - "integrity": "sha512-pRGXms87aEqmB4yPdcPI/VM7JegjDcBIeLadms0wrBkoyQiv+jL5LesxODhid6ujXZOj1xqMCYbCnX7HY+mLcQ==", + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.0.7.tgz", + "integrity": "sha512-oSa0GVAQNA7wFbLJYeaO3kV4iUcbKEqXDLxcIE8s1GfHddBOlXH2P1T4fXonCBl5qvV+joP0G0+fs7I0w2utZQ==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1700.3", - "@angular-devkit/core": "17.0.3", - "@angular-devkit/schematics": "17.0.3", - "@schematics/angular": "17.0.3", + "@angular-devkit/architect": "0.1700.7", + "@angular-devkit/core": "17.0.7", + "@angular-devkit/schematics": "17.0.7", + "@schematics/angular": "17.0.7", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "ini": "4.1.1", @@ -941,9 +941,9 @@ "dev": true }, "node_modules/@angular/common": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.0.4.tgz", - "integrity": "sha512-/y38PbuiaWOuOmP5ZELTlJSjZGijc6Nq2XQloT5pKsaH935prxPjyWazwlY6cUnJMQgSRU644/ULosDJec7Zxw==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.0.6.tgz", + "integrity": "sha512-FZtf8ol8W2V21ZDgFtcxmJ6JJKUO97QZ+wr/bosyYEryWMmn6VGrbOARhfW7BlrEgn14NdFkLb72KKtqoqRjrg==", "dependencies": { "tslib": "^2.3.0" }, @@ -951,14 +951,14 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.0.4", + "@angular/core": "17.0.6", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.0.4.tgz", - "integrity": "sha512-OweJui9EWCa1ZcZjkJHS5z1gqICqyryR1Gdmyr8vIa6HD8wU/5BaeBJPCDgYgt+qJkvcT/sPxgZQsc2pVeUwbQ==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.0.6.tgz", + "integrity": "sha512-PaCNnlPcL0rvByKCBUUyLWkKJYXOrcfKlYYvcacjOzEUgZeEpekG81hMRb9u/Pz+A+M4HJSTmdgzwGP35zo8qw==", "dependencies": { "tslib": "^2.3.0" }, @@ -966,7 +966,7 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.0.4" + "@angular/core": "17.0.6" }, "peerDependenciesMeta": { "@angular/core": { @@ -975,10 +975,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.0.4.tgz", - "integrity": "sha512-ywj8XNI+hvHHYGcNWvXaVHSRtcd3S7MqJNgXWfnb0JjAb282oGSvjEc7wnH4ERqkvnSrpk1kQ2Fj3uJ2P5zfmQ==", - "dev": true, + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.0.6.tgz", + "integrity": "sha512-C1Gfh9kbjYZezEMOwxnvUTHuPXa+6pk7mAfSj8e5oAO6E+wfo2dTxv1J5zxa3KYzxPYMNfF8OFvLuMKsw7lXjA==", "dependencies": { "@babel/core": "7.23.2", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -998,14 +997,14 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/compiler": "17.0.4", + "@angular/compiler": "17.0.6", "typescript": ">=5.2 <5.3" } }, "node_modules/@angular/core": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.0.4.tgz", - "integrity": "sha512-zk+z5sYPZd87pLxECx27quB5FvSmoi9PjJlcSlaBwwqaGnh/tPJI14u3q1dRY/CoZgP9egEiwc428+DzvOzJew==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.0.6.tgz", + "integrity": "sha512-QzfKRTDNgGOY9D5VxenUUz20cvPVC+uVw9xiqkDuHgGfLYVFlCAK9ymFYkdUCLTcVzJPxckP+spMpPX8nc4Aqw==", "dependencies": { "tslib": "^2.3.0" }, @@ -1018,9 +1017,9 @@ } }, "node_modules/@angular/forms": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.0.4.tgz", - "integrity": "sha512-R5J87dfJNWwi5SESD7tRkZnqG4u8KNAT4vImX4oG70/6vWioKUSWpLoSp1gpzy9UW51E85AKb8DNvIex7LclSg==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.0.6.tgz", + "integrity": "sha512-n/trsMtQHUBGiWz5lFaggMcMOuw0gH+96TCtHxQiUYJOdrbOemkFdGrNh3B4fGHmogWuOYJVF5FAm97WRES2XA==", "dependencies": { "tslib": "^2.3.0" }, @@ -1028,16 +1027,16 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.0.4", - "@angular/core": "17.0.4", - "@angular/platform-browser": "17.0.4", + "@angular/common": "17.0.6", + "@angular/core": "17.0.6", + "@angular/platform-browser": "17.0.6", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/localize": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-17.0.4.tgz", - "integrity": "sha512-4kLvkwAI9lVaxKzMVjF/0do/Xfn4r3W1bk9Xzb7fYLS21wz11ouL0aV7umtHT5DOZiwkY/F8rOYaJm5Fkz8ubw==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-17.0.6.tgz", + "integrity": "sha512-LHLadqRQ4lnM0VxWZld2JLO50t3URi7on0YhZp6p/xhY6cQLcTG3GDNGC/k8dg8JW/7aXJU0hmJEMcop9ELM7g==", "dependencies": { "@babel/core": "7.23.2", "fast-glob": "3.3.1", @@ -1052,14 +1051,14 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/compiler": "17.0.4", - "@angular/compiler-cli": "17.0.4" + "@angular/compiler": "17.0.6", + "@angular/compiler-cli": "17.0.6" } }, "node_modules/@angular/platform-browser": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.0.4.tgz", - "integrity": "sha512-lApUzVPfCEz/4aot77qzWUNg7yQgT0JSzy3BrBm95+2TbgH894J9Fswhig0sEN9jxGSkc3A5Yp5fs1HJcPqUiw==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.0.6.tgz", + "integrity": "sha512-nBhWH1MKT2WswgRNIoMnmNAt0n5/fG59BanJtodW71//Aj5aIE+BuVoFgK3wmO8IMoeP4i4GXRInBXs6lUMOJw==", "dependencies": { "tslib": "^2.3.0" }, @@ -1067,9 +1066,9 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/animations": "17.0.4", - "@angular/common": "17.0.4", - "@angular/core": "17.0.4" + "@angular/animations": "17.0.6", + "@angular/common": "17.0.6", + "@angular/core": "17.0.6" }, "peerDependenciesMeta": { "@angular/animations": { @@ -1078,9 +1077,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.0.4.tgz", - "integrity": "sha512-mZZNH+iFzFug0z7rBQKdFz375sR6Y4iBbHu2aJD2BpgA2/SJaZ0WHGlF4bHbtpCYkZi3f4wKF2+Cwe4G5ebPOQ==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.0.6.tgz", + "integrity": "sha512-5ZEmBtBkqamTaWjUXCls7G1f3xyK/ykXE7hnUV9CgGqXKrNkxblmbtOhoWdsbuIYjjdxQcAk1qtg/Rg21wcc4w==", "dependencies": { "tslib": "^2.3.0" }, @@ -1088,16 +1087,16 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.0.4", - "@angular/compiler": "17.0.4", - "@angular/core": "17.0.4", - "@angular/platform-browser": "17.0.4" + "@angular/common": "17.0.6", + "@angular/compiler": "17.0.6", + "@angular/core": "17.0.6", + "@angular/platform-browser": "17.0.6" } }, "node_modules/@angular/router": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-17.0.4.tgz", - "integrity": "sha512-hQ+T+h6YE9NqyOmjqAIHe/k8xtW+yh0Mp8FCcl8REBezNyLXmOdsScCIOOc7GeFtbjRnQyJrBo4QxZ81acHP7Q==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-17.0.6.tgz", + "integrity": "sha512-xW6yDxREpBOB9MoODSfIw5HwkwLK+OgK34Q6sGYs0ft9UryMoFwft+pHGAaDz2nzhA72n+Ht9B2eai78UE9jGQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -1105,9 +1104,9 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.0.4", - "@angular/core": "17.0.4", - "@angular/platform-browser": "17.0.4", + "@angular/common": "17.0.6", + "@angular/core": "17.0.6", + "@angular/platform-browser": "17.0.6", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -3597,9 +3596,9 @@ } }, "node_modules/@microsoft/signalr": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-7.0.12.tgz", - "integrity": "sha512-k1Xu+a73PsWgHwHDm6ctHwHTBnlqCzq7L33cbxdWhj90AGDFpxDSzaGCkZDoJFNHveUetix65zIWiazMvmMg3w==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-8.0.0.tgz", + "integrity": "sha512-K/wS/VmzRWePCGqGh8MU8OWbS1Zvu7DG7LSJS62fBB8rJUXwwj4axQtqrAAwKGUZHQF6CuteuQR9xMsVpM2JNA==", "dependencies": { "abort-controller": "^3.0.0", "eventsource": "^2.0.2", @@ -3625,12 +3624,12 @@ } }, "node_modules/@ngneat/transloco": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@ngneat/transloco/-/transloco-6.0.0.tgz", - "integrity": "sha512-hpL3tgY2EYZTTDsCRSN6v+7I0neA0lSLmMVEwTU90ZkRKOV1wIh9TIFXd1slWKklxe2xQHa1AFIn3NkHRP7R+A==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@ngneat/transloco/-/transloco-6.0.4.tgz", + "integrity": "sha512-hQSPdmzuxJIu2SBwvoiwjoUjxSnUGFyCOkJnV8IwzzmBSdgQxqMMci5WXg/bQeCYggA+RyXpUjjTudEvkWy5Rw==", "dependencies": { "@ngneat/transloco-utils": "^5.0.0", - "flat": "6.0.0", + "flat": "6.0.1", "fs-extra": "^11.0.0", "glob": "^10.0.0", "lodash.kebabcase": "^4.1.1", @@ -3680,9 +3679,9 @@ } }, "node_modules/@ngneat/transloco-preload-langs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@ngneat/transloco-preload-langs/-/transloco-preload-langs-5.0.0.tgz", - "integrity": "sha512-4ub18hzu5cHcgd7QGUQFl/MqbX8ZsHE6LInY7QFSLG6PpqrKSon+JqXjyWo8hxka8Ae5tMU5fDEEZCRXN19dlw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@ngneat/transloco-preload-langs/-/transloco-preload-langs-5.0.1.tgz", + "integrity": "sha512-+HDsEtBCFTD8YY31VX9N0dPcVp/CozxmcHXTvqjJ3M0BEkkygZIoiTQwaOPiJziNjFKl8FRhAvovWVV/t8hd8g==", "dependencies": { "tslib": "^2.2.0" }, @@ -3704,9 +3703,9 @@ } }, "node_modules/@ngneat/transloco/node_modules/flat": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-6.0.0.tgz", - "integrity": "sha512-/aYW7n5yD9HyW9ZHCzW2LGSpyTmbXEdRWdH5ded6K/a2ETgowOripjBqJorQ4/PBa3VPFub28fNruWp+onmIUg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-6.0.1.tgz", + "integrity": "sha512-/3FfIa8mbrg3xE7+wAhWeV+bd7L2Mof+xtZb5dRDKZ+wDvYJK4WDYeIOuOhre5Yv5aQObZrlbRmk3RTSiuQBtw==", "bin": { "flat": "cli.js" }, @@ -3715,9 +3714,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.0.3.tgz", - "integrity": "sha512-H39WQ/tM6kOErfiyU6QkPasMtuOZHbm6INkirSR3ol4e93o6gLJ0ptwg3IQlyGtZK2QexWagPC6jzsdGIaN3iw==", + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.0.7.tgz", + "integrity": "sha512-gwhUhpwXn0trwwKdSu9WlJbEcLt+s/2fPwoD9lZ0y3wXfrOogsfcNBJKeO5BZf1h+A3AWt7ePmgrZXSJM+865Q==", "dev": true, "engines": { "node": "^18.13.0 || >=20.9.0", @@ -3953,21 +3952,21 @@ } }, "node_modules/@nrwl/devkit": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.1.2.tgz", - "integrity": "sha512-INPZk4qts3xNJt8E9fttuVTufXdigPUOvUiAiPJmR2oUGDF8SeOlIYNForbz+XMRvxyIVtf45O32azUsgeZe3Q==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.1.3.tgz", + "integrity": "sha512-8HfIY7P3yIYfQ/XKuHoq0GGLA9GpwWtBlI9kPQ0ygjuJ9BkpiGMtQvO6003zs7c6vpc2vNeG+Jmi72+EKvoN5A==", "dev": true, "dependencies": { - "@nx/devkit": "17.1.2" + "@nx/devkit": "17.1.3" } }, "node_modules/@nrwl/tao": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.1.2.tgz", - "integrity": "sha512-tL+dlygeor/kLG5fuK5qaiVFJ4hEtvJ/E+xY9epp20UKCNQSEkrSFiesiXtX6E/PPf4YbOQ4B4itWR2EYCm03Q==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.1.3.tgz", + "integrity": "sha512-9YpfEkUpVqOweqgQvMDcWApNx4jhCqBNH5IByZj302Enp3TLnQSvhuX5Dfr8hNQRQokIpEn6tW8SGTctTM5LXw==", "dev": true, "dependencies": { - "nx": "17.1.2", + "nx": "17.1.3", "tslib": "^2.3.0" }, "bin": { @@ -3975,12 +3974,12 @@ } }, "node_modules/@nx/devkit": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.1.2.tgz", - "integrity": "sha512-9Izd9jsa++AaZSSlhi0zkv58k4clzE0kICurx9DjfWN6zXnD08HqJoUYCVVaeYS/SrWlQUbMig8e49BO8ZV5mw==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.1.3.tgz", + "integrity": "sha512-1Is7ooovg3kdGJ5VdkePulRUDaMYLLULr+LwXgx7oHSW7AY2iCmhkoOE/vSR7DJ6rkey2gYx7eT1IoRoORiIaQ==", "dev": true, "dependencies": { - "@nrwl/devkit": "17.1.2", + "@nrwl/devkit": "17.1.3", "ejs": "^3.1.7", "enquirer": "~2.3.6", "ignore": "^5.0.4", @@ -3993,9 +3992,9 @@ } }, "node_modules/@nx/nx-darwin-arm64": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-17.1.2.tgz", - "integrity": "sha512-U8fwkuw0vmDfeRQX9LSMt1XiAXM57fxOiuHlrIBn8hUBvMAugAgSAYd7K9YQjrFf9UFUtQeSHDU9N/c/n63hdg==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-17.1.3.tgz", + "integrity": "sha512-f4qLa0y3C4uuhYKgq+MU892WaQvtvmHqrEhHINUOxYXNiLy2sgyJPW0mOZvzXtC4dPaUmiVaFP5RMVzc8Lxhtg==", "cpu": [ "arm64" ], @@ -4009,9 +4008,9 @@ } }, "node_modules/@nx/nx-darwin-x64": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-17.1.2.tgz", - "integrity": "sha512-QR9Jrm32UK2nLdDRtjFabfCvF5SOQJ2IuYkw6Sxe16xGZU2DS9nQku0TQO3Uy2HV1xSR7vzj7ys5z4eI2k+/mA==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-17.1.3.tgz", + "integrity": "sha512-kh76ZjqkLeQUIAfTa9G/DFFf+e1sZ5ipDzk7zFGhZ2k68PoQoFdsFOO3C513JmuEdavspts6Hkifsqh61TaE+A==", "cpu": [ "x64" ], @@ -4025,9 +4024,9 @@ } }, "node_modules/@nx/nx-freebsd-x64": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-17.1.2.tgz", - "integrity": "sha512-6rDuFHJREVg5XpcM5RlE8pHP4bgcbns8sSemF/g75SV4iEkBqxRvSe88oBtF44b7IpX2zdONRDV4qQcRf3DxRg==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-17.1.3.tgz", + "integrity": "sha512-CRuVL5ZSLb+Gc8vwMUUe9Pl/1Z26YtXMKTahBMQh2dac63vzLgzqIV4c66aduUl1x2M0kGYBSIIRG9z0/BgWeg==", "cpu": [ "x64" ], @@ -4041,9 +4040,9 @@ } }, "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-17.1.2.tgz", - "integrity": "sha512-4FwqUX7NxVfJ0v7frBKNbjENz6pvp3slDfoG2/WmnAj5a6TCu7magwlg1qLQaHYJ1m/i8u7RrG0Uz4SYHWzkVw==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-17.1.3.tgz", + "integrity": "sha512-KDBmd5tSrg93g/oij/eGW4yeVNVK3DBIM4VYAS2vtkIgVOGoqcQ+SEIeMK3nMUJP9jGyblt3QNj5ZsJBtScwQw==", "cpu": [ "arm" ], @@ -4057,9 +4056,9 @@ } }, "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-17.1.2.tgz", - "integrity": "sha512-r6UATY0dVdxwpVJPf/f/KfRkFpMP06wC6HcfNMGbTBTKiKtsdYF42bWoSkDgtgP2bOx9FDH+Hwu3U/Rtj44FIA==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-17.1.3.tgz", + "integrity": "sha512-W2tNL/7sIwoQKLmuy68Usd6TZzIZvxZt4UE30kDwGc2RSap6RCHAvDbzSxtW+L4+deC9UxX0Tty0VuW+J8FjSg==", "cpu": [ "arm64" ], @@ -4073,9 +4072,9 @@ } }, "node_modules/@nx/nx-linux-arm64-musl": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-17.1.2.tgz", - "integrity": "sha512-MXGYY/KCzQhbj5UKwnRO2/GhByOkRlI+EeH1Mazam8wZ1BiBfcVWZoOUybIlxxes1o4cAnkZwB527tCmwrHvGw==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-17.1.3.tgz", + "integrity": "sha512-Oto3gkLd7yweuVUCsSHwm4JkAIbcxpPJP0ycRHI/PRHPMIOPiMX8r651QM1amMyKAbJtAe047nyb9Sh1X0FA4A==", "cpu": [ "arm64" ], @@ -4089,9 +4088,9 @@ } }, "node_modules/@nx/nx-linux-x64-gnu": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-17.1.2.tgz", - "integrity": "sha512-3cC131hJ3VhuxjzzBlwIdVp46onykOo78EmnURNdLxcWOpmcKgYXn7OnVwjrglYi+JL7D0vABGKKUpt1cs6/rA==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-17.1.3.tgz", + "integrity": "sha512-pJS994sa5PBPFak93RydTB9KdEmiVb3rgiSB7PDBegphERbzHEB77B7G8M5TZ62dGlMdplIEKmdhY5XNqeAf9A==", "cpu": [ "x64" ], @@ -4105,9 +4104,9 @@ } }, "node_modules/@nx/nx-linux-x64-musl": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-17.1.2.tgz", - "integrity": "sha512-1UrR87ByhE0zSXt0C+RNT5ZiAsctOSWZwPYQAGolz8K70BxomDeRVtIaRog5KK5SHlEd1ILvgsmrhovjLjrJNw==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-17.1.3.tgz", + "integrity": "sha512-4Hcx5Fg/88jV+bcTr6P0dM4unXNvKgrGJe3oK9/sgEhiW6pD2UAFjv16CCSRcWhDUAzUDqcwnD2fgg+vnAJG6g==", "cpu": [ "x64" ], @@ -4121,9 +4120,9 @@ } }, "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-17.1.2.tgz", - "integrity": "sha512-2M7FfzfPGAN7tCUWZilPGNk/RbbGcA00MKOA4MDqMwJtLobW8KqfMedilRNTEuyNibejOHwvGzA9T/Ac/ahHgA==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-17.1.3.tgz", + "integrity": "sha512-dUasEuskmDxUL36XA0GZqSb9233suE4wKhxrMobyFBzHUZ2tq/unzOpPjYfqDBie4QIvF8tEpAjQsLds8LWgbw==", "cpu": [ "arm64" ], @@ -4137,9 +4136,9 @@ } }, "node_modules/@nx/nx-win32-x64-msvc": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.1.2.tgz", - "integrity": "sha512-oxKCKunuo4wRusMlNu7PlhBijhtNy7eBZPAWyqUsdfnb+CjY2QncjCguW3fnsG9gHQFCa+y0b1WkSkvJ5G1DiQ==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.1.3.tgz", + "integrity": "sha512-eTuTpBHFvA5NFJh/iosmqCL4JOAjDrwXLSMgfKrZKjiApHMG1T/5Hb+PrsNpt+WnGp94ur7c4Dtx4xD5vlpAEw==", "cpu": [ "x64" ], @@ -4177,13 +4176,13 @@ } }, "node_modules/@schematics/angular": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.0.3.tgz", - "integrity": "sha512-pFHAqHMNm2WLoquJD4osSA/OAgH+wsFayPuqQnKjDEzeVW/YfJSbUksJ2iFt+uSfrhc/VxPf6pmGBMzi+9d0ng==", + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.0.7.tgz", + "integrity": "sha512-d7QKmcKrM4owb/2bR7Ipf23roiNbvbD/x7reNhQAtKAPLSHJ3Ulkf1+Yv+dj+9f+K7y9SBviEUSrD27BQ9WaxQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.0.3", - "@angular-devkit/schematics": "17.0.3", + "@angular-devkit/core": "17.0.7", + "@angular-devkit/schematics": "17.0.7", "jsonc-parser": "3.2.0" }, "engines": { @@ -4749,9 +4748,9 @@ "dev": true }, "node_modules/@types/luxon": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.5.tgz", - "integrity": "sha512-1cyf6Ge/94zlaWIZA2ei1pE6SZ8xpad2hXaYa5JEFiaUH0YS494CZwyi4MXNpXD9oEuv6ZH0Bmh0e7F9sPhmZA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.7.tgz", + "integrity": "sha512-gKc9P2d4g5uYwmy4s/MO/yOVPmvHyvzka1YH6i5dM03UrFofHSmgc0D0ymbDRStFWHusk6cwwF6nhLm/ckBbbQ==", "dev": true }, "node_modules/@types/mime": { @@ -5180,13 +5179,13 @@ "dev": true }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.11.0.tgz", - "integrity": "sha512-0A8KoVvIURG4uhxAdjSaxy8RdRE//HztaZdG8KiHLP8WOXSk0vlF7Pvogv+vlJA5Rnjj/wDcFENvDaHb+gKd1A==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.1.tgz", + "integrity": "sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.11.0", - "@typescript-eslint/visitor-keys": "6.11.0" + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -5197,13 +5196,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.11.0.tgz", - "integrity": "sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.1.tgz", + "integrity": "sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.11.0", - "@typescript-eslint/utils": "6.11.0", + "@typescript-eslint/typescript-estree": "6.13.1", + "@typescript-eslint/utils": "6.13.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -5224,9 +5223,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.11.0.tgz", - "integrity": "sha512-ZbEzuD4DwEJxwPqhv3QULlRj8KYTAnNsXxmfuUXFCxZmO6CF2gM/y+ugBSAQhrqaJL3M+oe4owdWunaHM6beqA==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.1.tgz", + "integrity": "sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -5237,13 +5236,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.11.0.tgz", - "integrity": "sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.1.tgz", + "integrity": "sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.11.0", - "@typescript-eslint/visitor-keys": "6.11.0", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -5297,17 +5296,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.11.0.tgz", - "integrity": "sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.1.tgz", + "integrity": "sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw==", "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.11.0", - "@typescript-eslint/types": "6.11.0", - "@typescript-eslint/typescript-estree": "6.11.0", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/typescript-estree": "6.13.1", "semver": "^7.5.4" }, "engines": { @@ -5355,12 +5354,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.11.0.tgz", - "integrity": "sha512-+SUN/W7WjBr05uRxPggJPSzyB8zUpaYo2hByKasWbqr3PM8AXfZt8UHdNpBS1v9SA62qnSSMF3380SwDqqprgQ==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.1.tgz", + "integrity": "sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.11.0", + "@typescript-eslint/types": "6.13.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -5818,7 +5817,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -6075,7 +6073,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, "engines": { "node": ">=8" } @@ -6685,7 +6682,6 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, "funding": [ { "type": "individual", @@ -6973,8 +6969,7 @@ "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==", - "dev": true + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/cookie": { "version": "0.4.2", @@ -7977,7 +7972,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -7987,7 +7981,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -9275,7 +9268,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -9815,9 +9807,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { "node": ">= 4" @@ -10059,7 +10051,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -11972,7 +11963,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -12118,13 +12108,13 @@ } }, "node_modules/nx": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/nx/-/nx-17.1.2.tgz", - "integrity": "sha512-pf94ri36cAiSzbYcPTJwQzttgAsHSjCLEni0Ilw6aVdjpoV2l6cggYxwddX7pgtCWuokVp/6KhAxVkbzvH65wg==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/nx/-/nx-17.1.3.tgz", + "integrity": "sha512-6LYoTt01nS1d/dvvYtRs+pEAMQmUVsd2fr/a8+X1cDjWrb8wsf1O3DwlBTqKOXOazpS3eOr0Ukc9N1svbu7uXA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@nrwl/tao": "17.1.2", + "@nrwl/tao": "17.1.3", "@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/parsers": "3.0.0-rc.46", "@zkochan/js-yaml": "0.0.6", @@ -12165,16 +12155,16 @@ "nx-cloud": "bin/nx-cloud.js" }, "optionalDependencies": { - "@nx/nx-darwin-arm64": "17.1.2", - "@nx/nx-darwin-x64": "17.1.2", - "@nx/nx-freebsd-x64": "17.1.2", - "@nx/nx-linux-arm-gnueabihf": "17.1.2", - "@nx/nx-linux-arm64-gnu": "17.1.2", - "@nx/nx-linux-arm64-musl": "17.1.2", - "@nx/nx-linux-x64-gnu": "17.1.2", - "@nx/nx-linux-x64-musl": "17.1.2", - "@nx/nx-win32-arm64-msvc": "17.1.2", - "@nx/nx-win32-x64-msvc": "17.1.2" + "@nx/nx-darwin-arm64": "17.1.3", + "@nx/nx-darwin-x64": "17.1.3", + "@nx/nx-freebsd-x64": "17.1.3", + "@nx/nx-linux-arm-gnueabihf": "17.1.3", + "@nx/nx-linux-arm64-gnu": "17.1.3", + "@nx/nx-linux-arm64-musl": "17.1.3", + "@nx/nx-linux-x64-gnu": "17.1.3", + "@nx/nx-linux-x64-musl": "17.1.3", + "@nx/nx-win32-arm64-msvc": "17.1.3", + "@nx/nx-win32-x64-msvc": "17.1.3" }, "peerDependencies": { "@swc-node/register": "^1.6.7", @@ -13400,7 +13390,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -13411,8 +13400,7 @@ "node_modules/reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", - "dev": true + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, "node_modules/regenerate": { "version": "1.4.2", @@ -13882,7 +13870,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "devOptional": true }, "node_modules/sass": { "version": "1.69.5", @@ -13998,7 +13986,6 @@ "version": "7.5.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -14013,7 +14000,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -14024,8 +14010,7 @@ "node_modules/semver/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/send": { "version": "0.16.2", @@ -15276,7 +15261,6 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15521,9 +15505,9 @@ } }, "node_modules/vite": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", - "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", + "integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -15834,9 +15818,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.1.tgz", + "integrity": "sha512-W5OZiCjXEmk0yZ66ZN82beM5Sz7l7coYxpRkzS+p9PP+ToQry8szKh+61eNktr7EA9DOwvFGhfC605jDHbP6QQ==", "dev": true, "engines": { "node": ">=10.0.0" diff --git a/UI/Web/package.json b/UI/Web/package.json index eee30e27b..6ee0f8d96 100644 --- a/UI/Web/package.json +++ b/UI/Web/package.json @@ -13,26 +13,26 @@ }, "private": true, "dependencies": { - "@angular/animations": "^17.0.4", - "@angular/cdk": "^17.0.1", - "@angular/common": "^17.0.4", - "@angular/compiler": "^17.0.4", - "@angular/core": "^17.0.4", - "@angular/forms": "^17.0.4", - "@angular/localize": "^17.0.4", - "@angular/platform-browser": "^17.0.4", - "@angular/platform-browser-dynamic": "^17.0.4", - "@angular/router": "^17.0.4", + "@angular/animations": "^17.0.6", + "@angular/cdk": "^17.0.4", + "@angular/common": "^17.0.6", + "@angular/compiler": "^17.0.6", + "@angular/core": "^17.0.6", + "@angular/forms": "^17.0.6", + "@angular/localize": "^17.0.6", + "@angular/platform-browser": "^17.0.6", + "@angular/platform-browser-dynamic": "^17.0.6", + "@angular/router": "^17.0.6", "@fortawesome/fontawesome-free": "^6.4.2", "@iharbeck/ngx-virtual-scroller": "^17.0.0", "@iplab/ngx-file-upload": "^17.0.0", - "@microsoft/signalr": "^7.0.12", + "@microsoft/signalr": "^8.0.0", "@ng-bootstrap/ng-bootstrap": "^16.0.0", - "@ngneat/transloco": "^6.0.0", + "@ngneat/transloco": "^6.0.4", "@ngneat/transloco-locale": "^5.1.1", "@ngneat/transloco-persist-lang": "^5.0.0", "@ngneat/transloco-persist-translations": "^5.0.0", - "@ngneat/transloco-preload-langs": "^5.0.0", + "@ngneat/transloco-preload-langs": "^5.0.1", "@popperjs/core": "^2.11.7", "@swimlane/ngx-charts": "^20.5.0", "@tweenjs/tween.js": "^21.0.0", @@ -58,17 +58,17 @@ "zone.js": "^0.14.2" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.0.3", - "@angular-eslint/builder": "^17.1.0", - "@angular-eslint/eslint-plugin": "^17.1.0", - "@angular-eslint/eslint-plugin-template": "^17.1.0", - "@angular-eslint/schematics": "^17.1.0", - "@angular-eslint/template-parser": "^17.1.0", - "@angular/cli": "^17.0.3", - "@angular/compiler-cli": "^17.0.4", + "@angular-devkit/build-angular": "^17.0.7", + "@angular-eslint/builder": "^17.1.1", + "@angular-eslint/eslint-plugin": "^17.1.1", + "@angular-eslint/eslint-plugin-template": "^17.1.1", + "@angular-eslint/schematics": "^17.1.1", + "@angular-eslint/template-parser": "^17.1.1", + "@angular/cli": "^17.0.7", + "@angular/compiler-cli": "^17.0.6", "@types/d3": "^7.4.3", "@types/file-saver": "^2.0.7", - "@types/luxon": "^3.3.5", + "@types/luxon": "^3.3.7", "@types/node": "^20.10.0", "@typescript-eslint/eslint-plugin": "^6.13.0", "@typescript-eslint/parser": "^6.13.0", diff --git a/UI/Web/src/app/_services/message-hub.service.ts b/UI/Web/src/app/_services/message-hub.service.ts index 4eb17fb97..9ca21659c 100644 --- a/UI/Web/src/app/_services/message-hub.service.ts +++ b/UI/Web/src/app/_services/message-hub.service.ts @@ -141,6 +141,7 @@ export class MessageHubService { accessTokenFactory: () => user.token }) .withAutomaticReconnect() + .withStatefulReconnect() .build(); this.hubConnection diff --git a/docker-build.sh b/docker-build.sh index 7e2b9c31a..072676a78 100755 --- a/docker-build.sh +++ b/docker-build.sh @@ -21,7 +21,6 @@ Build() slnFile=Kavita.sln - dotnet clean $slnFile -c Debug dotnet clean $slnFile -c Release dotnet msbuild -restore $slnFile -p:Configuration=Release -p:Platform="Any CPU" -p:RuntimeIdentifiers=$RID diff --git a/global.json b/global.json index 36e1a9e95..b5b37b60d 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.0", + "version": "8.0.0", "rollForward": "latestMajor", "allowPrerelease": false } diff --git a/monorepo-build.sh b/monorepo-build.sh index f2190b397..690120406 100755 --- a/monorepo-build.sh +++ b/monorepo-build.sh @@ -53,9 +53,6 @@ Package() echo "Copying LICENSE" cp ../LICENSE "$lOutputFolder"/LICENSE.txt - echo "Show API structure" - find - echo "Copying appsettings.json" cp ./config/appsettings.Development.json $lOutputFolder/config/appsettings.json diff --git a/openapi.json b/openapi.json index 377e11e1e..f76271a1c 100644 --- a/openapi.json +++ b/openapi.json @@ -7,7 +7,7 @@ "name": "GPL-3.0", "url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE" }, - "version": "0.7.11.1" + "version": "0.7.11.2" }, "servers": [ { @@ -3917,6 +3917,76 @@ } } }, + "/api/Opds/{apiKey}/more-in-genre": { + "get": { + "tags": [ + "Opds" + ], + "parameters": [ + { + "name": "apiKey", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "genreId", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "pageNumber", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/Opds/{apiKey}/recently-updated": { + "get": { + "tags": [ + "Opds" + ], + "parameters": [ + { + "name": "apiKey", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "pageNumber", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 1 + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, "/api/Opds/{apiKey}/on-deck": { "get": { "tags": [