From 4de977c1dd5a3b683aea06e9aeb89918ee03f4ab Mon Sep 17 00:00:00 2001 From: Kieran Date: Tue, 9 May 2023 13:56:57 +0000 Subject: [PATCH] v5 (#65) Co-authored-by: Kieran Reviewed-on: https://git.v0l.io/Kieran/void.cat/pulls/65 --- .drone.yml | 19 + Dockerfile | 21 +- VoidCat/Controllers/Admin/AdminController.cs | 29 +- VoidCat/Controllers/AuthController.cs | 10 +- VoidCat/Controllers/DownloadController.cs | 16 +- VoidCat/Controllers/IndexController.cs | 6 +- VoidCat/Controllers/UploadController.cs | 72 +- VoidCat/Controllers/UserController.cs | 44 +- VoidCat/Database/ApiKey.cs | 11 + .../Configurations/ApiKeyConfiguration.cs | 25 + .../EmailVerficationConfiguration.cs | 23 + .../Configurations/FileConfiguration.cs | 39 + .../Configurations/PaywallConfiguration.cs | 28 + .../PaywallOrderConfiguration.cs | 30 + .../PaywallOrderLightningConfiguration.cs | 22 + .../PaywallStrikeConfiguration.cs | 19 + .../UserAuthTokenConfiguration.cs | 36 + .../Configurations/UserConfiguration.cs | 38 + .../Configurations/UserFileConfiguration.cs | 21 + .../Configurations/UserRolesConfiguration.cs | 20 + .../VirusScanResultConfiguration.cs | 24 + VoidCat/Database/EmailVerification.cs | 11 + VoidCat/Database/File.cs | 19 + VoidCat/Database/Paywall.cs | 47 + VoidCat/Database/PaywallOrder.cs | 40 + VoidCat/Database/User.cs | 114 + VoidCat/Database/UserAuthToken.cs | 15 + VoidCat/Database/UserFile.cs | 10 + VoidCat/Database/VirusScanResult.cs | 12 + .../20230503115108_Init.Designer.cs | 353 ++ VoidCat/Migrations/20230503115108_Init.cs | 223 ++ .../20230503120701_Paywall.Designer.cs | 497 +++ VoidCat/Migrations/20230503120701_Paywall.cs | 121 + ...0508205513_EmailVerificationId.Designer.cs | 501 +++ .../20230508205513_EmailVerificationId.cs | 63 + .../Migrations/VoidContextModelSnapshot.cs | 498 +++ VoidCat/Model/AdminApiUser.cs | 7 + VoidCat/Model/ApiUser.cs | 51 + VoidCat/Model/EmailVerificationCode.cs | 9 - VoidCat/Model/Extensions.cs | 93 +- VoidCat/Model/IngressPayload.cs | 2 +- VoidCat/Model/Payments/PaymentMoney.cs | 22 - VoidCat/Model/Payments/PaymentOrder.cs | 69 - VoidCat/Model/Payments/PaymentServices.cs | 17 - VoidCat/Model/Payments/PaymentsConfig.cs | 45 - VoidCat/Model/User/ApiKey.cs | 18 - VoidCat/Model/User/AuthType.cs | 27 - VoidCat/Model/User/InternalUser.cs | 12 - VoidCat/Model/User/PrivateUser.cs | 17 - VoidCat/Model/User/PublicUser.cs | 6 - VoidCat/Model/User/User.cs | 67 - VoidCat/Model/User/UserAuthToken.cs | 25 - VoidCat/Model/User/UserFlags.cs | 23 - VoidCat/Model/VirusScanResult.cs | 32 +- VoidCat/Model/VoidFile.cs | 73 +- VoidCat/Model/VoidFileMeta.cs | 100 - VoidCat/Model/VoidSettings.cs | 13 + VoidCat/Pages/EmailCode.cshtml | 4 +- VoidCat/Pages/Index.cshtml | 4 +- VoidCat/Program.cs | 266 +- VoidCat/Properties/launchSettings.json | 4 +- VoidCat/Services/Abstractions/IApiKeyStore.cs | 2 +- .../Abstractions/IEmailVerification.cs | 18 +- .../Abstractions/IFileMetadataStore.cs | 29 +- VoidCat/Services/Abstractions/IFileStore.cs | 3 +- .../Services/Abstractions/IOAuthProvider.cs | 4 +- .../Services/Abstractions/IPaymentFactory.cs | 4 +- .../Abstractions/IPaymentOrderStore.cs | 6 +- .../Services/Abstractions/IPaymentProvider.cs | 6 +- .../Services/Abstractions/IPaymentStore.cs | 4 +- .../Abstractions/IPublicPrivateStore.cs | 38 - .../Abstractions/IUserAuthTokenStore.cs | 2 +- VoidCat/Services/Abstractions/IUserStore.cs | 29 +- .../Services/Abstractions/IVirusScanStore.cs | 2 +- .../Services/Abstractions/IVirusScanner.cs | 2 +- .../Services/Background/DeleteExpiredFiles.cs | 2 +- .../Background/DeleteUnverifiedAccounts.cs | 4 +- .../Background/VirusScannerService.cs | 8 +- VoidCat/Services/BasicCacheStore.cs | 10 +- VoidCat/Services/Files/FileInfoManager.cs | 74 +- VoidCat/Services/Files/FileStorageStartup.cs | 16 +- VoidCat/Services/Files/FileSystemFactory.cs | 2 +- .../Files/LocalDiskFileMetadataStore.cs | 49 +- .../Services/Files/LocalDiskFileStorage.cs | 17 +- .../Files/PostgresFileMetadataStore.cs | 172 +- VoidCat/Services/Files/S3FileMetadataStore.cs | 86 +- VoidCat/Services/Files/S3FileStore.cs | 18 +- VoidCat/Services/Files/StreamFileStore.cs | 16 +- .../Services/Migrations/Database/00-Init.cs | 100 - .../Migrations/Database/01-FileExpiry.cs | 19 - .../Migrations/Database/02-MinorVersion1.cs | 37 - .../Database/03-PaywallToPayments.cs | 27 - .../Database/04-OptionalPayments.cs | 20 - .../Migrations/Database/05-AccountTypes.cs | 44 - .../Database/06-EncryptionParams.cs | 20 - .../Migrations/Database/07-MagnetLink.cs | 20 - VoidCat/Services/Migrations/EFMigration.cs | 21 + .../Services/Migrations/EFMigrationSetup.cs | 88 + VoidCat/Services/Migrations/FixSize.cs | 52 - .../Migrations/FluentMigrationRunner.cs | 24 - .../Services/Migrations/MigrateToPostgres.cs | 169 - .../Services/Migrations/PopulateMetadataId.cs | 36 - .../Migrations/UserLookupKeyHashMigration.cs | 51 - .../Payment/CachePaymentOrderStore.cs | 6 +- VoidCat/Services/Payment/CachePaymentStore.cs | 15 +- .../Payment/LnProxyPaymentProvider.cs | 17 + VoidCat/Services/Payment/PaymentFactory.cs | 6 +- .../Payment/PostgresPaymentOrderStore.cs | 98 +- .../Services/Payment/PostgresPaymentStore.cs | 89 +- .../Services/Payment/StrikePaymentProvider.cs | 92 +- VoidCat/Services/PostgresConnectionFactory.cs | 26 - .../Users/Auth/CacheUserAuthTokenStore.cs | 2 +- .../Users/Auth/DiscordOAuthProvider.cs | 10 +- .../Users/Auth/GenericOAuth2Service.cs | 4 +- .../Users/Auth/GoogleOAuthProvider.cs | 14 +- .../Users/Auth/PostgresUserAuthTokenStore.cs | 45 +- .../Services/Users/BaseEmailVerification.cs | 18 +- VoidCat/Services/Users/CacheApiKeyStore.cs | 2 +- .../Services/Users/CacheEmailVerification.cs | 9 +- VoidCat/Services/Users/CacheUserStore.cs | 50 +- VoidCat/Services/Users/PostgresApiKeyStore.cs | 45 +- .../Users/PostgresEmailVerification.cs | 38 +- VoidCat/Services/Users/PostgresUserStore.cs | 198 +- .../Services/Users/PostgresUserUploadStore.cs | 95 +- VoidCat/Services/Users/UserManager.cs | 39 +- .../VirusScanner/CacheVirusScanStore.cs | 6 +- .../Services/VirusScanner/ClamAvScanner.cs | 3 +- .../VirusScanner/PostgresVirusScanStore.cs | 44 +- VoidCat/Services/VoidContext.cs | 31 + VoidCat/VoidCat.csproj | 47 +- VoidCat/VoidStartup.cs | 34 +- VoidCat/appsettings.Development.json | 9 - VoidCat/appsettings.json | 5 +- VoidCat/spa/d.ts | 4 + VoidCat/spa/package.json | 15 +- VoidCat/spa/public/icons.svg | 41 + VoidCat/spa/src/Admin/{Admin.js => Admin.tsx} | 33 +- .../src/Admin/{EditUser.js => EditUser.tsx} | 23 +- VoidCat/spa/src/Admin/UserList.js | 83 - VoidCat/spa/src/Admin/UserList.tsx | 93 + VoidCat/spa/src/Api/Api.ts | 145 + .../StreamEncryption.ts} | 68 +- VoidCat/spa/src/Api/StreamUploader.ts | 95 + VoidCat/spa/src/Api/Upload.ts | 90 + VoidCat/spa/src/Api/XHRUploader.ts | 93 + VoidCat/spa/src/{ => Api}/codecBytes.js | 0 VoidCat/spa/src/Api/index.ts | 174 + VoidCat/spa/src/App.js | 35 - VoidCat/spa/src/App.tsx | 61 + .../FileEdit/{FileEdit.js => FileEdit.tsx} | 60 +- .../Components/FileEdit/NoPaymentConfig.js | 26 - .../Components/FileEdit/NoPaymentConfig.tsx | 29 + .../FileEdit/StrikePaymentConfig.js | 65 - .../FileEdit/StrikePaymentConfig.tsx | 57 + .../{FilePayment.js => FilePayment.tsx} | 46 +- .../FilePreview/LightningPayment.js | 50 - .../FilePreview/LightningPayment.tsx | 51 + .../{TextPreview.js => TextPreview.tsx} | 10 +- .../FileUpload/{Dropzone.js => Dropzone.tsx} | 20 +- .../src/Components/FileUpload/FileUpload.js | 296 -- .../src/Components/FileUpload/FileUpload.tsx | 131 + .../{FooterLinks.js => FooterLinks.tsx} | 12 +- .../{GlobalStats.js => GlobalStats.tsx} | 20 +- .../src/Components/HomePage/MetricsGraph.js | 23 - .../src/Components/HomePage/MetricsGraph.tsx | 26 + .../Profile/{ApiKeyList.js => ApiKeyList.tsx} | 48 +- VoidCat/spa/src/Components/Shared/Api.js | 51 - .../Shared/{Countdown.js => Countdown.tsx} | 15 +- .../Shared/{FileList.js => FileList.tsx} | 61 +- ...leTransferHook.js => FileTransferHook.tsx} | 6 +- .../Shared/{Header.js => Header.tsx} | 35 +- VoidCat/spa/src/Components/Shared/Icon.tsx | 21 + .../{InlineProfile.js => InlineProfile.tsx} | 27 +- VoidCat/spa/src/Components/Shared/Login.js | 54 - VoidCat/spa/src/Components/Shared/Login.tsx | 64 + .../spa/src/Components/Shared/PageSelector.js | 33 - .../src/Components/Shared/PageSelector.tsx | 43 + .../src/Components/Shared/RateCalculator.js | 58 - .../src/Components/Shared/RateCalculator.ts | 68 + .../spa/src/Components/Shared/VoidButton.js | 41 - .../spa/src/Components/Shared/VoidButton.tsx | 56 + .../Shared/{VoidModal.js => VoidModal.tsx} | 8 +- .../{Components/Shared/Const.js => Const.ts} | 38 +- VoidCat/spa/src/Hooks/UseApi.tsx | 10 + .../spa/src/{LoginState.js => LoginState.ts} | 27 +- .../spa/src/Pages/{Donate.js => Donate.tsx} | 0 .../Pages/{FilePreview.js => FilePreview.tsx} | 82 +- .../src/Pages/{HomePage.js => HomePage.tsx} | 11 +- .../spa/src/Pages/{Profile.js => Profile.tsx} | 180 +- .../src/Pages/{UserLogin.js => UserLogin.tsx} | 6 +- .../{SiteInfoStore.js => SiteInfoStore.ts} | 7 +- VoidCat/spa/src/{Store.js => Store.ts} | 8 +- .../{Components/Shared/Util.js => Util.ts} | 25 +- VoidCat/spa/src/index.js | 11 - VoidCat/spa/src/index.tsx | 12 + VoidCat/spa/tsconfig.json | 14 + VoidCat/spa/yarn.lock | 3554 +++++++++-------- 197 files changed, 8010 insertions(+), 5170 deletions(-) create mode 100644 .drone.yml create mode 100644 VoidCat/Database/ApiKey.cs create mode 100644 VoidCat/Database/Configurations/ApiKeyConfiguration.cs create mode 100644 VoidCat/Database/Configurations/EmailVerficationConfiguration.cs create mode 100644 VoidCat/Database/Configurations/FileConfiguration.cs create mode 100644 VoidCat/Database/Configurations/PaywallConfiguration.cs create mode 100644 VoidCat/Database/Configurations/PaywallOrderConfiguration.cs create mode 100644 VoidCat/Database/Configurations/PaywallOrderLightningConfiguration.cs create mode 100644 VoidCat/Database/Configurations/PaywallStrikeConfiguration.cs create mode 100644 VoidCat/Database/Configurations/UserAuthTokenConfiguration.cs create mode 100644 VoidCat/Database/Configurations/UserConfiguration.cs create mode 100644 VoidCat/Database/Configurations/UserFileConfiguration.cs create mode 100644 VoidCat/Database/Configurations/UserRolesConfiguration.cs create mode 100644 VoidCat/Database/Configurations/VirusScanResultConfiguration.cs create mode 100644 VoidCat/Database/EmailVerification.cs create mode 100644 VoidCat/Database/File.cs create mode 100644 VoidCat/Database/Paywall.cs create mode 100644 VoidCat/Database/PaywallOrder.cs create mode 100644 VoidCat/Database/User.cs create mode 100644 VoidCat/Database/UserAuthToken.cs create mode 100644 VoidCat/Database/UserFile.cs create mode 100644 VoidCat/Database/VirusScanResult.cs create mode 100644 VoidCat/Migrations/20230503115108_Init.Designer.cs create mode 100644 VoidCat/Migrations/20230503115108_Init.cs create mode 100644 VoidCat/Migrations/20230503120701_Paywall.Designer.cs create mode 100644 VoidCat/Migrations/20230503120701_Paywall.cs create mode 100644 VoidCat/Migrations/20230508205513_EmailVerificationId.Designer.cs create mode 100644 VoidCat/Migrations/20230508205513_EmailVerificationId.cs create mode 100644 VoidCat/Migrations/VoidContextModelSnapshot.cs create mode 100644 VoidCat/Model/AdminApiUser.cs create mode 100644 VoidCat/Model/ApiUser.cs delete mode 100644 VoidCat/Model/EmailVerificationCode.cs delete mode 100644 VoidCat/Model/Payments/PaymentMoney.cs delete mode 100644 VoidCat/Model/Payments/PaymentOrder.cs delete mode 100644 VoidCat/Model/Payments/PaymentServices.cs delete mode 100644 VoidCat/Model/Payments/PaymentsConfig.cs delete mode 100644 VoidCat/Model/User/ApiKey.cs delete mode 100644 VoidCat/Model/User/AuthType.cs delete mode 100644 VoidCat/Model/User/InternalUser.cs delete mode 100644 VoidCat/Model/User/PrivateUser.cs delete mode 100644 VoidCat/Model/User/PublicUser.cs delete mode 100644 VoidCat/Model/User/User.cs delete mode 100644 VoidCat/Model/User/UserAuthToken.cs delete mode 100644 VoidCat/Model/User/UserFlags.cs delete mode 100644 VoidCat/Model/VoidFileMeta.cs delete mode 100644 VoidCat/Services/Abstractions/IPublicPrivateStore.cs delete mode 100644 VoidCat/Services/Migrations/Database/00-Init.cs delete mode 100644 VoidCat/Services/Migrations/Database/01-FileExpiry.cs delete mode 100644 VoidCat/Services/Migrations/Database/02-MinorVersion1.cs delete mode 100644 VoidCat/Services/Migrations/Database/03-PaywallToPayments.cs delete mode 100644 VoidCat/Services/Migrations/Database/04-OptionalPayments.cs delete mode 100644 VoidCat/Services/Migrations/Database/05-AccountTypes.cs delete mode 100644 VoidCat/Services/Migrations/Database/06-EncryptionParams.cs delete mode 100644 VoidCat/Services/Migrations/Database/07-MagnetLink.cs create mode 100644 VoidCat/Services/Migrations/EFMigration.cs create mode 100644 VoidCat/Services/Migrations/EFMigrationSetup.cs delete mode 100644 VoidCat/Services/Migrations/FixSize.cs delete mode 100644 VoidCat/Services/Migrations/FluentMigrationRunner.cs delete mode 100644 VoidCat/Services/Migrations/MigrateToPostgres.cs delete mode 100644 VoidCat/Services/Migrations/PopulateMetadataId.cs delete mode 100644 VoidCat/Services/Migrations/UserLookupKeyHashMigration.cs create mode 100644 VoidCat/Services/Payment/LnProxyPaymentProvider.cs delete mode 100644 VoidCat/Services/PostgresConnectionFactory.cs create mode 100644 VoidCat/Services/VoidContext.cs delete mode 100644 VoidCat/appsettings.Development.json create mode 100644 VoidCat/spa/d.ts create mode 100644 VoidCat/spa/public/icons.svg rename VoidCat/spa/src/Admin/{Admin.js => Admin.tsx} (58%) rename VoidCat/spa/src/Admin/{EditUser.js => EditUser.tsx} (64%) delete mode 100644 VoidCat/spa/src/Admin/UserList.js create mode 100644 VoidCat/spa/src/Admin/UserList.tsx create mode 100644 VoidCat/spa/src/Api/Api.ts rename VoidCat/spa/src/{Components/Shared/StreamEncryption.js => Api/StreamEncryption.ts} (55%) create mode 100644 VoidCat/spa/src/Api/StreamUploader.ts create mode 100644 VoidCat/spa/src/Api/Upload.ts create mode 100644 VoidCat/spa/src/Api/XHRUploader.ts rename VoidCat/spa/src/{ => Api}/codecBytes.js (100%) create mode 100644 VoidCat/spa/src/Api/index.ts delete mode 100644 VoidCat/spa/src/App.js create mode 100644 VoidCat/spa/src/App.tsx rename VoidCat/spa/src/Components/FileEdit/{FileEdit.js => FileEdit.tsx} (60%) delete mode 100644 VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.js create mode 100644 VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.tsx delete mode 100644 VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.js create mode 100644 VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.tsx rename VoidCat/spa/src/Components/FilePreview/{FilePayment.js => FilePayment.tsx} (50%) delete mode 100644 VoidCat/spa/src/Components/FilePreview/LightningPayment.js create mode 100644 VoidCat/spa/src/Components/FilePreview/LightningPayment.tsx rename VoidCat/spa/src/Components/FilePreview/{TextPreview.js => TextPreview.tsx} (72%) rename VoidCat/spa/src/Components/FileUpload/{Dropzone.js => Dropzone.tsx} (71%) delete mode 100644 VoidCat/spa/src/Components/FileUpload/FileUpload.js create mode 100644 VoidCat/spa/src/Components/FileUpload/FileUpload.tsx rename VoidCat/spa/src/Components/HomePage/{FooterLinks.js => FooterLinks.tsx} (58%) rename VoidCat/spa/src/Components/HomePage/{GlobalStats.js => GlobalStats.tsx} (65%) delete mode 100644 VoidCat/spa/src/Components/HomePage/MetricsGraph.js create mode 100644 VoidCat/spa/src/Components/HomePage/MetricsGraph.tsx rename VoidCat/spa/src/Components/Profile/{ApiKeyList.js => ApiKeyList.tsx} (63%) delete mode 100644 VoidCat/spa/src/Components/Shared/Api.js rename VoidCat/spa/src/Components/Shared/{Countdown.js => Countdown.tsx} (52%) rename VoidCat/spa/src/Components/Shared/{FileList.js => FileList.tsx} (54%) rename VoidCat/spa/src/Components/Shared/{FileTransferHook.js => FileTransferHook.tsx} (84%) rename VoidCat/spa/src/Components/Shared/{Header.js => Header.tsx} (63%) create mode 100644 VoidCat/spa/src/Components/Shared/Icon.tsx rename VoidCat/spa/src/Components/Shared/{InlineProfile.js => InlineProfile.tsx} (60%) delete mode 100644 VoidCat/spa/src/Components/Shared/Login.js create mode 100644 VoidCat/spa/src/Components/Shared/Login.tsx delete mode 100644 VoidCat/spa/src/Components/Shared/PageSelector.js create mode 100644 VoidCat/spa/src/Components/Shared/PageSelector.tsx delete mode 100644 VoidCat/spa/src/Components/Shared/RateCalculator.js create mode 100644 VoidCat/spa/src/Components/Shared/RateCalculator.ts delete mode 100644 VoidCat/spa/src/Components/Shared/VoidButton.js create mode 100644 VoidCat/spa/src/Components/Shared/VoidButton.tsx rename VoidCat/spa/src/Components/Shared/{VoidModal.js => VoidModal.tsx} (69%) rename VoidCat/spa/src/{Components/Shared/Const.js => Const.ts} (61%) create mode 100644 VoidCat/spa/src/Hooks/UseApi.tsx rename VoidCat/spa/src/{LoginState.js => LoginState.ts} (50%) rename VoidCat/spa/src/Pages/{Donate.js => Donate.tsx} (100%) rename VoidCat/spa/src/Pages/{FilePreview.js => FilePreview.tsx} (81%) rename VoidCat/spa/src/Pages/{HomePage.js => HomePage.tsx} (57%) rename VoidCat/spa/src/Pages/{Profile.js => Profile.tsx} (54%) rename VoidCat/spa/src/Pages/{UserLogin.js => UserLogin.tsx} (81%) rename VoidCat/spa/src/{SiteInfoStore.js => SiteInfoStore.ts} (53%) rename VoidCat/spa/src/{Store.js => Store.ts} (57%) rename VoidCat/spa/src/{Components/Shared/Util.js => Util.ts} (76%) delete mode 100644 VoidCat/spa/src/index.js create mode 100644 VoidCat/spa/src/index.tsx create mode 100644 VoidCat/spa/tsconfig.json diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..4df3b8e --- /dev/null +++ b/.drone.yml @@ -0,0 +1,19 @@ +--- +kind: pipeline +type: kubernetes +name: default + +metadata: + namespace: git + +steps: + - name: build + image: r.j3ss.co/img + privileged: true + environment: + TOKEN: + from_secret: token + commands: + - img login -u kieran -p $TOKEN git.v0l.io + - img build -t git.v0l.io/kieran/void-cat:latest . + - img push git.v0l.io/kieran/void-cat:latest \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 276e16d..bd32e17 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,26 @@ -# syntax=docker/dockerfile:1 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env WORKDIR /app #install npm -RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - +RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - RUN apt-get install -y nodejs #run yarn install -COPY VoidCat/spa/package.json VoidCat/spa/yarn.lock spa/ -RUN cd spa && npx yarn install - -# Copy everything else and build COPY . . -RUN rm -rf VoidCat/appsettings.*.json -RUN dotnet publish -c Release -o out VoidCat/VoidCat.csproj +RUN cd VoidCat/spa \ + && npx yarn \ + && npx yarn build + +RUN rm -rf VoidCat/appsettings.*.json \ + && git config --global --add safe.directory /app \ + && dotnet publish -c Release -o out VoidCat/VoidCat.csproj # Build runtime image FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app -RUN apt update && apt install -y --no-install-recommends ffmpeg && rm -rf /var/lib/apt/lists/* +RUN apt update \ + && apt install -y --no-install-recommends ffmpeg \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* COPY --from=build-env /app/out . ENTRYPOINT ["dotnet", "VoidCat.dll"] \ No newline at end of file diff --git a/VoidCat/Controllers/Admin/AdminController.cs b/VoidCat/Controllers/Admin/AdminController.cs index ca53d58..01a97ea 100644 --- a/VoidCat/Controllers/Admin/AdminController.cs +++ b/VoidCat/Controllers/Admin/AdminController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; @@ -34,16 +34,16 @@ public class AdminController : Controller /// [HttpPost] [Route("file")] - public async Task> ListFiles([FromBody] PagedRequest request) + public async Task> ListFiles([FromBody] PagedRequest request) { - var files = await _fileMetadata.ListFiles(request); + var files = await _fileMetadata.ListFiles(request); return new() { Page = files.Page, PageSize = files.PageSize, TotalResults = files.TotalResults, - Results = (await files.Results.SelectAwait(a => _fileInfo.Get(a.Id)).ToListAsync())! + Results = (await files.Results.SelectAwait(a => _fileInfo.Get(a.Id, false)).ToListAsync())! }; } @@ -74,7 +74,7 @@ public class AdminController : Controller var ret = await result.Results.SelectAwait(async a => { var uploads = await _userUploads.ListFiles(a.Id, new(0, int.MaxValue)); - return new AdminListedUser(a, uploads.TotalResults); + return new AdminListedUser(a.ToAdminApiUser(true), uploads.TotalResults); }).ToListAsync(); return new() @@ -93,14 +93,27 @@ public class AdminController : Controller /// [HttpPost] [Route("update-user")] - public async Task UpdateUser([FromBody] PrivateUser user) + public async Task UpdateUser([FromBody] AdminUpdateUser user) { var oldUser = await _userStore.Get(user.Id); if (oldUser == default) return BadRequest(); - await _userStore.AdminUpdateUser(user); + oldUser.Storage = user.Storage; + oldUser.Email = user.Email; + + await _userStore.AdminUpdateUser(oldUser); return Ok(); } - public record AdminListedUser(PrivateUser User, int Uploads); + public record AdminListedUser(AdminApiUser User, int Uploads); + + public class AdminUpdateUser + { + [JsonConverter(typeof(Base58GuidConverter))] + public Guid Id { get; init; } + + public string Email { get; init; } = null!; + + public string Storage { get; init; } = null!; + } } diff --git a/VoidCat/Controllers/AuthController.cs b/VoidCat/Controllers/AuthController.cs index dcceda0..a2e9650 100644 --- a/VoidCat/Controllers/AuthController.cs +++ b/VoidCat/Controllers/AuthController.cs @@ -4,8 +4,8 @@ using System.Security.Claims; using System.Text; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; using VoidCat.Services.Users; @@ -57,7 +57,7 @@ public class AuthController : Controller var user = await _manager.Login(req.Username, req.Password); var token = CreateToken(user, DateTime.UtcNow.AddHours(12)); var tokenWriter = new JwtSecurityTokenHandler(); - return new(tokenWriter.WriteToken(token), Profile: user.ToPublic()); + return new(tokenWriter.WriteToken(token), Profile: user.ToApiUser(true)); } catch (Exception ex) { @@ -91,7 +91,7 @@ public class AuthController : Controller var newUser = await _manager.Register(req.Username, req.Password); var token = CreateToken(newUser, DateTime.UtcNow.AddHours(12)); var tokenWriter = new JwtSecurityTokenHandler(); - return new(tokenWriter.WriteToken(token), Profile: newUser.ToPublic()); + return new(tokenWriter.WriteToken(token), Profile: newUser.ToApiUser(true)); } catch (Exception ex) { @@ -189,7 +189,7 @@ public class AuthController : Controller new(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()) }; - claims.AddRange(user.Roles.Select(a => new Claim(ClaimTypes.Role, a))); + claims.AddRange(user.Roles.Select(a => new Claim(ClaimTypes.Role, a.Role))); return new JwtSecurityToken(_settings.JwtSettings.Issuer, claims: claims, signingCredentials: credentials); @@ -210,7 +210,7 @@ public class AuthController : Controller public string? Captcha { get; init; } } - public sealed record LoginResponse(string? Jwt, string? Error = null, User? Profile = null); + public sealed record LoginResponse(string? Jwt, string? Error = null, ApiUser? Profile = null); public sealed record CreateApiKeyRequest(DateTime Expiry); } \ No newline at end of file diff --git a/VoidCat/Controllers/DownloadController.cs b/VoidCat/Controllers/DownloadController.cs index 31d5809..7c40045 100644 --- a/VoidCat/Controllers/DownloadController.cs +++ b/VoidCat/Controllers/DownloadController.cs @@ -1,8 +1,8 @@ using System.Net; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.Payments; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; @@ -52,7 +52,7 @@ public class DownloadController : Controller if (id.EndsWith(".torrent")) { - var t = await voidFile.Metadata!.MakeTorrent( + var t = await voidFile.Metadata.MakeTorrent(voidFile.Id, await _storage.Open(new(gid, Enumerable.Empty()), CancellationToken.None), _settings.SiteUrl, _settings.TorrentTrackers); @@ -107,9 +107,9 @@ public class DownloadController : Controller await Response.CompleteAsync(); } - private async Task SetupDownload(Guid id) + private async Task SetupDownload(Guid id) { - var meta = await _fileInfo.Get(id); + var meta = await _fileInfo.Get(id, false); if (meta == null) { Response.StatusCode = 404; @@ -117,10 +117,10 @@ public class DownloadController : Controller } // check payment order - if (meta.Payment != default && meta.Payment.Service != PaymentServices.None && meta.Payment.Required) + if (meta.Payment != default && meta.Payment.Service != PaywallService.None && meta.Payment.Required) { var orderId = Request.Headers.GetHeader("V-OrderId") ?? Request.Query["orderId"]; - if (!await IsOrderPaid(orderId)) + if (!await IsOrderPaid(orderId!)) { Response.StatusCode = (int)HttpStatusCode.PaymentRequired; return default; @@ -128,7 +128,7 @@ public class DownloadController : Controller } // prevent hot-linking viruses - var referer = Request.Headers.Referer.Count > 0 ? new Uri(Request.Headers.Referer.First()) : null; + var referer = Request.Headers.Referer.Count > 0 ? new Uri(Request.Headers.Referer.First()!) : null; var hasCorrectReferer = referer?.Host.Equals(_settings.SiteUrl.Host, StringComparison.InvariantCultureIgnoreCase) ?? false; @@ -151,7 +151,7 @@ public class DownloadController : Controller if (Guid.TryParse(orderId, out var oid)) { var order = await _paymentOrders.Get(oid); - if (order?.Status == PaymentOrderStatus.Paid) + if (order?.Status == PaywallOrderStatus.Paid) { return true; } diff --git a/VoidCat/Controllers/IndexController.cs b/VoidCat/Controllers/IndexController.cs index e642e84..e2e6431 100644 --- a/VoidCat/Controllers/IndexController.cs +++ b/VoidCat/Controllers/IndexController.cs @@ -40,14 +40,16 @@ public class IndexController : Controller var jsonManifest = await System.IO.File.ReadAllTextAsync(manifestPath); return View("~/Pages/Index.cshtml", new IndexModel { - Meta = await _fileMetadata.Get(gid), + Id = gid, + Meta = (await _fileMetadata.Get(gid))?.ToMeta(false), Manifest = JsonConvert.DeserializeObject(jsonManifest)! }); } public class IndexModel { - public FileMeta? Meta { get; init; } + public Guid Id { get; init; } + public VoidFileMeta? Meta { get; init; } public AssetManifest Manifest { get; init; } } diff --git a/VoidCat/Controllers/UploadController.cs b/VoidCat/Controllers/UploadController.cs index cd6b5fc..9f58a71 100644 --- a/VoidCat/Controllers/UploadController.cs +++ b/VoidCat/Controllers/UploadController.cs @@ -3,11 +3,11 @@ using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.StaticFiles; using Newtonsoft.Json; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.Payments; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; +using File = VoidCat.Database.File; namespace VoidCat.Controllers { @@ -63,6 +63,7 @@ namespace VoidCat.Controllers { throw new InvalidOperationException("Site is in maintenance mode"); } + var uid = HttpContext.GetUserId(); var mime = Request.Headers.GetHeader("V-Content-Type"); var filename = Request.Headers.GetHeader("V-Filename"); @@ -86,14 +87,14 @@ namespace VoidCat.Controllers var store = _settings.DefaultFileStore; if (uid.HasValue) { - var user = await _userStore.Get(uid.Value); + var user = await _userStore.Get(uid.Value); if (user?.Storage != default) { store = user.Storage!; } } - var meta = new SecretFileMeta + var meta = new File { MimeType = mime, Name = filename, @@ -109,7 +110,7 @@ namespace VoidCat.Controllers HttpContext.RequestAborted); // save metadata - await _metadata.Set(vf.Id, vf.Metadata!); + await _metadata.Add(vf); // attach file upload to user if (uid.HasValue) @@ -126,7 +127,7 @@ namespace VoidCat.Controllers return Content(urlBuilder.Uri.ToString(), "text/plain"); } - return Json(UploadResult.Success(vf)); + return Json(UploadResult.Success(vf.ToResponse(true))); } catch (Exception ex) { @@ -158,8 +159,9 @@ namespace VoidCat.Controllers { throw new InvalidOperationException("Site is in maintenance mode"); } + var gid = id.FromBase58Guid(); - var meta = await _metadata.Get(gid); + var meta = await _metadata.Get(gid); if (meta == default) return UploadResult.Error("File not found"); // Parse V-Segment header @@ -182,8 +184,8 @@ namespace VoidCat.Controllers }, HttpContext.RequestAborted); // update file size - await _metadata.Set(vf.Id, vf.Metadata!); - return UploadResult.Success(vf); + await _metadata.Update(vf.Id, vf); + return UploadResult.Success(vf.ToResponse(true)); } catch (Exception ex) { @@ -205,7 +207,10 @@ namespace VoidCat.Controllers var uid = HttpContext.GetUserId(); var isOwner = uid.HasValue && await _userUploads.Uploader(fid) == uid; - return isOwner ? Json(await _fileInfo.GetPrivate(fid)) : Json(await _fileInfo.Get(fid)); + var info = await _fileInfo.Get(fid, isOwner); + if (info == default) return StatusCode(404); + + return Json(info); } /// @@ -232,10 +237,10 @@ namespace VoidCat.Controllers /// [HttpGet] [Route("{id}/payment")] - public async ValueTask CreateOrder([FromRoute] string id) + public async ValueTask CreateOrder([FromRoute] string id) { var gid = id.FromBase58Guid(); - var file = await _fileInfo.Get(gid); + var file = await _fileInfo.Get(gid, false); var config = await _paymentStore.Get(gid); var provider = await _paymentFactory.CreateProvider(config!.Service); @@ -250,7 +255,7 @@ namespace VoidCat.Controllers /// [HttpGet] [Route("{id}/payment/{order:guid}")] - public async ValueTask GetOrderStatus([FromRoute] string id, [FromRoute] Guid order) + public async ValueTask GetOrderStatus([FromRoute] string id, [FromRoute] Guid order) { var gid = id.FromBase58Guid(); var config = await _paymentStore.Get(gid); @@ -270,17 +275,23 @@ namespace VoidCat.Controllers public async Task SetPaymentConfig([FromRoute] string id, [FromBody] SetPaymentConfigRequest req) { var gid = id.FromBase58Guid(); - var meta = await _metadata.Get(gid); + var meta = await _metadata.Get(gid); if (meta == default) return NotFound(); if (!meta.CanEdit(req.EditSecret)) return Unauthorized(); - if (req.Strike != default) + if (req.StrikeHandle != default) { - await _paymentStore.Add(gid, new StrikePaymentConfig() + await _paymentStore.Delete(gid); + await _paymentStore.Add(gid, new Paywall { - Service = PaymentServices.Strike, - Handle = req.Strike.Handle, - Cost = req.Strike.Cost, + File = meta, + Service = PaywallService.Strike, + PaywallStrike = new() + { + Handle = req.StrikeHandle + }, + Amount = req.Amount, + Currency = Enum.Parse(req.Currency), Required = req.Required }); @@ -303,14 +314,21 @@ namespace VoidCat.Controllers /// [HttpPost] [Route("{id}/meta")] - public async Task UpdateFileMeta([FromRoute] string id, [FromBody] SecretFileMeta fileMeta) + public async Task UpdateFileMeta([FromRoute] string id, [FromBody] VoidFileMeta fileMeta) { var gid = id.FromBase58Guid(); - var meta = await _metadata.Get(gid); + var meta = await _metadata.Get(gid); if (meta == default) return NotFound(); if (!meta.CanEdit(fileMeta.EditSecret)) return Unauthorized(); - await _metadata.Update(gid, fileMeta); + await _metadata.Update(gid, new() + { + Name = fileMeta.Name, + Description = fileMeta.Description, + Expires = fileMeta.Expires, + MimeType = fileMeta.MimeType + }); + return Ok(); } @@ -349,9 +367,9 @@ namespace VoidCat.Controllers } } - public record UploadResult(bool Ok, PrivateVoidFile? File, string? ErrorMessage) + public record UploadResult(bool Ok, VoidFileResponse? File, string? ErrorMessage) { - public static UploadResult Success(PrivateVoidFile vf) + public static UploadResult Success(VoidFileResponse vf) => new(true, vf, null); public static UploadResult Error(string message) @@ -363,7 +381,11 @@ namespace VoidCat.Controllers [JsonConverter(typeof(Base58GuidConverter))] public Guid EditSecret { get; init; } - public StrikePaymentConfig? Strike { get; init; } + public decimal Amount { get; init; } + + public string Currency { get; init; } = null!; + + public string? StrikeHandle { get; init; } public bool Required { get; init; } } diff --git a/VoidCat/Controllers/UserController.cs b/VoidCat/Controllers/UserController.cs index af2dfbf..fd5a34d 100644 --- a/VoidCat/Controllers/UserController.cs +++ b/VoidCat/Controllers/UserController.cs @@ -1,8 +1,9 @@ using Microsoft.AspNetCore.Mvc; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; +using UserFlags = VoidCat.Database.UserFlags; namespace VoidCat.Controllers; @@ -41,18 +42,11 @@ public class UserController : Controller if (isMe && !loggedUser.HasValue) return Unauthorized(); var requestedId = isMe ? loggedUser!.Value : id.FromBase58Guid(); - if (loggedUser == requestedId) - { - var pUser = await _store.Get(requestedId); - if (pUser == default) return NotFound(); + var user = await _store.Get(requestedId); + if (loggedUser != requestedId && !(user?.Flags.HasFlag(UserFlags.PublicProfile) ?? false)) + return NotFound(); - return Json(pUser); - } - - var user = await _store.Get(requestedId); - if (!(user?.Flags.HasFlag(UserFlags.PublicProfile) ?? false)) return NotFound(); - - return Json(user); + return Json(user!.ToApiUser(isMe)); } /// @@ -63,14 +57,20 @@ public class UserController : Controller /// /// [HttpPost] - public async Task UpdateUser([FromRoute] string id, [FromBody] PublicUser user) + public async Task UpdateUser([FromRoute] string id, [FromBody] ApiUser user) { var loggedUser = await GetAuthorizedUser(id); if (loggedUser == default) return Unauthorized(); if (!loggedUser.Flags.HasFlag(UserFlags.EmailVerified)) return Forbid(); - await _store.UpdateProfile(user); + loggedUser.Avatar = user.Avatar; + loggedUser.DisplayName = user.Name ?? "void user"; + loggedUser.Flags = UserFlags.EmailVerified | (user.PublicProfile ? UserFlags.PublicProfile : 0) | + (user.PublicUploads ? UserFlags.PublicUploads : 0); + + await _store.UpdateProfile(loggedUser); + return Ok(); } @@ -102,13 +102,13 @@ public class UserController : Controller var results = await _userUploads.ListFiles(id.FromBase58Guid(), request); var files = await results.Results.ToListAsync(); - var fileInfo = await Task.WhenAll(files.Select(a => _fileInfoManager.Get(a).AsTask())); - return Json(new RenderedResults() + var fileInfo = await _fileInfoManager.Get(files.ToArray(), false); + return Json(new RenderedResults() { PageSize = results.PageSize, Page = results.Page, TotalResults = results.TotalResults, - Results = fileInfo.Where(a => a != null).ToList()! + Results = fileInfo.ToList() }); } @@ -148,21 +148,21 @@ public class UserController : Controller if (!await _emailVerification.VerifyCode(user, token)) return BadRequest(); user.Flags |= UserFlags.EmailVerified; - await _store.UpdateProfile(user.ToPublic()); + await _store.UpdateProfile(user); return Accepted(); } - private async Task GetAuthorizedUser(string id) + private async Task GetAuthorizedUser(string id) { var loggedUser = HttpContext.GetUserId(); var gid = id.FromBase58Guid(); - var user = await _store.Get(gid); + var user = await _store.Get(gid); return user?.Id != loggedUser ? default : user; } - private async Task GetRequestedUser(string id) + private async Task GetRequestedUser(string id) { var gid = id.FromBase58Guid(); - return await _store.Get(gid); + return await _store.Get(gid); } } diff --git a/VoidCat/Database/ApiKey.cs b/VoidCat/Database/ApiKey.cs new file mode 100644 index 0000000..e5dfdba --- /dev/null +++ b/VoidCat/Database/ApiKey.cs @@ -0,0 +1,11 @@ +namespace VoidCat.Database; + +public class ApiKey +{ + public Guid Id { get; init; } = Guid.NewGuid(); + public Guid UserId { get; init; } + public User User { get; init; } = null!; + public string Token { get; init; } = null!; + public DateTime Expiry { get; init; } + public DateTime Created { get; init; } +} diff --git a/VoidCat/Database/Configurations/ApiKeyConfiguration.cs b/VoidCat/Database/Configurations/ApiKeyConfiguration.cs new file mode 100644 index 0000000..0603684 --- /dev/null +++ b/VoidCat/Database/Configurations/ApiKeyConfiguration.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class ApiKeyConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("ApiKey"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Token) + .IsRequired(); + + builder.Property(a => a.Expiry) + .IsRequired(); + + builder.Property(a => a.Created) + .IsRequired(); + + builder.HasOne(a => a.User) + .WithMany() + .HasForeignKey(a => a.UserId); + } +} diff --git a/VoidCat/Database/Configurations/EmailVerficationConfiguration.cs b/VoidCat/Database/Configurations/EmailVerficationConfiguration.cs new file mode 100644 index 0000000..b92b5ca --- /dev/null +++ b/VoidCat/Database/Configurations/EmailVerficationConfiguration.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class EmailVerficationConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("EmailVerification"); + builder.HasKey(a => a.Id); + + builder.Property(a => a.Code) + .IsRequired(); + + builder.Property(a => a.Expires) + .IsRequired(); + + builder.HasOne(a => a.User) + .WithMany() + .HasForeignKey(a => a.UserId); + } +} diff --git a/VoidCat/Database/Configurations/FileConfiguration.cs b/VoidCat/Database/Configurations/FileConfiguration.cs new file mode 100644 index 0000000..92bfdea --- /dev/null +++ b/VoidCat/Database/Configurations/FileConfiguration.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class FileConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Files"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Name); + builder.Property(a => a.Size) + .IsRequired(); + + builder.Property(a => a.Uploaded) + .IsRequired(); + + builder.Property(a => a.Description); + builder.Property(a => a.MimeType) + .IsRequired() + .HasDefaultValue("application/octet-stream"); + + builder.Property(a => a.Digest); + builder.Property(a => a.EditSecret) + .IsRequired(); + + builder.Property(a => a.Expires); + + builder.Property(a => a.Storage) + .IsRequired() + .HasDefaultValue("local-disk"); + + builder.Property(a => a.EncryptionParams); + builder.Property(a => a.MagnetLink); + + builder.HasIndex(a => a.Uploaded); + } +} diff --git a/VoidCat/Database/Configurations/PaywallConfiguration.cs b/VoidCat/Database/Configurations/PaywallConfiguration.cs new file mode 100644 index 0000000..4aeae84 --- /dev/null +++ b/VoidCat/Database/Configurations/PaywallConfiguration.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class PaywallConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Payment"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Service) + .IsRequired(); + + builder.Property(a => a.Currency) + .IsRequired(); + + builder.Property(a => a.Amount) + .IsRequired(); + + builder.Property(a => a.Required) + .IsRequired(); + + builder.HasOne(a => a.File) + .WithOne(a => a.Paywall) + .HasForeignKey(); + } +} diff --git a/VoidCat/Database/Configurations/PaywallOrderConfiguration.cs b/VoidCat/Database/Configurations/PaywallOrderConfiguration.cs new file mode 100644 index 0000000..6ff6d3b --- /dev/null +++ b/VoidCat/Database/Configurations/PaywallOrderConfiguration.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class PaywallOrderConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PaymentOrder"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Service) + .IsRequired(); + + builder.Property(a => a.Currency) + .IsRequired(); + + builder.Property(a => a.Amount) + .IsRequired(); + + builder.Property(a => a.Status) + .IsRequired(); + + builder.HasIndex(a => a.Status); + + builder.HasOne(a => a.File) + .WithMany() + .HasForeignKey(a => a.FileId); + } +} diff --git a/VoidCat/Database/Configurations/PaywallOrderLightningConfiguration.cs b/VoidCat/Database/Configurations/PaywallOrderLightningConfiguration.cs new file mode 100644 index 0000000..9217d90 --- /dev/null +++ b/VoidCat/Database/Configurations/PaywallOrderLightningConfiguration.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class PaywallOrderLightningConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PaymentOrderLightning"); + builder.HasKey(a => a.OrderId); + builder.Property(a => a.Invoice) + .IsRequired(); + + builder.Property(a => a.Expire) + .IsRequired(); + + builder.HasOne(a => a.Order) + .WithOne(a => a.OrderLightning) + .HasForeignKey(a => a.OrderId); + } +} diff --git a/VoidCat/Database/Configurations/PaywallStrikeConfiguration.cs b/VoidCat/Database/Configurations/PaywallStrikeConfiguration.cs new file mode 100644 index 0000000..4ec465f --- /dev/null +++ b/VoidCat/Database/Configurations/PaywallStrikeConfiguration.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class PaywallStrikeConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("PaymentStrike"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Handle) + .IsRequired(); + + builder.HasOne(a => a.Paywall) + .WithOne(a => a.PaywallStrike) + .HasForeignKey(); + } +} diff --git a/VoidCat/Database/Configurations/UserAuthTokenConfiguration.cs b/VoidCat/Database/Configurations/UserAuthTokenConfiguration.cs new file mode 100644 index 0000000..9a0548e --- /dev/null +++ b/VoidCat/Database/Configurations/UserAuthTokenConfiguration.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class UserAuthTokenConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("UsersAuthToken"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Provider) + .IsRequired(); + + builder.Property(a => a.AccessToken) + .IsRequired(); + + builder.Property(a => a.TokenType) + .IsRequired(); + + builder.Property(a => a.Expires) + .IsRequired(); + + builder.Property(a => a.RefreshToken) + .IsRequired(); + + builder.Property(a => a.Scope) + .IsRequired(); + + builder.Property(a => a.IdToken); + + builder.HasOne(a => a.User) + .WithMany() + .HasForeignKey(a => a.UserId); + } +} diff --git a/VoidCat/Database/Configurations/UserConfiguration.cs b/VoidCat/Database/Configurations/UserConfiguration.cs new file mode 100644 index 0000000..a1dc7ae --- /dev/null +++ b/VoidCat/Database/Configurations/UserConfiguration.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class UserConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Users"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Email) + .IsRequired(); + + builder.Property(a => a.Password) + .IsRequired(false); + + builder.Property(a => a.Created) + .IsRequired(); + + builder.Property(a => a.LastLogin); + builder.Property(a => a.DisplayName) + .IsRequired() + .HasDefaultValue("void user"); + + builder.Property(a => a.Flags) + .IsRequired(); + + builder.Property(a => a.Storage) + .IsRequired() + .HasDefaultValue("local-disk"); + + builder.Property(a => a.AuthType) + .IsRequired(); + + builder.HasIndex(a => a.Email); + } +} diff --git a/VoidCat/Database/Configurations/UserFileConfiguration.cs b/VoidCat/Database/Configurations/UserFileConfiguration.cs new file mode 100644 index 0000000..daa617f --- /dev/null +++ b/VoidCat/Database/Configurations/UserFileConfiguration.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class UserFileConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("UserFiles"); + builder.HasKey(a => new {a.UserId, a.FileId}); + + builder.HasOne(a => a.User) + .WithMany(a => a.UserFiles) + .HasForeignKey(a => a.UserId); + + builder.HasOne(a => a.File) + .WithOne() + .HasForeignKey(a => a.FileId); + } +} diff --git a/VoidCat/Database/Configurations/UserRolesConfiguration.cs b/VoidCat/Database/Configurations/UserRolesConfiguration.cs new file mode 100644 index 0000000..df0628d --- /dev/null +++ b/VoidCat/Database/Configurations/UserRolesConfiguration.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class UserRolesConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("UserRoles"); + builder.HasKey(a => new {a.UserId, a.Role}); + + builder.Property(a => a.Role) + .IsRequired(); + + builder.HasOne(a => a.User) + .WithMany(a => a.Roles) + .HasForeignKey(a => a.UserId); + } +} diff --git a/VoidCat/Database/Configurations/VirusScanResultConfiguration.cs b/VoidCat/Database/Configurations/VirusScanResultConfiguration.cs new file mode 100644 index 0000000..7dd2119 --- /dev/null +++ b/VoidCat/Database/Configurations/VirusScanResultConfiguration.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VoidCat.Database.Configurations; + +public class VirusScanResultConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("VirusScanResult"); + builder.HasKey(a => a.Id); + builder.Property(a => a.Scanner) + .IsRequired(); + + builder.Property(a => a.Score) + .IsRequired(); + + builder.Property(a => a.Names); + + builder.HasOne(a => a.File) + .WithMany() + .HasForeignKey(a => a.FileId); + } +} diff --git a/VoidCat/Database/EmailVerification.cs b/VoidCat/Database/EmailVerification.cs new file mode 100644 index 0000000..5813015 --- /dev/null +++ b/VoidCat/Database/EmailVerification.cs @@ -0,0 +1,11 @@ +namespace VoidCat.Database; + +public class EmailVerification +{ + public Guid Id { get; init; } = Guid.NewGuid(); + public Guid UserId { get; init; } + public User User { get; init; } = null!; + + public Guid Code { get; init; } = Guid.NewGuid(); + public DateTime Expires { get; init; } +} diff --git a/VoidCat/Database/File.cs b/VoidCat/Database/File.cs new file mode 100644 index 0000000..7052c6d --- /dev/null +++ b/VoidCat/Database/File.cs @@ -0,0 +1,19 @@ +namespace VoidCat.Database; + +public record File +{ + public Guid Id { get; init; } + public string? Name { get; set; } + public ulong Size { get; init; } + public DateTime Uploaded { get; init; } = DateTime.UtcNow; + public string? Description { get; set; } + public string MimeType { get; set; } = "application/octet-stream"; + public string? Digest { get; init; } + public Guid EditSecret { get; init; } + public DateTime? Expires { get; set; } + public string Storage { get; set; } = "local-disk"; + public string? EncryptionParams { get; set; } + public string? MagnetLink { get; set; } + + public Paywall? Paywall { get; init; } +} diff --git a/VoidCat/Database/Paywall.cs b/VoidCat/Database/Paywall.cs new file mode 100644 index 0000000..b696acf --- /dev/null +++ b/VoidCat/Database/Paywall.cs @@ -0,0 +1,47 @@ +namespace VoidCat.Database; + +public enum PaywallCurrency : byte +{ + BTC = 0, + USD = 1, + EUR = 2, + GBP = 3 +} + +public enum PaywallService +{ + /// + /// No service + /// + None, + + /// + /// Strike.me payment service + /// + Strike, + + /// + /// LNProxy payment + /// + LnProxy, +} + +public class Paywall +{ + public Guid Id { get; init; } = Guid.NewGuid(); + public File File { get; init; } = null!; + public PaywallService Service { get; init; } + public PaywallCurrency Currency { get; init; } + public decimal Amount { get; init; } + + public bool Required { get; init; } = true; + + public PaywallStrike? PaywallStrike { get; init; } +} + +public class PaywallStrike +{ + public Guid Id { get; init; } = Guid.NewGuid(); + public Paywall Paywall { get; init; } = null!; + public string Handle { get; init; } = null!; +} \ No newline at end of file diff --git a/VoidCat/Database/PaywallOrder.cs b/VoidCat/Database/PaywallOrder.cs new file mode 100644 index 0000000..fcdf5a0 --- /dev/null +++ b/VoidCat/Database/PaywallOrder.cs @@ -0,0 +1,40 @@ +namespace VoidCat.Database; + +public class PaywallOrder +{ + public Guid Id { get; init; } + public Guid FileId { get; init; } + public File File { get; init; } = null!; + public PaywallService Service { get; init; } + public PaywallCurrency Currency { get; init; } + public decimal Amount { get; init; } + public PaywallOrderStatus Status { get; set; } + + public PaywallOrderLightning? OrderLightning { get; init; } +} + +public enum PaywallOrderStatus : byte +{ + /// + /// Invoice is not paid yet + /// + Unpaid = 0, + + /// + /// Invoice is paid + /// + Paid = 1, + + /// + /// Invoice has expired and cant be paid + /// + Expired = 2 +} + +public class PaywallOrderLightning +{ + public Guid OrderId { get; init; } + public PaywallOrder Order { get; init; } = null!; + public string Invoice { get; init; } = null!; + public DateTime Expire { get; init; } +} \ No newline at end of file diff --git a/VoidCat/Database/User.cs b/VoidCat/Database/User.cs new file mode 100644 index 0000000..76afbd4 --- /dev/null +++ b/VoidCat/Database/User.cs @@ -0,0 +1,114 @@ +namespace VoidCat.Database; + +[Flags] +public enum UserFlags +{ + /// + /// Profile is public + /// + PublicProfile = 1, + + /// + /// Uploads list is public + /// + PublicUploads = 2, + + /// + /// Account has email verified + /// + EmailVerified = 4 +} + +public sealed class User +{ + /// + /// Unique Id of the user + /// + public Guid Id { get; init; } + + /// + /// Users email address + /// + public string Email { get; set; } = null!; + + /// + /// Users password (hashed) + /// + public string? Password { get; init; } + + /// + /// When the user account was created + /// + public DateTime Created { get; init; } = DateTime.UtcNow; + + /// + /// The last time the user logged in + /// + public DateTime? LastLogin { get; set; } + + /// + /// Display avatar for user profile + /// + public string? Avatar { get; set; } + + /// + /// Display name for user profile + /// + public string DisplayName { get; set; } = "void user"; + + /// + /// Profile flags + /// + public UserFlags Flags { get; set; } = UserFlags.PublicProfile; + + /// + /// Users storage system for new uploads + /// + public string Storage { get; set; } = "local-disk"; + + /// + /// Account authentication type + /// + public UserAuthType AuthType { get; init; } + + /// + /// Roles assigned to this user which grant them extra permissions + /// + public List Roles { get; init; } = new(); + + /// + /// All files uploaded by this user + /// + public List UserFiles { get; init; } = new(); +} + +public class UserRole +{ + public Guid UserId { get; init; } + public User User { get; init; } + + public string Role { get; init; } = null!; +} + +public enum UserAuthType +{ + /// + /// Encrypted password + /// + Internal = 0, + + /// + /// PGP challenge + /// + PGP = 1, + + /// + /// OAuth2 token + /// + OAuth2 = 2, + + /// + /// Lightning node challenge + /// + Lightning = 3 +} diff --git a/VoidCat/Database/UserAuthToken.cs b/VoidCat/Database/UserAuthToken.cs new file mode 100644 index 0000000..433faa1 --- /dev/null +++ b/VoidCat/Database/UserAuthToken.cs @@ -0,0 +1,15 @@ +namespace VoidCat.Database; + +public class UserAuthToken +{ + public Guid Id { get; init; } + public Guid UserId { get; init; } + public User User { get; init; } = null!; + public string Provider { get; init; } = null!; + public string AccessToken { get; init; } = null!; + public string TokenType { get; init; } = null!; + public DateTime Expires { get; init; } + public string RefreshToken { get; init; } = null!; + public string Scope { get; init; } = null!; + public string? IdToken { get; init; } +} diff --git a/VoidCat/Database/UserFile.cs b/VoidCat/Database/UserFile.cs new file mode 100644 index 0000000..4cfd9d6 --- /dev/null +++ b/VoidCat/Database/UserFile.cs @@ -0,0 +1,10 @@ +namespace VoidCat.Database; + +public class UserFile +{ + public Guid FileId { get; init; } + public File File { get; init; } + + public Guid UserId { get; init; } + public User User { get; init; } +} diff --git a/VoidCat/Database/VirusScanResult.cs b/VoidCat/Database/VirusScanResult.cs new file mode 100644 index 0000000..d21eacb --- /dev/null +++ b/VoidCat/Database/VirusScanResult.cs @@ -0,0 +1,12 @@ +namespace VoidCat.Database; + +public class VirusScanResult +{ + public Guid Id { get; init; } = Guid.NewGuid(); + public Guid FileId { get; init; } + public File File { get; init; } = null!; + public DateTime ScanTime { get; init; } + public string Scanner { get; init; } = null!; + public decimal Score { get; init; } + public string Names { get; init; } = null!; +} diff --git a/VoidCat/Migrations/20230503115108_Init.Designer.cs b/VoidCat/Migrations/20230503115108_Init.Designer.cs new file mode 100644 index 0000000..bf7a7e9 --- /dev/null +++ b/VoidCat/Migrations/20230503115108_Init.Designer.cs @@ -0,0 +1,353 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using VoidCat.Services; + +#nullable disable + +namespace VoidCat.Migrations +{ + [DbContext(typeof(VoidContext))] + [Migration("20230503115108_Init")] + partial class Init + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Expiry") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.Property("Code") + .HasColumnType("uuid"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasIndex("UserId"); + + b.ToTable("EmailVerification", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Digest") + .HasColumnType("text"); + + b.Property("EditSecret") + .HasColumnType("uuid"); + + b.Property("EncryptionParams") + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("MagnetLink") + .HasColumnType("text"); + + b.Property("MimeType") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("application/octet-stream"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Size") + .HasColumnType("numeric(20,0)"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.Property("Uploaded") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Uploaded"); + + b.ToTable("Files", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthType") + .HasColumnType("integer"); + + b.Property("Avatar") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("void user"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Flags") + .HasColumnType("integer"); + + b.Property("LastLogin") + .HasColumnType("timestamp with time zone"); + + b.Property("Password") + .HasColumnType("text"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("IdToken") + .HasColumnType("text"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text"); + + b.Property("RefreshToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("text"); + + b.Property("TokenType") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UsersAuthToken", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "FileId"); + + b.HasIndex("FileId") + .IsUnique(); + + b.ToTable("UserFiles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Role") + .HasColumnType("text"); + + b.HasKey("UserId", "Role"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.Property("Names") + .IsRequired() + .HasColumnType("text"); + + b.Property("ScanTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Scanner") + .IsRequired() + .HasColumnType("text"); + + b.Property("Score") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("VirusScanResult", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithOne() + .HasForeignKey("VoidCat.Database.UserFile", "FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("VoidCat.Database.User", "User") + .WithMany("UserFiles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Navigation("Roles"); + + b.Navigation("UserFiles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/VoidCat/Migrations/20230503115108_Init.cs b/VoidCat/Migrations/20230503115108_Init.cs new file mode 100644 index 0000000..d5d32c8 --- /dev/null +++ b/VoidCat/Migrations/20230503115108_Init.cs @@ -0,0 +1,223 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace VoidCat.Migrations +{ + /// + public partial class Init : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Files", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Name = table.Column(type: "text", nullable: true), + Size = table.Column(type: "numeric(20,0)", nullable: false), + Uploaded = table.Column(type: "timestamp with time zone", nullable: false), + Description = table.Column(type: "text", nullable: true), + MimeType = table.Column(type: "text", nullable: false, defaultValue: "application/octet-stream"), + Digest = table.Column(type: "text", nullable: true), + EditSecret = table.Column(type: "uuid", nullable: false), + Expires = table.Column(type: "timestamp with time zone", nullable: true), + Storage = table.Column(type: "text", nullable: false, defaultValue: "local-disk"), + EncryptionParams = table.Column(type: "text", nullable: true), + MagnetLink = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Files", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Email = table.Column(type: "text", nullable: false), + Password = table.Column(type: "text", nullable: true), + Created = table.Column(type: "timestamp with time zone", nullable: false), + LastLogin = table.Column(type: "timestamp with time zone", nullable: true), + Avatar = table.Column(type: "text", nullable: true), + DisplayName = table.Column(type: "text", nullable: false, defaultValue: "void user"), + Flags = table.Column(type: "integer", nullable: false), + Storage = table.Column(type: "text", nullable: false, defaultValue: "local-disk"), + AuthType = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "VirusScanResult", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + FileId = table.Column(type: "uuid", nullable: false), + ScanTime = table.Column(type: "timestamp with time zone", nullable: false), + Scanner = table.Column(type: "text", nullable: false), + Score = table.Column(type: "numeric", nullable: false), + Names = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_VirusScanResult", x => x.Id); + table.ForeignKey( + name: "FK_VirusScanResult_Files_FileId", + column: x => x.FileId, + principalTable: "Files", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiKey", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + UserId = table.Column(type: "uuid", nullable: false), + Token = table.Column(type: "text", nullable: false), + Expiry = table.Column(type: "timestamp with time zone", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiKey", x => x.Id); + table.ForeignKey( + name: "FK_ApiKey_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserFiles", + columns: table => new + { + FileId = table.Column(type: "uuid", nullable: false), + UserId = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserFiles", x => new { x.UserId, x.FileId }); + table.ForeignKey( + name: "FK_UserFiles_Files_FileId", + column: x => x.FileId, + principalTable: "Files", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserFiles_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserRoles", + columns: table => new + { + UserId = table.Column(type: "uuid", nullable: false), + Role = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserRoles", x => new { x.UserId, x.Role }); + table.ForeignKey( + name: "FK_UserRoles_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UsersAuthToken", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + UserId = table.Column(type: "uuid", nullable: false), + Provider = table.Column(type: "text", nullable: false), + AccessToken = table.Column(type: "text", nullable: false), + TokenType = table.Column(type: "text", nullable: false), + Expires = table.Column(type: "timestamp with time zone", nullable: false), + RefreshToken = table.Column(type: "text", nullable: false), + Scope = table.Column(type: "text", nullable: false), + IdToken = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UsersAuthToken", x => x.Id); + table.ForeignKey( + name: "FK_UsersAuthToken_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ApiKey_UserId", + table: "ApiKey", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_Files_Uploaded", + table: "Files", + column: "Uploaded"); + + migrationBuilder.CreateIndex( + name: "IX_UserFiles_FileId", + table: "UserFiles", + column: "FileId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Users_Email", + table: "Users", + column: "Email"); + + migrationBuilder.CreateIndex( + name: "IX_UsersAuthToken_UserId", + table: "UsersAuthToken", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_VirusScanResult_FileId", + table: "VirusScanResult", + column: "FileId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ApiKey"); + + migrationBuilder.DropTable( + name: "UserFiles"); + + migrationBuilder.DropTable( + name: "UserRoles"); + + migrationBuilder.DropTable( + name: "UsersAuthToken"); + + migrationBuilder.DropTable( + name: "VirusScanResult"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.DropTable( + name: "Files"); + } + } +} diff --git a/VoidCat/Migrations/20230503120701_Paywall.Designer.cs b/VoidCat/Migrations/20230503120701_Paywall.Designer.cs new file mode 100644 index 0000000..e45736d --- /dev/null +++ b/VoidCat/Migrations/20230503120701_Paywall.Designer.cs @@ -0,0 +1,497 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using VoidCat.Services; + +#nullable disable + +namespace VoidCat.Migrations +{ + [DbContext(typeof(VoidContext))] + [Migration("20230503120701_Paywall")] + partial class Paywall + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Expiry") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.Property("Code") + .HasColumnType("uuid"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasIndex("UserId"); + + b.ToTable("EmailVerification", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Digest") + .HasColumnType("text"); + + b.Property("EditSecret") + .HasColumnType("uuid"); + + b.Property("EncryptionParams") + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("MagnetLink") + .HasColumnType("text"); + + b.Property("MimeType") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("application/octet-stream"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Size") + .HasColumnType("numeric(20,0)"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.Property("Uploaded") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Uploaded"); + + b.ToTable("Files", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("Currency") + .HasColumnType("smallint"); + + b.Property("Required") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("Service") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Payment", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("Currency") + .HasColumnType("smallint"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.Property("Service") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.HasIndex("Status"); + + b.ToTable("PaymentOrder", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrderLightning", b => + { + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("Expire") + .HasColumnType("timestamp with time zone"); + + b.Property("Invoice") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("OrderId"); + + b.ToTable("PaymentOrderLightning", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallStrike", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Handle") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("PaymentStrike", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthType") + .HasColumnType("integer"); + + b.Property("Avatar") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("void user"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Flags") + .HasColumnType("integer"); + + b.Property("LastLogin") + .HasColumnType("timestamp with time zone"); + + b.Property("Password") + .HasColumnType("text"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("IdToken") + .HasColumnType("text"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text"); + + b.Property("RefreshToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("text"); + + b.Property("TokenType") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UsersAuthToken", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "FileId"); + + b.HasIndex("FileId") + .IsUnique(); + + b.ToTable("UserFiles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Role") + .HasColumnType("text"); + + b.HasKey("UserId", "Role"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.Property("Names") + .IsRequired() + .HasColumnType("text"); + + b.Property("ScanTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Scanner") + .IsRequired() + .HasColumnType("text"); + + b.Property("Score") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("VirusScanResult", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithOne("Paywall") + .HasForeignKey("VoidCat.Database.Paywall", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrderLightning", b => + { + b.HasOne("VoidCat.Database.PaywallOrder", "Order") + .WithOne("OrderLightning") + .HasForeignKey("VoidCat.Database.PaywallOrderLightning", "OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallStrike", b => + { + b.HasOne("VoidCat.Database.Paywall", "Paywall") + .WithOne("PaywallStrike") + .HasForeignKey("VoidCat.Database.PaywallStrike", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Paywall"); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithOne() + .HasForeignKey("VoidCat.Database.UserFile", "FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("VoidCat.Database.User", "User") + .WithMany("UserFiles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.File", b => + { + b.Navigation("Paywall"); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.Navigation("PaywallStrike"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.Navigation("OrderLightning"); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Navigation("Roles"); + + b.Navigation("UserFiles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/VoidCat/Migrations/20230503120701_Paywall.cs b/VoidCat/Migrations/20230503120701_Paywall.cs new file mode 100644 index 0000000..bad719e --- /dev/null +++ b/VoidCat/Migrations/20230503120701_Paywall.cs @@ -0,0 +1,121 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace VoidCat.Migrations +{ + /// + public partial class Paywall : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Payment", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Service = table.Column(type: "integer", nullable: false), + Currency = table.Column(type: "smallint", nullable: false), + Amount = table.Column(type: "numeric", nullable: false), + Required = table.Column(type: "boolean", nullable: false, defaultValue: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Payment", x => x.Id); + table.ForeignKey( + name: "FK_Payment_Files_Id", + column: x => x.Id, + principalTable: "Files", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PaymentOrder", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + FileId = table.Column(type: "uuid", nullable: false), + Service = table.Column(type: "integer", nullable: false), + Currency = table.Column(type: "smallint", nullable: false), + Amount = table.Column(type: "numeric", nullable: false), + Status = table.Column(type: "smallint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PaymentOrder", x => x.Id); + table.ForeignKey( + name: "FK_PaymentOrder_Files_FileId", + column: x => x.FileId, + principalTable: "Files", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PaymentStrike", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Handle = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PaymentStrike", x => x.Id); + table.ForeignKey( + name: "FK_PaymentStrike_Payment_Id", + column: x => x.Id, + principalTable: "Payment", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PaymentOrderLightning", + columns: table => new + { + OrderId = table.Column(type: "uuid", nullable: false), + Invoice = table.Column(type: "text", nullable: false), + Expire = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PaymentOrderLightning", x => x.OrderId); + table.ForeignKey( + name: "FK_PaymentOrderLightning_PaymentOrder_OrderId", + column: x => x.OrderId, + principalTable: "PaymentOrder", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_PaymentOrder_FileId", + table: "PaymentOrder", + column: "FileId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentOrder_Status", + table: "PaymentOrder", + column: "Status"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "PaymentOrderLightning"); + + migrationBuilder.DropTable( + name: "PaymentStrike"); + + migrationBuilder.DropTable( + name: "PaymentOrder"); + + migrationBuilder.DropTable( + name: "Payment"); + } + } +} diff --git a/VoidCat/Migrations/20230508205513_EmailVerificationId.Designer.cs b/VoidCat/Migrations/20230508205513_EmailVerificationId.Designer.cs new file mode 100644 index 0000000..ff8ff4d --- /dev/null +++ b/VoidCat/Migrations/20230508205513_EmailVerificationId.Designer.cs @@ -0,0 +1,501 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using VoidCat.Services; + +#nullable disable + +namespace VoidCat.Migrations +{ + [DbContext(typeof(VoidContext))] + [Migration("20230508205513_EmailVerificationId")] + partial class EmailVerificationId + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Expiry") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .HasColumnType("uuid"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EmailVerification", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Digest") + .HasColumnType("text"); + + b.Property("EditSecret") + .HasColumnType("uuid"); + + b.Property("EncryptionParams") + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("MagnetLink") + .HasColumnType("text"); + + b.Property("MimeType") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("application/octet-stream"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Size") + .HasColumnType("numeric(20,0)"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.Property("Uploaded") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Uploaded"); + + b.ToTable("Files", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("Currency") + .HasColumnType("smallint"); + + b.Property("Required") + .HasColumnType("boolean"); + + b.Property("Service") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Payment", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("Currency") + .HasColumnType("smallint"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.Property("Service") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.HasIndex("Status"); + + b.ToTable("PaymentOrder", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrderLightning", b => + { + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("Expire") + .HasColumnType("timestamp with time zone"); + + b.Property("Invoice") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("OrderId"); + + b.ToTable("PaymentOrderLightning", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallStrike", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Handle") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("PaymentStrike", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthType") + .HasColumnType("integer"); + + b.Property("Avatar") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("void user"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Flags") + .HasColumnType("integer"); + + b.Property("LastLogin") + .HasColumnType("timestamp with time zone"); + + b.Property("Password") + .HasColumnType("text"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("IdToken") + .HasColumnType("text"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text"); + + b.Property("RefreshToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("text"); + + b.Property("TokenType") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UsersAuthToken", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "FileId"); + + b.HasIndex("FileId") + .IsUnique(); + + b.ToTable("UserFiles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Role") + .HasColumnType("text"); + + b.HasKey("UserId", "Role"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.Property("Names") + .IsRequired() + .HasColumnType("text"); + + b.Property("ScanTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Scanner") + .IsRequired() + .HasColumnType("text"); + + b.Property("Score") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("VirusScanResult", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithOne("Paywall") + .HasForeignKey("VoidCat.Database.Paywall", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrderLightning", b => + { + b.HasOne("VoidCat.Database.PaywallOrder", "Order") + .WithOne("OrderLightning") + .HasForeignKey("VoidCat.Database.PaywallOrderLightning", "OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallStrike", b => + { + b.HasOne("VoidCat.Database.Paywall", "Paywall") + .WithOne("PaywallStrike") + .HasForeignKey("VoidCat.Database.PaywallStrike", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Paywall"); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithOne() + .HasForeignKey("VoidCat.Database.UserFile", "FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("VoidCat.Database.User", "User") + .WithMany("UserFiles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.File", b => + { + b.Navigation("Paywall"); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.Navigation("PaywallStrike"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.Navigation("OrderLightning"); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Navigation("Roles"); + + b.Navigation("UserFiles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/VoidCat/Migrations/20230508205513_EmailVerificationId.cs b/VoidCat/Migrations/20230508205513_EmailVerificationId.cs new file mode 100644 index 0000000..dcd1aa9 --- /dev/null +++ b/VoidCat/Migrations/20230508205513_EmailVerificationId.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace VoidCat.Migrations +{ + /// + public partial class EmailVerificationId : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "EmailVerification", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + UserId = table.Column(type: "uuid", nullable: false), + Code = table.Column(type: "uuid", nullable: false), + Expires = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.ForeignKey( + name: "FK_EmailVerification_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.AlterColumn( + name: "Required", + table: "Payment", + type: "boolean", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_EmailVerification", + table: "EmailVerification", + column: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable("EmailVerification"); + + migrationBuilder.AlterColumn( + name: "Required", + table: "Payment", + type: "boolean", + nullable: false, + defaultValue: true, + oldClrType: typeof(bool), + oldType: "boolean"); + } + } +} diff --git a/VoidCat/Migrations/VoidContextModelSnapshot.cs b/VoidCat/Migrations/VoidContextModelSnapshot.cs new file mode 100644 index 0000000..32e384f --- /dev/null +++ b/VoidCat/Migrations/VoidContextModelSnapshot.cs @@ -0,0 +1,498 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using VoidCat.Services; + +#nullable disable + +namespace VoidCat.Migrations +{ + [DbContext(typeof(VoidContext))] + partial class VoidContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Expiry") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .HasColumnType("uuid"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EmailVerification", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Digest") + .HasColumnType("text"); + + b.Property("EditSecret") + .HasColumnType("uuid"); + + b.Property("EncryptionParams") + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("MagnetLink") + .HasColumnType("text"); + + b.Property("MimeType") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("application/octet-stream"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Size") + .HasColumnType("numeric(20,0)"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.Property("Uploaded") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("Uploaded"); + + b.ToTable("Files", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("Currency") + .HasColumnType("smallint"); + + b.Property("Required") + .HasColumnType("boolean"); + + b.Property("Service") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Payment", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("numeric"); + + b.Property("Currency") + .HasColumnType("smallint"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.Property("Service") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.HasIndex("Status"); + + b.ToTable("PaymentOrder", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrderLightning", b => + { + b.Property("OrderId") + .HasColumnType("uuid"); + + b.Property("Expire") + .HasColumnType("timestamp with time zone"); + + b.Property("Invoice") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("OrderId"); + + b.ToTable("PaymentOrderLightning", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallStrike", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Handle") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("PaymentStrike", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuthType") + .HasColumnType("integer"); + + b.Property("Avatar") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("void user"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Flags") + .HasColumnType("integer"); + + b.Property("LastLogin") + .HasColumnType("timestamp with time zone"); + + b.Property("Password") + .HasColumnType("text"); + + b.Property("Storage") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("local-disk"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccessToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("IdToken") + .HasColumnType("text"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("text"); + + b.Property("RefreshToken") + .IsRequired() + .HasColumnType("text"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("text"); + + b.Property("TokenType") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UsersAuthToken", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.HasKey("UserId", "FileId"); + + b.HasIndex("FileId") + .IsUnique(); + + b.ToTable("UserFiles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Role") + .HasColumnType("text"); + + b.HasKey("UserId", "Role"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("FileId") + .HasColumnType("uuid"); + + b.Property("Names") + .IsRequired() + .HasColumnType("text"); + + b.Property("ScanTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Scanner") + .IsRequired() + .HasColumnType("text"); + + b.Property("Score") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("VirusScanResult", (string)null); + }); + + modelBuilder.Entity("VoidCat.Database.ApiKey", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.EmailVerification", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithOne("Paywall") + .HasForeignKey("VoidCat.Database.Paywall", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrderLightning", b => + { + b.HasOne("VoidCat.Database.PaywallOrder", "Order") + .WithOne("OrderLightning") + .HasForeignKey("VoidCat.Database.PaywallOrderLightning", "OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallStrike", b => + { + b.HasOne("VoidCat.Database.Paywall", "Paywall") + .WithOne("PaywallStrike") + .HasForeignKey("VoidCat.Database.PaywallStrike", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Paywall"); + }); + + modelBuilder.Entity("VoidCat.Database.UserAuthToken", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserFile", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithOne() + .HasForeignKey("VoidCat.Database.UserFile", "FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("VoidCat.Database.User", "User") + .WithMany("UserFiles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.UserRole", b => + { + b.HasOne("VoidCat.Database.User", "User") + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("VoidCat.Database.VirusScanResult", b => + { + b.HasOne("VoidCat.Database.File", "File") + .WithMany() + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("VoidCat.Database.File", b => + { + b.Navigation("Paywall"); + }); + + modelBuilder.Entity("VoidCat.Database.Paywall", b => + { + b.Navigation("PaywallStrike"); + }); + + modelBuilder.Entity("VoidCat.Database.PaywallOrder", b => + { + b.Navigation("OrderLightning"); + }); + + modelBuilder.Entity("VoidCat.Database.User", b => + { + b.Navigation("Roles"); + + b.Navigation("UserFiles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/VoidCat/Model/AdminApiUser.cs b/VoidCat/Model/AdminApiUser.cs new file mode 100644 index 0000000..c0d1d2a --- /dev/null +++ b/VoidCat/Model/AdminApiUser.cs @@ -0,0 +1,7 @@ +namespace VoidCat.Model; + +public class AdminApiUser : ApiUser +{ + public string Storage { get; init; } = null!; + public string Email { get; init; } = null!; +} diff --git a/VoidCat/Model/ApiUser.cs b/VoidCat/Model/ApiUser.cs new file mode 100644 index 0000000..d6da920 --- /dev/null +++ b/VoidCat/Model/ApiUser.cs @@ -0,0 +1,51 @@ +using Newtonsoft.Json; +using VoidCat.Database; + +namespace VoidCat.Model; + +/// +/// A user object which can be returned via the API +/// +public class ApiUser +{ + /// + /// Unique Id of the user + /// + [JsonConverter(typeof(Base58GuidConverter))] + public Guid Id { get; init; } + + /// + /// Display name + /// + public string? Name { get; init; } + + /// + /// Avatar + /// + public string? Avatar { get; init; } + + /// + /// If profile can be viewed by anyone + /// + public bool PublicProfile { get; init; } + + /// + /// If the users uploads can be viewed by anyone + /// + public bool PublicUploads { get; init; } + + /// + /// If the account is not email verified + /// + public bool? NeedsVerification { get; init; } + + /// + /// A list of roles the user has + /// + public List Roles { get; init; } = new(); + + /// + /// When the account was created + /// + public DateTime Created { get; init; } +} diff --git a/VoidCat/Model/EmailVerificationCode.cs b/VoidCat/Model/EmailVerificationCode.cs deleted file mode 100644 index 767c415..0000000 --- a/VoidCat/Model/EmailVerificationCode.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace VoidCat.Model; - -/// -/// Email verification token -/// -/// -/// -/// -public sealed record EmailVerificationCode(Guid User, Guid Code, DateTime Expires); \ No newline at end of file diff --git a/VoidCat/Model/Extensions.cs b/VoidCat/Model/Extensions.cs index b6c7df7..521c3cc 100644 --- a/VoidCat/Model/Extensions.cs +++ b/VoidCat/Model/Extensions.cs @@ -6,8 +6,9 @@ using Amazon.Runtime; using Amazon.S3; using BencodeNET.Objects; using BencodeNET.Torrents; +using VoidCat.Database; using VoidCat.Model.Exceptions; -using VoidCat.Model.User; +using File = VoidCat.Database.File; namespace VoidCat.Model; @@ -82,7 +83,7 @@ public static class Extensions return !string.IsNullOrEmpty(h.Value.ToString()) ? h.Value.ToString() : default; } - public static bool CanEdit(this SecretFileMeta file, Guid? editSecret) + public static bool CanEdit(this File file, Guid? editSecret) { return file.EditSecret == editSecret; } @@ -231,12 +232,15 @@ public static class Extensions /// /// /// - public static bool CheckPassword(this InternalUser vu, string password) + public static bool CheckPassword(this Database.User vu, string password) { - if (vu.AuthType != AuthType.Internal) + if (vu.AuthType != UserAuthType.Internal) throw new InvalidOperationException("User type is not internal, cannot check password!"); - var hashParts = vu.Password.Split(":"); + if (string.IsNullOrEmpty(vu.Password)) + throw new InvalidOperationException("User password is not set"); + + var hashParts = vu.Password!.Split(":"); return vu.Password == password.Hash(hashParts[0], hashParts.Length == 3 ? hashParts[1] : null); } @@ -245,7 +249,7 @@ public static class Extensions /// /// /// - public static void Patch(this FileMeta oldMeta, FileMeta meta) + public static void Patch(this File oldMeta, File meta) { oldMeta.Description = meta.Description ?? oldMeta.Description; oldMeta.Name = meta.Name ?? oldMeta.Name; @@ -276,13 +280,14 @@ public static class Extensions public static bool HasGoogle(this VoidSettings settings) => settings.Google != null; - public static async Task MakeTorrent(this FileMeta meta, Stream fileStream, Uri baseAddress, List trackers) + public static async Task MakeTorrent(this VoidFileMeta meta, Guid id, Stream fileStream, Uri baseAddress, + List trackers) { const int pieceSize = 262_144; const int pieceHashLen = 20; var webSeed = new UriBuilder(baseAddress) { - Path = $"/d/{meta.Id.ToBase58()}" + Path = $"/d/{id.ToBase58()}" }; async Task BuildPieces() @@ -310,7 +315,7 @@ public static class Extensions FileSize = (long)meta.Size }, Comment = meta.Name, - CreationDate = meta.Uploaded.UtcDateTime, + CreationDate = meta.Uploaded, IsPrivate = false, PieceSize = pieceSize, Pieces = await BuildPieces(), @@ -324,4 +329,72 @@ public static class Extensions return t; } -} \ No newline at end of file + + public static VoidFileResponse ToResponse(this File f, bool withEditSecret) + { + return new() + { + Id = f.Id, + Metadata = f.ToMeta(withEditSecret) + }; + } + + public static VoidFileMeta ToMeta(this File f, bool withEditSecret) + { + return new() + { + Name = f.Name, + Description = f.Description, + Uploaded = f.Uploaded, + MimeType = f.MimeType, + Size = f.Size, + Digest = f.Digest, + Expires = f.Expires, + EditSecret = withEditSecret ? f.EditSecret : null, + Storage = f.Storage, + EncryptionParams = f.EncryptionParams, + MagnetLink = f.MagnetLink + }; + } + + public static ApiUser ToApiUser(this User u, bool isSelf) + { + return new() + { + Id = u.Id, + Name = u.DisplayName, + Avatar = u.Avatar, + Created = u.Created, + NeedsVerification = isSelf ? !u.Flags.HasFlag(UserFlags.EmailVerified) : null, + PublicProfile = u.Flags.HasFlag(UserFlags.PublicProfile), + PublicUploads = u.Flags.HasFlag(UserFlags.PublicUploads), + Roles = u.Roles.Select(a => a.Role).ToList() + }; + } + + public static AdminApiUser ToAdminApiUser(this User u, bool isSelf) + { + return new() + { + Id = u.Id, + Name = u.DisplayName, + Avatar = u.Avatar, + Created = u.Created, + NeedsVerification = isSelf ? !u.Flags.HasFlag(UserFlags.EmailVerified) : null, + PublicProfile = u.Flags.HasFlag(UserFlags.PublicProfile), + PublicUploads = u.Flags.HasFlag(UserFlags.PublicUploads), + Roles = u.Roles.Select(a => a.Role).ToList(), + Storage = u.Storage, + Email = u.Email + }; + } + public static VirusStatus ToVirusStatus(this VirusScanResult r) + { + return new() + { + ScanTime = r.ScanTime, + IsVirus = r.Score > 0.7m, + Names = r.Names + }; + } +} diff --git a/VoidCat/Model/IngressPayload.cs b/VoidCat/Model/IngressPayload.cs index b0776c6..89cb6f9 100644 --- a/VoidCat/Model/IngressPayload.cs +++ b/VoidCat/Model/IngressPayload.cs @@ -1,6 +1,6 @@ namespace VoidCat.Model; -public sealed record IngressPayload(Stream InStream, SecretFileMeta Meta, int Segment, int TotalSegments, bool ShouldStripMetadata) +public sealed record IngressPayload(Stream InStream, Database.File Meta, int Segment, int TotalSegments, bool ShouldStripMetadata) { public Guid Id { get; init; } = Guid.NewGuid(); public Guid? EditSecret { get; init; } diff --git a/VoidCat/Model/Payments/PaymentMoney.cs b/VoidCat/Model/Payments/PaymentMoney.cs deleted file mode 100644 index c6419db..0000000 --- a/VoidCat/Model/Payments/PaymentMoney.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Text.Json.Serialization; - -namespace VoidCat.Model.Payments; - -/// -/// Money amount for payment orders -/// -/// -/// -public record PaymentMoney(decimal Amount, PaymentCurrencies Currency); - -/// -/// Supported payment currencies -/// -[JsonConverter(typeof(JsonStringEnumConverter))] -public enum PaymentCurrencies : byte -{ - BTC = 0, - USD = 1, - EUR = 2, - GBP = 3 -} diff --git a/VoidCat/Model/Payments/PaymentOrder.cs b/VoidCat/Model/Payments/PaymentOrder.cs deleted file mode 100644 index dac7ca0..0000000 --- a/VoidCat/Model/Payments/PaymentOrder.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace VoidCat.Model.Payments; - -/// -/// Status of payment order -/// -public enum PaymentOrderStatus : byte -{ - /// - /// Invoice is not paid yet - /// - Unpaid, - - /// - /// Invoice is paid - /// - Paid, - - /// - /// Invoice has expired and cant be paid - /// - Expired -} - -/// -/// Base payment order -/// -public class PaymentOrder -{ - /// - /// Unique id of the order - /// - public Guid Id { get; init; } - - /// - /// File id this order is for - /// - public Guid File { get; init; } - - /// - /// Service used to generate this order - /// - public PaymentServices Service { get; init; } - - /// - /// The price of the order - /// - public PaymentMoney Price { get; init; } = null!; - - /// - /// Current status of the order - /// - public PaymentOrderStatus Status { get; set; } -} - -/// -/// A payment order lightning network invoice -/// -public class LightningPaymentOrder : PaymentOrder -{ - /// - /// Lightning invoice - /// - public string Invoice { get; init; } = null!; - - /// - /// Expire time of the order - /// - public DateTime Expire { get; init; } -} \ No newline at end of file diff --git a/VoidCat/Model/Payments/PaymentServices.cs b/VoidCat/Model/Payments/PaymentServices.cs deleted file mode 100644 index 6e66e9e..0000000 --- a/VoidCat/Model/Payments/PaymentServices.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace VoidCat.Model.Payments; - -/// -/// Payment services supported by the system -/// -public enum PaymentServices -{ - /// - /// No service - /// - None, - - /// - /// Strike.me payment service - /// - Strike -} \ No newline at end of file diff --git a/VoidCat/Model/Payments/PaymentsConfig.cs b/VoidCat/Model/Payments/PaymentsConfig.cs deleted file mode 100644 index af50b8b..0000000 --- a/VoidCat/Model/Payments/PaymentsConfig.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace VoidCat.Model.Payments; - -/// -/// Base payment config -/// -public abstract class PaymentConfig -{ - /// - /// File this config is for - /// - public Guid File { get; init; } - - /// - /// Service used to pay the payment - /// - public PaymentServices Service { get; init; } = PaymentServices.None; - - /// - /// The cost for the payment to pass - /// - public PaymentMoney Cost { get; init; } = new(0m, PaymentCurrencies.BTC); - - /// - /// If the payment is required - /// - public bool Required { get; init; } = true; -} - -/// -public sealed class NoPaymentConfig : PaymentConfig -{ - -} - -/// -/// Payment config for service -/// -/// -public sealed class StrikePaymentConfig : PaymentConfig -{ - /// - /// Strike username to pay to - /// - public string Handle { get; init; } = null!; -} \ No newline at end of file diff --git a/VoidCat/Model/User/ApiKey.cs b/VoidCat/Model/User/ApiKey.cs deleted file mode 100644 index d9f547b..0000000 --- a/VoidCat/Model/User/ApiKey.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace VoidCat.Model.User; - -public sealed class ApiKey -{ - [JsonConverter(typeof(Base58GuidConverter))] - public Guid Id { get; init; } - - [JsonConverter(typeof(Base58GuidConverter))] - public Guid UserId { get; init; } - - public string Token { get; init; } - - public DateTime Expiry { get; init; } - - public DateTime Created { get; init; } -} diff --git a/VoidCat/Model/User/AuthType.cs b/VoidCat/Model/User/AuthType.cs deleted file mode 100644 index 9d0edb2..0000000 --- a/VoidCat/Model/User/AuthType.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace VoidCat.Model.User; - -/// -/// User account authentication type -/// -public enum AuthType -{ - /// - /// Encrypted password - /// - Internal = 0, - - /// - /// PGP challenge - /// - PGP = 1, - - /// - /// OAuth2 token - /// - OAuth2 = 2, - - /// - /// Lightning node challenge - /// - Lightning = 3 -} \ No newline at end of file diff --git a/VoidCat/Model/User/InternalUser.cs b/VoidCat/Model/User/InternalUser.cs deleted file mode 100644 index 7ead244..0000000 --- a/VoidCat/Model/User/InternalUser.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace VoidCat.Model.User; - -/// -/// Internal user object used by the system -/// -public sealed class InternalUser : PrivateUser -{ - /// - /// A password hash for the user in the format - /// - public string Password { get; init; } = null!; -} \ No newline at end of file diff --git a/VoidCat/Model/User/PrivateUser.cs b/VoidCat/Model/User/PrivateUser.cs deleted file mode 100644 index 12bc51d..0000000 --- a/VoidCat/Model/User/PrivateUser.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace VoidCat.Model.User; - -/// -/// A user object which includes the Email -/// -public class PrivateUser : User -{ - /// - /// Users email address - /// - public string Email { get; set; } = null!; - - /// - /// Users storage system for new uploads - /// - public string? Storage { get; set; } -} \ No newline at end of file diff --git a/VoidCat/Model/User/PublicUser.cs b/VoidCat/Model/User/PublicUser.cs deleted file mode 100644 index 13768c1..0000000 --- a/VoidCat/Model/User/PublicUser.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace VoidCat.Model.User; - -/// -public sealed class PublicUser : User -{ -} \ No newline at end of file diff --git a/VoidCat/Model/User/User.cs b/VoidCat/Model/User/User.cs deleted file mode 100644 index b9e0ba1..0000000 --- a/VoidCat/Model/User/User.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Newtonsoft.Json; - -namespace VoidCat.Model.User; - -/// -/// The base user object for the system -/// -public abstract class User -{ - /// - /// Unique Id of the user - /// - [JsonConverter(typeof(Base58GuidConverter))] - public Guid Id { get; init; } - - /// - /// Roles assigned to this user which grant them extra permissions - /// - public HashSet Roles { get; init; } = new() {Model.Roles.User}; - - /// - /// When the user account was created - /// - public DateTimeOffset Created { get; init; } - - /// - /// The last time the user logged in - /// - public DateTimeOffset LastLogin { get; set; } - - /// - /// Display avatar for user profile - /// - public string? Avatar { get; set; } - - /// - /// Display name for user profile - /// - public string? DisplayName { get; set; } = "void user"; - - /// - /// Profile flags - /// - public UserFlags Flags { get; set; } = UserFlags.PublicProfile; - - /// - /// Account authentication type - /// - public AuthType AuthType { get; init; } - - /// - /// Returns the Public object for this user - /// - /// - public PublicUser ToPublic() - { - return new() - { - Id = Id, - Roles = Roles, - Created = Created, - LastLogin = LastLogin, - Avatar = Avatar, - Flags = Flags - }; - } -} \ No newline at end of file diff --git a/VoidCat/Model/User/UserAuthToken.cs b/VoidCat/Model/User/UserAuthToken.cs deleted file mode 100644 index 775a3dc..0000000 --- a/VoidCat/Model/User/UserAuthToken.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace VoidCat.Model.User; - -/// -/// OAuth2 access token -/// -public sealed class UserAuthToken -{ - public Guid Id { get; init; } - - public Guid User { get; init; } - - public string Provider { get; init; } - - public string AccessToken { get; init; } - - public string TokenType { get; init; } - - public DateTime Expires { get; init; } - - public string RefreshToken { get; init; } - - public string Scope { get; init; } - - public string IdToken { get; init; } -} \ No newline at end of file diff --git a/VoidCat/Model/User/UserFlags.cs b/VoidCat/Model/User/UserFlags.cs deleted file mode 100644 index 2d23f4f..0000000 --- a/VoidCat/Model/User/UserFlags.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace VoidCat.Model.User; - -/// -/// Account status flags -/// -[Flags] -public enum UserFlags -{ - /// - /// Profile is public - /// - PublicProfile = 1, - - /// - /// Uploads list is public - /// - PublicUploads = 2, - - /// - /// Account has email verified - /// - EmailVerified = 4 -} \ No newline at end of file diff --git a/VoidCat/Model/VirusScanResult.cs b/VoidCat/Model/VirusScanResult.cs index aab6c0c..8955626 100644 --- a/VoidCat/Model/VirusScanResult.cs +++ b/VoidCat/Model/VirusScanResult.cs @@ -1,38 +1,14 @@ -using Newtonsoft.Json; - -namespace VoidCat.Model; +namespace VoidCat.Model; /// /// Results for virus scan of a single file /// -public sealed class VirusScanResult +public sealed class VirusStatus { - /// - /// Unique Id for this scan - /// - [JsonConverter(typeof(Base58GuidConverter))] - public Guid Id { get; init; } - - /// - /// Id of the file that was scanned - /// - [JsonConverter(typeof(Base58GuidConverter))] - public Guid File { get; init; } - /// /// Time the file was scanned /// - public DateTimeOffset ScanTime { get; init; } = DateTimeOffset.UtcNow; - - /// - /// The name of the virus scanner software - /// - public string Scanner { get; init; } = null!; - - /// - /// Virus detection score, this can mean different things for each scanner but the value should be between 0 and 1 - /// - public decimal Score { get; init; } + public DateTime ScanTime { get; init; } /// /// Detected virus names @@ -42,5 +18,5 @@ public sealed class VirusScanResult /// /// If we consider this result as a virus or not /// - public bool IsVirus => Score >= 0.75m && !string.IsNullOrEmpty(Names); + public bool IsVirus { get; init; } } \ No newline at end of file diff --git a/VoidCat/Model/VoidFile.cs b/VoidCat/Model/VoidFile.cs index c832145..3b4b456 100644 --- a/VoidCat/Model/VoidFile.cs +++ b/VoidCat/Model/VoidFile.cs @@ -1,48 +1,35 @@ using Newtonsoft.Json; -using VoidCat.Model.Payments; -using VoidCat.Model.User; +using VoidCat.Database; -namespace VoidCat.Model +namespace VoidCat.Model; + +/// +/// Primary response type for file information +/// +public class VoidFileResponse { - public abstract record VoidFile where TMeta : FileMeta - { - /// - /// Id of the file - /// - [JsonConverter(typeof(Base58GuidConverter))] - public Guid Id { get; init; } + [JsonConverter(typeof(Base58GuidConverter))] + public Guid Id { get; init; } + public VoidFileMeta Metadata { get; init; } = null!; + public Paywall? Payment { get; init; } + public ApiUser? Uploader { get; init; } + public Bandwidth? Bandwidth { get; init; } + public VirusStatus? VirusScan { get; init; } +} - /// - /// Metadta related to the file - /// - public TMeta? Metadata { get; init; } - - /// - /// Optional payment config - /// - public PaymentConfig? Payment { get; init; } - - /// - /// User profile that uploaded the file - /// - public PublicUser? Uploader { get; init; } - - /// - /// Traffic stats for this file - /// - public Bandwidth? Bandwidth { get; init; } - - /// - /// Virus scanner results - /// - public VirusScanResult? VirusScan { get; init; } - } - - public sealed record PublicVoidFile : VoidFile - { - } - - public sealed record PrivateVoidFile : VoidFile - { - } +public class VoidFileMeta +{ + public string? Name { get; init; } + public ulong Size { get; init; } + public DateTime Uploaded { get; init; } + public string? Description { get; init; } + public string MimeType { get; init; } + public string? Digest { get; init; } + + [JsonConverter(typeof(Base58GuidConverter))] + public Guid? EditSecret { get; init; } + public DateTime? Expires { get; init; } + public string Storage { get; init; } = "local-disk"; + public string? EncryptionParams { get; init; } + public string? MagnetLink { get; init; } } \ No newline at end of file diff --git a/VoidCat/Model/VoidFileMeta.cs b/VoidCat/Model/VoidFileMeta.cs deleted file mode 100644 index fc622a0..0000000 --- a/VoidCat/Model/VoidFileMeta.cs +++ /dev/null @@ -1,100 +0,0 @@ -using Newtonsoft.Json; -using VoidCat.Services.Abstractions; - -// ReSharper disable InconsistentNaming - -namespace VoidCat.Model; - -/// -/// Base metadata must contain version number -/// -public interface IFileMeta -{ - const int CurrentVersion = 3; - - int Version { get; init; } -} - -/// -/// File metadata which is managed by -/// -public record FileMeta : IFileMeta -{ - /// - /// Metadata version - /// - public int Version { get; init; } = IFileMeta.CurrentVersion; - - /// - /// Internal Id of the file - /// - [JsonConverter(typeof(Base58GuidConverter))] - public Guid Id { get; set; } - - /// - /// Filename - /// - public string? Name { get; set; } - - /// - /// Size of the file in storage - /// - public ulong Size { get; init; } - - /// - /// Date file was uploaded - /// - public DateTimeOffset Uploaded { get; init; } = DateTimeOffset.UtcNow; - - /// - /// Description about the file - /// - public string? Description { get; set; } - - /// - /// The content type of the file - /// - public string? MimeType { get; set; } - - /// - /// SHA-256 hash of the file - /// - public string? Digest { get; set; } - - /// - /// Url to download the file - /// - public Uri? Url { get; set; } - - /// - /// Time when the file will expire and be deleted - /// - public DateTimeOffset? Expires { get; set; } - - /// - /// What storage system the file is on - /// - public string? Storage { get; set; } - - /// - /// Encryption params as JSON string - /// - public string? EncryptionParams { get; set; } - - /// - /// Magnet link for downloads - /// - public string? MagnetLink { get; set; } -} - -/// -/// with attached -/// -public record SecretFileMeta : FileMeta -{ - /// - /// A secret key used to make edits to the file after its uploaded - /// - [JsonConverter(typeof(Base58GuidConverter))] - public Guid EditSecret { get; init; } -} \ No newline at end of file diff --git a/VoidCat/Model/VoidSettings.cs b/VoidCat/Model/VoidSettings.cs index d9ea86e..b03fa1a 100644 --- a/VoidCat/Model/VoidSettings.cs +++ b/VoidCat/Model/VoidSettings.cs @@ -127,6 +127,11 @@ namespace VoidCat.Model "udp://tracker.openbittorrent.com:6969/announce", "http://tracker.openbittorrent.com:80/announce" }; + + /// + /// Lightning node configuration for LNProxy services + /// + public LndConfig? LndConfig { get; init; } } public sealed class TorSettings @@ -207,4 +212,12 @@ namespace VoidCat.Model public string? ClientId { get; init; } public string? ClientSecret { get; init; } } + + public sealed class LndConfig + { + public string Network { get; init; } = "regtest"; + public Uri Endpoint { get; init; } + public string CertPath { get; init; } = null!; + public string MacaroonPath { get; init; } = null!; + } } diff --git a/VoidCat/Pages/EmailCode.cshtml b/VoidCat/Pages/EmailCode.cshtml index b6ca55d..1fa134a 100644 --- a/VoidCat/Pages/EmailCode.cshtml +++ b/VoidCat/Pages/EmailCode.cshtml @@ -1,6 +1,6 @@ @using VoidCat.Model @using VoidCat.Services.Users -@model VoidCat.Model.EmailVerificationCode +@model VoidCat.Database.EmailVerification @@ -31,7 +31,7 @@

void.cat

Your verification code is below please copy this to complete verification

-
@(Model?.Code.ToBase58() ?? "?????????????")
+
@(Model.Code.ToBase58())

This code will expire in @BaseEmailVerification.HoursExpire hours

diff --git a/VoidCat/Pages/Index.cshtml b/VoidCat/Pages/Index.cshtml index 2e9e993..f95e32f 100644 --- a/VoidCat/Pages/Index.cshtml +++ b/VoidCat/Pages/Index.cshtml @@ -17,12 +17,12 @@ - + var mime = Model.Meta.MimeType; if (mime != default) { - var link = $"https://{Context.Request.Host}/d/{Model.Meta.Id.ToBase58()}"; + var link = $"https://{Context.Request.Host}/d/{Model.Id.ToBase58()}"; if (mime.StartsWith("image/")) { diff --git a/VoidCat/Program.cs b/VoidCat/Program.cs index 2c836b2..e5e1fca 100644 --- a/VoidCat/Program.cs +++ b/VoidCat/Program.cs @@ -1,150 +1,188 @@ +using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using Prometheus; -using VoidCat; using VoidCat.Model; +using VoidCat.Services; using VoidCat.Services.Analytics; using VoidCat.Services.Migrations; -JsonConvert.DefaultSettings = () => VoidStartup.ConfigJsonSettings(new()); +namespace VoidCat; -RunModes mode = args.Length == 0 ? RunModes.All : 0; - -if (args.Contains("--run-webserver")) +static class Program { - mode |= RunModes.Webserver; -} - -if (args.Contains("--run-migrations")) -{ - mode |= RunModes.Migrations; -} - -if (args.Contains("--run-background-jobs")) -{ - mode |= RunModes.BackgroundJobs; -} - -Console.WriteLine($"Running with modes: {mode}"); - -async Task RunMigrations(IServiceProvider services) -{ - using var migrationScope = services.CreateScope(); - var migrations = migrationScope.ServiceProvider.GetServices(); - var logger = migrationScope.ServiceProvider.GetRequiredService>(); - foreach (var migration in migrations.OrderBy(a => a.Order)) + [Flags] + enum RunModes { - logger.LogInformation("Running migration: {Migration}", migration.GetType().Name); - var res = await migration.Migrate(args); - logger.LogInformation("== Result: {Result}", res.ToString()); - if (res == IMigration.MigrationResult.ExitCompleted) + Webserver = 1, + BackgroundJobs = 2, + Migrations = 4, + All = 255 + } + + public static async Task Main(string[] args) + { + JsonConvert.DefaultSettings = () => VoidStartup.ConfigJsonSettings(new()); + + RunModes mode = args.Length == 0 ? RunModes.All : 0; + if (args.Contains("--run-webserver")) { - return; + mode |= RunModes.Webserver; } - } -} -if (mode.HasFlag(RunModes.Webserver)) -{ - var builder = WebApplication.CreateBuilder(args); - var services = builder.Services; + if (args.Contains("--run-migrations")) + { + mode |= RunModes.Migrations; + } - var configuration = builder.Configuration; - var voidSettings = configuration.GetSection("Settings").Get(); - services.AddSingleton(voidSettings); - services.AddSingleton(voidSettings.Strike ?? new()); + if (args.Contains("--run-background-jobs")) + { + mode |= RunModes.BackgroundJobs; + } - var seqSettings = configuration.GetSection("Seq"); - builder.Logging.AddSeq(seqSettings); + Console.WriteLine($"Running with modes: {mode}"); - services.AddBaseServices(voidSettings); - services.AddDatabaseServices(voidSettings); - services.AddWebServices(voidSettings); + async Task RunMigrations(IServiceProvider services) + { + using var migrationScope = services.CreateScope(); + var migrations = migrationScope.ServiceProvider.GetServices(); + var logger = migrationScope.ServiceProvider.GetRequiredService>(); + foreach (var migration in migrations.OrderBy(a => a.Order)) + { + logger.LogInformation("Running migration: {Migration}", migration.GetType().Name); + var res = await migration.Migrate(args); + logger.LogInformation("== Result: {Result}", res.ToString()); + if (res == IMigration.MigrationResult.ExitCompleted) + { + return; + } + } + } - if (mode.HasFlag(RunModes.Migrations)) - { - services.AddMigrations(voidSettings); - } + if (mode.HasFlag(RunModes.Webserver)) + { + var builder = WebApplication.CreateBuilder(args); + var services = builder.Services; - if (mode.HasFlag(RunModes.BackgroundJobs)) - { - services.AddBackgroundServices(voidSettings); - } + var configuration = builder.Configuration; + var voidSettings = configuration.GetSection("Settings").Get(); + services.AddSingleton(voidSettings); + services.AddSingleton(voidSettings.Strike ?? new()); - var app = builder.Build(); + var seqSettings = configuration.GetSection("Seq"); + builder.Logging.AddSeq(seqSettings); - if (mode.HasFlag(RunModes.Migrations)) - { - await RunMigrations(app.Services); - } + ConfigureDb(services, voidSettings); + services.AddBaseServices(voidSettings); + services.AddDatabaseServices(voidSettings); + services.AddWebServices(voidSettings); + + if (mode.HasFlag(RunModes.Migrations)) + { + services.AddMigrations(voidSettings); + } + + if (mode.HasFlag(RunModes.BackgroundJobs)) + { + services.AddBackgroundServices(voidSettings); + } + + var app = builder.Build(); + + if (mode.HasFlag(RunModes.Migrations)) + { + await RunMigrations(app.Services); + } #if HostSPA - app.UseStaticFiles(); + app.UseStaticFiles(); #endif - app.UseHttpLogging(); - app.UseRouting(); - app.UseCors(); - app.UseSwagger(); - app.UseSwaggerUI(); - app.UseAuthentication(); - app.UseAuthorization(); + app.UseHttpLogging(); + app.UseRouting(); + app.UseCors(); + app.UseSwagger(); + app.UseSwaggerUI(); + app.UseAuthentication(); + app.UseAuthorization(); - app.UseHealthChecks("/healthz"); + app.UseHealthChecks("/healthz"); - app.UseMiddleware(); - app.UseEndpoints(ep => - { - ep.MapControllers(); - ep.MapMetrics(); - ep.MapRazorPages(); + app.UseMiddleware(); + app.UseEndpoints(ep => + { + ep.MapControllers(); + ep.MapMetrics(); + ep.MapRazorPages(); #if HostSPA - ep.MapFallbackToFile("index.html"); + ep.MapFallbackToFile("index.html"); #endif - }); + }); - app.Run(); -} -else -{ - // daemon style, dont run web server - var builder = Host.CreateDefaultBuilder(args); - builder.ConfigureServices((context, services) => - { - var voidSettings = context.Configuration.GetSection("Settings").Get(); - services.AddSingleton(voidSettings); - services.AddSingleton(voidSettings.Strike ?? new()); - - services.AddBaseServices(voidSettings); - services.AddDatabaseServices(voidSettings); - if (mode.HasFlag(RunModes.Migrations)) - { - services.AddMigrations(voidSettings); + await app.RunAsync(); } - - if (mode.HasFlag(RunModes.BackgroundJobs)) + else { - services.AddBackgroundServices(voidSettings); - } - }); - builder.ConfigureLogging((context, logging) => { logging.AddSeq(context.Configuration.GetSection("Seq")); }); + // daemon style, dont run web server + var builder = Host.CreateDefaultBuilder(args); + builder.ConfigureServices((context, services) => + { + var voidSettings = context.Configuration.GetSection("Settings").Get(); + services.AddSingleton(voidSettings); + services.AddSingleton(voidSettings.Strike ?? new()); - var app = builder.Build(); - if (mode.HasFlag(RunModes.Migrations)) - { - await RunMigrations(app.Services); + ConfigureDb(services, voidSettings); + services.AddBaseServices(voidSettings); + services.AddDatabaseServices(voidSettings); + if (mode.HasFlag(RunModes.Migrations)) + { + services.AddMigrations(voidSettings); + } + + if (mode.HasFlag(RunModes.BackgroundJobs)) + { + services.AddBackgroundServices(voidSettings); + } + }); + + builder.ConfigureLogging((context, logging) => { logging.AddSeq(context.Configuration.GetSection("Seq")); }); + + var app = builder.Build(); + if (mode.HasFlag(RunModes.Migrations)) + { + await RunMigrations(app.Services); + } + + if (mode.HasFlag(RunModes.BackgroundJobs)) + { + await app.RunAsync(); + } + } } - if (mode.HasFlag(RunModes.BackgroundJobs)) + private static void ConfigureDb(IServiceCollection services, VoidSettings settings) { - app.Run(); + if (settings.HasPostgres()) + { + services.AddDbContext(o => + o.UseNpgsql(settings.Postgres!)); + } + } + + /// + /// Dummy method for EF core migrations + /// + /// + /// + // ReSharper disable once UnusedMember.Global + public static IHostBuilder CreateHostBuilder(string[] args) + { + var dummyHost = Host.CreateDefaultBuilder(args); + dummyHost.ConfigureServices((ctx, svc) => + { + var settings = ctx.Configuration.GetSection("Settings").Get(); + ConfigureDb(svc, settings); + }); + + return dummyHost; } } - -[Flags] -internal enum RunModes -{ - Webserver = 1, - BackgroundJobs = 2, - Migrations = 4, - All = 255 -} \ No newline at end of file diff --git a/VoidCat/Properties/launchSettings.json b/VoidCat/Properties/launchSettings.json index 152fc9e..bd4846b 100644 --- a/VoidCat/Properties/launchSettings.json +++ b/VoidCat/Properties/launchSettings.json @@ -6,8 +6,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "https://localhost:7195", - "launchUrl": "https://localhost:3000", + "applicationUrl": "http://localhost:7195", + "launchUrl": "http://localhost:3000", "dotnetRunMessages": true }, "Docker": { diff --git a/VoidCat/Services/Abstractions/IApiKeyStore.cs b/VoidCat/Services/Abstractions/IApiKeyStore.cs index c0ebb0c..b130ed1 100644 --- a/VoidCat/Services/Abstractions/IApiKeyStore.cs +++ b/VoidCat/Services/Abstractions/IApiKeyStore.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.User; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; diff --git a/VoidCat/Services/Abstractions/IEmailVerification.cs b/VoidCat/Services/Abstractions/IEmailVerification.cs index 67137b9..1662ae2 100644 --- a/VoidCat/Services/Abstractions/IEmailVerification.cs +++ b/VoidCat/Services/Abstractions/IEmailVerification.cs @@ -1,11 +1,21 @@ -using VoidCat.Model; -using VoidCat.Model.User; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; public interface IEmailVerification { - ValueTask SendNewCode(PrivateUser user); + /// + /// Send email verification code + /// + /// + /// + ValueTask SendNewCode(User user); - ValueTask VerifyCode(PrivateUser user, Guid code); + /// + /// Perform account verification + /// + /// + /// + /// + ValueTask VerifyCode(User user, Guid code); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IFileMetadataStore.cs b/VoidCat/Services/Abstractions/IFileMetadataStore.cs index b1a4ea6..ac648a4 100644 --- a/VoidCat/Services/Abstractions/IFileMetadataStore.cs +++ b/VoidCat/Services/Abstractions/IFileMetadataStore.cs @@ -1,44 +1,48 @@ using VoidCat.Model; +using File = VoidCat.Database.File; namespace VoidCat.Services.Abstractions; /// /// File metadata contains all data about a file except for the file data itself /// -public interface IFileMetadataStore : IPublicPrivateStore +public interface IFileMetadataStore { /// /// Get metadata for a single file /// /// - /// /// - ValueTask Get(Guid id) where TMeta : FileMeta; + ValueTask Get(Guid id); /// /// Get metadata for multiple files /// /// - /// /// - ValueTask> Get(Guid[] ids) where TMeta : FileMeta; + ValueTask> Get(Guid[] ids); + + /// + /// Add new file metadata to this store + /// + /// + /// + ValueTask Add(File f); /// /// Update file metadata /// /// /// - /// /// - ValueTask Update(Guid id, TMeta meta) where TMeta : FileMeta; + ValueTask Update(Guid id, File meta); /// /// List all files in the store /// /// - /// /// - ValueTask> ListFiles(PagedRequest request) where TMeta : FileMeta; + ValueTask> ListFiles(PagedRequest request); /// /// Returns basic stats about the file store @@ -46,6 +50,13 @@ public interface IFileMetadataStore : IPublicPrivateStore ValueTask Stats(); + /// + /// Delete metadata object from the store + /// + /// + /// + ValueTask Delete(Guid id); + /// /// Simple stats of the current store /// diff --git a/VoidCat/Services/Abstractions/IFileStore.cs b/VoidCat/Services/Abstractions/IFileStore.cs index d7effef..6326437 100644 --- a/VoidCat/Services/Abstractions/IFileStore.cs +++ b/VoidCat/Services/Abstractions/IFileStore.cs @@ -1,4 +1,5 @@ using VoidCat.Model; +using File = VoidCat.Database.File; namespace VoidCat.Services.Abstractions; @@ -18,7 +19,7 @@ public interface IFileStore /// /// /// - ValueTask Ingress(IngressPayload payload, CancellationToken cts); + ValueTask Ingress(IngressPayload payload, CancellationToken cts); /// /// Egress a file from the system (Download) diff --git a/VoidCat/Services/Abstractions/IOAuthProvider.cs b/VoidCat/Services/Abstractions/IOAuthProvider.cs index 9efa80b..ff79b28 100644 --- a/VoidCat/Services/Abstractions/IOAuthProvider.cs +++ b/VoidCat/Services/Abstractions/IOAuthProvider.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.User; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; @@ -30,5 +30,5 @@ public interface IOAuthProvider /// /// /// - ValueTask GetUserDetails(UserAuthToken token); + ValueTask GetUserDetails(UserAuthToken token); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaymentFactory.cs b/VoidCat/Services/Abstractions/IPaymentFactory.cs index 49235ba..c2c11f2 100644 --- a/VoidCat/Services/Abstractions/IPaymentFactory.cs +++ b/VoidCat/Services/Abstractions/IPaymentFactory.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.Payments; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; @@ -12,5 +12,5 @@ public interface IPaymentFactory /// /// /// - ValueTask CreateProvider(PaymentServices svc); + ValueTask CreateProvider(PaywallService svc); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaymentOrderStore.cs b/VoidCat/Services/Abstractions/IPaymentOrderStore.cs index e998d24..4033535 100644 --- a/VoidCat/Services/Abstractions/IPaymentOrderStore.cs +++ b/VoidCat/Services/Abstractions/IPaymentOrderStore.cs @@ -1,11 +1,11 @@ -using VoidCat.Model.Payments; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; /// /// Payment order store /// -public interface IPaymentOrderStore : IBasicStore +public interface IPaymentOrderStore : IBasicStore { /// /// Update the status of an order @@ -13,5 +13,5 @@ public interface IPaymentOrderStore : IBasicStore /// /// /// - ValueTask UpdateStatus(Guid order, PaymentOrderStatus status); + ValueTask UpdateStatus(Guid order, PaywallOrderStatus status); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaymentProvider.cs b/VoidCat/Services/Abstractions/IPaymentProvider.cs index 3ada1d5..bdecad1 100644 --- a/VoidCat/Services/Abstractions/IPaymentProvider.cs +++ b/VoidCat/Services/Abstractions/IPaymentProvider.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.Payments; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; @@ -12,12 +12,12 @@ public interface IPaymentProvider /// /// /// - ValueTask CreateOrder(PaymentConfig file); + ValueTask CreateOrder(Paywall file); /// /// Get the status of an existing order with the provider /// /// /// - ValueTask GetOrderStatus(Guid id); + ValueTask GetOrderStatus(Guid id); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaymentStore.cs b/VoidCat/Services/Abstractions/IPaymentStore.cs index 71e18ac..1413ca5 100644 --- a/VoidCat/Services/Abstractions/IPaymentStore.cs +++ b/VoidCat/Services/Abstractions/IPaymentStore.cs @@ -1,10 +1,10 @@ -using VoidCat.Model.Payments; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; /// /// Store for payment configs /// -public interface IPaymentStore : IBasicStore +public interface IPaymentStore : IBasicStore { } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPublicPrivateStore.cs b/VoidCat/Services/Abstractions/IPublicPrivateStore.cs deleted file mode 100644 index 939ffa9..0000000 --- a/VoidCat/Services/Abstractions/IPublicPrivateStore.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace VoidCat.Services.Abstractions; - -/// -/// Store interface where there is a public and private model -/// -/// -/// -public interface IPublicPrivateStore -{ - /// - /// Get the public model - /// - /// - /// - ValueTask Get(Guid id); - - /// - /// Get the private model (contains sensitive data) - /// - /// - /// - ValueTask GetPrivate(Guid id); - - /// - /// Set the private obj in the store - /// - /// - /// - /// - ValueTask Set(Guid id, TPrivate obj); - - /// - /// Delete the object from the store - /// - /// - /// - ValueTask Delete(Guid id); -} \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IUserAuthTokenStore.cs b/VoidCat/Services/Abstractions/IUserAuthTokenStore.cs index 1ac8f47..774e053 100644 --- a/VoidCat/Services/Abstractions/IUserAuthTokenStore.cs +++ b/VoidCat/Services/Abstractions/IUserAuthTokenStore.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.User; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; diff --git a/VoidCat/Services/Abstractions/IUserStore.cs b/VoidCat/Services/Abstractions/IUserStore.cs index d1a7f62..de1e93f 100644 --- a/VoidCat/Services/Abstractions/IUserStore.cs +++ b/VoidCat/Services/Abstractions/IUserStore.cs @@ -1,20 +1,26 @@ -using VoidCat.Model; -using VoidCat.Model.User; +using VoidCat.Database; +using VoidCat.Model; namespace VoidCat.Services.Abstractions; /// /// User store /// -public interface IUserStore : IPublicPrivateStore +public interface IUserStore { /// /// Get a single user /// /// - /// /// - ValueTask Get(Guid id) where T : User; + ValueTask Get(Guid id); + + /// + /// Add a new user to the store + /// + /// + /// + ValueTask Add(User u); /// /// Lookup a user by their email address @@ -28,14 +34,14 @@ public interface IUserStore : IPublicPrivateStore /// /// /// - ValueTask> ListUsers(PagedRequest request); + ValueTask> ListUsers(PagedRequest request); /// /// Update a users profile /// /// /// - ValueTask UpdateProfile(PublicUser newUser); + ValueTask UpdateProfile(User newUser); /// /// Updates the last login timestamp for the user @@ -50,5 +56,12 @@ public interface IUserStore : IPublicPrivateStore /// /// /// - ValueTask AdminUpdateUser(PrivateUser user); + ValueTask AdminUpdateUser(User user); + + /// + /// Delete a user from the system + /// + /// + /// + ValueTask Delete(Guid id); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IVirusScanStore.cs b/VoidCat/Services/Abstractions/IVirusScanStore.cs index bacd56f..524064c 100644 --- a/VoidCat/Services/Abstractions/IVirusScanStore.cs +++ b/VoidCat/Services/Abstractions/IVirusScanStore.cs @@ -1,4 +1,4 @@ -using VoidCat.Model; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; diff --git a/VoidCat/Services/Abstractions/IVirusScanner.cs b/VoidCat/Services/Abstractions/IVirusScanner.cs index fea46b3..37fcdd0 100644 --- a/VoidCat/Services/Abstractions/IVirusScanner.cs +++ b/VoidCat/Services/Abstractions/IVirusScanner.cs @@ -1,4 +1,4 @@ -using VoidCat.Model; +using VoidCat.Database; namespace VoidCat.Services.Abstractions; diff --git a/VoidCat/Services/Background/DeleteExpiredFiles.cs b/VoidCat/Services/Background/DeleteExpiredFiles.cs index d337346..f6d6919 100644 --- a/VoidCat/Services/Background/DeleteExpiredFiles.cs +++ b/VoidCat/Services/Background/DeleteExpiredFiles.cs @@ -29,7 +29,7 @@ public sealed class DeleteExpiredFiles : BackgroundService var fileInfoManager = scope.ServiceProvider.GetRequiredService(); var fileStoreFactory = scope.ServiceProvider.GetRequiredService(); - var files = await metadata.ListFiles(new(0, int.MaxValue)); + var files = await metadata.ListFiles(new(0, int.MaxValue)); await foreach (var f in files.Results.WithCancellation(stoppingToken)) { try diff --git a/VoidCat/Services/Background/DeleteUnverifiedAccounts.cs b/VoidCat/Services/Background/DeleteUnverifiedAccounts.cs index 0ab20d0..f894b74 100644 --- a/VoidCat/Services/Background/DeleteUnverifiedAccounts.cs +++ b/VoidCat/Services/Background/DeleteUnverifiedAccounts.cs @@ -1,5 +1,5 @@ -using VoidCat.Model; -using VoidCat.Model.User; +using VoidCat.Database; +using VoidCat.Model; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; diff --git a/VoidCat/Services/Background/VirusScannerService.cs b/VoidCat/Services/Background/VirusScannerService.cs index ada6570..6f8ac2c 100644 --- a/VoidCat/Services/Background/VirusScannerService.cs +++ b/VoidCat/Services/Background/VirusScannerService.cs @@ -29,8 +29,9 @@ public class VirusScannerService : BackgroundService var page = 0; while (true) { - var files = await _fileStore.ListFiles(new(page, 1_000)); + var files = await _fileStore.ListFiles(new(page, 1_000)); if (files.Pages < page) break; + page++; await foreach (var file in files.Results.WithCancellation(stoppingToken)) @@ -46,8 +47,7 @@ public class VirusScannerService : BackgroundService { var result = await _scanner.ScanFile(file.Id, stoppingToken); await _scanStore.Add(result.Id, result); - _logger.LogInformation("Scanned file {Id}, IsVirus = {Result}", result.File, - result.IsVirus); + _logger.LogInformation("Scanned file {Id}, IsVirus = {Result}", result.File, result.Score); } catch (RateLimitedException rx) { @@ -66,4 +66,4 @@ public class VirusScannerService : BackgroundService await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); } } -} \ No newline at end of file +} diff --git a/VoidCat/Services/BasicCacheStore.cs b/VoidCat/Services/BasicCacheStore.cs index 1b5f998..42f0059 100644 --- a/VoidCat/Services/BasicCacheStore.cs +++ b/VoidCat/Services/BasicCacheStore.cs @@ -5,29 +5,29 @@ namespace VoidCat.Services; /// public abstract class BasicCacheStore : IBasicStore { - protected readonly ICache _cache; + protected readonly ICache Cache; protected BasicCacheStore(ICache cache) { - _cache = cache; + Cache = cache; } /// public virtual ValueTask Get(Guid id) { - return _cache.Get(MapKey(id)); + return Cache.Get(MapKey(id)); } /// public virtual ValueTask Add(Guid id, TStore obj) { - return _cache.Set(MapKey(id), obj); + return Cache.Set(MapKey(id), obj); } /// public virtual ValueTask Delete(Guid id) { - return _cache.Delete(MapKey(id)); + return Cache.Delete(MapKey(id)); } /// diff --git a/VoidCat/Services/Files/FileInfoManager.cs b/VoidCat/Services/Files/FileInfoManager.cs index 75322e8..48eefe1 100644 --- a/VoidCat/Services/Files/FileInfoManager.cs +++ b/VoidCat/Services/Files/FileInfoManager.cs @@ -1,5 +1,6 @@ +using System.Collections.Immutable; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Files; @@ -32,36 +33,47 @@ public sealed class FileInfoManager /// Get all metadata for a single file /// /// + /// /// - public ValueTask Get(Guid id) + public async ValueTask Get(Guid id, bool withEditSecret) { - return Get(id); - } + var meta = await _metadataStore.Get(id); + if (meta == default) return default; - /// - /// Get all private metadata for a single file - /// - /// - /// - public ValueTask GetPrivate(Guid id) - { - return Get(id); + var payment = await _paymentStore.Get(id); + var bandwidth = await _statsReporter.GetBandwidth(id); + var virusScan = await _virusScanStore.GetByFile(id); + var uploader = await _userUploadsStore.Uploader(id); + + var user = uploader.HasValue ? await _userStore.Get(uploader.Value) : null; + + return new VoidFileResponse + { + Id = id, + Metadata = meta.ToMeta(withEditSecret), + Payment = payment, + Bandwidth = bandwidth, + Uploader = user?.Flags.HasFlag(UserFlags.PublicProfile) == true || withEditSecret ? user?.ToApiUser(false) : null, + VirusScan = virusScan?.ToVirusStatus() + }; } /// /// Get all metadata for multiple files /// /// + /// /// - public async ValueTask> Get(Guid[] ids) + public async ValueTask> Get(Guid[] ids, bool withEditSecret) { - var ret = new List(); - foreach (var id in ids) + //todo: improve this + var ret = new List(); + foreach (var i in ids) { - var v = await Get(id); - if (v != default) + var x = await Get(i, withEditSecret); + if (x != default) { - ret.Add(v); + ret.Add(x); } } @@ -80,28 +92,4 @@ public sealed class FileInfoManager await _statsReporter.Delete(id); await _virusScanStore.Delete(id); } - - private async ValueTask Get(Guid id) - where TMeta : FileMeta where TFile : VoidFile, new() - { - var meta = _metadataStore.Get(id); - var payment = _paymentStore.Get(id); - var bandwidth = _statsReporter.GetBandwidth(id); - var virusScan = _virusScanStore.GetByFile(id); - var uploader = _userUploadsStore.Uploader(id); - await Task.WhenAll(meta.AsTask(), payment.AsTask(), bandwidth.AsTask(), virusScan.AsTask(), uploader.AsTask()); - - if (meta.Result == default) return default; - var user = uploader.Result.HasValue ? await _userStore.Get(uploader.Result.Value) : null; - - return new TFile() - { - Id = id, - Metadata = meta.Result, - Payment = payment.Result, - Bandwidth = bandwidth.Result, - Uploader = user?.Flags.HasFlag(UserFlags.PublicProfile) == true ? user : null, - VirusScan = virusScan.Result - }; - } -} \ No newline at end of file +} diff --git a/VoidCat/Services/Files/FileStorageStartup.cs b/VoidCat/Services/Files/FileStorageStartup.cs index d0dd16e..551a3ba 100644 --- a/VoidCat/Services/Files/FileStorageStartup.cs +++ b/VoidCat/Services/Files/FileStorageStartup.cs @@ -11,23 +11,23 @@ public static class FileStorageStartup services.AddTransient(); services.AddTransient(); services.AddTransient(); - + if (settings.CloudStorage != default) { // S3 storage foreach (var s3 in settings.CloudStorage.S3 ?? Array.Empty()) { - services.AddTransient((svc) => - new S3FileStore(s3, - svc.GetRequiredService(), - svc.GetRequiredService(), - svc.GetRequiredService())); - if (settings.MetadataStore == s3.Name) { services.AddSingleton((svc) => new S3FileMetadataStore(s3, svc.GetRequiredService>())); } + + services.AddTransient((svc) => + new S3FileStore(s3, + svc.GetRequiredService(), + svc.GetRequiredService(), + svc.GetRequiredService())); } } @@ -37,7 +37,7 @@ public static class FileStorageStartup services.AddTransient(); if (settings.MetadataStore is "postgres" or "local-disk") { - services.AddSingleton(); + services.AddTransient(); } } else diff --git a/VoidCat/Services/Files/FileSystemFactory.cs b/VoidCat/Services/Files/FileSystemFactory.cs index e0a72f9..fc79dfb 100644 --- a/VoidCat/Services/Files/FileSystemFactory.cs +++ b/VoidCat/Services/Files/FileSystemFactory.cs @@ -36,7 +36,7 @@ public class FileStoreFactory : IFileStore public string? Key => null; /// - public ValueTask Ingress(IngressPayload payload, CancellationToken cts) + public ValueTask Ingress(IngressPayload payload, CancellationToken cts) { var store = GetFileStore(payload.Meta.Storage!); if (store == default) diff --git a/VoidCat/Services/Files/LocalDiskFileMetadataStore.cs b/VoidCat/Services/Files/LocalDiskFileMetadataStore.cs index 0395bed..ab4f563 100644 --- a/VoidCat/Services/Files/LocalDiskFileMetadataStore.cs +++ b/VoidCat/Services/Files/LocalDiskFileMetadataStore.cs @@ -22,18 +22,18 @@ public class LocalDiskFileMetadataStore : IFileMetadataStore } /// - public ValueTask Get(Guid id) where TMeta : FileMeta + public ValueTask Get(Guid id) { - return GetMeta(id); + return GetMeta(id); } /// - public async ValueTask> Get(Guid[] ids) where TMeta : FileMeta + public async ValueTask> Get(Guid[] ids) { - var ret = new List(); + var ret = new List(); foreach (var id in ids) { - var r = await GetMeta(id); + var r = await GetMeta(id); if (r != null) { ret.Add(r); @@ -42,11 +42,16 @@ public class LocalDiskFileMetadataStore : IFileMetadataStore return ret; } + + public ValueTask Add(Database.File f) + { + return Set(f.Id, f); + } /// - public async ValueTask Update(Guid id, TMeta meta) where TMeta : FileMeta + public async ValueTask Update(Guid id, Database.File meta) { - var oldMeta = await Get(id); + var oldMeta = await Get(id); if (oldMeta == default) return; oldMeta.Patch(meta); @@ -54,22 +59,18 @@ public class LocalDiskFileMetadataStore : IFileMetadataStore } /// - public ValueTask> ListFiles(PagedRequest request) where TMeta : FileMeta + public ValueTask> ListFiles(PagedRequest request) { - async IAsyncEnumerable EnumerateFiles() + async IAsyncEnumerable EnumerateFiles() { foreach (var metaFile in Directory.EnumerateFiles(Path.Join(_settings.DataDirectory, MetadataDir), "*.json")) { var json = await File.ReadAllTextAsync(metaFile); - var meta = JsonConvert.DeserializeObject(json); + var meta = JsonConvert.DeserializeObject(json); if (meta != null) { - yield return meta with - { - // TODO: remove after migration decay - Id = Guid.Parse(Path.GetFileNameWithoutExtension(metaFile)) - }; + yield return meta; } } } @@ -86,7 +87,7 @@ public class LocalDiskFileMetadataStore : IFileMetadataStore _ => results }; - return ValueTask.FromResult(new PagedResult + return ValueTask.FromResult(new PagedResult { Page = request.Page, PageSize = request.PageSize, @@ -97,26 +98,14 @@ public class LocalDiskFileMetadataStore : IFileMetadataStore /// public async ValueTask Stats() { - var files = await ListFiles(new(0, Int32.MaxValue)); + var files = await ListFiles(new(0, Int32.MaxValue)); var count = await files.Results.CountAsync(); var size = await files.Results.SumAsync(a => (long) a.Size); return new(count, (ulong) size); } /// - public ValueTask Get(Guid id) - { - return GetMeta(id); - } - - /// - public ValueTask GetPrivate(Guid id) - { - return GetMeta(id); - } - - /// - public async ValueTask Set(Guid id, SecretFileMeta meta) + public async ValueTask Set(Guid id, Database.File meta) { var path = MapMeta(id); var json = JsonConvert.SerializeObject(meta); diff --git a/VoidCat/Services/Files/LocalDiskFileStorage.cs b/VoidCat/Services/Files/LocalDiskFileStorage.cs index 88cc4fc..a3c6b8e 100644 --- a/VoidCat/Services/Files/LocalDiskFileStorage.cs +++ b/VoidCat/Services/Files/LocalDiskFileStorage.cs @@ -42,7 +42,7 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore public string Key => "local-disk"; /// - public async ValueTask Ingress(IngressPayload payload, CancellationToken cts) + public async ValueTask Ingress(IngressPayload payload, CancellationToken cts) { var finalPath = MapPath(payload.Id); await using var fsTemp = new FileStream(finalPath, @@ -53,7 +53,7 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore if (payload.ShouldStripMetadata && payload.Segment == payload.TotalSegments) { fsTemp.Close(); - var ext = Path.GetExtension(vf.Metadata!.Name); + var ext = Path.GetExtension(vf.Name); var srcPath = $"{finalPath}_orig{ext}"; File.Move(finalPath, srcPath); @@ -69,12 +69,9 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore var hash = await SHA256.Create().ComputeHashAsync(fInfo.OpenRead(), cts); vf = vf with { - Metadata = vf.Metadata! with - { - Size = (ulong)fInfo.Length, - Digest = hash.ToHex(), - MimeType = res.MimeType ?? vf.Metadata.MimeType - } + Size = (ulong)fInfo.Length, + Digest = hash.ToHex(), + MimeType = res.MimeType ?? vf.MimeType }; } else @@ -86,7 +83,7 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore if (payload.Segment == payload.TotalSegments) { - var t = await vf.Metadata!.MakeTorrent( + var t = await vf.ToMeta(false).MakeTorrent(vf.Id, new FileStream(finalPath, FileMode.Open), _settings.SiteUrl, _settings.TorrentTrackers); @@ -94,7 +91,7 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore var ub = new UriBuilder(_settings.SiteUrl); ub.Path = $"/d/{vf.Id.ToBase58()}.torrent"; - vf.Metadata!.MagnetLink = $"{t.GetMagnetLink()}&xs={Uri.EscapeDataString(ub.ToString())}"; + vf.MagnetLink = $"{t.GetMagnetLink()}&xs={Uri.EscapeDataString(ub.ToString())}"; } return vf; diff --git a/VoidCat/Services/Files/PostgresFileMetadataStore.cs b/VoidCat/Services/Files/PostgresFileMetadataStore.cs index 9876e0c..dcbcb57 100644 --- a/VoidCat/Services/Files/PostgresFileMetadataStore.cs +++ b/VoidCat/Services/Files/PostgresFileMetadataStore.cs @@ -1,4 +1,4 @@ -using Dapper; +using Microsoft.EntityFrameworkCore; using VoidCat.Model; using VoidCat.Services.Abstractions; @@ -7,119 +7,103 @@ namespace VoidCat.Services.Files; /// public class PostgresFileMetadataStore : IFileMetadataStore { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; + private readonly IServiceScopeFactory _scopeFactory; - public PostgresFileMetadataStore(PostgresConnectionFactory connection) + public PostgresFileMetadataStore(VoidContext db, IServiceScopeFactory scopeFactory) { - _connection = connection; + _db = db; + _scopeFactory = scopeFactory; } - - /// + public string? Key => "postgres"; - - /// - public ValueTask Get(Guid id) - { - return Get(id); - } /// - public ValueTask GetPrivate(Guid id) + public async ValueTask Get(Guid id) { - return Get(id); + return await _db.Files + .AsNoTracking() + .Include(a => a.Paywall) + .SingleOrDefaultAsync(a => a.Id == id); } - /// - public async ValueTask Set(Guid id, SecretFileMeta obj) + public async ValueTask Add(Database.File f) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"insert into -""Files""(""Id"", ""Name"", ""Size"", ""Uploaded"", ""Description"", ""MimeType"", ""Digest"", ""EditSecret"", ""Expires"", ""Storage"", ""EncryptionParams"", ""MagnetLink"") -values(:id, :name, :size, :uploaded, :description, :mimeType, :digest, :editSecret, :expires, :store, :encryptionParams, :magnetLink) -on conflict (""Id"") do update set -""Name"" = :name, -""Size"" = :size, -""Description"" = :description, -""MimeType"" = :mimeType, -""Expires"" = :expires, -""Storage"" = :store, -""EncryptionParams"" = :encryptionParams, -""MagnetLink"" = :magnetLink", - new - { - id, - name = obj.Name, - size = (long) obj.Size, - uploaded = obj.Uploaded.ToUniversalTime(), - description = obj.Description, - mimeType = obj.MimeType, - digest = obj.Digest, - editSecret = obj.EditSecret, - expires = obj.Expires?.ToUniversalTime(), - store = obj.Storage, - encryptionParams = obj.EncryptionParams, - magnetLink = obj.MagnetLink, - }); + _db.Files.Add(f); + await _db.SaveChangesAsync(); } /// public async ValueTask Delete(Guid id) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync("delete from \"Files\" where \"Id\" = :id", new {id}); + await _db.Files + .Where(a => a.Id == id) + .ExecuteDeleteAsync(); } /// - public async ValueTask Get(Guid id) where TMeta : FileMeta + public async ValueTask> Get(Guid[] ids) { - await using var conn = await _connection.Get(); - return await conn.QuerySingleOrDefaultAsync(@"select * from ""Files"" where ""Id"" = :id", - new {id}); + return await _db.Files + .Include(a => a.Paywall) + .Where(a => ids.Contains(a.Id)) + .ToArrayAsync(); } /// - public async ValueTask> Get(Guid[] ids) where TMeta : FileMeta + public async ValueTask Update(Guid id, Database.File obj) { - await using var conn = await _connection.Get(); - var ret = await conn.QueryAsync("select * from \"Files\" where \"Id\" in :ids", new {ids}); - return ret.ToList(); - } - - /// - public async ValueTask Update(Guid id, TMeta meta) where TMeta : FileMeta - { - var oldMeta = await Get(id); - if (oldMeta == default) return; - - oldMeta.Patch(meta); - await Set(id, oldMeta); - } - - /// - public async ValueTask> ListFiles(PagedRequest request) where TMeta : FileMeta - { - await using var conn = await _connection.Get(); - var count = await conn.ExecuteScalarAsync(@"select count(*) from ""Files"""); - - async IAsyncEnumerable Enumerate() + var existing = await _db.Files.FindAsync(id); + if (existing == default) { - var orderBy = request.SortBy switch - { - PagedSortBy.Date => "Uploaded", - PagedSortBy.Name => "Name", - PagedSortBy.Size => "Size", - _ => "Id" - }; - await using var iconn = await _connection.Get(); - var orderDirection = request.SortOrder == PageSortOrder.Asc ? "asc" : "desc"; - var results = await iconn.QueryAsync( - $"select * from \"Files\" order by \"{orderBy}\" {orderDirection} offset @offset limit @limit", - new {offset = request.PageSize * request.Page, limit = request.PageSize}); + return; + } - foreach (var meta in results) + existing.Patch(obj); + await _db.SaveChangesAsync(); + } + + /// + public async ValueTask> ListFiles(PagedRequest request) + { + var count = await _db.Files.CountAsync(); + + async IAsyncEnumerable Enumerate() + { + using var scope = _scopeFactory.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var q = db.Files.AsNoTracking().AsQueryable(); + switch (request.SortBy, request.SortOrder) { - yield return meta; + case (PagedSortBy.Id, PageSortOrder.Asc): + q = q.OrderBy(a => a.Id); + break; + case (PagedSortBy.Id, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.Id); + break; + case (PagedSortBy.Name, PageSortOrder.Asc): + q = q.OrderBy(a => a.Name); + break; + case (PagedSortBy.Name, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.Name); + break; + case (PagedSortBy.Date, PageSortOrder.Asc): + q = q.OrderBy(a => a.Uploaded); + break; + case (PagedSortBy.Date, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.Uploaded); + break; + case (PagedSortBy.Size, PageSortOrder.Asc): + q = q.OrderBy(a => a.Size); + break; + case (PagedSortBy.Size, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.Size); + break; + } + + await foreach (var r in q.Skip(request.Page * request.PageSize).Take(request.PageSize).AsAsyncEnumerable()) + { + yield return r; } } @@ -135,9 +119,11 @@ on conflict (""Id"") do update set /// public async ValueTask Stats() { - await using var conn = await _connection.Get(); - var v = await conn.QuerySingleAsync<(long Files, long Size)>( - @"select count(1) ""Files"", cast(sum(""Size"") as bigint) ""Size"" from ""Files"""); - return new(v.Files, (ulong) v.Size); + var size = await _db.Files + .AsNoTracking() + .SumAsync(a => (long)a.Size); + + var count = await _db.Files.CountAsync(); + return new(count, (ulong)size); } -} \ No newline at end of file +} diff --git a/VoidCat/Services/Files/S3FileMetadataStore.cs b/VoidCat/Services/Files/S3FileMetadataStore.cs index 18381b2..95a1dbe 100644 --- a/VoidCat/Services/Files/S3FileMetadataStore.cs +++ b/VoidCat/Services/Files/S3FileMetadataStore.cs @@ -19,22 +19,35 @@ public class S3FileMetadataStore : IFileMetadataStore _client = _config.CreateClient(); } - /// public string? Key => _config.Name; /// - public ValueTask Get(Guid id) where TMeta : FileMeta + public async ValueTask Get(Guid id) { - return GetMeta(id); + try + { + var obj = await _client.GetObjectAsync(_config.BucketName, ToKey(id)); + + using var sr = new StreamReader(obj.ResponseStream); + var json = await sr.ReadToEndAsync(); + var ret = JsonConvert.DeserializeObject(json); + return ret; + } + catch (AmazonS3Exception aex) + { + _logger.LogError(aex, "Failed to get metadata for {Id}, {Error}", id, aex.Message); + } + + return default; } /// - public async ValueTask> Get(Guid[] ids) where TMeta : FileMeta + public async ValueTask> Get(Guid[] ids) { - var ret = new List(); + var ret = new List(); foreach (var id in ids) { - var r = await GetMeta(id); + var r = await Get(id); if (r != null) { ret.Add(r); @@ -43,11 +56,15 @@ public class S3FileMetadataStore : IFileMetadataStore return ret; } + public ValueTask Add(Database.File f) + { + return Set(f.Id, f); + } /// - public async ValueTask Update(Guid id, TMeta meta) where TMeta : FileMeta + public async ValueTask Update(Guid id, Database.File meta) { - var oldMeta = await Get(id); + var oldMeta = await Get(id); if (oldMeta == default) return; oldMeta.Patch(meta); @@ -55,9 +72,9 @@ public class S3FileMetadataStore : IFileMetadataStore } /// - public ValueTask> ListFiles(PagedRequest request) where TMeta : FileMeta + public ValueTask> ListFiles(PagedRequest request) { - async IAsyncEnumerable Enumerate() + async IAsyncEnumerable Enumerate() { var obj = await _client.ListObjectsV2Async(new() { @@ -70,7 +87,7 @@ public class S3FileMetadataStore : IFileMetadataStore { if (Guid.TryParse(file.Key.Split("metadata_")[1], out var id)) { - var meta = await GetMeta(id); + var meta = await Get(id); if (meta != default) { yield return meta; @@ -79,7 +96,7 @@ public class S3FileMetadataStore : IFileMetadataStore } } - return ValueTask.FromResult(new PagedResult + return ValueTask.FromResult(new PagedResult { Page = request.Page, PageSize = request.PageSize, @@ -90,26 +107,19 @@ public class S3FileMetadataStore : IFileMetadataStore /// public async ValueTask Stats() { - var files = await ListFiles(new(0, Int32.MaxValue)); + var files = await ListFiles(new(0, Int32.MaxValue)); var count = await files.Results.CountAsync(); var size = await files.Results.SumAsync(a => (long) a.Size); return new(count, (ulong) size); } /// - public ValueTask Get(Guid id) + public async ValueTask Delete(Guid id) { - return GetMeta(id); + await _client.DeleteObjectAsync(_config.BucketName, ToKey(id)); } - /// - public ValueTask GetPrivate(Guid id) - { - return GetMeta(id); - } - - /// - public async ValueTask Set(Guid id, SecretFileMeta meta) + private async ValueTask Set(Guid id, Database.File meta) { await _client.PutObjectAsync(new() { @@ -120,35 +130,5 @@ public class S3FileMetadataStore : IFileMetadataStore }); } - /// - public async ValueTask Delete(Guid id) - { - await _client.DeleteObjectAsync(_config.BucketName, ToKey(id)); - } - - private async ValueTask GetMeta(Guid id) where TMeta : FileMeta - { - try - { - var obj = await _client.GetObjectAsync(_config.BucketName, ToKey(id)); - - using var sr = new StreamReader(obj.ResponseStream); - var json = await sr.ReadToEndAsync(); - var ret = JsonConvert.DeserializeObject(json); - if (ret != default) - { - ret.Id = id; - } - - return ret; - } - catch (AmazonS3Exception aex) - { - _logger.LogError(aex, "Failed to get metadata for {Id}, {Error}", id, aex.Message); - } - - return default; - } - private static string ToKey(Guid id) => $"metadata_{id}"; } \ No newline at end of file diff --git a/VoidCat/Services/Files/S3FileStore.cs b/VoidCat/Services/Files/S3FileStore.cs index 4af3764..1cd8f3d 100644 --- a/VoidCat/Services/Files/S3FileStore.cs +++ b/VoidCat/Services/Files/S3FileStore.cs @@ -9,13 +9,13 @@ namespace VoidCat.Services.Files; /// public class S3FileStore : StreamFileStore, IFileStore { - private readonly FileInfoManager _fileInfo; + private readonly IFileMetadataStore _fileInfo; private readonly AmazonS3Client _client; private readonly S3BlobConfig _config; private readonly IAggregateStatsCollector _statsCollector; private readonly ICache _cache; - public S3FileStore(S3BlobConfig settings, IAggregateStatsCollector stats, FileInfoManager fileInfo, ICache cache) : base(stats) + public S3FileStore(S3BlobConfig settings, IAggregateStatsCollector stats, IFileMetadataStore fileInfo, ICache cache) : base(stats) { _fileInfo = fileInfo; _cache = cache; @@ -28,7 +28,7 @@ public class S3FileStore : StreamFileStore, IFileStore public string Key => _config.Name; /// - public async ValueTask Ingress(IngressPayload payload, CancellationToken cts) + public async ValueTask Ingress(IngressPayload payload, CancellationToken cts) { if (payload.IsMultipart) return await IngressMultipart(payload, cts); @@ -75,15 +75,15 @@ public class S3FileStore : StreamFileStore, IFileStore Key = request.Id.ToString(), ResponseHeaderOverrides = new() { - ContentDisposition = $"inline; filename=\"{meta?.Metadata?.Name}\"", - ContentType = meta?.Metadata?.MimeType + ContentDisposition = $"inline; filename=\"{meta?.Name}\"", + ContentType = meta?.MimeType } }); return new(new Uri(url)); } - public async ValueTask> ListFiles(PagedRequest request) + public async ValueTask> ListFiles(PagedRequest request) { try { @@ -103,7 +103,7 @@ public class S3FileStore : StreamFileStore, IFileStore _ => objs.S3Objects.AsEnumerable() }; - async IAsyncEnumerable EnumerateFiles(IEnumerable page) + async IAsyncEnumerable EnumerateFiles(IEnumerable page) { foreach (var item in page) { @@ -133,7 +133,7 @@ public class S3FileStore : StreamFileStore, IFileStore Page = request.Page, PageSize = request.PageSize, TotalResults = 0, - Results = AsyncEnumerable.Empty() + Results = AsyncEnumerable.Empty() }; } } @@ -163,7 +163,7 @@ public class S3FileStore : StreamFileStore, IFileStore return obj.ResponseStream; } - private async Task IngressMultipart(IngressPayload payload, CancellationToken cts) + private async Task IngressMultipart(IngressPayload payload, CancellationToken cts) { string? uploadId = null; var cacheKey = $"s3:{_config.Name}:multipart-upload-id:{payload.Id}"; diff --git a/VoidCat/Services/Files/StreamFileStore.cs b/VoidCat/Services/Files/StreamFileStore.cs index 5f2907b..359f5ea 100644 --- a/VoidCat/Services/Files/StreamFileStore.cs +++ b/VoidCat/Services/Files/StreamFileStore.cs @@ -31,7 +31,7 @@ public abstract class StreamFileStore } } - protected async ValueTask IngressToStream(Stream outStream, IngressPayload payload, + protected async ValueTask IngressToStream(Stream outStream, IngressPayload payload, CancellationToken cts) { var id = payload.Id; @@ -48,13 +48,14 @@ public abstract class StreamFileStore return HandleCompletedUpload(payload, total); } - protected PrivateVoidFile HandleCompletedUpload(IngressPayload payload, ulong totalSize) + protected Database.File HandleCompletedUpload(IngressPayload payload, ulong totalSize) { var meta = payload.Meta; if (payload.IsAppend) { meta = meta with { + Id = payload.Id, Size = meta.Size + totalSize }; } @@ -62,19 +63,14 @@ public abstract class StreamFileStore { meta = meta with { - Uploaded = DateTimeOffset.UtcNow, + Id = payload.Id, + Uploaded = DateTime.UtcNow, EditSecret = Guid.NewGuid(), Size = totalSize }; } - var vf = new PrivateVoidFile() - { - Id = payload.Id, - Metadata = meta - }; - - return vf; + return meta; } private async Task IngressInternal(Guid id, Stream ingress, Stream outStream, diff --git a/VoidCat/Services/Migrations/Database/00-Init.cs b/VoidCat/Services/Migrations/Database/00-Init.cs deleted file mode 100644 index 47f537a..0000000 --- a/VoidCat/Services/Migrations/Database/00-Init.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Data; -using FluentMigrator; -using VoidCat.Model.User; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20220604_2232)] -public class Init : Migration -{ - public override void Up() - { - Create.Table("Users") - .WithColumn("Id").AsGuid().PrimaryKey() - .WithColumn("Email").AsString().Indexed() - .WithColumn("Password").AsString() - .WithColumn("Created").AsDateTimeOffset().WithDefault(SystemMethods.CurrentUTCDateTime) - .WithColumn("LastLogin").AsDateTimeOffset().Nullable() - .WithColumn("Avatar").AsString().Nullable() - .WithColumn("DisplayName").AsString().WithDefaultValue("void user") - .WithColumn("Flags").AsInt32().WithDefaultValue((int) UserFlags.PublicProfile); - - Create.Table("Files") - .WithColumn("Id").AsGuid().PrimaryKey() - .WithColumn("Name").AsString().Nullable() - .WithColumn("Size").AsInt64() - .WithColumn("Uploaded").AsDateTimeOffset().Indexed().WithDefault(SystemMethods.CurrentUTCDateTime) - .WithColumn("Description").AsString().Nullable() - .WithColumn("MimeType").AsString().WithDefaultValue("application/octet-stream") - .WithColumn("Digest").AsString().Nullable() - .WithColumn("EditSecret").AsGuid(); - - Create.Table("UserFiles") - .WithColumn("File").AsGuid().ForeignKey("Files", "Id").OnDelete(Rule.Cascade).Indexed() - .WithColumn("User").AsGuid().ForeignKey("Users", "Id").OnDelete(Rule.Cascade).Indexed(); - - Create.UniqueConstraint() - .OnTable("UserFiles") - .Columns("File", "User"); - - Create.Table("Paywall") - .WithColumn("File").AsGuid().ForeignKey("Files", "Id").OnDelete(Rule.Cascade).PrimaryKey() - .WithColumn("Service").AsInt16() - .WithColumn("Currency").AsInt16() - .WithColumn("Amount").AsDecimal(); - - Create.Table("PaywallStrike") - .WithColumn("File").AsGuid().ForeignKey("Paywall", "File").OnDelete(Rule.Cascade).PrimaryKey() - .WithColumn("Handle").AsString(); - - Create.Table("PaywallOrder") - .WithColumn("Id").AsGuid().PrimaryKey() - .WithColumn("File").AsGuid().ForeignKey("Files", "Id").OnDelete(Rule.Cascade).Indexed() - .WithColumn("Service").AsInt16() - .WithColumn("Currency").AsInt16() - .WithColumn("Amount").AsDecimal() - .WithColumn("Status").AsInt16().Indexed(); - - Create.Table("PaywallOrderLightning") - .WithColumn("Order").AsGuid().ForeignKey("PaywallOrder", "Id").OnDelete(Rule.Cascade).PrimaryKey() - .WithColumn("Invoice").AsString() - .WithColumn("Expire").AsDateTimeOffset(); - - Create.Table("UserRoles") - .WithColumn("User").AsGuid().ForeignKey("Users", "Id").OnDelete(Rule.Cascade).Indexed() - .WithColumn("Role").AsString().NotNullable(); - - Create.UniqueConstraint() - .OnTable("UserRoles") - .Columns("User", "Role"); - - Create.Table("EmailVerification") - .WithColumn("User").AsGuid().ForeignKey("Users", "Id").OnDelete(Rule.Cascade) - .WithColumn("Code").AsGuid() - .WithColumn("Expires").AsDateTimeOffset(); - - Create.UniqueConstraint() - .OnTable("EmailVerification") - .Columns("User", "Code"); - - Create.Table("VirusScanResult") - .WithColumn("Id").AsGuid().PrimaryKey() - .WithColumn("File").AsGuid().ForeignKey("Files", "Id").OnDelete(Rule.Cascade).Indexed() - .WithColumn("ScanTime").AsDateTimeOffset().WithDefault(SystemMethods.CurrentUTCDateTime) - .WithColumn("Scanner").AsString() - .WithColumn("Score").AsDecimal() - .WithColumn("Names").AsString().Nullable(); - } - - public override void Down() - { - Delete.Table("Users"); - Delete.Table("Files"); - Delete.Table("UsersFiles"); - Delete.Table("Paywall"); - Delete.Table("PaywallStrike"); - Delete.Table("UserRoles"); - Delete.Table("EmailVerification"); - Delete.Table("VirusScanResult"); - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/Database/01-FileExpiry.cs b/VoidCat/Services/Migrations/Database/01-FileExpiry.cs deleted file mode 100644 index 5d0501f..0000000 --- a/VoidCat/Services/Migrations/Database/01-FileExpiry.cs +++ /dev/null @@ -1,19 +0,0 @@ -using FluentMigrator; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20220615_2238)] -public class FileExpiry : Migration { - public override void Up() - { - Create.Column("Expires") - .OnTable("Files") - .AsDateTimeOffset().Nullable().Indexed(); - } - - public override void Down() - { - Delete.Column("Expires") - .FromTable("Files"); - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/Database/02-MinorVersion1.cs b/VoidCat/Services/Migrations/Database/02-MinorVersion1.cs deleted file mode 100644 index 3dff2e4..0000000 --- a/VoidCat/Services/Migrations/Database/02-MinorVersion1.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Data; -using FluentMigrator; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20220725_1137)] -public class MinorVersion1 : Migration -{ - public override void Up() - { - Create.Table("ApiKey") - .WithColumn("Id").AsGuid().PrimaryKey() - .WithColumn("UserId").AsGuid().ForeignKey("Users", "Id").OnDelete(Rule.Cascade).Indexed() - .WithColumn("Token").AsString() - .WithColumn("Expiry").AsDateTimeOffset() - .WithColumn("Created").AsDateTimeOffset().WithDefault(SystemMethods.CurrentUTCDateTime); - - Create.Column("Storage") - .OnTable("Files") - .AsString().WithDefaultValue("local-disk"); - - Create.Column("Storage") - .OnTable("Users") - .AsString().WithDefaultValue("local-disk"); - } - - public override void Down() - { - Delete.Table("ApiKey"); - - Delete.Column("Storage") - .FromTable("Files"); - - Delete.Column("Storage") - .FromTable("Users"); - } -} diff --git a/VoidCat/Services/Migrations/Database/03-PaywallToPayments.cs b/VoidCat/Services/Migrations/Database/03-PaywallToPayments.cs deleted file mode 100644 index 1ecbd30..0000000 --- a/VoidCat/Services/Migrations/Database/03-PaywallToPayments.cs +++ /dev/null @@ -1,27 +0,0 @@ -using FluentMigrator; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20220908_1527)] -public class PaywallToPayments : Migration -{ - public override void Up() - { - Rename.Table("Paywall") - .To("Payment"); - - Rename.Table("PaywallOrder") - .To("PaymentOrder"); - - Rename.Table("PaywallStrike") - .To("PaymentStrike"); - - Rename.Table("PaywallOrderLightning") - .To("PaymentOrderLightning"); - } - - public override void Down() - { - // yolo - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/Database/04-OptionalPayments.cs b/VoidCat/Services/Migrations/Database/04-OptionalPayments.cs deleted file mode 100644 index 554f482..0000000 --- a/VoidCat/Services/Migrations/Database/04-OptionalPayments.cs +++ /dev/null @@ -1,20 +0,0 @@ -using FluentMigrator; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20220908_1602)] -public class OptionalPayments : Migration{ - public override void Up() - { - Create.Column("Required") - .OnTable("Payment") - .AsBoolean() - .WithDefaultValue(true); - } - - public override void Down() - { - Delete.Column("Required") - .FromTable("Payment"); - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/Database/05-AccountTypes.cs b/VoidCat/Services/Migrations/Database/05-AccountTypes.cs deleted file mode 100644 index e447866..0000000 --- a/VoidCat/Services/Migrations/Database/05-AccountTypes.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Data; -using FluentMigrator; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20220907_2015)] -public class AccountTypes : Migration -{ - public override void Up() - { - Create.Column("AuthType") - .OnTable("Users") - .AsInt16() - .WithDefaultValue(0); - - Alter.Column("Password") - .OnTable("Users") - .AsString() - .Nullable(); - - Create.Table("UsersAuthToken") - .WithColumn("Id").AsGuid().PrimaryKey() - .WithColumn("User").AsGuid().ForeignKey("Users", "Id").OnDelete(Rule.Cascade).Indexed() - .WithColumn("Provider").AsString() - .WithColumn("AccessToken").AsString() - .WithColumn("TokenType").AsString() - .WithColumn("Expires").AsDateTimeOffset() - .WithColumn("RefreshToken").AsString() - .WithColumn("Scope").AsString(); - } - - public override void Down() - { - Delete.Column("Type") - .FromTable("Users"); - - Alter.Column("Password") - .OnTable("Users") - .AsString() - .NotNullable(); - - Delete.Table("UsersAuthToken"); - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/Database/06-EncryptionParams.cs b/VoidCat/Services/Migrations/Database/06-EncryptionParams.cs deleted file mode 100644 index b25e0e3..0000000 --- a/VoidCat/Services/Migrations/Database/06-EncryptionParams.cs +++ /dev/null @@ -1,20 +0,0 @@ -using FluentMigrator; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20220911_1635)] -public class EncryptionParams : Migration{ - public override void Up() - { - Create.Column("EncryptionParams") - .OnTable("Files") - .AsString() - .Nullable(); - } - - public override void Down() - { - Delete.Column("EncryptionParams") - .FromTable("Files"); - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/Database/07-MagnetLink.cs b/VoidCat/Services/Migrations/Database/07-MagnetLink.cs deleted file mode 100644 index 3370b4b..0000000 --- a/VoidCat/Services/Migrations/Database/07-MagnetLink.cs +++ /dev/null @@ -1,20 +0,0 @@ -using FluentMigrator; - -namespace VoidCat.Services.Migrations.Database; - -[Migration(20230304_1509)] -public class MagnetLink : Migration { - public override void Up() - { - Create.Column("MagnetLink") - .OnTable("Files") - .AsString() - .Nullable(); - } - - public override void Down() - { - Delete.Column("MagnetLink") - .FromTable("Files"); - } -} diff --git a/VoidCat/Services/Migrations/EFMigration.cs b/VoidCat/Services/Migrations/EFMigration.cs new file mode 100644 index 0000000..7d2aeb2 --- /dev/null +++ b/VoidCat/Services/Migrations/EFMigration.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; + +namespace VoidCat.Services.Migrations; + +public class EFMigration : IMigration +{ + private readonly VoidContext _db; + + public EFMigration(VoidContext db) + { + _db = db; + } + + public int Order => 0; + + public async ValueTask Migrate(string[] args) + { + await _db.Database.MigrateAsync(); + return IMigration.MigrationResult.Completed; + } +} diff --git a/VoidCat/Services/Migrations/EFMigrationSetup.cs b/VoidCat/Services/Migrations/EFMigrationSetup.cs new file mode 100644 index 0000000..6a0a733 --- /dev/null +++ b/VoidCat/Services/Migrations/EFMigrationSetup.cs @@ -0,0 +1,88 @@ +using System.Data.Common; +using Microsoft.EntityFrameworkCore; +using Npgsql; +using VoidCat.Model; + +namespace VoidCat.Services.Migrations; + +public class EFMigrationSetup : IMigration +{ + private readonly VoidContext _db; + private readonly VoidSettings _settings; + + public EFMigrationSetup(VoidContext db, VoidSettings settings) + { + _db = db; + _settings = settings; + } + + public int Order => -99; + + public async ValueTask Migrate(string[] args) + { + if (!_settings.HasPostgres()) return IMigration.MigrationResult.Skipped; + + var conn = (_db.Database.GetDbConnection() as NpgsqlConnection)!; + await conn.OpenAsync(); + try + { + await using var cmd = new NpgsqlCommand("select max(\"Version\") from \"VersionInfo\"", conn); + + var vMax = await cmd.ExecuteScalarAsync() as long?; + if (!(vMax > 0)) return IMigration.MigrationResult.Skipped; + + await PrepEfMigration(conn); + } + catch (DbException dx) when (dx.SqlState is "42P01") + { + //ignored, VersionInfo does not exist + return IMigration.MigrationResult.Skipped; + } + + return IMigration.MigrationResult.Completed; + } + + private static async Task PrepEfMigration(NpgsqlConnection conn) + { + await using var tx = await conn.BeginTransactionAsync(); + + await new NpgsqlCommand(@" +ALTER TABLE ""Files"" ALTER COLUMN ""Size"" TYPE numeric(20) USING ""Size""::numeric; +ALTER TABLE ""Payment"" RENAME COLUMN ""File"" TO ""FileId""; +ALTER TABLE ""UserFiles"" RENAME COLUMN ""File"" TO ""FileId""; +ALTER TABLE ""UserFiles"" RENAME COLUMN ""User"" TO ""UserId""; +ALTER TABLE ""UserRoles"" RENAME COLUMN ""User"" TO ""UserId""; +ALTER TABLE ""UsersAuthToken"" RENAME COLUMN ""User"" TO ""UserId""; +ALTER TABLE ""UsersAuthToken"" ADD ""IdToken"" text NULL; +ALTER TABLE ""VirusScanResult"" RENAME COLUMN ""File"" TO ""FileId""; +ALTER TABLE ""ApiKey"" RENAME CONSTRAINT ""FK_ApiKey_UserId_Users_Id"" TO ""FK_ApiKey_Users_UserId""; +ALTER TABLE ""UserFiles"" RENAME CONSTRAINT ""FK_UserFiles_File_Files_Id"" TO ""FK_UserFiles_Files_FileId""; +ALTER TABLE ""UserFiles"" RENAME CONSTRAINT ""FK_UserFiles_User_Users_Id"" TO ""FK_UserFiles_Users_UserId""; +ALTER TABLE ""UserRoles"" RENAME CONSTRAINT ""FK_UserRoles_User_Users_Id"" TO ""FK_UserRoles_Users_UserId""; +ALTER TABLE ""UsersAuthToken"" RENAME CONSTRAINT ""FK_UsersAuthToken_User_Users_Id"" TO ""FK_UsersAuthToken_Users_UserId""; +ALTER TABLE ""VirusScanResult"" RENAME CONSTRAINT ""FK_VirusScanResult_File_Files_Id"" TO ""FK_VirusScanResult_Files_FileId""; + +DROP TABLE ""EmailVerification""; +DROP TABLE ""PaymentOrderLightning""; +DROP TABLE ""PaymentOrder""; +DROP TABLE ""PaymentStrike""; +DROP TABLE ""Payment""; +DROP TABLE ""VersionInfo""; +", conn, tx).ExecuteNonQueryAsync(); + + // manually create init migration entry for EF to skip Init migration + await new NpgsqlCommand(@" +CREATE TABLE ""__EFMigrationsHistory"" ( + ""MigrationId"" varchar(150) NOT NULL, + ""ProductVersion"" varchar(32) NOT NULL, +CONSTRAINT ""PK___EFMigrationsHistory"" PRIMARY KEY (""MigrationId"") +)", conn, tx).ExecuteNonQueryAsync(); + + await new NpgsqlCommand( + "INSERT INTO \"__EFMigrationsHistory\" (\"MigrationId\", \"ProductVersion\") VALUES('20230503115108_Init', '7.0.5')", conn, + tx) + .ExecuteNonQueryAsync(); + + await tx.CommitAsync(); + } +} diff --git a/VoidCat/Services/Migrations/FixSize.cs b/VoidCat/Services/Migrations/FixSize.cs deleted file mode 100644 index b7df523..0000000 --- a/VoidCat/Services/Migrations/FixSize.cs +++ /dev/null @@ -1,52 +0,0 @@ -using VoidCat.Model; -using VoidCat.Services.Abstractions; -using VoidCat.Services.Files; - -namespace VoidCat.Services.Migrations; - -/// -public class FixSize : IMigration -{ - private readonly ILogger _logger; - private readonly IFileMetadataStore _fileMetadata; - private readonly FileStoreFactory _fileStore; - - public FixSize(ILogger logger, IFileMetadataStore fileMetadata, FileStoreFactory fileStore) - { - _logger = logger; - _fileMetadata = fileMetadata; - _fileStore = fileStore; - } - - /// - public int Order => 2; - - /// - public async ValueTask Migrate(string[] args) - { - var files = await _fileMetadata.ListFiles(new(0, int.MaxValue)); - await foreach (var file in files.Results) - { - try - { - var fs = await _fileStore.Open(new(file.Id, Enumerable.Empty()), CancellationToken.None); - if (file.Size != (ulong)fs.Length) - { - _logger.LogInformation("Updating file size {Id} to {Size}", file.Id, fs.Length); - var newFile = file with - { - Size = (ulong)fs.Length - }; - - await _fileMetadata.Set(newFile.Id, newFile); - } - } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to fix file {id}", file.Id); - } - } - - return IMigration.MigrationResult.Completed; - } -} diff --git a/VoidCat/Services/Migrations/FluentMigrationRunner.cs b/VoidCat/Services/Migrations/FluentMigrationRunner.cs deleted file mode 100644 index 15ca921..0000000 --- a/VoidCat/Services/Migrations/FluentMigrationRunner.cs +++ /dev/null @@ -1,24 +0,0 @@ -using FluentMigrator.Runner; - -namespace VoidCat.Services.Migrations; - -/// -public class FluentMigrationRunner : IMigration -{ - private readonly IMigrationRunner _runner; - - public FluentMigrationRunner(IMigrationRunner runner) - { - _runner = runner; - } - - /// - public int Order => -1; - - /// - public ValueTask Migrate(string[] args) - { - _runner.MigrateUp(); - return ValueTask.FromResult(IMigration.MigrationResult.Completed); - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/MigrateToPostgres.cs b/VoidCat/Services/Migrations/MigrateToPostgres.cs deleted file mode 100644 index 8566175..0000000 --- a/VoidCat/Services/Migrations/MigrateToPostgres.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System.Security.Cryptography; -using Newtonsoft.Json; -using VoidCat.Model; -using VoidCat.Model.User; -using VoidCat.Services.Abstractions; -using VoidCat.Services.Files; -using VoidCat.Services.Payment; -using VoidCat.Services.Users; - -namespace VoidCat.Services.Migrations; - -/// -public class MigrateToPostgres : IMigration -{ - private readonly ILogger _logger; - private readonly VoidSettings _settings; - private readonly IFileMetadataStore _fileMetadata; - private readonly ICache _cache; - private readonly IPaymentStore _paymentStore; - private readonly IUserStore _userStore; - private readonly IUserUploadsStore _userUploads; - private readonly FileStoreFactory _fileStore; - - public MigrateToPostgres(VoidSettings settings, ILogger logger, IFileMetadataStore fileMetadata, - ICache cache, IPaymentStore paymentStore, IUserStore userStore, IUserUploadsStore userUploads, - FileStoreFactory fileStore) - { - _logger = logger; - _settings = settings; - _fileMetadata = fileMetadata; - _cache = cache; - _paymentStore = paymentStore; - _userStore = userStore; - _userUploads = userUploads; - _fileStore = fileStore; - } - - /// - public int Order => 0; - - /// - public async ValueTask Migrate(string[] args) - { - if (args.Contains("--migrate-local-metadata-to-postgres")) - { - await MigrateFiles(); - return IMigration.MigrationResult.ExitCompleted; - } - - if (args.Contains("--migrate-cache-paywall-to-postgres")) - { - await MigratePaywall(); - return IMigration.MigrationResult.ExitCompleted; - } - - if (args.Contains("--migrate-cache-users-to-postgres")) - { - await MigrateUsers(); - return IMigration.MigrationResult.ExitCompleted; - } - - return IMigration.MigrationResult.Skipped; - } - - private async Task MigrateFiles() - { - var localDiskMetaStore = - new LocalDiskFileMetadataStore(_settings); - - var files = await localDiskMetaStore.ListFiles(new(0, int.MaxValue)); - await foreach (var file in files.Results) - { - try - { - if (string.IsNullOrEmpty(file.Digest)) - { - var fs = await _fileStore.Open(new(file.Id, Enumerable.Empty()), - CancellationToken.None); - - var hash = await SHA256.Create().ComputeHashAsync(fs); - file.Digest = hash.ToHex(); - } - - file.MimeType ??= "application/octet-stream"; - await _fileMetadata.Set(file.Id, file); - if (file.Uploader.HasValue) - { - await _userUploads.AddFile(file.Uploader.Value, file.Id); - } - - await localDiskMetaStore.Delete(file.Id); - _logger.LogInformation("Migrated file metadata for {File}", file.Id); - } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to migrate file metadata for {File}", file.Id); - } - } - } - - private async Task MigratePaywall() - { - var cachePaywallStore = new CachePaymentStore(_cache); - - var files = await _fileMetadata.ListFiles(new(0, int.MaxValue)); - await foreach (var file in files.Results) - { - try - { - var old = await cachePaywallStore.Get(file.Id); - if (old != default) - { - await _paymentStore.Add(file.Id, old); - _logger.LogInformation("Migrated paywall config for {File}", file.Id); - } - } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to migrate paywall config for {File}", file.Id); - } - } - } - - private async Task MigrateUsers() - { - var cacheUsers = new CacheUserStore(_cache); - - var users = await cacheUsers.ListUsers(new(0, int.MaxValue)); - await foreach (var user in users.Results) - { - try - { - var privateUser = await cacheUsers.Get(user.Id); - privateUser!.Password ??= privateUser.PasswordHash; - - await _userStore.Set(privateUser!.Id, new InternalUser() - { - Id = privateUser.Id, - Avatar = privateUser.Avatar, - Created = privateUser.Created, - DisplayName = privateUser.DisplayName, - Email = privateUser.Email, - Flags = privateUser.Flags, - LastLogin = privateUser.LastLogin, - Password = privateUser.Password!, - Roles = privateUser.Roles - }); - - _logger.LogInformation("Migrated user {USer}", user.Id); - } - catch (Exception ex) - { - _logger.LogError(ex, "Failed to migrate user {User}", user.Id); - } - } - } - - private class PrivateUser : Model.User.PrivateUser - { - public string? PasswordHash { get; set; } - public string? Password { get; set; } - } - - private record UploaderSecretVoidFileMeta : SecretFileMeta - { - [JsonConverter(typeof(Base58GuidConverter))] - public Guid? Uploader { get; set; } - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/PopulateMetadataId.cs b/VoidCat/Services/Migrations/PopulateMetadataId.cs deleted file mode 100644 index 7e38548..0000000 --- a/VoidCat/Services/Migrations/PopulateMetadataId.cs +++ /dev/null @@ -1,36 +0,0 @@ -using VoidCat.Model; -using VoidCat.Services.Abstractions; - -namespace VoidCat.Services.Migrations; - -/// -public class PopulateMetadataId : IMigration -{ - private readonly IFileMetadataStore _metadataStore; - - public PopulateMetadataId(IFileMetadataStore metadataStore) - { - _metadataStore = metadataStore; - } - - /// - public int Order => 2; - - /// - public async ValueTask Migrate(string[] args) - { - if (!args.Contains("--add-metadata-id")) - { - return IMigration.MigrationResult.Skipped; - } - - var files = await _metadataStore.ListFiles(new(0, Int32.MaxValue)); - await foreach (var file in files.Results) - { - // read-write file metadata - await _metadataStore.Set(file.Id, file); - } - - return IMigration.MigrationResult.ExitCompleted; - } -} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/UserLookupKeyHashMigration.cs b/VoidCat/Services/Migrations/UserLookupKeyHashMigration.cs deleted file mode 100644 index 9bed290..0000000 --- a/VoidCat/Services/Migrations/UserLookupKeyHashMigration.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Newtonsoft.Json; -using StackExchange.Redis; -using VoidCat.Model; - -namespace VoidCat.Services.Migrations; - -/// -public class UserLookupKeyHashMigration : IMigration -{ - private readonly IDatabase _database; - - public UserLookupKeyHashMigration(IDatabase database) - { - _database = database; - } - - /// - public int Order => 2; - - /// - public async ValueTask Migrate(string[] args) - { - var users = await _database.SetMembersAsync("users"); - foreach (var userId in users) - { - if (!Guid.TryParse(userId, out var gid)) continue; - - var userJson = await _database.StringGetAsync($"user:{gid}"); - var user = JsonConvert.DeserializeObject(userJson); - if (user == default) continue; - - if (await _database.KeyExistsAsync(MapOld(user.Email))) - { - await _database.KeyDeleteAsync(MapOld(user.Email)); - await _database.StringSetAsync(MapNew(user.Email), $"\"{userId}\""); - } - } - - return IMigration.MigrationResult.Completed; - } - - private static RedisKey MapOld(string email) => $"user:email:{email}"; - private static RedisKey MapNew(string email) => $"user:email:{email.Hash("md5")}"; - - internal class UserEmail - { - public UserEmail(string email) => Email = email; - - public string Email { get; init; } - } -} \ No newline at end of file diff --git a/VoidCat/Services/Payment/CachePaymentOrderStore.cs b/VoidCat/Services/Payment/CachePaymentOrderStore.cs index 4221a6f..eab4b42 100644 --- a/VoidCat/Services/Payment/CachePaymentOrderStore.cs +++ b/VoidCat/Services/Payment/CachePaymentOrderStore.cs @@ -1,17 +1,17 @@ -using VoidCat.Model.Payments; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Payment; /// -public class CachePaymentOrderStore : BasicCacheStore, IPaymentOrderStore +public class CachePaymentOrderStore : BasicCacheStore, IPaymentOrderStore { public CachePaymentOrderStore(ICache cache) : base(cache) { } /// - public async ValueTask UpdateStatus(Guid order, PaymentOrderStatus status) + public async ValueTask UpdateStatus(Guid order, PaywallOrderStatus status) { var old = await Get(order); if (old == default) return; diff --git a/VoidCat/Services/Payment/CachePaymentStore.cs b/VoidCat/Services/Payment/CachePaymentStore.cs index 44da897..1b51eee 100644 --- a/VoidCat/Services/Payment/CachePaymentStore.cs +++ b/VoidCat/Services/Payment/CachePaymentStore.cs @@ -1,10 +1,10 @@ -using VoidCat.Model.Payments; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Payment; /// -public class CachePaymentStore : BasicCacheStore, IPaymentStore +public class CachePaymentStore : BasicCacheStore, IPaymentStore { public CachePaymentStore(ICache database) : base(database) @@ -12,15 +12,10 @@ public class CachePaymentStore : BasicCacheStore, IPaymentStore } /// - public override async ValueTask Get(Guid id) + public override async ValueTask Get(Guid id) { - var cfg = await _cache.Get(MapKey(id)); - return cfg?.Service switch - { - PaymentServices.None => cfg, - PaymentServices.Strike => await _cache.Get(MapKey(id)), - _ => default - }; + var cfg = await Cache.Get(MapKey(id)); + return cfg; } /// diff --git a/VoidCat/Services/Payment/LnProxyPaymentProvider.cs b/VoidCat/Services/Payment/LnProxyPaymentProvider.cs new file mode 100644 index 0000000..62ca32f --- /dev/null +++ b/VoidCat/Services/Payment/LnProxyPaymentProvider.cs @@ -0,0 +1,17 @@ +using VoidCat.Database; +using VoidCat.Services.Abstractions; + +namespace VoidCat.Services.Payment; + +public class LnProxyPaymentProvider : IPaymentProvider +{ + public ValueTask CreateOrder(Paywall file) + { + throw new NotImplementedException(); + } + + public ValueTask GetOrderStatus(Guid id) + { + throw new NotImplementedException(); + } +} diff --git a/VoidCat/Services/Payment/PaymentFactory.cs b/VoidCat/Services/Payment/PaymentFactory.cs index be30a2b..2243555 100644 --- a/VoidCat/Services/Payment/PaymentFactory.cs +++ b/VoidCat/Services/Payment/PaymentFactory.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.Payments; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Payment; @@ -12,11 +12,11 @@ public class PaymentFactory : IPaymentFactory _services = services; } - public ValueTask CreateProvider(PaymentServices svc) + public ValueTask CreateProvider(PaywallService svc) { return ValueTask.FromResult(svc switch { - PaymentServices.Strike => _services.GetRequiredService(), + PaywallService.Strike => _services.GetRequiredService(), _ => throw new ArgumentException("Must have a payment config", nameof(svc)) }); } diff --git a/VoidCat/Services/Payment/PostgresPaymentOrderStore.cs b/VoidCat/Services/Payment/PostgresPaymentOrderStore.cs index cc710bb..05320de 100644 --- a/VoidCat/Services/Payment/PostgresPaymentOrderStore.cs +++ b/VoidCat/Services/Payment/PostgresPaymentOrderStore.cs @@ -1,5 +1,5 @@ -using Dapper; -using VoidCat.Model.Payments; +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Payment; @@ -7,98 +7,42 @@ namespace VoidCat.Services.Payment; /// public class PostgresPaymentOrderStore : IPaymentOrderStore { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; - public PostgresPaymentOrderStore(PostgresConnectionFactory connection) + public PostgresPaymentOrderStore(VoidContext db) { - _connection = connection; + _db = db; } /// - public async ValueTask Get(Guid id) + public async ValueTask Get(Guid id) { - await using var conn = await _connection.Get(); - var order = await conn.QuerySingleOrDefaultAsync( - @"select * from ""PaymentOrder"" where ""Id"" = :id", new {id}); - if (order.Service is PaymentServices.Strike) - { - var lnDetails = await conn.QuerySingleAsync( - @"select * from ""PaymentOrderLightning"" where ""Order"" = :id", new - { - id = order.Id - }); - return new LightningPaymentOrder - { - Id = order.Id, - File = order.File, - Price = new(order.Amount, order.Currency), - Service = order.Service, - Status = order.Status, - Invoice = lnDetails.Invoice, - Expire = lnDetails.Expire - }; - } - - return order; + return await _db.PaywallOrders + .AsNoTracking() + .Include(a => a.OrderLightning) + .SingleOrDefaultAsync(a => a.Id == id); } /// - public ValueTask> Get(Guid[] ids) + public async ValueTask Add(Guid id, PaywallOrder obj) { - throw new NotImplementedException(); - } - - /// - public async ValueTask Add(Guid id, PaymentOrder obj) - { - await using var conn = await _connection.Get(); - await using var txn = await conn.BeginTransactionAsync(); - await conn.ExecuteAsync( - @"insert into ""PaymentOrder""(""Id"", ""File"", ""Service"", ""Currency"", ""Amount"", ""Status"") -values(:id, :file, :service, :currency, :amt, :status)", - new - { - id, - file = obj.File, - service = (int) obj.Service, - currency = (int) obj.Price.Currency, - amt = obj.Price.Amount, // :amount wasn't working? - status = (int) obj.Status - }); - - if (obj is LightningPaymentOrder ln) - { - await conn.ExecuteAsync( - @"insert into ""PaymentOrderLightning""(""Order"", ""Invoice"", ""Expire"") values(:order, :invoice, :expire)", - new - { - order = id, - invoice = ln.Invoice, - expire = ln.Expire.ToUniversalTime() - }); - } - - await txn.CommitAsync(); + _db.PaywallOrders.Add(obj); + await _db.SaveChangesAsync(); } /// public async ValueTask Delete(Guid id) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"delete from ""PaymentOrder"" where ""Id"" = :id", new {id}); + await _db.PaywallOrders + .Where(a => a.Id == id) + .ExecuteDeleteAsync(); } /// - public async ValueTask UpdateStatus(Guid order, PaymentOrderStatus status) + public async ValueTask UpdateStatus(Guid order, PaywallOrderStatus status) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"update ""PaymentOrder"" set ""Status"" = :status where ""Id"" = :id", - new {id = order, status = (int) status}); + await _db.PaywallOrders + .Where(a => a.Id == order) + .ExecuteUpdateAsync(s => s.SetProperty(p => p.Status, status)); } - - private sealed class DtoPaymentOrder : PaymentOrder - { - public PaymentCurrencies Currency { get; init; } - public decimal Amount { get; init; } - } -} \ No newline at end of file +} diff --git a/VoidCat/Services/Payment/PostgresPaymentStore.cs b/VoidCat/Services/Payment/PostgresPaymentStore.cs index 2715437..5cae360 100644 --- a/VoidCat/Services/Payment/PostgresPaymentStore.cs +++ b/VoidCat/Services/Payment/PostgresPaymentStore.cs @@ -1,5 +1,5 @@ -using Dapper; -using VoidCat.Model.Payments; +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Payment; @@ -7,89 +7,34 @@ namespace VoidCat.Services.Payment; /// public sealed class PostgresPaymentStore : IPaymentStore { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; - public PostgresPaymentStore(PostgresConnectionFactory connection) + public PostgresPaymentStore(VoidContext db) { - _connection = connection; + _db = db; } /// - public async ValueTask Get(Guid id) + public async ValueTask Get(Guid id) { - await using var conn = await _connection.Get(); - var dto = await conn.QuerySingleOrDefaultAsync( - @"select * from ""Payment"" where ""File"" = :file", new {file = id}); - if (dto != default) - { - switch (dto.Service) - { - case PaymentServices.Strike: - { - var handle = - await conn.ExecuteScalarAsync( - @"select ""Handle"" from ""PaymentStrike"" where ""File"" = :file", new {file = id}); - return new StrikePaymentConfig - { - Cost = new(dto.Amount, dto.Currency), - File = dto.File, - Handle = handle, - Service = PaymentServices.Strike, - Required = dto.Required - }; - } - } - } - - return default; + return await _db.Paywalls + .AsNoTracking() + .Include(a => a.PaywallStrike) + .SingleOrDefaultAsync(a => a.Id == id); } /// - public ValueTask> Get(Guid[] ids) + public async ValueTask Add(Guid id, Paywall obj) { - throw new NotImplementedException(); - } - - /// - public async ValueTask Add(Guid id, PaymentConfig obj) - { - await using var conn = await _connection.Get(); - await using var txn = await conn.BeginTransactionAsync(); - await conn.ExecuteAsync( - @"insert into ""Payment""(""File"", ""Service"", ""Amount"", ""Currency"", ""Required"") values(:file, :service, :amount, :currency, :required) -on conflict(""File"") do update set ""Service"" = :service, ""Amount"" = :amount, ""Currency"" = :currency, ""Required"" = :required", - new - { - file = id, - service = (int)obj.Service, - amount = obj.Cost.Amount, - currency = obj.Cost.Currency, - required = obj.Required - }); - - if (obj is StrikePaymentConfig sc) - { - await conn.ExecuteAsync(@"insert into ""PaymentStrike""(""File"", ""Handle"") values(:file, :handle) -on conflict(""File"") do update set ""Handle"" = :handle", new - { - file = id, - handle = sc.Handle - }); - } - - await txn.CommitAsync(); + _db.Paywalls.Add(obj); + await _db.SaveChangesAsync(); } /// public async ValueTask Delete(Guid id) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"delete from ""Payment"" where ""File"" = :file", new {file = id}); + await _db.Paywalls + .Where(a => a.Id == id) + .ExecuteDeleteAsync(); } - - private sealed class DtoPaymentConfig : PaymentConfig - { - public PaymentCurrencies Currency { get; init; } - public decimal Amount { get; init; } - } -} \ No newline at end of file +} diff --git a/VoidCat/Services/Payment/StrikePaymentProvider.cs b/VoidCat/Services/Payment/StrikePaymentProvider.cs index 3cf84eb..668194e 100644 --- a/VoidCat/Services/Payment/StrikePaymentProvider.cs +++ b/VoidCat/Services/Payment/StrikePaymentProvider.cs @@ -1,6 +1,6 @@ using System.Globalization; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.Payments; using VoidCat.Services.Abstractions; using VoidCat.Services.Strike; @@ -21,16 +21,20 @@ public class StrikePaymentProvider : IPaymentProvider } /// - public async ValueTask CreateOrder(PaymentConfig config) + public async ValueTask CreateOrder(Paywall config) { - IsStrikePayment(config, out var strikeConfig); - _logger.LogInformation("Generating invoice for {Currency} {Amount}", config.Cost.Currency, config.Cost.Amount); + if (config.Service != PaywallService.Strike || config.PaywallStrike == default) + { + throw new InvalidOperationException("Paywall config is not Strike"); + } + + _logger.LogInformation("Generating invoice for {Currency} {Amount}", config.Currency, config.Amount); - var currency = MapCurrency(strikeConfig.Cost.Currency); + var currency = MapCurrency(config.Currency); if (currency == Currencies.USD) { // map USD to USDT if USD is not available and USDT is - var profile = await _strike.GetProfile(strikeConfig.Handle); + var profile = await _strike.GetProfile(config.PaywallStrike!.Handle); if (profile != default) { var usd = profile.Currencies.FirstOrDefault(a => a.Currency == Currencies.USD); @@ -44,28 +48,32 @@ public class StrikePaymentProvider : IPaymentProvider var invoice = await _strike.GenerateInvoice(new() { - Handle = strikeConfig.Handle, + Handle = config.PaywallStrike.Handle, Amount = new() { - Amount = strikeConfig.Cost.Amount.ToString(CultureInfo.InvariantCulture), + Amount = config.Amount.ToString(CultureInfo.InvariantCulture), Currency = currency }, - Description = config.File.ToBase58() + Description = config.File.Id.ToBase58() }); if (invoice != default) { var quote = await _strike.GetInvoiceQuote(invoice.InvoiceId); if (quote != default) { - var order = new LightningPaymentOrder + var order = new PaywallOrder { Id = invoice.InvoiceId, - File = config.File, - Service = PaymentServices.Strike, - Price = config.Cost, - Status = PaymentOrderStatus.Unpaid, - Invoice = quote.LnInvoice!, - Expire = DateTime.SpecifyKind(quote.Expiration.DateTime, DateTimeKind.Utc) + FileId = config.File.Id, + Service = PaywallService.Strike, + Amount = config.Amount, + Status = PaywallOrderStatus.Unpaid, + OrderLightning = new() + { + OrderId = invoice.InvoiceId, + Invoice = quote.LnInvoice!, + Expire = DateTime.SpecifyKind(quote.Expiration.DateTime, DateTimeKind.Utc) + } }; await _orderStore.Add(order.Id, order); return order; @@ -80,10 +88,10 @@ public class StrikePaymentProvider : IPaymentProvider } /// - public async ValueTask GetOrderStatus(Guid id) + public async ValueTask GetOrderStatus(Guid id) { var order = await _orderStore.Get(id); - if (order is {Status: PaymentOrderStatus.Paid or PaymentOrderStatus.Expired}) return order; + if (order is {Status: PaywallOrderStatus.Paid or PaywallOrderStatus.Expired}) return order; var providerOrder = await _strike.GetInvoice(id); if (providerOrder != default) @@ -94,9 +102,9 @@ public class StrikePaymentProvider : IPaymentProvider return new() { Id = id, - Price = new(decimal.Parse(providerOrder!.Amount!.Amount!), - MapCurrency(providerOrder.Amount!.Currency!.Value)), - Service = PaymentServices.Strike, + Amount = decimal.Parse(providerOrder.Amount!.Amount!), + Currency = MapCurrency(providerOrder.Amount!.Currency!.Value), + Service = PaywallService.Strike, Status = status }; } @@ -104,44 +112,34 @@ public class StrikePaymentProvider : IPaymentProvider return default; } - private PaymentOrderStatus MapStatus(InvoiceState providerOrderState) + private PaywallOrderStatus MapStatus(InvoiceState providerOrderState) => providerOrderState switch { - InvoiceState.UNPAID => PaymentOrderStatus.Unpaid, - InvoiceState.PENDING => PaymentOrderStatus.Unpaid, - InvoiceState.PAID => PaymentOrderStatus.Paid, - InvoiceState.CANCELLED => PaymentOrderStatus.Expired, + InvoiceState.UNPAID => PaywallOrderStatus.Unpaid, + InvoiceState.PENDING => PaywallOrderStatus.Unpaid, + InvoiceState.PAID => PaywallOrderStatus.Paid, + InvoiceState.CANCELLED => PaywallOrderStatus.Expired, _ => throw new ArgumentOutOfRangeException(nameof(providerOrderState), providerOrderState, null) }; - private static Currencies MapCurrency(PaymentCurrencies c) + private static Currencies MapCurrency(PaywallCurrency c) => c switch { - PaymentCurrencies.BTC => Currencies.BTC, - PaymentCurrencies.USD => Currencies.USD, - PaymentCurrencies.EUR => Currencies.EUR, - PaymentCurrencies.GBP => Currencies.GBP, + PaywallCurrency.BTC => Currencies.BTC, + PaywallCurrency.USD => Currencies.USD, + PaywallCurrency.EUR => Currencies.EUR, + PaywallCurrency.GBP => Currencies.GBP, _ => throw new ArgumentOutOfRangeException(nameof(c), c, null) }; - private static PaymentCurrencies MapCurrency(Currencies c) + private static PaywallCurrency MapCurrency(Currencies c) => c switch { - Currencies.BTC => PaymentCurrencies.BTC, - Currencies.USD => PaymentCurrencies.USD, - Currencies.USDT => PaymentCurrencies.USD, - Currencies.EUR => PaymentCurrencies.EUR, - Currencies.GBP => PaymentCurrencies.GBP, + Currencies.BTC => PaywallCurrency.BTC, + Currencies.USD => PaywallCurrency.USD, + Currencies.USDT => PaywallCurrency.USD, + Currencies.EUR => PaywallCurrency.EUR, + Currencies.GBP => PaywallCurrency.GBP, _ => throw new ArgumentOutOfRangeException(nameof(c), c, null) }; - - private static void IsStrikePayment(PaymentConfig? cfg, out StrikePaymentConfig strikeConfig) - { - if (cfg?.Service != PaymentServices.Strike) - { - throw new ArgumentException("Must be strike Payment"); - } - - strikeConfig = (cfg as StrikePaymentConfig)!; - } } \ No newline at end of file diff --git a/VoidCat/Services/PostgresConnectionFactory.cs b/VoidCat/Services/PostgresConnectionFactory.cs deleted file mode 100644 index e5126cb..0000000 --- a/VoidCat/Services/PostgresConnectionFactory.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Data; -using Npgsql; -using VoidCat.Model; - -namespace VoidCat.Services; - -public sealed class PostgresConnectionFactory -{ - private readonly VoidSettings _settings; - - public PostgresConnectionFactory(VoidSettings settings) - { - _settings = settings; - } - - public async Task Get() - { - var conn = new NpgsqlConnection(_settings.Postgres); - if (!conn.State.HasFlag(ConnectionState.Open)) - { - await conn.OpenAsync(); - } - - return conn; - } -} \ No newline at end of file diff --git a/VoidCat/Services/Users/Auth/CacheUserAuthTokenStore.cs b/VoidCat/Services/Users/Auth/CacheUserAuthTokenStore.cs index 4f5c30e..45e5a81 100644 --- a/VoidCat/Services/Users/Auth/CacheUserAuthTokenStore.cs +++ b/VoidCat/Services/Users/Auth/CacheUserAuthTokenStore.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.User; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users.Auth; diff --git a/VoidCat/Services/Users/Auth/DiscordOAuthProvider.cs b/VoidCat/Services/Users/Auth/DiscordOAuthProvider.cs index b139fd0..26c07f3 100644 --- a/VoidCat/Services/Users/Auth/DiscordOAuthProvider.cs +++ b/VoidCat/Services/Users/Auth/DiscordOAuthProvider.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; namespace VoidCat.Services.Users.Auth; @@ -19,7 +19,7 @@ public class DiscordOAuthProvider : GenericOAuth2Service public override string Id => "discord"; /// - public override async ValueTask GetUserDetails(UserAuthToken token) + public override async ValueTask GetUserDetails(UserAuthToken token) { var req = new HttpRequestMessage(HttpMethod.Get, "https://discord.com/api/users/@me"); req.Headers.Authorization = new("Bearer", token.AccessToken); @@ -31,14 +31,14 @@ public class DiscordOAuthProvider : GenericOAuth2Service return new() { Id = Guid.NewGuid(), - AuthType = AuthType.OAuth2, + AuthType = UserAuthType.OAuth2, DisplayName = $"{user!.Username}", Avatar = !string.IsNullOrEmpty(user.Avatar) ? $"https://cdn.discordapp.com/avatars/{user.Id}/{user.Avatar}.png" : null, Email = user.Email!, - Created = DateTimeOffset.UtcNow, - LastLogin = DateTimeOffset.UtcNow + Created = DateTime.UtcNow, + LastLogin = DateTime.UtcNow }; } diff --git a/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs b/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs index eb41ebd..b72e63b 100644 --- a/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs +++ b/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users.Auth; @@ -49,7 +49,7 @@ public abstract class GenericOAuth2Service : IOAuthProvider } /// - public abstract ValueTask GetUserDetails(UserAuthToken token); + public abstract ValueTask GetUserDetails(UserAuthToken token); /// /// Build query args for authorize diff --git a/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs b/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs index d4b7ff6..92f502b 100644 --- a/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs +++ b/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs @@ -1,6 +1,6 @@ using System.IdentityModel.Tokens.Jwt; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; namespace VoidCat.Services.Users.Auth; @@ -18,7 +18,7 @@ public class GoogleOAuthProvider : GenericOAuth2Service public override string Id => "google"; /// - public override ValueTask GetUserDetails(UserAuthToken token) + public override ValueTask GetUserDetails(UserAuthToken token) { var jwt = new JwtSecurityToken(token.IdToken); @@ -27,14 +27,14 @@ public class GoogleOAuthProvider : GenericOAuth2Service ? v as string : default; - return ValueTask.FromResult(new InternalUser() + return ValueTask.FromResult(new User() { Id = Guid.NewGuid(), - Created = DateTimeOffset.UtcNow, - LastLogin = DateTimeOffset.UtcNow, - AuthType = AuthType.OAuth2, + Created = DateTime.UtcNow, + LastLogin = DateTime.UtcNow, + AuthType = UserAuthType.OAuth2, Email = GetPayloadValue("email") ?? throw new InvalidOperationException("Failed to get email from Google JWT"), - DisplayName = GetPayloadValue("name"), + DisplayName = GetPayloadValue("name") ?? "void user", Avatar = GetPayloadValue("picture") })!; } diff --git a/VoidCat/Services/Users/Auth/PostgresUserAuthTokenStore.cs b/VoidCat/Services/Users/Auth/PostgresUserAuthTokenStore.cs index 7acdd1a..64dc723 100644 --- a/VoidCat/Services/Users/Auth/PostgresUserAuthTokenStore.cs +++ b/VoidCat/Services/Users/Auth/PostgresUserAuthTokenStore.cs @@ -1,5 +1,5 @@ -using Dapper; -using VoidCat.Model.User; +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users.Auth; @@ -7,50 +7,33 @@ namespace VoidCat.Services.Users.Auth; /// public class PostgresUserAuthTokenStore : IUserAuthTokenStore { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; - public PostgresUserAuthTokenStore(PostgresConnectionFactory connection) + public PostgresUserAuthTokenStore(VoidContext db) { - _connection = connection; + _db = db; } /// public async ValueTask Get(Guid id) { - await using var conn = await _connection.Get(); - return await conn.QuerySingleOrDefaultAsync( - @"select * from ""UsersAuthToken"" where ""User"" = :id", new {id}); + return await _db.UserAuthTokens + .AsNoTracking() + .SingleOrDefaultAsync(a => a.Id == id); } /// public async ValueTask Add(Guid id, UserAuthToken obj) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"insert into ""UsersAuthToken""(""Id"", ""User"", ""Provider"", ""AccessToken"", ""TokenType"", ""Expires"", ""RefreshToken"", ""Scope"") -values(:id, :user, :provider, :accessToken, :tokenType, :expires, :refreshToken, :scope) -on conflict(""Id"") do update set -""AccessToken"" = :accessToken, -""TokenType"" = :tokenType, -""Expires"" = :expires, -""RefreshToken"" = :refreshToken, -""Scope"" = :scope", new - { - id = obj.Id, - user = obj.User, - provider = obj.Provider, - accessToken = obj.AccessToken, - tokenType = obj.TokenType, - expires = obj.Expires.ToUniversalTime(), - refreshToken = obj.RefreshToken, - scope = obj.Scope - }); + _db.UserAuthTokens.Add(obj); + await _db.SaveChangesAsync(); } /// public async ValueTask Delete(Guid id) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"delete from ""UsersAuthToken"" where ""Id"" = :id", new {id}); + await _db.UserAuthTokens + .Where(a => a.Id == id) + .ExecuteDeleteAsync(); } -} \ No newline at end of file +} diff --git a/VoidCat/Services/Users/BaseEmailVerification.cs b/VoidCat/Services/Users/BaseEmailVerification.cs index dd2f346..5219a3f 100644 --- a/VoidCat/Services/Users/BaseEmailVerification.cs +++ b/VoidCat/Services/Users/BaseEmailVerification.cs @@ -1,7 +1,7 @@ using System.Net; using System.Net.Mail; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users; @@ -23,9 +23,13 @@ public abstract class BaseEmailVerification : IEmailVerification } /// - public async ValueTask SendNewCode(PrivateUser user) + public async ValueTask SendNewCode(User user) { - var token = new EmailVerificationCode(user.Id, Guid.NewGuid(), DateTime.UtcNow.AddHours(HoursExpire)); + var token = new EmailVerification{ + UserId = user.Id, + Code = Guid.NewGuid(), + Expires = DateTime.UtcNow.AddHours(HoursExpire) + }; await SaveToken(token); _logger.LogInformation("Saved email verification token for User={Id} Token={Token}", user.Id, token.Code); @@ -60,12 +64,12 @@ public abstract class BaseEmailVerification : IEmailVerification } /// - public async ValueTask VerifyCode(PrivateUser user, Guid code) + public async ValueTask VerifyCode(User user, Guid code) { var token = await GetToken(user.Id, code); if (token == default) return false; - var isValid = user.Id == token.User && + var isValid = user.Id == token.UserId && DateTime.SpecifyKind(token.Expires, DateTimeKind.Utc) > DateTimeOffset.UtcNow; if (isValid) { @@ -75,7 +79,7 @@ public abstract class BaseEmailVerification : IEmailVerification return isValid; } - protected abstract ValueTask SaveToken(EmailVerificationCode code); - protected abstract ValueTask GetToken(Guid user, Guid code); + protected abstract ValueTask SaveToken(EmailVerification code); + protected abstract ValueTask GetToken(Guid user, Guid code); protected abstract ValueTask DeleteToken(Guid user, Guid code); } \ No newline at end of file diff --git a/VoidCat/Services/Users/CacheApiKeyStore.cs b/VoidCat/Services/Users/CacheApiKeyStore.cs index d15de60..36aa3e0 100644 --- a/VoidCat/Services/Users/CacheApiKeyStore.cs +++ b/VoidCat/Services/Users/CacheApiKeyStore.cs @@ -1,4 +1,4 @@ -using VoidCat.Model.User; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users; diff --git a/VoidCat/Services/Users/CacheEmailVerification.cs b/VoidCat/Services/Users/CacheEmailVerification.cs index 05923d0..12541bc 100644 --- a/VoidCat/Services/Users/CacheEmailVerification.cs +++ b/VoidCat/Services/Users/CacheEmailVerification.cs @@ -1,4 +1,5 @@ -using VoidCat.Model; +using VoidCat.Database; +using VoidCat.Model; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users; @@ -15,15 +16,15 @@ public class CacheEmailVerification : BaseEmailVerification } /// - protected override ValueTask SaveToken(EmailVerificationCode code) + protected override ValueTask SaveToken(EmailVerification code) { return _cache.Set(MapToken(code.Code), code, code.Expires - DateTime.UtcNow); } /// - protected override ValueTask GetToken(Guid user, Guid code) + protected override ValueTask GetToken(Guid user, Guid code) { - return _cache.Get(MapToken(code)); + return _cache.Get(MapToken(code)); } /// diff --git a/VoidCat/Services/Users/CacheUserStore.cs b/VoidCat/Services/Users/CacheUserStore.cs index 31101cf..30fa0ff 100644 --- a/VoidCat/Services/Users/CacheUserStore.cs +++ b/VoidCat/Services/Users/CacheUserStore.cs @@ -1,5 +1,5 @@ +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users; @@ -15,32 +15,26 @@ public class CacheUserStore : IUserStore _cache = cache; } + /// + public ValueTask Add(User u) + { + return Set(u.Id, u); + } + /// public async ValueTask LookupUser(string email) { return await _cache.Get(MapKey(email)); } - /// - public ValueTask Get(Guid id) where T : User - { - return _cache.Get(MapKey(id)); - } - /// public ValueTask Get(Guid id) { - return Get(id); + return _cache.Get(MapKey(id)); } /// - public ValueTask GetPrivate(Guid id) - { - return Get(id); - } - - /// - public async ValueTask Set(Guid id, InternalUser user) + public async ValueTask Set(Guid id, User user) { if (id != user.Id) throw new InvalidOperationException(); @@ -50,11 +44,12 @@ public class CacheUserStore : IUserStore } /// - public async ValueTask> ListUsers(PagedRequest request) + public async ValueTask> ListUsers(PagedRequest request) { var users = (await _cache.GetList(UserList)) .Select(a => Guid.TryParse(a, out var g) ? g : null) .Where(a => a.HasValue).Select(a => a.Value); + users = (request.SortBy, request.SortOrder) switch { (PagedSortBy.Id, PageSortOrder.Asc) => users?.OrderBy(a => a), @@ -62,9 +57,9 @@ public class CacheUserStore : IUserStore _ => users }; - async IAsyncEnumerable EnumerateUsers(IEnumerable ids) + async IAsyncEnumerable EnumerateUsers(IEnumerable ids) { - var usersLoaded = await Task.WhenAll(ids.Select(async a => await Get(a))); + var usersLoaded = await Task.WhenAll(ids.Select(async a => await Get(a))); foreach (var user in usersLoaded) { if (user != default) @@ -84,9 +79,9 @@ public class CacheUserStore : IUserStore } /// - public async ValueTask UpdateProfile(PublicUser newUser) + public async ValueTask UpdateProfile(User newUser) { - var oldUser = await Get(newUser.Id); + var oldUser = await Get(newUser.Id); if (oldUser == null) return; //retain flags @@ -103,18 +98,18 @@ public class CacheUserStore : IUserStore /// public async ValueTask UpdateLastLogin(Guid id, DateTime timestamp) { - var user = await Get(id); + var user = await Get(id); if (user != default) { user.LastLogin = timestamp; await Set(user.Id, user); } } - + /// - public async ValueTask AdminUpdateUser(PrivateUser user) + public async ValueTask AdminUpdateUser(User user) { - var oldUser = await Get(user.Id); + var oldUser = await Get(user.Id); if (oldUser == null) return; oldUser.Email = user.Email; @@ -126,12 +121,13 @@ public class CacheUserStore : IUserStore /// public async ValueTask Delete(Guid id) { - var user = await Get(id); + var user = await Get(id); if (user == default) throw new InvalidOperationException(); + await Delete(user); } - private async ValueTask Delete(PrivateUser user) + private async ValueTask Delete(User user) { await _cache.Delete(MapKey(user.Id)); await _cache.RemoveFromList(UserList, user.Id.ToString()); @@ -140,4 +136,4 @@ public class CacheUserStore : IUserStore private static string MapKey(Guid id) => $"user:{id}"; private static string MapKey(string email) => $"user:email:{email.Hash("md5")}"; -} \ No newline at end of file +} diff --git a/VoidCat/Services/Users/PostgresApiKeyStore.cs b/VoidCat/Services/Users/PostgresApiKeyStore.cs index ccb029e..c542653 100644 --- a/VoidCat/Services/Users/PostgresApiKeyStore.cs +++ b/VoidCat/Services/Users/PostgresApiKeyStore.cs @@ -1,5 +1,5 @@ -using Dapper; -using VoidCat.Model.User; +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users; @@ -7,53 +7,42 @@ namespace VoidCat.Services.Users; /// public class PostgresApiKeyStore : IApiKeyStore { - private readonly PostgresConnectionFactory _factory; + private readonly VoidContext _db; - public PostgresApiKeyStore(PostgresConnectionFactory factory) + public PostgresApiKeyStore(VoidContext db) { - _factory = factory; + _db = db; } /// public async ValueTask Get(Guid id) { - await using var conn = await _factory.Get(); - return await conn.QuerySingleOrDefaultAsync(@"select * from ""ApiKey"" where ""Id"" = :id", new {id}); - } - - /// - public async ValueTask> Get(Guid[] ids) - { - await using var conn = await _factory.Get(); - return (await conn.QueryAsync(@"select * from ""ApiKey"" where ""Id"" in :ids", new {ids})).ToList(); + return await _db.ApiKeys + .AsNoTracking() + .SingleOrDefaultAsync(a => a.Id == id); } /// public async ValueTask Add(Guid id, ApiKey obj) { - await using var conn = await _factory.Get(); - await conn.ExecuteAsync(@"insert into ""ApiKey""(""Id"", ""UserId"", ""Token"", ""Expiry"") -values(:id, :userId, :token, :expiry)", new - { - id = obj.Id, - userId = obj.UserId, - token = obj.Token, - expiry = obj.Expiry.ToUniversalTime() - }); + _db.ApiKeys.Add(obj); + await _db.SaveChangesAsync(); } /// public async ValueTask Delete(Guid id) { - await using var conn = await _factory.Get(); - await conn.ExecuteAsync(@"delete from ""ApiKey"" where ""Id"" = :id", new {id}); + await _db.ApiKeys + .Where(a => a.Id == id) + .ExecuteDeleteAsync(); } /// public async ValueTask> ListKeys(Guid id) { - await using var conn = await _factory.Get(); - return (await conn.QueryAsync(@"select ""Id"", ""UserId"", ""Expiry"", ""Created"" from ""ApiKey"" where ""UserId"" = :id", new {id})) - .ToList(); + return await _db.ApiKeys + .AsNoTracking() + .Where(a => a.UserId == id) + .ToArrayAsync(); } } diff --git a/VoidCat/Services/Users/PostgresEmailVerification.cs b/VoidCat/Services/Users/PostgresEmailVerification.cs index 825daf2..bf19c08 100644 --- a/VoidCat/Services/Users/PostgresEmailVerification.cs +++ b/VoidCat/Services/Users/PostgresEmailVerification.cs @@ -1,4 +1,5 @@ -using Dapper; +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; using VoidCat.Model; namespace VoidCat.Services.Users; @@ -6,43 +7,34 @@ namespace VoidCat.Services.Users; /// public class PostgresEmailVerification : BaseEmailVerification { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; public PostgresEmailVerification(ILogger logger, VoidSettings settings, - RazorPartialToStringRenderer renderer, PostgresConnectionFactory connection) : base(logger, settings, renderer) + RazorPartialToStringRenderer renderer, VoidContext db) : base(logger, settings, renderer) { - _connection = connection; + _db = db; } /// - protected override async ValueTask SaveToken(EmailVerificationCode code) + protected override async ValueTask SaveToken(EmailVerification code) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"insert into ""EmailVerification""(""User"", ""Code"", ""Expires"") values(:user, :code, :expires)", - new - { - user = code.User, - code = code.Code, - expires = code.Expires.ToUniversalTime() - }); + _db.EmailVerifications.Add(code); + await _db.SaveChangesAsync(); } /// - protected override async ValueTask GetToken(Guid user, Guid code) + protected override async ValueTask GetToken(Guid user, Guid code) { - await using var conn = await _connection.Get(); - return await conn.QuerySingleOrDefaultAsync( - @"select * from ""EmailVerification"" where ""User"" = :user and ""Code"" = :code", - new {user, code}); + return await _db.EmailVerifications + .AsNoTracking() + .SingleOrDefaultAsync(a => a.UserId == user && a.Code == code); } /// protected override async ValueTask DeleteToken(Guid user, Guid code) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"delete from ""EmailVerification"" where ""User"" = :user and ""Code"" = :code", - new {user, code}); + await _db.EmailVerifications + .Where(a => a.UserId == user && a.Code == code) + .ExecuteDeleteAsync(); } } \ No newline at end of file diff --git a/VoidCat/Services/Users/PostgresUserStore.cs b/VoidCat/Services/Users/PostgresUserStore.cs index 72e26af..c55eb23 100644 --- a/VoidCat/Services/Users/PostgresUserStore.cs +++ b/VoidCat/Services/Users/PostgresUserStore.cs @@ -1,6 +1,6 @@ -using Dapper; +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; namespace VoidCat.Services.Users; @@ -8,129 +8,84 @@ namespace VoidCat.Services.Users; /// public class PostgresUserStore : IUserStore { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; + private readonly IServiceScopeFactory _scopeFactory; - public PostgresUserStore(PostgresConnectionFactory connection) + public PostgresUserStore(VoidContext db, IServiceScopeFactory scopeFactory) { - _connection = connection; + _db = db; + _scopeFactory = scopeFactory; } /// public async ValueTask Get(Guid id) { - return await Get(id); + return await _db.Users + .AsNoTracking() + .Include(a => a.Roles) + .SingleOrDefaultAsync(a => a.Id == id); } /// - public async ValueTask GetPrivate(Guid id) + public async ValueTask Add(User obj) { - return await Get(id); - } - - /// - public async ValueTask Set(Guid id, InternalUser obj) - { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"insert into -""Users""(""Id"", ""Email"", ""Password"", ""Created"", ""LastLogin"", ""DisplayName"", ""Avatar"", ""Flags"", ""AuthType"") -values(:id, :email, :password, :created, :lastLogin, :displayName, :avatar, :flags, :authType)", - new - { - Id = id, - email = obj.Email, - password = obj.Password, - created = obj.Created, - displayName = obj.DisplayName, - lastLogin = obj.LastLogin.ToUniversalTime(), - avatar = obj.Avatar, - flags = (int)obj.Flags, - authType = (int)obj.AuthType - }); - - if (obj.Roles.Any(a => a != Roles.User)) - { - foreach (var r in obj.Roles.Where(a => a != Roles.User)) - { - await conn.ExecuteAsync( - @"insert into ""UserRoles""(""User"", ""Role"") values(:user, :role)", - new {user = obj.Id, role = r}); - } - } + _db.Users.Add(obj); + await _db.SaveChangesAsync(); } /// public async ValueTask Delete(Guid id) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"delete from ""Users"" where ""Id"" = :id", new {id}); - } - - /// - public async ValueTask Get(Guid id) where T : User - { - await using var conn = await _connection.Get(); - var user = await conn.QuerySingleOrDefaultAsync(@"select * from ""Users"" where ""Id"" = :id", - new {id}); - - if (user != default) - { - var roles = await conn.QueryAsync( - @"select ""Role"" from ""UserRoles"" where ""User"" = :id", - new {id}); - - foreach (var r in roles) - { - user.Roles.Add(r); - } - } - - return user; + await _db.Users + .Where(a => a.Id == id) + .ExecuteDeleteAsync(); } /// public async ValueTask LookupUser(string email) { - await using var conn = await _connection.Get(); - return await conn.QuerySingleOrDefaultAsync( - @"select ""Id"" from ""Users"" where ""Email"" = :email", - new {email}); + return await _db.Users + .AsNoTracking() + .Where(a => a.Email == email) + .Select(a => a.Id) + .SingleOrDefaultAsync(); } /// - public async ValueTask> ListUsers(PagedRequest request) + public async ValueTask> ListUsers(PagedRequest request) { - await using var conn = await _connection.Get(); - var totalUsers = await conn.ExecuteScalarAsync(@"select count(*) from ""Users"""); + var totalUsers = await _db.Users.CountAsync(); - async IAsyncEnumerable Enumerate() + async IAsyncEnumerable Enumerate() { - var orderBy = request.SortBy switch + using var scope = _scopeFactory.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var q = db.Users.AsNoTracking().AsQueryable(); + switch (request.SortBy, request.SortOrder) { - PagedSortBy.Date => "Created", - PagedSortBy.Name => "DisplayName", - _ => "Id" - }; + case (PagedSortBy.Id, PageSortOrder.Asc): + q = q.OrderBy(a => a.Id); + break; + case (PagedSortBy.Id, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.Id); + break; + case (PagedSortBy.Name, PageSortOrder.Asc): + q = q.OrderBy(a => a.DisplayName); + break; + case (PagedSortBy.Name, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.DisplayName); + break; + case (PagedSortBy.Date, PageSortOrder.Asc): + q = q.OrderBy(a => a.Created); + break; + case (PagedSortBy.Date, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.Created); + break; + } - var sortBy = request.SortOrder switch + await foreach (var r in q.Skip(request.Page * request.PageSize).Take(request.PageSize).AsAsyncEnumerable()) { - PageSortOrder.Dsc => "desc", - _ => "asc" - }; - - await using var iconn = await _connection.Get(); - var users = await iconn.ExecuteReaderAsync( - $@"select * from ""Users"" order by ""{orderBy}"" {sortBy} offset :offset limit :limit", - new - { - offset = request.PageSize * request.Page, - limit = request.PageSize - }); - - var rowParser = users.GetRowParser(); - while (await users.ReadAsync()) - { - yield return rowParser(users); + yield return r; } } @@ -144,43 +99,42 @@ values(:id, :email, :password, :created, :lastLogin, :displayName, :avatar, :fla } /// - public async ValueTask UpdateProfile(PublicUser newUser) + public async ValueTask UpdateProfile(User newUser) { - var oldUser = await Get(newUser.Id); - if (oldUser == null) return; + var u = await _db.Users + .FindAsync(newUser.Id); - var emailFlag = oldUser.Flags.HasFlag(UserFlags.EmailVerified) ? UserFlags.EmailVerified : 0; - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"update ""Users"" set ""DisplayName"" = :displayName, ""Avatar"" = :avatar, ""Flags"" = :flags where ""Id"" = :id", - new - { - id = newUser.Id, - displayName = newUser.DisplayName, - avatar = newUser.Avatar, - flags = newUser.Flags | emailFlag - }); + if (u == null) return; + + var emailFlag = u.Flags.HasFlag(UserFlags.EmailVerified) ? UserFlags.EmailVerified : 0; + u.DisplayName = newUser.DisplayName; + u.Avatar = newUser.Avatar; + u.Flags = newUser.Flags | emailFlag; + await _db.SaveChangesAsync(); } /// public async ValueTask UpdateLastLogin(Guid id, DateTime timestamp) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"update ""Users"" set ""LastLogin"" = :timestamp where ""Id"" = :id", - new {id, timestamp}); + var u = await _db.Users + .FindAsync(id); + + if (u == null) return; + + u.LastLogin = timestamp; + await _db.SaveChangesAsync(); } /// - public async ValueTask AdminUpdateUser(PrivateUser user) + public async ValueTask AdminUpdateUser(User user) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"update ""Users"" set ""Email"" = :email, ""Storage"" = :storage where ""Id"" = :id", - new - { - id = user.Id, - email = user.Email, - storage = user.Storage - }); + var u = await _db.Users + .FindAsync(user.Id); + + if (u == null) return; + + u.Email = user.Email; + u.Storage = user.Storage; + await _db.SaveChangesAsync(); } } diff --git a/VoidCat/Services/Users/PostgresUserUploadStore.cs b/VoidCat/Services/Users/PostgresUserUploadStore.cs index 420f0f5..de9cd3a 100644 --- a/VoidCat/Services/Users/PostgresUserUploadStore.cs +++ b/VoidCat/Services/Users/PostgresUserUploadStore.cs @@ -1,4 +1,4 @@ -using Dapper; +using Microsoft.EntityFrameworkCore; using VoidCat.Model; using VoidCat.Services.Abstractions; @@ -7,46 +7,63 @@ namespace VoidCat.Services.Users; /// public class PostgresUserUploadStore : IUserUploadsStore { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; + private readonly IServiceScopeFactory _scopeFactory; - public PostgresUserUploadStore(PostgresConnectionFactory connection) + public PostgresUserUploadStore(VoidContext db, IServiceScopeFactory scopeFactory) { - _connection = connection; + _db = db; + _scopeFactory = scopeFactory; } public async ValueTask> ListFiles(Guid user, PagedRequest request) { - var query = @"select {0} -from ""UserFiles"" uf, ""Files"" f -where uf.""User"" = :user -and uf.""File"" = f.""Id"""; - var queryOrder = @"order by f.""{1}"" {2} limit :limit offset :offset"; - - await using var conn = await _connection.Get(); - var count = await conn.ExecuteScalarAsync(string.Format(query, "count(*)"), new {user}); + var count = await _db.UserFiles.Where(a => a.UserId == user).CountAsync(); async IAsyncEnumerable EnumerateFiles() { - var orderBy = request.SortBy switch + using var scope = _scopeFactory.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var q = db.UserFiles + .AsNoTracking() + .Include(a => a.File) + .Where(a => a.UserId == user) + .AsQueryable(); + + switch (request.SortBy, request.SortOrder) { - PagedSortBy.Name => "Name", - PagedSortBy.Date => "Uploaded", - PagedSortBy.Size => "Size", - _ => "Id" - }; - var sortOrder = request.SortOrder switch + case (PagedSortBy.Id, PageSortOrder.Asc): + q = q.OrderBy(a => a.FileId); + break; + case (PagedSortBy.Id, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.FileId); + break; + case (PagedSortBy.Name, PageSortOrder.Asc): + q = q.OrderBy(a => a.File.Name); + break; + case (PagedSortBy.Name, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.File.Name); + break; + case (PagedSortBy.Date, PageSortOrder.Asc): + q = q.OrderBy(a => a.File.Uploaded); + break; + case (PagedSortBy.Date, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.File.Uploaded); + break; + case (PagedSortBy.Size, PageSortOrder.Asc): + q = q.OrderBy(a => a.File.Size); + break; + case (PagedSortBy.Size, PageSortOrder.Dsc): + q = q.OrderByDescending(a => a.File.Size); + break; + } + + await foreach (var r in q.Skip(request.Page * request.PageSize) + .Take(request.PageSize) + .Select(a => a.FileId) + .AsAsyncEnumerable()) { - PageSortOrder.Dsc => "desc", - _ => "asc" - }; - await using var connInner = await _connection.Get(); - var files = await connInner.ExecuteReaderAsync( - string.Format(query + queryOrder, "uf.\"File\"", orderBy, sortOrder), - new {user, offset = request.Page * request.PageSize, limit = request.PageSize}); - var rowParser = files.GetRowParser(); - while (await files.ReadAsync()) - { - yield return rowParser(files); + yield return r; } } @@ -62,19 +79,21 @@ and uf.""File"" = f.""Id"""; /// public async ValueTask AddFile(Guid user, Guid file) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"insert into ""UserFiles""(""File"", ""User"") values(:file, :user)", new + _db.UserFiles.Add(new() { - file, - user + UserId = user, + FileId = file }); + + await _db.SaveChangesAsync(); } /// public async ValueTask Uploader(Guid file) { - await using var conn = await _connection.Get(); - return await conn.ExecuteScalarAsync( - @"select ""User"" from ""UserFiles"" where ""File"" = :file", new {file}); + return await _db.UserFiles + .Where(a => a.FileId == file) + .Select(a => a.UserId) + .SingleOrDefaultAsync(); } -} \ No newline at end of file +} diff --git a/VoidCat/Services/Users/UserManager.cs b/VoidCat/Services/Users/UserManager.cs index bd224bc..268e724 100644 --- a/VoidCat/Services/Users/UserManager.cs +++ b/VoidCat/Services/Users/UserManager.cs @@ -1,5 +1,5 @@ +using VoidCat.Database; using VoidCat.Model; -using VoidCat.Model.User; using VoidCat.Services.Abstractions; using VoidCat.Services.Users.Auth; @@ -9,17 +9,14 @@ public class UserManager { private readonly IUserStore _store; private readonly IEmailVerification _emailVerification; - private readonly IUserAuthTokenStore _tokenStore; private readonly OAuthFactory _oAuthFactory; private static bool _checkFirstRegister; - public UserManager(IUserStore store, IEmailVerification emailVerification, OAuthFactory oAuthFactory, - IUserAuthTokenStore tokenStore) + public UserManager(IUserStore store, IEmailVerification emailVerification, OAuthFactory oAuthFactory) { _store = store; _emailVerification = emailVerification; _oAuthFactory = oAuthFactory; - _tokenStore = tokenStore; } /// @@ -29,12 +26,12 @@ public class UserManager /// /// /// - public async ValueTask Login(string email, string password) + public async ValueTask Login(string email, string password) { var userId = await _store.LookupUser(email); if (!userId.HasValue) throw new InvalidOperationException("User does not exist"); - var user = await _store.GetPrivate(userId.Value); + var user = await _store.Get(userId.Value); if (!(user?.CheckPassword(password) ?? false)) throw new InvalidOperationException("User does not exist"); await HandleLogin(user); @@ -48,19 +45,19 @@ public class UserManager /// /// /// - public async ValueTask Register(string email, string password) + public async ValueTask Register(string email, string password) { var existingUser = await _store.LookupUser(email); if (existingUser != Guid.Empty && existingUser != null) throw new InvalidOperationException("User already exists"); - var newUser = new InternalUser + var newUser = new User { Id = Guid.NewGuid(), Email = email, Password = password.HashPassword(), - Created = DateTimeOffset.UtcNow, - LastLogin = DateTimeOffset.UtcNow + Created = DateTime.UtcNow, + LastLogin = DateTime.UtcNow }; await SetupNewUser(newUser); @@ -84,7 +81,7 @@ public class UserManager /// /// /// - public async ValueTask LoginOrRegister(string code, string provider) + public async ValueTask LoginOrRegister(string code, string provider) { var px = _oAuthFactory.GetProvider(provider); var token = await px.GetToken(code); @@ -98,8 +95,8 @@ public class UserManager var uid = await _store.LookupUser(user.Email); if (uid.HasValue) { - var existingUser = await _store.GetPrivate(uid.Value); - if (existingUser?.AuthType == AuthType.OAuth2) + var existingUser = await _store.Get(uid.Value); + if (existingUser?.AuthType == UserAuthType.OAuth2) { return existingUser; } @@ -111,7 +108,7 @@ public class UserManager return user; } - private async Task SetupNewUser(InternalUser newUser) + private async Task SetupNewUser(User newUser) { // automatically set first user to admin if (!_checkFirstRegister) @@ -120,17 +117,21 @@ public class UserManager var users = await _store.ListUsers(new(0, 1)); if (users.TotalResults == 0) { - newUser.Roles.Add(Roles.Admin); + newUser.Roles.Add(new() + { + UserId = newUser.Id, + Role = Roles.Admin + }); } } - await _store.Set(newUser.Id, newUser); + await _store.Add(newUser); await _emailVerification.SendNewCode(newUser); } - private async Task HandleLogin(InternalUser user) + private async Task HandleLogin(User user) { - user.LastLogin = DateTimeOffset.UtcNow; + user.LastLogin = DateTime.UtcNow; await _store.UpdateLastLogin(user.Id, DateTime.UtcNow); } } \ No newline at end of file diff --git a/VoidCat/Services/VirusScanner/CacheVirusScanStore.cs b/VoidCat/Services/VirusScanner/CacheVirusScanStore.cs index 6c9e143..070fa10 100644 --- a/VoidCat/Services/VirusScanner/CacheVirusScanStore.cs +++ b/VoidCat/Services/VirusScanner/CacheVirusScanStore.cs @@ -1,4 +1,4 @@ -using VoidCat.Model; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.VirusScanner; @@ -14,13 +14,13 @@ public class CacheVirusScanStore : BasicCacheStore, IVirusScanS public override async ValueTask Add(Guid id, VirusScanResult obj) { await base.Add(id, obj); - await _cache.AddToList(MapFilesKey(id), obj.Id.ToString()); + await Cache.AddToList(MapFilesKey(id), obj.Id.ToString()); } /// public async ValueTask GetByFile(Guid id) { - var scans = await _cache.GetList(MapFilesKey(id)); + var scans = await Cache.GetList(MapFilesKey(id)); if (scans.Length > 0) { return await Get(Guid.Parse(scans.Last())); diff --git a/VoidCat/Services/VirusScanner/ClamAvScanner.cs b/VoidCat/Services/VirusScanner/ClamAvScanner.cs index c564e37..a2ed29e 100644 --- a/VoidCat/Services/VirusScanner/ClamAvScanner.cs +++ b/VoidCat/Services/VirusScanner/ClamAvScanner.cs @@ -1,4 +1,5 @@ using nClam; +using VoidCat.Database; using VoidCat.Model; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; @@ -37,7 +38,7 @@ public class ClamAvScanner : IVirusScanner return new() { Id = Guid.NewGuid(), - File = id, + FileId = id, Score = result.Result == ClamScanResults.VirusDetected ? 1m : 0m, Names = string.Join(",", result.InfectedFiles?.Select(a => a.VirusName.Trim()) ?? Array.Empty()), Scanner = "ClamAV" diff --git a/VoidCat/Services/VirusScanner/PostgresVirusScanStore.cs b/VoidCat/Services/VirusScanner/PostgresVirusScanStore.cs index eb1dfd3..919e22e 100644 --- a/VoidCat/Services/VirusScanner/PostgresVirusScanStore.cs +++ b/VoidCat/Services/VirusScanner/PostgresVirusScanStore.cs @@ -1,5 +1,5 @@ -using Dapper; -using VoidCat.Model; +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; using VoidCat.Services.Abstractions; namespace VoidCat.Services.VirusScanner; @@ -7,49 +7,43 @@ namespace VoidCat.Services.VirusScanner; /// public class PostgresVirusScanStore : IVirusScanStore { - private readonly PostgresConnectionFactory _connection; + private readonly VoidContext _db; - public PostgresVirusScanStore(PostgresConnectionFactory connection) + public PostgresVirusScanStore(VoidContext db) { - _connection = connection; + _db = db; } /// public async ValueTask Get(Guid id) { - await using var conn = await _connection.Get(); - return await conn.QueryFirstOrDefaultAsync( - @"select * from ""VirusScanResult"" where ""Id"" = :id order by ""ScanTime"" desc", new {id}); + return await _db.VirusScanResults + .AsNoTracking() + .FirstOrDefaultAsync(a => a.Id == id); } /// public async ValueTask GetByFile(Guid id) { - await using var conn = await _connection.Get(); - return await conn.QueryFirstOrDefaultAsync( - @"select * from ""VirusScanResult"" where ""File"" = :file order by ""ScanTime"" desc", new {file = id}); + return await _db.VirusScanResults + .AsNoTracking() + .Where(a => a.FileId == id) + .OrderByDescending(a => a.ScanTime) + .FirstOrDefaultAsync(); } /// public async ValueTask Add(Guid id, VirusScanResult obj) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync( - @"insert into ""VirusScanResult""(""Id"", ""File"", ""Scanner"", ""Score"", ""Names"") values(:id, :file, :scanner, :score, :names)", - new - { - id, - file = obj.File, - scanner = obj.Scanner, - score = obj.Score, - names = obj.Names - }); + _db.VirusScanResults.Add(obj); + await _db.SaveChangesAsync(); } /// public async ValueTask Delete(Guid id) { - await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"delete from ""VirusScanResult"" where ""Id"" = :id", new {id}); + await _db.VirusScanResults + .Where(a => a.Id == id) + .ExecuteDeleteAsync(); } -} \ No newline at end of file +} diff --git a/VoidCat/Services/VoidContext.cs b/VoidCat/Services/VoidContext.cs new file mode 100644 index 0000000..0f76a7d --- /dev/null +++ b/VoidCat/Services/VoidContext.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; +using VoidCat.Database; +using File = VoidCat.Database.File; + +namespace VoidCat.Services; + +public class VoidContext : DbContext +{ + public VoidContext() + { + } + + public VoidContext(DbContextOptions ctx) : base(ctx) + { + } + + public DbSet Users => Set(); + public DbSet Files => Set(); + public DbSet VirusScanResults => Set(); + public DbSet Paywalls => Set(); + public DbSet PaywallOrders => Set(); + public DbSet UserAuthTokens => Set(); + public DbSet ApiKeys => Set(); + public DbSet EmailVerifications => Set(); + public DbSet UserFiles => Set(); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfigurationsFromAssembly(typeof(VoidContext).Assembly); + } +} diff --git a/VoidCat/VoidCat.csproj b/VoidCat/VoidCat.csproj index 0c42610..49afa01 100644 --- a/VoidCat/VoidCat.csproj +++ b/VoidCat/VoidCat.csproj @@ -7,22 +7,30 @@ Linux spa\ $(DefaultItemExcludes);$(SpaRoot)node_modules\** - True - $(DefineConstants);HostSPA $(AssemblyName).xml - 4.2.0 + 5.0.0 + CS1591 - + - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + @@ -32,12 +40,16 @@ + + + + @@ -61,27 +73,13 @@ - - - - - - - - - - - - - - - - + <_CopyItems Include="$(SpaRoot)build\**\*.*" /> + $(Value) @@ -92,6 +90,9 @@ + + + diff --git a/VoidCat/VoidStartup.cs b/VoidCat/VoidStartup.cs index d7ea51f..04d71c1 100644 --- a/VoidCat/VoidStartup.cs +++ b/VoidCat/VoidStartup.cs @@ -1,13 +1,10 @@ -using System.Data; -using System.Reflection; +using System.Reflection; using System.Text; -using FluentMigrator.Runner; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.HttpLogging; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Newtonsoft.Json; -using Npgsql; using StackExchange.Redis; using VoidCat.Model; using VoidCat.Services; @@ -35,24 +32,6 @@ public static class VoidStartup var cx = ConnectionMultiplexer.Connect(voidSettings.Redis!); services.AddSingleton(cx); services.AddSingleton(cx.GetDatabase()); - } - - if (voidSettings.HasPostgres()) - { - services.AddSingleton(); - services.AddTransient(_ => new NpgsqlConnection(voidSettings.Postgres)); - - // fluent migrations - services.AddTransient(); - services.AddFluentMigratorCore() - .ConfigureRunner(r => - r.AddPostgres() - .WithGlobalConnectionString(voidSettings.Postgres) - .ScanIn(typeof(Program).Assembly).For.Migrations()); - } - - if (voidSettings.HasRedis()) - { services.AddTransient(); } else @@ -187,13 +166,10 @@ public static class VoidStartup public static void AddMigrations(this IServiceCollection services, VoidSettings voidSettings) { - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - if (voidSettings.HasRedis()) + if (voidSettings.HasPostgres()) { - services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } } @@ -202,6 +178,8 @@ public static class VoidStartup s.NullValueHandling = NullValueHandling.Ignore; s.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; s.MissingMemberHandling = MissingMemberHandling.Ignore; + s.Converters = new List {new Base58GuidConverter()}; + s.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; return s; } } diff --git a/VoidCat/appsettings.Development.json b/VoidCat/appsettings.Development.json deleted file mode 100644 index 770d3e9..0000000 --- a/VoidCat/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "DetailedErrors": true, - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/VoidCat/appsettings.json b/VoidCat/appsettings.json index fd8cefa..8991dca 100644 --- a/VoidCat/appsettings.json +++ b/VoidCat/appsettings.json @@ -8,6 +8,9 @@ "AllowedHosts": "*", "Settings": { "SiteUrl": "http://localhost:7195", - "DataDirectory": "./data" + "DataDirectory": "./data", + "CorsOrigins": [ + "http://localhost:3000" + ] } } diff --git a/VoidCat/spa/d.ts b/VoidCat/spa/d.ts new file mode 100644 index 0000000..acdf689 --- /dev/null +++ b/VoidCat/spa/d.ts @@ -0,0 +1,4 @@ +declare module "*.png" { + const value: string; + export default value; +} \ No newline at end of file diff --git a/VoidCat/spa/package.json b/VoidCat/spa/package.json index afd5c7f..bc37623 100644 --- a/VoidCat/spa/package.json +++ b/VoidCat/spa/package.json @@ -6,20 +6,27 @@ "dependencies": { "@hcaptcha/react-hcaptcha": "^1.1.1", "@reduxjs/toolkit": "^1.7.2", - "feather-icons-react": "^0.5.0", + "@types/node": "^18.16.3", + "@types/qrcode.react": "^1.0.2", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.1", + "@types/sjcl": "^1.0.30", "moment": "^2.29.4", "qrcode.react": "^1.0.1", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-helmet": "^6.1.0", "react-redux": "^7.2.6", "react-router-dom": "^6.2.1", "react-scripts": "5.0.0", "recharts": "^2.1.10", - "sjcl": "^1.0.8" + "sjcl": "^1.0.8", + "typescript": "^5.0.4" }, "devDependencies": { "@craco/craco": "^6.4.5", + "@types/preval.macro": "^3.0.0", + "@types/react-helmet": "^6.1.6", "cra-bundle-analyzer": "^0.1.1", "http-proxy-middleware": "^2.0.6", "preval.macro": "^5.0.0" diff --git a/VoidCat/spa/public/icons.svg b/VoidCat/spa/public/icons.svg new file mode 100644 index 0000000..5e3228a --- /dev/null +++ b/VoidCat/spa/public/icons.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VoidCat/spa/src/Admin/Admin.js b/VoidCat/spa/src/Admin/Admin.tsx similarity index 58% rename from VoidCat/spa/src/Admin/Admin.js rename to VoidCat/spa/src/Admin/Admin.tsx index 79a99a4..1093dae 100644 --- a/VoidCat/spa/src/Admin/Admin.js +++ b/VoidCat/spa/src/Admin/Admin.tsx @@ -5,22 +5,25 @@ import {Navigate} from "react-router-dom"; import {FileList} from "../Components/Shared/FileList"; import {UserList} from "./UserList"; -import {useApi} from "../Components/Shared/Api"; import {VoidButton} from "../Components/Shared/VoidButton"; import VoidModal from "../Components/Shared/VoidModal"; import EditUser from "./EditUser"; +import useApi from "Hooks/UseApi"; +import {RootState} from "Store"; +import {AdminProfile} from "../Api"; + export function Admin() { - const auth = useSelector((state) => state.login.jwt); - const {AdminApi} = useApi(); - const [editUser, setEditUser] = useState(null); + const auth = useSelector((state: RootState) => state.login.jwt); + const AdminApi = useApi(); + const [editUser, setEditUser] = useState(); - async function deleteFile(e, id) { + async function deleteFile(id: string) { if (window.confirm(`Are you sure you want to delete: ${id}?`)) { - let req = await AdminApi.deleteFile(id); - if (req.ok) { - - } else { + try { + await AdminApi.adminDeleteFile(id); + } catch (e) { + console.error(e); alert("Failed to delete file!"); } } @@ -34,20 +37,20 @@ export function Admin() {

Users

[ Delete, - setEditUser(i)}>Edit + setEditUser(i)}>Edit ]}/>

Files

- { + AdminApi.adminListFiles(r)} actions={(i) => { return - deleteFile(e, i.id)}>Delete + deleteFile(i.id)}>Delete }}/> - {editUser !== null ? + {editUser && - setEditUser(null)}/> - : null} + setEditUser(undefined)}/> + } ); } diff --git a/VoidCat/spa/src/Admin/EditUser.js b/VoidCat/spa/src/Admin/EditUser.tsx similarity index 64% rename from VoidCat/spa/src/Admin/EditUser.js rename to VoidCat/spa/src/Admin/EditUser.tsx index a02fd72..9de2375 100644 --- a/VoidCat/spa/src/Admin/EditUser.js +++ b/VoidCat/spa/src/Admin/EditUser.tsx @@ -1,20 +1,21 @@ import {useState} from "react"; import {useSelector} from "react-redux"; -import {useApi} from "../Components/Shared/Api"; + import {VoidButton} from "../Components/Shared/VoidButton"; +import useApi from "Hooks/UseApi"; +import {AdminProfile} from "Api"; +import {RootState} from "Store"; -export default function EditUser(props) { - const user = props.user; - const onClose = props.onClose; +export default function EditUser({user, onClose}: {user: AdminProfile, onClose: () => void}) { - const adminApi = useApi().AdminApi; - const fileStores = useSelector((state) => state.info?.info?.fileStores ?? ["local-disk"]) + const adminApi = useApi(); + const fileStores = useSelector((state: RootState) => state.info?.info?.fileStores ?? ["local-disk"]) const [storage, setStorage] = useState(user.storage); const [email, setEmail] = useState(user.email); async function updateUser() { - await adminApi.updateUser({ - id: user.id, + await adminApi.adminUpdateUser({ + ...user, email, storage }); @@ -23,7 +24,7 @@ export default function EditUser(props) { return ( <> - Editing user '{user.displayName}' ({user.id}) + Editing user '{user.name}' ({user.id})
Email:
setEmail(e.target.value)}/>
@@ -39,8 +40,8 @@ export default function EditUser(props) {
Roles:
{user.roles.map(e => {e})}
- updateUser()}>Save - onClose()}>Cancel + updateUser()}>Save + onClose()}>Cancel ); } \ No newline at end of file diff --git a/VoidCat/spa/src/Admin/UserList.js b/VoidCat/spa/src/Admin/UserList.js deleted file mode 100644 index 74b8bfb..0000000 --- a/VoidCat/spa/src/Admin/UserList.js +++ /dev/null @@ -1,83 +0,0 @@ -import {useDispatch} from "react-redux"; -import {useEffect, useState} from "react"; -import moment from "moment"; -import {PagedSortBy, PageSortOrder} from "../Components/Shared/Const"; -import {useApi} from "../Components/Shared/Api"; -import {logout} from "../LoginState"; -import {PageSelector} from "../Components/Shared/PageSelector"; - -export function UserList(props) { - const {AdminApi} = useApi(); - const dispatch = useDispatch(); - const [users, setUsers] = useState(); - const [page, setPage] = useState(0); - const pageSize = 10; - const [accessDenied, setAccessDenied] = useState(); - const actions = props.actions; - - async function loadUserList() { - let pageReq = { - page: page, - pageSize, - sortBy: PagedSortBy.Date, - sortOrder: PageSortOrder.Dsc - }; - let req = await AdminApi.userList(pageReq); - if (req.ok) { - setUsers(await req.json()); - } else if (req.status === 401) { - dispatch(logout()); - } else if (req.status === 403) { - setAccessDenied(true); - } - } - - function renderUser(obj) { - const user = obj.user; - return ( - - {user.displayName} - {moment(user.created).fromNow()} - {moment(user.lastLogin).fromNow()} - {obj.uploads} - {actions(user)} - - ); - } - - useEffect(() => { - loadUserList(); - }, [page]); - - if (accessDenied === true) { - return

Access Denied

; - } - - return ( - - - - - - - - - - - - {users ? users.results.map(renderUser) : null} - - - - - - -
NameCreatedLast LoginFilesActions
- {users ? setPage(x)} - page={page} - total={users.totalResults} - pageSize={pageSize}/> : null} -
- ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Admin/UserList.tsx b/VoidCat/spa/src/Admin/UserList.tsx new file mode 100644 index 0000000..598ac61 --- /dev/null +++ b/VoidCat/spa/src/Admin/UserList.tsx @@ -0,0 +1,93 @@ +import {useDispatch} from "react-redux"; +import {ReactNode, useEffect, useState} from "react"; +import moment from "moment"; + +import {logout} from "../LoginState"; +import {PageSelector} from "../Components/Shared/PageSelector"; + +import useApi from "Hooks/UseApi"; +import {AdminProfile, AdminUserListResult, ApiError, PagedResponse, PagedSortBy, PageSortOrder} from "Api"; + +interface UserListProps { + actions: (u: AdminProfile) => ReactNode +} + +export function UserList({actions}: UserListProps) { + const AdminApi = useApi(); + const dispatch = useDispatch(); + + const [users, setUsers] = useState>(); + const [page, setPage] = useState(0); + const pageSize = 10; + const [accessDenied, setAccessDenied] = useState(); + + async function loadUserList() { + try { + const pageReq = { + page: page, + pageSize, + sortBy: PagedSortBy.Date, + sortOrder: PageSortOrder.Dsc + }; + const rsp = await AdminApi.adminUserList(pageReq); + setUsers(rsp); + } catch (e) { + console.error(e); + if (e instanceof ApiError) { + if (e.statusCode === 401) { + dispatch(logout()); + } else if (e.statusCode === 403) { + setAccessDenied(true); + } + } + } + } + + function renderUser(r: AdminUserListResult) { + return ( + + {r.user.name} + {moment(r.user.created).fromNow()} + {moment(r.user.lastLogin).fromNow()} + {r.uploads} + {actions(r.user)} + + ); + } + + useEffect(() => { + loadUserList().catch(console.error); + }, [page]); + + if (accessDenied === true) { + return

Access Denied

; + } + + return ( + + + + + + + + + + + + {users && users.results.map(renderUser)} + + + + + + +
NameCreatedLast LoginFilesActions
+ {users && setPage(x)} + page={page} + total={users.totalResults} + pageSize={pageSize}/>} +
+ ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Api/Api.ts b/VoidCat/spa/src/Api/Api.ts new file mode 100644 index 0000000..81371df --- /dev/null +++ b/VoidCat/spa/src/Api/Api.ts @@ -0,0 +1,145 @@ +import { + AdminProfile, AdminUserListResult, + ApiError, ApiKey, + LoginSession, + PagedRequest, + PagedResponse, + PaymentOrder, + Profile, SetPaymentConfigRequest, + SiteInfoResponse, + VoidFileResponse +} from "./index"; +import {ProgressHandler, ProxyChallengeHandler, StateChangeHandler, VoidUploader} from "./Upload"; +import {StreamUploader} from "./StreamUploader"; +import {XHRUploader} from "./XHRUploader"; + +export class VoidApi { + readonly #uri: string + readonly #auth?: string + + constructor(uri: string, auth?: string) { + this.#uri = uri; + this.#auth = auth; + } + + async #req(method: string, url: string, body?: object): Promise { + let headers: HeadersInit = { + "Accept": "application/json" + }; + if (this.#auth) { + headers["Authorization"] = `Bearer ${this.#auth}`; + } + if (body) { + headers["Content-Type"] = "application/json"; + } + + const res = await fetch(`${this.#uri}${url}`, { + method, + headers, + mode: "cors", + body: body ? JSON.stringify(body) : undefined + }); + const text = await res.text(); + if (res.ok) { + return text ? JSON.parse(text) as T : {} as T; + } else { + throw new ApiError(res.status, text); + } + } + + /** + * Get uploader for uploading files + */ + getUploader( + file: File | Blob, + stateChange: StateChangeHandler, + progress: ProgressHandler, + proxyChallenge: ProxyChallengeHandler, + chunkSize?: number + ): VoidUploader { + if (StreamUploader.canUse()) { + return new StreamUploader(this.#uri, file, stateChange, progress, proxyChallenge, this.#auth, chunkSize); + } else { + return new XHRUploader(this.#uri, file, stateChange, progress, proxyChallenge, this.#auth, chunkSize); + } + } + + /** + * General site information + */ + info() { + return this.#req("GET", "/info") + } + + fileInfo(id: string) { + return this.#req("GET", `/upload/${id}`); + } + + setPaymentConfig(id: string, cfg: SetPaymentConfigRequest) { + return this.#req("POST", `/upload/${id}/payment`, cfg); + } + + createOrder(id: string) { + return this.#req("GET", `/upload/${id}/payment`); + } + + getOrder(file: string, order: string) { + return this.#req("GET", `/upload/${file}/payment/${order}`); + } + + login(username: string, password: string, captcha?: string) { + return this.#req("POST", `/auth/login`, {username, password, captcha}); + } + + register(username: string, password: string, captcha?: string) { + return this.#req("POST", `/auth/register`, {username, password, captcha}); + } + + getUser(id: string) { + return this.#req("GET", `/user/${id}`); + } + + updateUser(u: Profile) { + return this.#req("POST", `/user/${u.id}`, u); + } + + listUserFiles(uid: string, pageReq: PagedRequest) { + return this.#req>("POST", `/user/${uid}/files`, pageReq); + } + + submitVerifyCode(uid: string, code: string) { + return this.#req("POST", `/user/${uid}/verify`, {code}); + } + + sendNewCode(uid: string) { + return this.#req("GET", `/user/${uid}/verify`); + } + + updateFileMetadata(id: string, meta: any) { + return this.#req("POST", `/upload/${id}/meta`, meta); + } + + listApiKeys() { + return this.#req>("GET", `/auth/api-key`); + } + + createApiKey(req: any) { + return this.#req("POST", `/auth/api-key`, req); + } + + adminListFiles(pageReq: PagedRequest) { + return this.#req>("POST", "/admin/file", pageReq); + } + + adminDeleteFile(id: string) { + return this.#req("DELETE", `/admin/file/${id}`); + } + + adminUserList(pageReq: PagedRequest) { + return this.#req>("POST", `/admin/users`, pageReq); + } + + adminUpdateUser(u: AdminProfile) { + return this.#req("POST", `/admin/update-user`, u); + } +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/StreamEncryption.js b/VoidCat/spa/src/Api/StreamEncryption.ts similarity index 55% rename from VoidCat/spa/src/Components/Shared/StreamEncryption.js rename to VoidCat/spa/src/Api/StreamEncryption.ts index 721a6a2..b999635 100644 --- a/VoidCat/spa/src/Components/Shared/StreamEncryption.js +++ b/VoidCat/spa/src/Api/StreamEncryption.ts @@ -1,15 +1,27 @@ -import {sjclcodec} from "../../codecBytes"; -import sjcl from "sjcl"; -import {buf2hex} from "./Util"; +import {sjclcodec} from "./codecBytes"; +import sjcl, {SjclCipher} from "sjcl"; + +import {buf2hex} from "Util"; + +interface EncryptionParams { + ts: number, + cs: number +} /** * AES-GCM TransformStream */ export class StreamEncryption { - constructor(key, iv, params) { - if (key === undefined && iv === undefined) { - key = buf2hex(window.crypto.getRandomValues(new Uint8Array(16))); - iv = buf2hex(window.crypto.getRandomValues(new Uint8Array(12))); + readonly #tagSize: number; + readonly #chunkSize: number; + readonly #aes: SjclCipher; + readonly #key: sjcl.BitArray; + readonly #iv: sjcl.BitArray; + + constructor(key: string | sjcl.BitArray | undefined, iv: string | sjcl.BitArray | undefined, params?: EncryptionParams | string) { + if (!key && !iv) { + key = buf2hex(globalThis.crypto.getRandomValues(new Uint8Array(16))); + iv = buf2hex(globalThis.crypto.getRandomValues(new Uint8Array(12))); } if (typeof key === "string" && typeof iv === "string") { key = sjcl.codec.hex.toBits(key); @@ -18,40 +30,37 @@ export class StreamEncryption { throw "Key and IV must be hex string or bitArray"; } if (typeof params === "string") { - params = JSON.parse(params); + params = JSON.parse(params) as EncryptionParams; } - this.TagSize = params?.ts ?? 128; - this.ChunkSize = params?.cs ?? (1024 * 1024 * 10); - this.aes = new sjcl.cipher.aes(key); - this.key = key; - this.iv = iv; + this.#tagSize = params?.ts ?? 128; + this.#chunkSize = params?.cs ?? (1024 * 1024 * 10); + this.#aes = new sjcl.cipher.aes(key); + this.#key = key; + this.#iv = iv; - console.log(`ts=${this.TagSize}, cs=${this.ChunkSize}, key=${key}, iv=${this.iv}`); + console.log(`ts=${this.#tagSize}, cs=${this.#chunkSize}, key=${key}, iv=${this.#iv}`); } /** * Return formatted encryption key - * @returns {string} */ getKey() { - return `${sjcl.codec.hex.fromBits(this.key)}:${sjcl.codec.hex.fromBits(this.iv)}`; + return `${sjcl.codec.hex.fromBits(this.#key)}:${sjcl.codec.hex.fromBits(this.#iv)}`; } - + /** * Get encryption params - * @returns {{cs: (*|number), ts: number}} */ getParams() { return { - ts: this.TagSize, - cs: this.ChunkSize + ts: this.#tagSize, + cs: this.#chunkSize } } /** * Get encryption TransformStream - * @returns {TransformStream} */ getEncryptionTransform() { return this._getCryptoStream(0); @@ -59,16 +68,15 @@ export class StreamEncryption { /** * Get decryption TransformStream - * @returns {TransformStream} */ getDecryptionTransform() { return this._getCryptoStream(1); } - _getCryptoStream(mode) { + _getCryptoStream(mode: number) { let offset = 0; - let buffer = new Uint8Array(this.ChunkSize + (mode === 1 ? this.TagSize / 8 : 0)); - return new window.TransformStream({ + let buffer = new Uint8Array(this.#chunkSize + (mode === 1 ? this.#tagSize / 8 : 0)); + return new TransformStream({ transform: async (chunk, controller) => { chunk = await chunk; try { @@ -80,8 +88,8 @@ export class StreamEncryption { let buff = sjclcodec.toBits(buffer); let encryptedBuf = sjclcodec.fromBits( mode === 0 ? - sjcl.mode.gcm.encrypt(this.aes, buff, this.iv, [], this.TagSize) : - sjcl.mode.gcm.decrypt(this.aes, buff, this.iv, [], this.TagSize) + sjcl.mode.gcm.encrypt(this.#aes, buff, this.#iv, [], this.#tagSize) : + sjcl.mode.gcm.decrypt(this.#aes, buff, this.#iv, [], this.#tagSize) ); controller.enqueue(new Uint8Array(encryptedBuf)); @@ -98,13 +106,13 @@ export class StreamEncryption { let buff = sjclcodec.toBits(lastBuffer); let encryptedBuf = sjclcodec.fromBits( mode === 0 ? - sjcl.mode.gcm.encrypt(this.aes, buff, this.iv, [], this.TagSize) : - sjcl.mode.gcm.decrypt(this.aes, buff, this.iv, [], this.TagSize) + sjcl.mode.gcm.encrypt(this.#aes, buff, this.#iv, [], this.#tagSize) : + sjcl.mode.gcm.decrypt(this.#aes, buff, this.#iv, [], this.#tagSize) ); controller.enqueue(new Uint8Array(encryptedBuf)); } }, { - highWaterMark: this.ChunkSize + highWaterMark: this.#chunkSize }); } } \ No newline at end of file diff --git a/VoidCat/spa/src/Api/StreamUploader.ts b/VoidCat/spa/src/Api/StreamUploader.ts new file mode 100644 index 0000000..9f5b0ae --- /dev/null +++ b/VoidCat/spa/src/Api/StreamUploader.ts @@ -0,0 +1,95 @@ +import {UploadState, VoidUploader} from "./Upload"; +import {VoidUploadResult} from "./index"; +import {StreamEncryption} from "./StreamEncryption"; + +export class StreamUploader extends VoidUploader { + #encrypt?: StreamEncryption; + + static canUse() { + const rawUA = globalThis.navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); + const majorVersion = rawUA ? parseInt(rawUA[2], 10) : 0; + return majorVersion >= 105 && "getRandomValues" in globalThis.crypto && globalThis.location.protocol === "https:"; + } + + canEncrypt(): boolean { + return true; + } + + setEncryption(s: boolean) { + if (s) { + this.#encrypt = new StreamEncryption(undefined, undefined, undefined); + } else { + this.#encrypt = undefined; + } + } + + getEncryptionKey() { + return this.#encrypt?.getKey() + } + + async upload(): Promise { + this.onStateChange(UploadState.Hashing); + const hash = await this.digest(this.file); + let offset = 0; + + const DefaultChunkSize = 1024 * 1024; + const rsBase = new ReadableStream({ + start: async () => { + this.onStateChange(UploadState.Uploading); + }, + pull: async (controller) => { + const chunk = await this.readChunk(offset, controller.desiredSize ?? DefaultChunkSize); + if (chunk.byteLength === 0) { + controller.close(); + return; + } + this.onProgress(offset + chunk.byteLength); + offset += chunk.byteLength + controller.enqueue(chunk); + }, + cancel: (reason) => { + console.log(reason); + }, + type: "bytes" + }, { + highWaterMark: DefaultChunkSize + }); + + const headers = { + "Content-Type": "application/octet-stream", + "V-Content-Type": !this.file.type ? "application/octet-stream" : this.file.type, + "V-Filename": this.file.name, + "V-Full-Digest": hash + } as Record; + if (this.#encrypt) { + headers["V-EncryptionParams"] = JSON.stringify(this.#encrypt!.getParams()); + } + if (this.auth) { + headers["Authorization"] = `Bearer ${this.auth}`; + } + const req = await fetch(`${this.uri}/upload`, { + method: "POST", + mode: "cors", + body: this.#encrypt ? rsBase.pipeThrough(this.#encrypt!.getEncryptionTransform()) : rsBase, + headers, + // @ts-ignore New stream spec + duplex: 'half' + }); + + if (req.ok) { + return await req.json() as VoidUploadResult; + } else { + throw new Error("Unknown error"); + } + } + + async readChunk(offset: number, size: number) { + if (offset > this.file.size) { + return new Uint8Array(0); + } + const end = Math.min(offset + size, this.file.size); + const blob = this.file.slice(offset, end, this.file.type); + const data = await blob.arrayBuffer(); + return new Uint8Array(data); + } +} \ No newline at end of file diff --git a/VoidCat/spa/src/Api/Upload.ts b/VoidCat/spa/src/Api/Upload.ts new file mode 100644 index 0000000..8eaca92 --- /dev/null +++ b/VoidCat/spa/src/Api/Upload.ts @@ -0,0 +1,90 @@ +import {VoidUploadResult} from "./index"; +import sjcl from "sjcl"; +import {sjclcodec} from "./codecBytes"; +import {buf2hex} from "../Util"; + +/** + * Generic upload state + */ +export enum UploadState { + NotStarted, + Starting, + Hashing, + Uploading, + Done, + Failed, + Challenge +} + +export type StateChangeHandler = (s: UploadState) => void; +export type ProgressHandler = (loaded: number) => void; +export type ProxyChallengeHandler = (html: string) => void; + +/** + * Base file uploader class + */ +export abstract class VoidUploader { + protected uri: string; + protected file: File | Blob; + protected auth?: string; + protected maxChunkSize: number; + protected onStateChange: StateChangeHandler; + protected onProgress: ProgressHandler; + protected onProxyChallenge: ProxyChallengeHandler; + + constructor( + uri: string, + file: File | Blob, + stateChange: StateChangeHandler, + progress: ProgressHandler, + proxyChallenge: ProxyChallengeHandler, + auth?: string, + chunkSize?: number + ) { + this.uri = uri; + this.file = file; + this.onStateChange = stateChange; + this.onProgress = progress; + this.onProxyChallenge = proxyChallenge; + this.auth = auth; + this.maxChunkSize = chunkSize ?? Number.MAX_VALUE; + } + + /** + * SHA-256 hash the entire blob + * @param file + * @protected + */ + protected async digest(file: Blob) { + const ChunkSize = 1024 * 1024; + + // must compute hash in chunks, subtle crypto cannot hash files > 2Gb + const sha = new sjcl.hash.sha256(); + let progress = 0; + for (let x = 0; x < Math.ceil(file.size / ChunkSize); x++) { + const offset = x * ChunkSize; + const slice = file.slice(offset, offset + ChunkSize); + const chunk = await slice.arrayBuffer(); + sha.update(sjclcodec.toBits(new Uint8Array(chunk))); + this.onProgress(progress += chunk.byteLength); + } + return buf2hex(sjclcodec.fromBits(sha.finalize())); + } + + abstract upload(): Promise; + + /** + * Can we use local encryption + */ + abstract canEncrypt(): boolean; + + /** + * Enable/Disable encryption, file will be encrypted on the fly locally before uploading + */ + abstract setEncryption(s: boolean): void; + + /** + * Get the encryption key, should be called after enableEncryption() + */ + abstract getEncryptionKey(): string | undefined; +} \ No newline at end of file diff --git a/VoidCat/spa/src/Api/XHRUploader.ts b/VoidCat/spa/src/Api/XHRUploader.ts new file mode 100644 index 0000000..f7753bb --- /dev/null +++ b/VoidCat/spa/src/Api/XHRUploader.ts @@ -0,0 +1,93 @@ +import {UploadState, VoidUploader} from "./Upload"; +import {VoidUploadResult} from "./index"; + +export class XHRUploader extends VoidUploader { + canEncrypt(): boolean { + return false; + } + + setEncryption() { + //noop + } + + getEncryptionKey() { + return undefined; + } + + async upload(): Promise { + this.onStateChange(UploadState.Hashing); + const hash = await this.digest(this.file); + if (this.file.size > this.maxChunkSize) { + return await this.#doSplitXHRUpload(hash, this.maxChunkSize); + } else { + return await this.#xhrSegment(this.file, hash); + } + } + + async #doSplitXHRUpload(hash: string, splitSize: number) { + let xhr = null; + const segments = Math.ceil(this.file.size / splitSize); + for (let s = 0; s < segments; s++) { + const offset = s * splitSize; + const slice = this.file.slice(offset, offset + splitSize, this.file.type); + xhr = await this.#xhrSegment(slice, hash, xhr?.file?.id, xhr?.file?.metadata?.editSecret, s + 1, segments); + if (!xhr.ok) { + break; + } + } + return xhr!; + } + + /** + * Upload a segment of the file + * @param segment + * @param fullDigest Full file hash + * @param id + * @param editSecret + * @param part Segment number + * @param partOf Total number of segments + */ + async #xhrSegment(segment: ArrayBuffer | Blob, fullDigest: string, id?: string, editSecret?: string, part?: number, partOf?: number) { + this.onStateChange(UploadState.Uploading); + + return await new Promise((resolve, reject) => { + try { + const req = new XMLHttpRequest(); + req.onreadystatechange = () => { + if (req.readyState === XMLHttpRequest.DONE && req.status === 200) { + const rsp = JSON.parse(req.responseText) as VoidUploadResult; + resolve(rsp); + } else if (req.readyState === XMLHttpRequest.DONE && req.status === 403) { + const contentType = req.getResponseHeader("content-type"); + if (contentType?.toLowerCase().trim().indexOf("text/html") === 0) { + this.onProxyChallenge(req.response); + this.onStateChange(UploadState.Challenge); + reject(new Error("CF Challenge")); + } + } + }; + req.upload.onprogress = (e) => { + if (e instanceof ProgressEvent) { + this.onProgress(e.loaded); + } + }; + req.open("POST", id ? `${this.uri}/upload/${id}` : `${this.uri}/upload`); + req.setRequestHeader("Content-Type", "application/octet-stream"); + req.setRequestHeader("V-Content-Type", !this.file.type ? "application/octet-stream" : this.file.type); + req.setRequestHeader("V-Filename", this.file.name); + req.setRequestHeader("V-Full-Digest", fullDigest); + req.setRequestHeader("V-Segment", `${part}/${partOf}`) + if (this.auth) { + req.withCredentials = true; + req.setRequestHeader("Authorization", `Bearer ${this.auth}`); + } + if (editSecret) { + req.setRequestHeader("V-EditSecret", editSecret); + } + req.send(segment); + } catch (e) { + reject(e); + } + }); + } +} \ No newline at end of file diff --git a/VoidCat/spa/src/codecBytes.js b/VoidCat/spa/src/Api/codecBytes.js similarity index 100% rename from VoidCat/spa/src/codecBytes.js rename to VoidCat/spa/src/Api/codecBytes.js diff --git a/VoidCat/spa/src/Api/index.ts b/VoidCat/spa/src/Api/index.ts new file mode 100644 index 0000000..47da9ae --- /dev/null +++ b/VoidCat/spa/src/Api/index.ts @@ -0,0 +1,174 @@ +export {VoidApi} from "./Api" +export {UploadState} from "./Upload"; +export {StreamEncryption} from "./StreamEncryption"; + +export class ApiError extends Error { + readonly statusCode: number + + constructor(statusCode: number, msg: string) { + super(msg); + this.statusCode = statusCode; + } +} + +export interface LoginSession { + jwt?: string + profile?: Profile + error?: string +} + +export interface AdminUserListResult { + user: AdminProfile + uploads: number +} + +export interface Profile { + id: string + avatar?: string + name?: string + created: string + lastLogin: string + roles: Array + publicProfile: boolean + publicUploads: boolean + needsVerification?: boolean +} + +export interface PagedResponse { + totalResults: number, + results: Array +} + +export interface AdminProfile extends Profile { + email: string + storage: string +} + +export interface Bandwidth { + ingress: number + egress: number +} + +export interface BandwidthPoint { + time: string + ingress: number + egress: number +} + +export interface SiteInfoResponse { + count: number + totalBytes: number + buildInfo: { + version: string + gitHash: string + buildTime: string + } + bandwidth: Bandwidth + fileStores: Array + uploadSegmentSize: number + captchaSiteKey?: string + oAuthProviders: Array + timeSeriesMetrics?: Array +} + +export interface PagedRequest { + pageSize: number + page: number +} + +export interface VoidUploadResult { + ok: boolean + file?: VoidFileResponse + errorMessage?: string +} + +export interface VoidFileResponse { + id: string, + metadata?: VoidFileMeta + payment?: Payment + uploader?: Profile + bandwidth?: Bandwidth + virusScan?: VirusScanStatus +} + +export interface VoidFileMeta { + name?: string + description?: string + size: number + uploaded: string + mimeType: string + expires?: string + url?: string + editSecret?: string + encryptionParams?: string + magnetLink?: string +} + +export interface VirusScanStatus { + isVirus: boolean + names?: string +} + +export interface Payment { + service: PaymentServices + required: boolean + currency: PaymentCurrencies + amount: number + strikeHandle?: string +} + +export interface SetPaymentConfigRequest { + editSecret: string + currency: PaymentCurrencies + amount: number + strikeHandle?: string + required: boolean +} + +export interface PaymentOrder { + id: string + status: PaymentOrderState + orderLightning?: PaymentOrderLightning +} + +export interface PaymentOrderLightning { + invoice: string + expire: string +} + +export interface ApiKey { + id: string + created: string + expiry: string + token: string +} + +export enum PaymentCurrencies { + BTC = 0, + USD = 1, + EUR = 2, + GBP = 3 +} + +export enum PaymentServices { + None = 0, + Strike = 1 +} + +export enum PaymentOrderState { + Unpaid = 0, + Paid = 1, + Expired = 2 +} + +export enum PagedSortBy { + Name = 0, + Date = 1, + Size = 2, + Id = 3 +} + +export enum PageSortOrder { + Asc = 0, + Dsc = 1 +} diff --git a/VoidCat/spa/src/App.js b/VoidCat/spa/src/App.js deleted file mode 100644 index 7ad0c14..0000000 --- a/VoidCat/spa/src/App.js +++ /dev/null @@ -1,35 +0,0 @@ -import './App.css'; - -import {BrowserRouter, Routes, Route} from "react-router-dom"; -import {Provider} from "react-redux"; -import store from "./Store"; -import {FilePreview} from "./Pages/FilePreview"; -import {HomePage} from "./Pages/HomePage"; -import {Admin} from "./Admin/Admin"; -import {UserLogin} from "./Pages/UserLogin"; -import {Profile} from "./Pages/Profile"; -import {Header} from "./Components/Shared/Header"; -import {Donate} from "./Pages/Donate"; - - -function App() { - return ( -
- - -
- - }/> - }/> - }/> - }/> - }/> - }/> - - - -
- ); -} - -export default App; diff --git a/VoidCat/spa/src/App.tsx b/VoidCat/spa/src/App.tsx new file mode 100644 index 0000000..47a68cf --- /dev/null +++ b/VoidCat/spa/src/App.tsx @@ -0,0 +1,61 @@ +import './App.css'; + +import {createBrowserRouter, Outlet, RouterProvider} from "react-router-dom"; +import {Provider} from "react-redux"; + +import store from "./Store"; +import {FilePreview} from "./Pages/FilePreview"; +import {HomePage} from "./Pages/HomePage"; +import {Admin} from "./Admin/Admin"; +import {UserLogin} from "./Pages/UserLogin"; +import {ProfilePage} from "./Pages/Profile"; +import {Header} from "./Components/Shared/Header"; +import {Donate} from "./Pages/Donate"; + + +const router = createBrowserRouter([ + { + element: , + children: [ + { + path: "/", + element: + }, + { + path: "/login", + element: + }, + { + path: "/u/:id", + element: + }, + { + path: "/admin", + element: + }, + { + path: "/:id", + element: + }, + { + path: "/donate", + element: + } + ] + } +]) + +export function AppLayout() { + return ( +
+ +
+ + +
+ ); +} + +export default function App() { + return +} diff --git a/VoidCat/spa/src/Components/FileEdit/FileEdit.js b/VoidCat/spa/src/Components/FileEdit/FileEdit.tsx similarity index 60% rename from VoidCat/spa/src/Components/FileEdit/FileEdit.js rename to VoidCat/spa/src/Components/FileEdit/FileEdit.tsx index ed725b7..35f0d60 100644 --- a/VoidCat/spa/src/Components/FileEdit/FileEdit.js +++ b/VoidCat/spa/src/Components/FileEdit/FileEdit.tsx @@ -5,49 +5,59 @@ import moment from "moment"; import {StrikePaymentConfig} from "./StrikePaymentConfig"; import {NoPaymentConfig} from "./NoPaymentConfig"; -import {useApi} from "../Shared/Api"; import {VoidButton} from "../Shared/VoidButton"; -import {PaymentServices} from "../Shared/Const"; -export function FileEdit(props) { - const {Api} = useApi(); - const file = props.file; - const meta = file.metadata; - const profile = useSelector(state => state.login.profile); +import useApi from "Hooks/UseApi"; +import {RootState} from "Store"; +import {Payment, PaymentServices, SetPaymentConfigRequest, VoidFileResponse} from "Api"; + +interface FileEditProps { + file: VoidFileResponse +} + +export function FileEdit({file}: FileEditProps) { + const Api = useApi(); + const profile = useSelector((s: RootState) => s.login.profile); const [payment, setPayment] = useState(file.payment?.service); - const [name, setName] = useState(meta?.name); - const [description, setDescription] = useState(meta?.description); - const [expiry, setExpiry] = useState(meta?.expires === undefined || meta?.expires === null ? null : moment(meta?.expires).unix() * 1000); + const [name, setName] = useState(file.metadata?.name ?? ""); + const [description, setDescription] = useState(file.metadata?.description ?? ""); + const [expiry, setExpiry] = useState(file.metadata?.expires ? moment(file.metadata?.expires).unix() * 1000 : undefined); - const privateFile = file?.uploader?.id && profile?.id === file.uploader.id + const localFile = window.localStorage.getItem(file.id); + const privateFile: VoidFileResponse = profile?.id === file.uploader?.id ? file - : JSON.parse(window.localStorage.getItem(file.id)); - if (!privateFile || privateFile?.metadata?.editSecret === null) { + : localFile ? JSON.parse(localFile) : undefined; + if (!privateFile?.metadata?.editSecret) { return null; } - async function saveConfig(cfg) { - let req = await Api.setPaymentConfig(file.id, cfg); - return req.ok; + async function savePaymentConfig(cfg: SetPaymentConfigRequest) { + try { + await Api.setPaymentConfig(file.id, cfg); + return true; + } catch (e) { + console.error(e); + return false; + } } async function saveMeta() { - let meta = { + const meta = { name, description, editSecret: privateFile?.metadata?.editSecret, expires: moment(expiry).toISOString() }; - await Api.updateMetadata(file.id, meta); + await Api.updateFileMetadata(file.id, meta); } function renderPaymentConfig() { switch (payment) { case PaymentServices.None: { - return ; + return ; } case PaymentServices.Strike: { - return + return } } return null; @@ -65,21 +75,21 @@ export function FileEdit(props) {
Expiry
{ - console.log(e.target.value); if (e.target.value.length > 0) { setExpiry(moment.utc(e.target.value).unix() * 1000); } else { - setExpiry(null); + setExpiry(undefined); } - }}/>
- saveMeta()} options={{showSuccess: true}}>Save + saveMeta()} options={{showSuccess: true}}> + Save +

Payment Config

diff --git a/VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.js b/VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.js deleted file mode 100644 index 53064d0..0000000 --- a/VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.js +++ /dev/null @@ -1,26 +0,0 @@ -import FeatherIcon from "feather-icons-react"; -import {useState} from "react"; -import {VoidButton} from "../Shared/VoidButton"; - -export function NoPaymentConfig(props) { - const [saveStatus, setSaveStatus] = useState(); - const privateFile = props.privateFile; - const onSaveConfig = props.onSaveConfig; - - async function saveConfig() { - let cfg = { - editSecret: privateFile.metadata.editSecret - }; - - if (typeof onSaveConfig === "function") { - setSaveStatus(await onSaveConfig(cfg)); - } - } - - return ( -
- Save - {saveStatus ? : null} -
- ) -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.tsx b/VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.tsx new file mode 100644 index 0000000..9e970c1 --- /dev/null +++ b/VoidCat/spa/src/Components/FileEdit/NoPaymentConfig.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import {VoidButton} from "../Shared/VoidButton"; +import {PaymentCurrencies, SetPaymentConfigRequest, VoidFileResponse} from "../../Api"; + +interface NoPaymentConfigProps { + privateFile: VoidFileResponse + onSaveConfig: (c: SetPaymentConfigRequest) => Promise +} + +export function NoPaymentConfig({privateFile, onSaveConfig}: NoPaymentConfigProps) { + async function saveConfig() { + const cfg = { + editSecret: privateFile.metadata!.editSecret, + required: false, + amount: 0, + currency: PaymentCurrencies.BTC + } as SetPaymentConfigRequest; + + await onSaveConfig(cfg) + } + + return ( +
+ + Save + +
+ ) +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.js b/VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.js deleted file mode 100644 index eb87208..0000000 --- a/VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.js +++ /dev/null @@ -1,65 +0,0 @@ -import {useState} from "react"; -import FeatherIcon from "feather-icons-react"; -import {PaymentCurrencies} from "../Shared/Const"; -import {VoidButton} from "../Shared/VoidButton"; - -export function StrikePaymentConfig(props) { - const file = props.file; - const privateFile = props.privateFile; - const onSaveConfig = props.onSaveConfig; - const payment = file.payment; - const editSecret = privateFile.metadata.editSecret; - - const [username, setUsername] = useState(payment?.handle ?? "hrf"); - const [currency, setCurrency] = useState(payment?.cost.currency ?? PaymentCurrencies.USD); - const [price, setPrice] = useState(payment?.cost.amount ?? 1); - const [required, setRequired] = useState(payment?.required); - const [saveStatus, setSaveStatus] = useState(); - - async function saveStrikeConfig(e) { - let cfg = { - editSecret, - strike: { - handle: username, - cost: { - currency: currency, - amount: price - } - }, - required - }; - - if (typeof onSaveConfig === "function") { - if (await onSaveConfig(cfg)) { - setSaveStatus(true); - } else { - alert("Error settings payment config!"); - setSaveStatus(false); - } - } - } - - return ( -
-
-
Stike username:
-
setUsername(e.target.value)}/>
-
Currency:
-
- -
-
Price:
-
setPrice(parseFloat(e.target.value))}/>
-
Required:
-
setRequired(e.target.checked)}/>
-
- Save - {saveStatus ? : null} -
- ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.tsx b/VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.tsx new file mode 100644 index 0000000..f6df600 --- /dev/null +++ b/VoidCat/spa/src/Components/FileEdit/StrikePaymentConfig.tsx @@ -0,0 +1,57 @@ +import {useState} from "react"; +import {VoidButton} from "../Shared/VoidButton"; + +import {PaymentCurrencies, SetPaymentConfigRequest, VoidFileResponse} from "Api"; + +interface StrikePaymentConfigProps { + file: VoidFileResponse + privateFile: VoidFileResponse + onSaveConfig: (cfg: SetPaymentConfigRequest) => Promise +} + +export function StrikePaymentConfig({file, privateFile, onSaveConfig}: StrikePaymentConfigProps) { + const payment = file.payment; + const editSecret = privateFile.metadata!.editSecret; + + const [username, setUsername] = useState(payment?.strikeHandle ?? "hrf"); + const [currency, setCurrency] = useState(payment?.currency ?? PaymentCurrencies.USD); + const [price, setPrice] = useState(payment?.amount ?? 1); + const [required, setRequired] = useState(payment?.required); + + async function saveStrikeConfig() { + const cfg = { + editSecret, + strikeHandle: username, + currency, + amount: price, + required + } as SetPaymentConfigRequest; + + await onSaveConfig(cfg) + } + + return ( +
+
+
Strike username:
+
setUsername(e.target.value)}/>
+
Currency:
+
+ +
+
Price:
+
setPrice(Number(e.target.value))}/>
+
Required:
+
setRequired(e.target.checked)}/>
+
+ + Save + +
+ ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FilePreview/FilePayment.js b/VoidCat/spa/src/Components/FilePreview/FilePayment.tsx similarity index 50% rename from VoidCat/spa/src/Components/FilePreview/FilePayment.js rename to VoidCat/spa/src/Components/FilePreview/FilePayment.tsx index 9b8ecdd..db9e5cd 100644 --- a/VoidCat/spa/src/Components/FilePreview/FilePayment.js +++ b/VoidCat/spa/src/Components/FilePreview/FilePayment.tsx @@ -1,24 +1,31 @@ import "./FilePayment.css"; import {useState} from "react"; -import {FormatCurrency} from "../Shared/Util"; -import {PaymentServices} from "../Shared/Const"; import {LightningPayment} from "./LightningPayment"; -import {useApi} from "../Shared/Api"; import {VoidButton} from "../Shared/VoidButton"; -export function FilePayment(props) { - const {Api} = useApi(); - const file = props.file; - const pw = file.payment; - const paymentKey = `payment-${file.id}`; - const onPaid = props.onPaid; +import useApi from "Hooks/UseApi"; +import {FormatCurrency} from "Util"; +import {PaymentOrder, PaymentServices, VoidFileResponse} from "Api"; - const [order, setOrder] = useState(); +interface FilePaymentProps { + file: VoidFileResponse + onPaid: () => Promise +} + +export function FilePayment({file, onPaid}: FilePaymentProps) { + const Api = useApi(); + const paymentKey = `payment-${file.id}`; + const [order, setOrder] = useState(); + + // Payment not required + if (!file.payment) return null; async function fetchOrder() { - let req = await Api.createOrder(file.id); - if (req.ok && req.status === 200) { - setOrder(await req.json()); + try { + const rsp = await Api.createOrder(file.id); + setOrder(rsp); + } catch (e) { + console.error(e); } } @@ -26,7 +33,7 @@ export function FilePayment(props) { setOrder(undefined); } - function handlePaid(order) { + function handlePaid(order: PaymentOrder) { window.localStorage.setItem(paymentKey, JSON.stringify(order)); if (typeof onPaid === "function") { onPaid(); @@ -34,26 +41,27 @@ export function FilePayment(props) { } if (!order) { - if (pw.required) { + const amountString = FormatCurrency(file.payment.amount, file.payment.currency); + if (file.payment.required) { return (

- You must pay {FormatCurrency(pw.cost.amount, pw.cost.currency)} to view this file. + You must pay {amountString} to view this file.

Pay
); } else { return ( - Tip {FormatCurrency(pw.cost.amount, pw.cost.currency)} + Tip {amountString} ); } } else { - switch (pw.service) { + switch (file.payment.service) { case PaymentServices.Strike: { return ; } } - return null; } + return null; } \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FilePreview/LightningPayment.js b/VoidCat/spa/src/Components/FilePreview/LightningPayment.js deleted file mode 100644 index 295843f..0000000 --- a/VoidCat/spa/src/Components/FilePreview/LightningPayment.js +++ /dev/null @@ -1,50 +0,0 @@ -import QRCode from "qrcode.react"; -import {useEffect} from "react"; - -import {Countdown} from "../Shared/Countdown"; -import {PaymentOrderState} from "../Shared/Const"; -import {useApi} from "../Shared/Api"; - -export function LightningPayment(props) { - const {Api} = useApi(); - const file = props.file; - const order = props.order; - const onPaid = props.onPaid; - const link = `lightning:${order.invoice}`; - - function openInvoice() { - let a = document.createElement("a"); - a.href = link; - a.click(); - } - - async function checkStatus() { - let req = await Api.getOrder(file.id, order.id); - if (req.ok) { - let order = await req.json(); - - if (order.status === PaymentOrderState.Paid && typeof onPaid === "function") { - onPaid(order); - } - } - } - - useEffect(() => { - let t = setInterval(checkStatus, 2500); - return () => clearInterval(t); - }, []); - - return ( -
-

Pay with Lightning ⚡

- -
-
Expires:
-
-
-
- ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FilePreview/LightningPayment.tsx b/VoidCat/spa/src/Components/FilePreview/LightningPayment.tsx new file mode 100644 index 0000000..e3f01bf --- /dev/null +++ b/VoidCat/spa/src/Components/FilePreview/LightningPayment.tsx @@ -0,0 +1,51 @@ +import QRCode from "qrcode.react"; +import {useEffect} from "react"; + +import {Countdown} from "../Shared/Countdown"; + +import useApi from "Hooks/UseApi"; +import {PaymentOrder, PaymentOrderState, VoidFileResponse} from "Api"; + +interface LightningPaymentProps { + file: VoidFileResponse + order: PaymentOrder + onPaid: (s: PaymentOrder) => void + onReset: () => void +} + +export function LightningPayment({file, order, onPaid, onReset}: LightningPaymentProps) { + const Api = useApi(); + const link = `lightning:${order.orderLightning?.invoice}`; + + function openInvoice() { + const a = document.createElement("a"); + a.href = link; + a.click(); + } + + async function checkStatus() { + const os = await Api.getOrder(file.id, order.id); + if (os.status === PaymentOrderState.Paid && typeof onPaid === "function") { + onPaid(os); + } + } + + useEffect(() => { + let t = setInterval(checkStatus, 2500); + return () => clearInterval(t); + }, []); + + return ( +
+

Pay with Lightning ⚡

+ +
+
Expires:
+
+
+
+ ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FilePreview/TextPreview.js b/VoidCat/spa/src/Components/FilePreview/TextPreview.tsx similarity index 72% rename from VoidCat/spa/src/Components/FilePreview/TextPreview.js rename to VoidCat/spa/src/Components/FilePreview/TextPreview.tsx index 10c3dcb..368bc28 100644 --- a/VoidCat/spa/src/Components/FilePreview/TextPreview.js +++ b/VoidCat/spa/src/Components/FilePreview/TextPreview.tsx @@ -1,10 +1,10 @@ import {useEffect, useState} from "react"; import "./TextPreview.css"; -export function TextPreview(props) { +export function TextPreview({link}: { link: string }) { let [content, setContent] = useState("Loading.."); - async function getContent(link) { + async function getContent(link: string) { let req = await fetch(`${link}?t=${new Date().getTime()}`, { headers: { "pragma": "no-cache", @@ -19,10 +19,10 @@ export function TextPreview(props) { } useEffect(() => { - if (props.link !== undefined && props.link !== "#") { - getContent(props.link); + if (link !== undefined && link !== "#") { + getContent(link).catch(console.error); } - }, [props.link]); + }, [link]); return (
{content}
diff --git a/VoidCat/spa/src/Components/FileUpload/Dropzone.js b/VoidCat/spa/src/Components/FileUpload/Dropzone.tsx similarity index 71% rename from VoidCat/spa/src/Components/FileUpload/Dropzone.js rename to VoidCat/spa/src/Components/FileUpload/Dropzone.tsx index 8d7e8fe..cdbc789 100644 --- a/VoidCat/spa/src/Components/FileUpload/Dropzone.js +++ b/VoidCat/spa/src/Components/FileUpload/Dropzone.tsx @@ -2,26 +2,28 @@ import "./Dropzone.css"; import {Fragment, useEffect, useState} from "react"; import {FileUpload} from "./FileUpload"; -export function Dropzone(props) { - let [files, setFiles] = useState([]); +export function Dropzone() { + let [files, setFiles] = useState>([]); - function selectFiles(e) { + function selectFiles() { let i = document.createElement('input'); i.setAttribute('type', 'file'); i.setAttribute('multiple', ''); i.addEventListener('change', function (evt) { - setFiles(evt.target.files); + if (evt.target && "files" in evt.target) { + setFiles(evt.target.files as Array); + } }); i.click(); } - function dropFiles(e) { + function dropFiles(e: DragEvent | ClipboardEvent) { e.preventDefault(); e.stopPropagation(); - if ("dataTransfer" in e && e.dataTransfer.files.length > 0) { - setFiles(e.dataTransfer.files); - } else if ("clipboardData" in e && e.clipboardData.files.length > 0) { - setFiles(e.clipboardData.files); + if ("dataTransfer" in e && (e.dataTransfer?.files?.length ?? 0) > 0) { + setFiles([...e.dataTransfer!.files]); + } else if ("clipboardData" in e && (e.clipboardData?.files?.length ?? 0) > 0) { + setFiles([...e.clipboardData!.files]); } } diff --git a/VoidCat/spa/src/Components/FileUpload/FileUpload.js b/VoidCat/spa/src/Components/FileUpload/FileUpload.js deleted file mode 100644 index 39fb482..0000000 --- a/VoidCat/spa/src/Components/FileUpload/FileUpload.js +++ /dev/null @@ -1,296 +0,0 @@ -import "./FileUpload.css"; -import {useEffect, useState} from "react"; -import {useSelector} from "react-redux"; - -import {buf2hex, ConstName, FormatBytes} from "../Shared/Util"; -import {ApiHost} from "../Shared/Const"; -import {StreamEncryption} from "../Shared/StreamEncryption"; -import {VoidButton} from "../Shared/VoidButton"; -import {useFileTransfer} from "../Shared/FileTransferHook"; -import sjcl from "sjcl"; -import {sjclcodec} from "../../codecBytes"; - -const UploadState = { - NotStarted: 0, - Starting: 1, - Hashing: 2, - Uploading: 3, - Done: 4, - Failed: 5, - Challenge: 6 -}; - -export const DigestAlgo = "SHA-256"; - -export function FileUpload(props) { - const auth = useSelector(state => state.login.jwt); - const info = useSelector(state => state.info.info); - const {speed, progress, loaded, setFileSize, reset, update} = useFileTransfer(); - const [result, setResult] = useState(); - const [uState, setUState] = useState(UploadState.NotStarted); - const [challenge, setChallenge] = useState(); - const [encryptionKey, setEncryptionKey] = useState(); - const [encrypt, setEncrypt] = useState(true); - - function handleProgress(e) { - if (e instanceof ProgressEvent) { - loaded(e.loaded); - } - } - - async function doStreamUpload() { - setFileSize(props.file.size); - setUState(UploadState.Hashing); - let hash = await digest(props.file); - reset(); - let offset = 0; - - async function readChunk(size) { - if (offset > props.file.size) { - return new Uint8Array(0); - } - let end = Math.min(offset + size, props.file.size); - let blob = props.file.slice(offset, end, props.file.type); - let data = await blob.arrayBuffer(); - offset += data.byteLength; - return new Uint8Array(data); - } - - let rs = new ReadableStream({ - start: async () => { - setUState(UploadState.Uploading); - }, - pull: async (controller) => { - try { - let chunk = await readChunk(controller.desiredSize); - if (chunk.byteLength === 0) { - controller.close(); - return; - } - update(chunk.length); - controller.enqueue(chunk); - } catch (e) { - console.error(e); - throw e; - } - }, - cancel: (reason) => { - console.log(reason); - }, - type: "bytes" - }, { - highWaterMark: 1024 * 1024 - }); - - let enc = encrypt ? (() => { - let ret = new StreamEncryption(); - setEncryptionKey(ret.getKey()); - return ret; - })() : null; - rs = encrypt ? rs.pipeThrough(enc.getEncryptionTransform()) : rs; - - let headers = { - "Content-Type": "application/octet-stream", - "V-Content-Type": props.file.type, - "V-Filename": props.file.name, - "V-Full-Digest": hash - }; - if (encrypt) { - headers["V-EncryptionParams"] = JSON.stringify(enc.getParams()); - } - if (auth) { - headers["Authorization"] = `Bearer ${auth}`; - } - let req = await fetch(`${ApiHost}/upload`, { - method: "POST", - mode: "cors", - body: rs, - headers, - duplex: 'half' - }); - - if (req.ok) { - let rsp = await req.json(); - console.log(rsp); - handleResult(rsp); - } - } - - /** - * Upload a segment of the file - * @param segment {ArrayBuffer} - * @param fullDigest {string} Full file hash - * @param id {string?} - * @param editSecret {string?} - * @param part {int?} Segment number - * @param partOf {int?} Total number of segments - * @returns {Promise} - */ - async function xhrSegment(segment, fullDigest, id, editSecret, part, partOf) { - setUState(UploadState.Uploading); - - return await new Promise((resolve, reject) => { - try { - let req = new XMLHttpRequest(); - req.onreadystatechange = (ev) => { - if (req.readyState === XMLHttpRequest.DONE && req.status === 200) { - let rsp = JSON.parse(req.responseText); - console.log(rsp); - resolve(rsp); - } else if (req.readyState === XMLHttpRequest.DONE && req.status === 403) { - let contentType = req.getResponseHeader("content-type"); - if (contentType.toLowerCase().trim().indexOf("text/html") === 0) { - setChallenge(req.response); - setUState(UploadState.Challenge); - reject(); - } - } - }; - req.upload.onprogress = handleProgress; - req.open("POST", typeof (id) === "string" ? `${ApiHost}/upload/${id}` : `${ApiHost}/upload`); - req.setRequestHeader("Content-Type", "application/octet-stream"); - req.setRequestHeader("V-Content-Type", props.file.type.length === 0 ? "application/octet-stream" : props.file.type); - req.setRequestHeader("V-Filename", props.file.name); - req.setRequestHeader("V-Full-Digest", fullDigest); - req.setRequestHeader("V-Segment", `${part}/${partOf}`) - if (auth) { - req.setRequestHeader("Authorization", `Bearer ${auth}`); - } - if (typeof (editSecret) === "string") { - req.setRequestHeader("V-EditSecret", editSecret); - } - req.withCredentials = true; - req.send(segment); - } catch (e) { - reject(e); - } - }); - } - - async function doXHRUpload() { - setFileSize(props.file.size); - let uploadSize = info.uploadSegmentSize ?? Number.MAX_VALUE; - - setUState(UploadState.Hashing); - let hash = await digest(props.file); - reset(); - if (props.file.size >= uploadSize) { - await doSplitXHRUpload(hash, uploadSize); - } else { - let xhr = await xhrSegment(props.file, hash); - handleResult(xhr); - } - } - - async function doSplitXHRUpload(hash, splitSize) { - let xhr = null; - const segments = Math.ceil(props.file.size / splitSize); - for (let s = 0; s < segments; s++) { - reset(); - let offset = s * splitSize; - let slice = props.file.slice(offset, offset + splitSize, props.file.type); - xhr = await xhrSegment(slice, hash, xhr?.file?.id, xhr?.file?.metadata?.editSecret, s + 1, segments); - if (!xhr.ok) { - break; - } - } - handleResult(xhr); - } - - function handleResult(result) { - if (result.ok) { - setUState(UploadState.Done); - setResult(result.file); - window.localStorage.setItem(result.file.id, JSON.stringify(result.file)); - } else { - setUState(UploadState.Failed); - setResult(result.errorMessage); - } - } - - function getChromeVersion() { - let raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); - return raw ? parseInt(raw[2], 10) : false; - } - - async function digest(file) { - const ChunkSize = 1024 * 1024; - // must compute hash in chunks, subtle crypto cannot hash files > 2Gb - let sha = new sjcl.hash.sha256(); - for (let x = 0; x < Math.ceil(file.size / ChunkSize); x++) { - let offset = x * ChunkSize; - let slice = file.slice(offset, offset + ChunkSize); - let chunk = await slice.arrayBuffer(); - sha.update(sjclcodec.toBits(new Uint8Array(chunk))); - update(chunk.byteLength); - } - return buf2hex(sjclcodec.fromBits(sha.finalize())); - } - - function renderStatus() { - if (result) { - let link = `/${result.id}`; - return uState === UploadState.Done ? -
-
Link:
-
{result.id}
- {encryptionKey ? <> -
Encryption Key:
-
- navigator.clipboard.writeText(encryptionKey)}>Copy -
- : null} -
- : {result}; - } else if (uState === UploadState.NotStarted) { - return ( - <> -
-
Encrypt file:
-
setEncrypt(e.target.checked)}/> -
-
- doStreamUpload()}>Upload - - ) - } else { - return ( -
-
Speed:
-
{FormatBytes(speed)}/s
-
Progress:
-
{(progress * 100).toFixed(0)}%
-
Status:
-
{ConstName(UploadState, uState)}
-
- ); - } - } - - function getChallengeElement() { - let elm = document.createElement("iframe"); - elm.contentWindow.document.write(challenge); - return
; - } - - return ( -
-
-
-
Name:
-
{props.file.name}
-
Size:
-
{FormatBytes(props.file.size)}
-
-
-
- {renderStatus()} -
- {uState === UploadState.Challenge ? -
window.location.reload()}> - {getChallengeElement()} -
- : null} -
- ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/FileUpload/FileUpload.tsx b/VoidCat/spa/src/Components/FileUpload/FileUpload.tsx new file mode 100644 index 0000000..af60ca9 --- /dev/null +++ b/VoidCat/spa/src/Components/FileUpload/FileUpload.tsx @@ -0,0 +1,131 @@ +import "./FileUpload.css"; +import {useEffect, useMemo, useState} from "react"; +import {useSelector} from "react-redux"; + +import {VoidButton} from "../Shared/VoidButton"; +import {useFileTransfer} from "../Shared/FileTransferHook"; + +import {RootState} from "Store"; +import {ConstName, FormatBytes} from "Util"; +import {UploadState, VoidFileResponse} from "Api"; +import useApi from "Hooks/UseApi"; + +interface FileUploadProps { + file: File | Blob +} + +export function FileUpload({file}: FileUploadProps) { + const info = useSelector((s: RootState) => s.info.info); + const {speed, progress, loaded, setFileSize, reset} = useFileTransfer(); + const Api = useApi(); + const [result, setResult] = useState(); + const [error, setError] = useState(""); + const [uState, setUState] = useState(UploadState.NotStarted); + const [challenge, setChallenge] = useState(""); + const [encryptionKey, setEncryptionKey] = useState(""); + const [encrypt, setEncrypt] = useState(true); + + const uploader = useMemo(() => { + return Api.getUploader(file, setUState, loaded, setChallenge, info?.uploadSegmentSize); + }, [Api, file]); + + useEffect(() => { + uploader.setEncryption(encrypt); + }, [uploader, encrypt]); + + useEffect(() => { + reset(); + setFileSize(file.size); + if (!uploader.canEncrypt() && uState === UploadState.NotStarted) { + startUpload().catch(console.error) + } + }, [file, uploader, uState]); + + async function startUpload() { + setUState(UploadState.Starting); + try { + const result = await uploader.upload(); + console.debug(result); + if (result.ok) { + setUState(UploadState.Done); + setResult(result.file); + setEncryptionKey(uploader.getEncryptionKey() ?? ""); + window.localStorage.setItem(result.file!.id, JSON.stringify(result.file!)); + } else { + setUState(UploadState.Failed); + setError(result.errorMessage!); + } + } catch (e) { + setUState(UploadState.Failed); + if (e instanceof Error) { + setError(e.message); + } else { + setError("Unknown error"); + } + } + } + + function renderStatus() { + if (result && uState === UploadState.Done) { + let link = `/${result.id}`; + return (
+
Link:
+
{result.id}
+ {encryptionKey ? <> +
Encryption Key:
+
+ navigator.clipboard.writeText(encryptionKey)}>Copy +
+ : null} +
) + } else if (uState === UploadState.NotStarted) { + return ( + <> +
+
Encrypt file:
+
setEncrypt(e.target.checked)}/> +
+
+ startUpload()}>Upload + + ) + } else { + return ( +
+
Speed:
+
{FormatBytes(speed)}/s
+
Progress:
+
{(progress * 100).toFixed(0)}%
+
Status:
+
{error ? error : ConstName(UploadState, uState)}
+
+ ); + } + } + + function getChallengeElement() { + let elm = document.createElement("iframe"); + elm.contentWindow?.document.write(challenge); + return
; + } + + return ( +
+
+
+
Name:
+
{file.name}
+
Size:
+
{FormatBytes(file.size)}
+
+
+
+ {renderStatus()} +
+ {uState === UploadState.Challenge && +
window.location.reload()}> + {getChallengeElement()} +
} +
+ ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/HomePage/FooterLinks.js b/VoidCat/spa/src/Components/HomePage/FooterLinks.tsx similarity index 58% rename from VoidCat/spa/src/Components/HomePage/FooterLinks.js rename to VoidCat/spa/src/Components/HomePage/FooterLinks.tsx index 9205c84..652984d 100644 --- a/VoidCat/spa/src/Components/HomePage/FooterLinks.js +++ b/VoidCat/spa/src/Components/HomePage/FooterLinks.tsx @@ -1,20 +1,18 @@ import "./FooterLinks.css" -import StrikeLogo from "../../image/strike.png"; import {useSelector} from "react-redux"; import {Link} from "react-router-dom"; +import {RootState} from "Store"; + export function FooterLinks() { - const profile = useSelector(state => state.login.profile); + const profile = useSelector((s:RootState) => s.login.profile); return (
- + Discord - - Get Strike Strike logo - - + GitHub Donate diff --git a/VoidCat/spa/src/Components/HomePage/GlobalStats.js b/VoidCat/spa/src/Components/HomePage/GlobalStats.tsx similarity index 65% rename from VoidCat/spa/src/Components/HomePage/GlobalStats.js rename to VoidCat/spa/src/Components/HomePage/GlobalStats.tsx index b980cb4..b3328dc 100644 --- a/VoidCat/spa/src/Components/HomePage/GlobalStats.js +++ b/VoidCat/spa/src/Components/HomePage/GlobalStats.tsx @@ -1,38 +1,40 @@ import "./GlobalStats.css"; import {Fragment} from "react"; -import FeatherIcon from "feather-icons-react"; -import {FormatBytes} from "../Shared/Util"; import moment from "moment"; import {useSelector} from "react-redux"; +import Icon from "Components/Shared/Icon"; +import {RootState} from "Store"; +import {FormatBytes} from "Util"; + export function GlobalStats() { - let stats = useSelector(state => state.info.info); + let stats = useSelector((s: RootState) => s.info.info); return (
- + {FormatBytes(stats?.bandwidth?.ingress ?? 0, 2)}
- + {FormatBytes(stats?.bandwidth?.egress ?? 0, 2)}
- + {FormatBytes(stats?.totalBytes ?? 0, 2)}
- + {stats?.count ?? 0}
- {stats?.buildInfo ?
+ {stats?.buildInfo &&
{stats.buildInfo.version}-{stats.buildInfo.gitHash}
{moment(stats.buildInfo.buildTime).fromNow()} -
: null} +
}
); } \ No newline at end of file diff --git a/VoidCat/spa/src/Components/HomePage/MetricsGraph.js b/VoidCat/spa/src/Components/HomePage/MetricsGraph.js deleted file mode 100644 index 4900cfe..0000000 --- a/VoidCat/spa/src/Components/HomePage/MetricsGraph.js +++ /dev/null @@ -1,23 +0,0 @@ -import {Bar, BarChart, Tooltip, XAxis} from "recharts"; -import {FormatBytes} from "../Shared/Util"; -import moment from "moment"; - -export function MetricsGraph(props) { - const metrics = props.metrics; - - if (!metrics?.timeSeriesMetrics || metrics?.timeSeriesMetrics.length === 0) return null; - - return ( - - `${moment(v).format("DD-MMM")}`}/> - - FormatBytes(v, 2)} labelStyle={{color: "#aaa"}} itemStyle={{color: "#eee"}} - contentStyle={{backgroundColor: "#111"}}/> - - ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/HomePage/MetricsGraph.tsx b/VoidCat/spa/src/Components/HomePage/MetricsGraph.tsx new file mode 100644 index 0000000..1d6028e --- /dev/null +++ b/VoidCat/spa/src/Components/HomePage/MetricsGraph.tsx @@ -0,0 +1,26 @@ +import {Bar, BarChart, Tooltip, XAxis} from "recharts"; +import moment from "moment"; + +import {FormatBytes} from "Util"; +import {BandwidthPoint} from "../../Api"; + +interface MetricsGraphProps { + metrics?: Array +} +export function MetricsGraph({metrics}: MetricsGraphProps) { + if (!metrics || metrics.length === 0) return null; + + return ( + + `${moment(v).format("DD-MMM")}`}/> + + FormatBytes(v as number)} labelStyle={{color: "#aaa"}} itemStyle={{color: "#eee"}} + contentStyle={{backgroundColor: "#111"}}/> + + ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Profile/ApiKeyList.js b/VoidCat/spa/src/Components/Profile/ApiKeyList.tsx similarity index 63% rename from VoidCat/spa/src/Components/Profile/ApiKeyList.js rename to VoidCat/spa/src/Components/Profile/ApiKeyList.tsx index 4760fc7..66f94f5 100644 --- a/VoidCat/spa/src/Components/Profile/ApiKeyList.js +++ b/VoidCat/spa/src/Components/Profile/ApiKeyList.tsx @@ -1,38 +1,44 @@ import {useEffect, useState} from "react"; import moment from "moment"; -import {useApi} from "../Shared/Api"; import {VoidButton} from "../Shared/VoidButton"; import VoidModal from "../Shared/VoidModal"; +import useApi from "Hooks/UseApi"; +import {ApiKey} from "Api"; + export default function ApiKeyList() { - const {Api} = useApi(); - const [apiKeys, setApiKeys] = useState([]); - const [newApiKey, setNewApiKey] = useState(); + const Api = useApi(); + const [apiKeys, setApiKeys] = useState([]); + const [newApiKey, setNewApiKey] = useState(); const DefaultExpiry = 1000 * 60 * 60 * 24 * 90; async function loadApiKeys() { - let keys = await Api.listApiKeys(); - setApiKeys(await keys.json()); + try { + const keys = await Api.listApiKeys(); + setApiKeys(keys); + } catch (e) { + console.error(e); + } } async function createApiKey() { - let rsp = await Api.createApiKey({ - expiry: new Date(new Date().getTime() + DefaultExpiry) - }); - if (rsp.ok) { - setNewApiKey(await rsp.json()); + try { + const rsp = await Api.createApiKey({ + expiry: new Date(new Date().getTime() + DefaultExpiry) + }); + setNewApiKey(rsp); + } catch (e) { + console.error(e); } } - + function openDocs() { window.open("/swagger", "_blank") } - + useEffect(() => { - if (Api) { - loadApiKeys(); - } + loadApiKeys().catch(console.error); }, []); return ( @@ -42,8 +48,8 @@ export default function ApiKeyList() {

API Keys

- createApiKey()}>+New - openDocs()}>Docs + createApiKey()}>+New + openDocs()}>Docs
@@ -66,12 +72,12 @@ export default function ApiKeyList() { )}
- {newApiKey ? + {newApiKey && Please save this now as it will not be shown again:
{newApiKey.token}
- setNewApiKey(undefined)}>Close -
: null} + setNewApiKey(undefined)}>Close + } ); } \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/Api.js b/VoidCat/spa/src/Components/Shared/Api.js deleted file mode 100644 index 0fe38b9..0000000 --- a/VoidCat/spa/src/Components/Shared/Api.js +++ /dev/null @@ -1,51 +0,0 @@ -import {useSelector} from "react-redux"; -import {ApiHost} from "./Const"; - -export function useApi() { - const auth = useSelector(state => state.login.jwt); - - async function getJson(method, url, body, token) { - let headers = { - "Accept": "application/json" - }; - if (token) { - headers["Authorization"] = `Bearer ${token}`; - } - if (body) { - headers["Content-Type"] = "application/json"; - } - - return await fetch(`${ApiHost}${url}`, { - method, - headers, - mode: "cors", - body: body ? JSON.stringify(body) : undefined - }); - } - - return { - AdminApi: { - fileList: (pageReq) => getJson("POST", "/admin/file", pageReq, auth), - deleteFile: (id) => getJson("DELETE", `/admin/file/${id}`, undefined, auth), - userList: (pageReq) => getJson("POST", `/admin/users`, pageReq, auth), - updateUser: (user) => getJson("POST", `/admin/update-user`, user, auth) - }, - Api: { - info: () => getJson("GET", "/info"), - fileInfo: (id) => getJson("GET", `/upload/${id}`, undefined, auth), - setPaymentConfig: (id, cfg) => getJson("POST", `/upload/${id}/payment`, cfg, auth), - createOrder: (id) => getJson("GET", `/upload/${id}/payment`), - getOrder: (file, order) => getJson("GET", `/upload/${file}/payment/${order}`), - login: (username, password, captcha) => getJson("POST", `/auth/login`, {username, password, captcha}), - register: (username, password, captcha) => getJson("POST", `/auth/register`, {username, password, captcha}), - getUser: (id) => getJson("GET", `/user/${id}`, undefined, auth), - updateUser: (u) => getJson("POST", `/user/${u.id}`, u, auth), - listUserFiles: (uid, pageReq) => getJson("POST", `/user/${uid}/files`, pageReq, auth), - submitVerifyCode: (uid, code) => getJson("POST", `/user/${uid}/verify`, code, auth), - sendNewCode: (uid) => getJson("GET", `/user/${uid}/verify`, undefined, auth), - updateMetadata: (id, meta) => getJson("POST", `/upload/${id}/meta`, meta, auth), - listApiKeys: () => getJson("GET", `/auth/api-key`, undefined, auth), - createApiKey: (req) => getJson("POST", `/auth/api-key`, req, auth) - } - }; -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/Countdown.js b/VoidCat/spa/src/Components/Shared/Countdown.tsx similarity index 52% rename from VoidCat/spa/src/Components/Shared/Countdown.js rename to VoidCat/spa/src/Components/Shared/Countdown.tsx index 4aa89fc..5e6f614 100644 --- a/VoidCat/spa/src/Components/Shared/Countdown.js +++ b/VoidCat/spa/src/Components/Shared/Countdown.tsx @@ -1,14 +1,17 @@ import {useEffect, useState} from "react"; -export function Countdown(props) { +interface CountdownProps { + to: number | string | Date + onEnded?: () => void +} +export function Countdown({onEnded, to}: CountdownProps) { const [time, setTime] = useState(0); - const onEnded = props.onEnded; useEffect(() => { - let t = setInterval(() => { - let to = new Date(props.to).getTime(); - let now = new Date().getTime(); - let seconds = (to - now) / 1000.0; + const t = setInterval(() => { + const toDate = new Date(to).getTime(); + const now = new Date().getTime(); + const seconds = (toDate - now) / 1000.0; setTime(Math.max(0, seconds)); if (seconds <= 0 && typeof onEnded === "function") { onEnded(); diff --git a/VoidCat/spa/src/Components/Shared/FileList.js b/VoidCat/spa/src/Components/Shared/FileList.tsx similarity index 54% rename from VoidCat/spa/src/Components/Shared/FileList.js rename to VoidCat/spa/src/Components/Shared/FileList.tsx index 599f9a7..687d6cf 100644 --- a/VoidCat/spa/src/Components/Shared/FileList.js +++ b/VoidCat/spa/src/Components/Shared/FileList.tsx @@ -1,40 +1,51 @@ import {useDispatch} from "react-redux"; -import {useEffect, useState} from "react"; +import {ReactNode, useEffect, useState} from "react"; import {Link} from "react-router-dom"; import moment from "moment"; -import {PagedSortBy, PageSortOrder} from "./Const"; import {logout} from "../../LoginState"; -import {FormatBytes} from "./Util"; import {PageSelector} from "./PageSelector"; -export function FileList(props) { +import {ApiError, PagedRequest, PagedResponse, PagedSortBy, PageSortOrder, VoidFileResponse} from "Api"; +import {FormatBytes} from "Util"; + +interface FileListProps { + actions?: (f: VoidFileResponse) => ReactNode + loadPage: (req: PagedRequest) => Promise> +} + +export function FileList(props: FileListProps) { const loadPage = props.loadPage; const actions = props.actions; const dispatch = useDispatch(); - const [files, setFiles] = useState(); + const [files, setFiles] = useState>(); const [page, setPage] = useState(0); const pageSize = 20; - const [accessDenied, setAccessDenied] = useState(false); + const [accessDenied, setAccessDenied] = useState(); async function loadFileList() { - let pageReq = { - page: page, - pageSize, - sortBy: PagedSortBy.Date, - sortOrder: PageSortOrder.Dsc - }; - let req = await loadPage(pageReq); - if (req.ok) { - setFiles(await req.json()); - } else if (req.status === 401) { - dispatch(logout()); - } else if (req.status === 403) { - setAccessDenied(true); + try { + const pageReq = { + page: page, + pageSize, + sortBy: PagedSortBy.Date, + sortOrder: PageSortOrder.Dsc + }; + const rsp = await loadPage(pageReq); + setFiles(rsp); + } catch (e) { + console.error(e); + if (e instanceof ApiError) { + if (e.statusCode === 401) { + dispatch(logout()); + } else if (e.statusCode === 403) { + setAccessDenied(true); + } + } } } - function renderItem(i) { + function renderItem(i: VoidFileResponse) { const meta = i.metadata; const bw = i.bandwidth; @@ -51,7 +62,7 @@ export function FileList(props) { } useEffect(() => { - loadFileList() + loadFileList().catch(console.error) }, [page]); if (accessDenied === true) { @@ -77,9 +88,11 @@ export function FileList(props) { - {files ? - setPage(x)} page={page} total={files.totalResults} - pageSize={pageSize}/> : null} + + {files && + setPage(x)} page={page} total={files.totalResults} + pageSize={pageSize}/>} + diff --git a/VoidCat/spa/src/Components/Shared/FileTransferHook.js b/VoidCat/spa/src/Components/Shared/FileTransferHook.tsx similarity index 84% rename from VoidCat/spa/src/Components/Shared/FileTransferHook.js rename to VoidCat/spa/src/Components/Shared/FileTransferHook.tsx index 30a68ff..cff69d1 100644 --- a/VoidCat/spa/src/Components/Shared/FileTransferHook.js +++ b/VoidCat/spa/src/Components/Shared/FileTransferHook.tsx @@ -8,15 +8,15 @@ export function useFileTransfer() { return { speed, progress, - setFileSize: (size) => { + setFileSize: (size: number) => { calc.SetFileSize(size); }, - update: (bytes) => { + update: (bytes: number) => { calc.ReportProgress(bytes); setSpeed(calc.GetSpeed()); setProgress(calc.GetProgress()); }, - loaded: (loaded) => { + loaded: (loaded: number) => { calc.ReportLoaded(loaded); setSpeed(calc.GetSpeed()); setProgress(calc.GetProgress()); diff --git a/VoidCat/spa/src/Components/Shared/Header.js b/VoidCat/spa/src/Components/Shared/Header.tsx similarity index 63% rename from VoidCat/spa/src/Components/Shared/Header.js rename to VoidCat/spa/src/Components/Shared/Header.tsx index fbe1328..de2dad3 100644 --- a/VoidCat/spa/src/Components/Shared/Header.js +++ b/VoidCat/spa/src/Components/Shared/Header.tsx @@ -6,41 +6,42 @@ import {Link} from "react-router-dom"; import {useDispatch, useSelector} from "react-redux"; import {InlineProfile} from "./InlineProfile"; -import {useApi} from "./Api"; import {logout, setAuth, setProfile} from "../../LoginState"; import {setInfo} from "../../SiteInfoStore"; +import useApi from "Hooks/UseApi"; +import {RootState} from "Store"; + export function Header() { const dispatch = useDispatch(); - const jwt = useSelector(state => state.login.jwt); - const profile = useSelector(state => state.login.profile) - const {Api} = useApi(); + const jwt = useSelector((s: RootState) => s.login.jwt); + const profile = useSelector((s: RootState) => s.login.profile) + const Api = useApi(); async function initProfile() { if (jwt && !profile) { - let rsp = await Api.getUser("me"); - if (rsp.ok) { - dispatch(setProfile(await rsp.json())); - } else { + try { + const me = await Api.getUser("me"); + dispatch(setProfile(me)); + } catch (e) { + console.error(e); dispatch(logout()); } - } else if(window.location.pathname === "/login" && window.location.hash.length > 1) { + } else if (window.location.pathname === "/login" && window.location.hash.length > 1) { dispatch(setAuth({ - jwt: window.location.hash.substring(1), - profile: null + jwt: window.location.hash.substring(1) })); } } + async function loadStats() { - let req = await Api.info(); - if (req.ok) { - dispatch(setInfo(await req.json())); - } + const info = await Api.info(); + dispatch(setInfo(info)); } useEffect(() => { - initProfile(); - loadStats(); + initProfile().catch(console.error); + loadStats().catch(console.error); }, [jwt]); return ( diff --git a/VoidCat/spa/src/Components/Shared/Icon.tsx b/VoidCat/spa/src/Components/Shared/Icon.tsx new file mode 100644 index 0000000..338faa9 --- /dev/null +++ b/VoidCat/spa/src/Components/Shared/Icon.tsx @@ -0,0 +1,21 @@ +import { MouseEventHandler } from "react"; + +type Props = { + name: string; + size?: number; + className?: string; + onClick?: MouseEventHandler; +}; + +const Icon = (props: Props) => { + const size = props.size || 20; + const href = "/icons.svg#" + props.name; + + return ( + + + + ); +}; + +export default Icon; diff --git a/VoidCat/spa/src/Components/Shared/InlineProfile.js b/VoidCat/spa/src/Components/Shared/InlineProfile.tsx similarity index 60% rename from VoidCat/spa/src/Components/Shared/InlineProfile.js rename to VoidCat/spa/src/Components/Shared/InlineProfile.tsx index c6fe873..ecde60c 100644 --- a/VoidCat/spa/src/Components/Shared/InlineProfile.js +++ b/VoidCat/spa/src/Components/Shared/InlineProfile.tsx @@ -1,16 +1,27 @@ import "./InlineProfile.css"; -import {DefaultAvatar} from "./Const"; +import {CSSProperties} from "react"; import {Link} from "react-router-dom"; +import {DefaultAvatar} from "Const"; +import {Profile} from "../../Api"; + const DefaultSize = 64; -export function InlineProfile(props) { - const profile = props.profile; - const options = { +interface InlineProfileProps { + profile: Profile + options?: { + size?: number + showName?: boolean + link?: boolean + } +} + +export function InlineProfile({profile, options}: InlineProfileProps) { + options = { size: DefaultSize, showName: true, link: true, - ...props.options + ...options }; let avatarUrl = profile.avatar ?? DefaultAvatar; @@ -19,16 +30,16 @@ export function InlineProfile(props) { } let avatarStyles = { backgroundImage: `url(${avatarUrl})` - }; + } as CSSProperties; if (options.size !== DefaultSize) { avatarStyles.width = `${options.size}px`; avatarStyles.height = `${options.size}px`; } - let elms = ( + const elms = (
- {options.showName ?
{profile.displayName}
: null} + {options.showName ?
{profile.name}
: null}
); if (options.link === true) { diff --git a/VoidCat/spa/src/Components/Shared/Login.js b/VoidCat/spa/src/Components/Shared/Login.js deleted file mode 100644 index 9fdec8f..0000000 --- a/VoidCat/spa/src/Components/Shared/Login.js +++ /dev/null @@ -1,54 +0,0 @@ -import {useState} from "react"; -import {useDispatch, useSelector} from "react-redux"; -import {setAuth} from "../../LoginState"; -import {useApi} from "./Api"; -import "./Login.css"; -import HCaptcha from "@hcaptcha/react-hcaptcha"; -import {VoidButton} from "./VoidButton"; - -export function Login() { - const {Api} = useApi(); - const [username, setUsername] = useState(); - const [password, setPassword] = useState(); - const [error, setError] = useState(); - const [captchaResponse, setCaptchaResponse] = useState(); - const captchaKey = useSelector(state => state.info.info?.captchaSiteKey); - const oAuthProviders = useSelector(state => state.info.info?.oAuthProviders); - const dispatch = useDispatch(); - - async function login(fnLogin) { - setError(null); - - let req = await fnLogin(username, password, captchaResponse); - if (req.ok) { - let rsp = await req.json(); - if (rsp.jwt) { - dispatch(setAuth(rsp)); - } else { - setError(rsp.error); - } - } - } - - return ( -
-

Login

-
-
Username:
-
setUsername(e.target.value)} placeholder="user@example.com"/> -
-
Password:
-
setPassword(e.target.value)}/>
-
- {captchaKey ? : null} - login(Api.login)}>Login - login(Api.register)}>Register -
- {oAuthProviders ? - oAuthProviders.map(a => window.location.href = `/auth/${a}`}> - Login with {a} - ) : null} - {error ?
{error}
: null} -
- ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/Login.tsx b/VoidCat/spa/src/Components/Shared/Login.tsx new file mode 100644 index 0000000..45cadb2 --- /dev/null +++ b/VoidCat/spa/src/Components/Shared/Login.tsx @@ -0,0 +1,64 @@ +import {useState} from "react"; +import {useDispatch, useSelector} from "react-redux"; +import HCaptcha from "@hcaptcha/react-hcaptcha"; + +import "./Login.css"; +import {setAuth} from "../../LoginState"; +import {VoidButton} from "./VoidButton"; + +import useApi from "Hooks/UseApi"; +import {RootState} from "Store"; + +export function Login() { + const Api = useApi(); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const [captchaResponse, setCaptchaResponse] = useState(""); + const captchaKey = useSelector((s: RootState) => s.info.info?.captchaSiteKey); + const oAuthProviders = useSelector((s: RootState) => s.info.info?.oAuthProviders); + const dispatch = useDispatch(); + + async function login(fnLogin: typeof Api.login) { + setError(""); + + try { + const rsp = await fnLogin(username, password, captchaResponse); + if (rsp.jwt) { + dispatch(setAuth({ + jwt: rsp.jwt, + profile: rsp.profile! + })); + } else { + setError(rsp.error!); + } + } catch (e) { + if (e instanceof Error) { + setError(e.message); + } + } + } + + return ( +
+

Login

+
+
Username:
+
setUsername(e.target.value)} + value={username}/> +
+
Password:
+
setPassword(e.target.value)} value={password}/>
+
+ {captchaKey ? setCaptchaResponse(v)}/> : null} + login(Api.login.bind(Api))}>Login + login(Api.register.bind(Api))}>Register +
+ {oAuthProviders ? + oAuthProviders.map(a => window.location.href = `/auth/${a}`}> + Login with {a} + ) : null} + {error &&
{error}
} +
+ ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/PageSelector.js b/VoidCat/spa/src/Components/Shared/PageSelector.js deleted file mode 100644 index dcc8d22..0000000 --- a/VoidCat/spa/src/Components/Shared/PageSelector.js +++ /dev/null @@ -1,33 +0,0 @@ -import "./PageSelector.css"; - -export function PageSelector(props) { - const total = props.total; - const pageSize = props.pageSize; - const page = props.page; - const onSelectPage = props.onSelectPage; - const options = { - showPages: 3, - ...(props.options || {}) - }; - - let totalPages = Math.floor(total / pageSize); - let first = Math.max(0, page - options.showPages); - let firstDiff = page - first; - let last = Math.min(totalPages, page + options.showPages + options.showPages - firstDiff); - - let buttons = []; - for (let x = first; x <= last; x++) { - buttons.push(
onSelectPage(x)} key={x} className={page === x ? "active" : null}> - {x + 1} -
); - } - - return ( -
-
onSelectPage(0)}><<
- {buttons} -
onSelectPage(totalPages)}>>>
- Total: {total} -
- ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/PageSelector.tsx b/VoidCat/spa/src/Components/Shared/PageSelector.tsx new file mode 100644 index 0000000..f635a7b --- /dev/null +++ b/VoidCat/spa/src/Components/Shared/PageSelector.tsx @@ -0,0 +1,43 @@ +import "./PageSelector.css"; + +interface PageSelectorProps { + total: number + pageSize: number + page: number + onSelectPage?: (v: number) => void + options?: { + showPages: number + } +} + +export function PageSelector(props: PageSelectorProps) { + const total = props.total; + const pageSize = props.pageSize; + const page = props.page; + const onSelectPage = props.onSelectPage; + const options = { + showPages: 3, + ...props.options + }; + + const totalPages = Math.floor(total / pageSize); + const first = Math.max(0, page - options.showPages); + const firstDiff = page - first; + const last = Math.min(totalPages, page + options.showPages + options.showPages - firstDiff); + + const buttons = []; + for (let x = first; x <= last; x++) { + buttons.push(
onSelectPage?.(x)} key={x} className={page === x ? "active" : ""}> + {x + 1} +
); + } + + return ( +
+
onSelectPage?.(0)}><<
+ {buttons} +
onSelectPage?.(totalPages)}>>>
+ Total: {total} +
+ ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/RateCalculator.js b/VoidCat/spa/src/Components/Shared/RateCalculator.js deleted file mode 100644 index e8be691..0000000 --- a/VoidCat/spa/src/Components/Shared/RateCalculator.js +++ /dev/null @@ -1,58 +0,0 @@ -export class RateCalculator { - constructor() { - this.Reset(); - this.fileSize = 0; - } - - SetFileSize(size) { - this.fileSize = size; - } - - GetProgress() { - return this.progress; - } - - GetSpeed() { - return this.speed; - } - - Reset() { - this.reports = []; - this.lastLoaded = 0; - this.progress = 0; - this.speed = 0; - } - - ReportProgress(amount) { - this.reports.push({ - time: new Date().getTime(), - amount - }); - this.lastLoaded += amount; - this.progress = this.lastLoaded / parseFloat(this.fileSize); - this.speed = this.RateWindow(5); - } - - ReportLoaded(loaded) { - this.reports.push({ - time: new Date().getTime(), - amount: loaded - this.lastLoaded - }); - this.lastLoaded = loaded; - this.progress = this.lastLoaded / parseFloat(this.fileSize); - this.speed = this.RateWindow(5); - } - - RateWindow(s) { - let total = 0.0; - - let windowStart = new Date().getTime() - (s * 1000); - for (let r of this.reports) { - if (r.time >= windowStart) { - total += r.amount; - } - } - - return total / s; - } -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/RateCalculator.ts b/VoidCat/spa/src/Components/Shared/RateCalculator.ts new file mode 100644 index 0000000..9ee258a --- /dev/null +++ b/VoidCat/spa/src/Components/Shared/RateCalculator.ts @@ -0,0 +1,68 @@ +interface RateReport { + time: number + amount: number +} + +export class RateCalculator { + #reports: Array = []; + #lastLoaded = 0; + #progress = 0; + #speed = 0; + #fileSize = 0; + + constructor() { + this.Reset(); + } + + SetFileSize(size: number) { + this.#fileSize = size; + } + + GetProgress() { + return this.#progress; + } + + GetSpeed() { + return this.#speed; + } + + Reset() { + this.#reports = []; + this.#lastLoaded = 0; + this.#progress = 0; + this.#speed = 0; + } + + ReportProgress(amount: number) { + this.#reports.push({ + time: new Date().getTime(), + amount + }); + this.#lastLoaded += amount; + this.#progress = this.#lastLoaded / this.#fileSize; + this.#speed = this.RateWindow(5); + } + + ReportLoaded(loaded: number) { + this.#reports.push({ + time: new Date().getTime(), + amount: loaded - this.#lastLoaded + }); + this.#lastLoaded = loaded; + this.#progress = this.#lastLoaded / this.#fileSize; + this.#speed = this.RateWindow(5); + } + + RateWindow(s: number) { + let total = 0.0; + + const windowStart = new Date().getTime() - (s * 1000); + for (let r of this.#reports) { + if (r.time >= windowStart) { + total += r.amount; + } + } + + return total / s; + } +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/VoidButton.js b/VoidCat/spa/src/Components/Shared/VoidButton.js deleted file mode 100644 index 54a2803..0000000 --- a/VoidCat/spa/src/Components/Shared/VoidButton.js +++ /dev/null @@ -1,41 +0,0 @@ -import {useEffect, useState} from "react"; -import FeatherIcon from "feather-icons-react"; - -export function VoidButton(props) { - const options = { - showSuccess: false, - ...props.options - }; - const [success, setSuccess] = useState(false); - - async function handleClick(e) { - if (e.target.classList.contains("disabled")) return; - e.target.classList.add("disabled"); - - let fn = props.onClick; - if (typeof fn === "function") { - let ret = fn(e); - if (typeof ret === "object" && typeof ret.then === "function") { - await ret; - } - setSuccess(options.showSuccess); - } - - e.target.classList.remove("disabled"); - } - - useEffect(() => { - if (success === true) { - setTimeout(() => setSuccess(false), 1000); - } - }, [success]); - - return ( -
-
-
{props.children}
-
- {success ?
: null} -
- ); -} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/VoidButton.tsx b/VoidCat/spa/src/Components/Shared/VoidButton.tsx new file mode 100644 index 0000000..b40a95b --- /dev/null +++ b/VoidCat/spa/src/Components/Shared/VoidButton.tsx @@ -0,0 +1,56 @@ +import React, {MouseEvent, ReactNode, useEffect, useState} from "react"; +import Icon from "./Icon"; + +interface VoidButtonProps { + onClick?: (e: MouseEvent) => Promise | unknown + options?: { + showSuccess: boolean + } + children: ReactNode +} + +export function VoidButton(props: VoidButtonProps) { + const options = { + showSuccess: false, + ...props.options + }; + const [disabled, setDisabled] = useState(false); + const [success, setSuccess] = useState(false); + + async function handleClick(e: MouseEvent) { + if (disabled) return; + setDisabled(true); + + let fn = props.onClick; + try { + if (typeof fn === "function") { + const ret = fn(e); + if (ret && typeof ret === "object" && "then" in ret) { + await (ret as Promise); + } + setSuccess(options.showSuccess); + } + } catch (e) { + console.error(e); + } + + setDisabled(false); + } + + useEffect(() => { + if (success) { + setTimeout(() => setSuccess(false), 1000); + } + }, [success]); + + return ( +
+
+
+ {props.children} +
+
+ {success &&
} +
+ ); +} \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/VoidModal.js b/VoidCat/spa/src/Components/Shared/VoidModal.tsx similarity index 69% rename from VoidCat/spa/src/Components/Shared/VoidModal.js rename to VoidCat/spa/src/Components/Shared/VoidModal.tsx index c3b90b9..9bb7d4f 100644 --- a/VoidCat/spa/src/Components/Shared/VoidModal.js +++ b/VoidCat/spa/src/Components/Shared/VoidModal.tsx @@ -1,6 +1,12 @@ import "./VoidModal.css"; +import {CSSProperties, ReactNode} from "react"; -export default function VoidModal(props) { +interface VoidModalProps { + title?: string + style?: CSSProperties + children: ReactNode +} +export default function VoidModal(props: VoidModalProps) { const title = props.title; const style = props.style; diff --git a/VoidCat/spa/src/Components/Shared/Const.js b/VoidCat/spa/src/Const.ts similarity index 61% rename from VoidCat/spa/src/Components/Shared/Const.js rename to VoidCat/spa/src/Const.ts index c9770ca..3f70ccc 100644 --- a/VoidCat/spa/src/Components/Shared/Const.js +++ b/VoidCat/spa/src/Const.ts @@ -35,40 +35,4 @@ export const ZiB = Math.pow(1024, 7); /** * @constant {number} - Size of 1 YiB */ -export const YiB = Math.pow(1024, 8); - -export const PaymentCurrencies = { - BTC: 0, - USD: 1, - EUR: 2, - GBP: 3 -} - -export const PaymentServices = { - None: 0, - Strike: 1 -} - -export const PaymentOrderState = { - Unpaid: 0, - Paid: 1, - Expired: 2 -} - -export const PagedSortBy = { - Name: 0, - Date: 1, - Size: 2, - Id: 3 -} - -export const PageSortOrder = { - Asc: 0, - Dsc: 1 -} - -export const UserFlags = { - PublicProfile: 1, - PublicUploads: 2, - EmailVerified: 4 -} \ No newline at end of file +export const YiB = Math.pow(1024, 8); \ No newline at end of file diff --git a/VoidCat/spa/src/Hooks/UseApi.tsx b/VoidCat/spa/src/Hooks/UseApi.tsx new file mode 100644 index 0000000..a40bab4 --- /dev/null +++ b/VoidCat/spa/src/Hooks/UseApi.tsx @@ -0,0 +1,10 @@ +import {useSelector} from "react-redux"; + +import {RootState} from "Store"; +import {VoidApi} from "Api"; +import {ApiHost} from "Const"; + +export default function useApi() { + const auth = useSelector((s: RootState) => s.login.jwt); + return new VoidApi(ApiHost, auth); +} \ No newline at end of file diff --git a/VoidCat/spa/src/LoginState.js b/VoidCat/spa/src/LoginState.ts similarity index 50% rename from VoidCat/spa/src/LoginState.js rename to VoidCat/spa/src/LoginState.ts index c87118b..98c1648 100644 --- a/VoidCat/spa/src/LoginState.js +++ b/VoidCat/spa/src/LoginState.ts @@ -1,24 +1,35 @@ -import {createSlice} from "@reduxjs/toolkit"; +import {createSlice, PayloadAction} from "@reduxjs/toolkit"; +import {Profile} from "./Api"; + +interface LoginStore { + jwt?: string + profile?: Profile +} + +interface SetAuthPayload { + jwt: string + profile?: Profile +} const LocalStorageKey = "token"; export const LoginState = createSlice({ name: "Login", initialState: { - jwt: window.localStorage.getItem(LocalStorageKey), - profile: null - }, + jwt: window.localStorage.getItem(LocalStorageKey) ?? undefined, + profile: undefined + } as LoginStore, reducers: { - setAuth: (state, action) => { + setAuth: (state, action: PayloadAction) => { state.jwt = action.payload.jwt; state.profile = action.payload.profile; window.localStorage.setItem(LocalStorageKey, state.jwt); }, - setProfile: (state, action) => { + setProfile: (state, action: PayloadAction) => { state.profile = action.payload; }, logout: (state) => { - state.jwt = null; - state.profile = null; + state.jwt = undefined; + state.profile = undefined; window.localStorage.removeItem(LocalStorageKey); } } diff --git a/VoidCat/spa/src/Pages/Donate.js b/VoidCat/spa/src/Pages/Donate.tsx similarity index 100% rename from VoidCat/spa/src/Pages/Donate.js rename to VoidCat/spa/src/Pages/Donate.tsx diff --git a/VoidCat/spa/src/Pages/FilePreview.js b/VoidCat/spa/src/Pages/FilePreview.tsx similarity index 81% rename from VoidCat/spa/src/Pages/FilePreview.js rename to VoidCat/spa/src/Pages/FilePreview.tsx index 6a4291f..efec3e9 100644 --- a/VoidCat/spa/src/Pages/FilePreview.js +++ b/VoidCat/spa/src/Pages/FilePreview.tsx @@ -1,35 +1,35 @@ import "./FilePreview.css"; import {Fragment, useEffect, useState} from "react"; import {useParams} from "react-router-dom"; -import FeatherIcon from "feather-icons-react"; import {Helmet} from "react-helmet"; import {TextPreview} from "../Components/FilePreview/TextPreview"; import {FileEdit} from "../Components/FileEdit/FileEdit"; import {FilePayment} from "../Components/FilePreview/FilePayment"; -import {useApi} from "../Components/Shared/Api"; -import {FormatBytes} from "../Components/Shared/Util"; -import {ApiHost} from "../Components/Shared/Const"; import {InlineProfile} from "../Components/Shared/InlineProfile"; -import {StreamEncryption} from "../Components/Shared/StreamEncryption"; import {VoidButton} from "../Components/Shared/VoidButton"; import {useFileTransfer} from "../Components/Shared/FileTransferHook"; +import Icon from "../Components/Shared/Icon"; + +import useApi from "Hooks/UseApi"; +import {PaymentOrder, VoidFileResponse, StreamEncryption} from "Api"; +import {FormatBytes} from "Util"; +import {ApiHost} from "Const"; export function FilePreview() { - const {Api} = useApi(); + const Api = useApi(); const params = useParams(); - const [info, setInfo] = useState(); - const [order, setOrder] = useState(); + const [info, setInfo] = useState(); + const [order, setOrder] = useState(); const [link, setLink] = useState("#"); const [key, setKey] = useState(""); const [error, setError] = useState(""); const {speed, progress, update, setFileSize} = useFileTransfer(); async function loadInfo() { - let req = await Api.fileInfo(params.id); - if (req.ok) { - let info = await req.json(); - setInfo(info); + if (params.id) { + const i = await Api.fileInfo(params.id); + setInfo(i); } } @@ -56,6 +56,8 @@ export function FilePreview() { } async function decryptFile() { + if (!info) return; + try { let hashKey = key.match(/([0-9a-z]{32}):([0-9a-z]{24})/); if (hashKey?.length === 3) { @@ -64,22 +66,25 @@ export function FilePreview() { let rsp = await fetch(link); if (rsp.ok) { - let reader = rsp.body - .pipeThrough(enc.getDecryptionTransform()) + const reader = rsp.body?.pipeThrough(enc.getDecryptionTransform()) .pipeThrough(decryptionProgressTransform()); - let newResponse = new Response(reader); - setLink(window.URL.createObjectURL(await newResponse.blob(), {type: info.metadata.mimeType})); + const newResponse = new Response(reader); + setLink(window.URL.createObjectURL(await newResponse.blob())); } } else { setError("Invalid encryption key format"); } } catch (e) { - setError(e.message); + if (e instanceof Error) { + setError(e.message); + } else { + setError("Unknown error") + } } } function decryptionProgressTransform() { - return new window.TransformStream({ + return new TransformStream({ transform: (chunk, controller) => { update(chunk.length); controller.enqueue(chunk); @@ -95,24 +100,22 @@ export function FilePreview() { setKey(e.target.value)}/> decryptFile()}>Decrypt - {progress > 0 ? `${(100 * progress).toFixed(0)}% (${FormatBytes(speed)}/s)` : null} - {error ?

{error}

: null} + {progress > 0 && `${(100 * progress).toFixed(0)}% (${FormatBytes(speed)}/s)`} + {error &&

{error}

}
); } function renderPayment() { - if (info.payment && info.payment.service !== 0) { - if (!order) { - return ; - } - } + if (!info) return; - return null; + if (info.payment && info.payment.service !== 0 && !order) { + return ; + } } function renderPreview() { - if (!canAccessFile()) return; + if (!canAccessFile() || !info) return; if (info.metadata) { switch (info.metadata.mimeType) { @@ -163,11 +166,10 @@ export function FilePreview() { } } } - return null; } function renderOpenGraphTags() { - let tags = [ + const tags = [ , , , @@ -190,7 +192,7 @@ export function FilePreview() { } function renderVirusWarning() { - if (info.virusScan && info.virusScan.isVirus === true) { + if (info?.virusScan?.isVirus === true) { let scanResult = info.virusScan; return (
@@ -207,17 +209,17 @@ export function FilePreview() { } useEffect(() => { - loadInfo(); + loadInfo().catch(console.error); }, []); useEffect(() => { if (info) { - let fileLink = info.metadata?.url ?? `${ApiHost}/d/${info.id}`; - setFileSize(info.metadata.size); + const fileLink = info.metadata?.url ?? `${ApiHost}/d/${info.id}`; + setFileSize(info.metadata?.size ?? 0); - let order = window.localStorage.getItem(`payment-${info.id}`); + const order = window.localStorage.getItem(`payment-${info.id}`); if (order) { - let orderObj = JSON.parse(order); + const orderObj = JSON.parse(order); setOrder(orderObj); setLink(`${fileLink}?orderId=${orderObj.id}`); } else { @@ -246,17 +248,17 @@ export function FilePreview() { <> - + Magnet - + Torrent - + Direct Download } @@ -267,11 +269,11 @@ export function FilePreview() { {renderEncryptedDownload()}
- + {FormatBytes(info?.bandwidth?.egress ?? 0, 2)}
- + {FormatBytes(info?.metadata?.size ?? 0, 2)}
diff --git a/VoidCat/spa/src/Pages/HomePage.js b/VoidCat/spa/src/Pages/HomePage.tsx similarity index 57% rename from VoidCat/spa/src/Pages/HomePage.js rename to VoidCat/spa/src/Pages/HomePage.tsx index 110710d..fa821d7 100644 --- a/VoidCat/spa/src/Pages/HomePage.js +++ b/VoidCat/spa/src/Pages/HomePage.tsx @@ -1,16 +1,19 @@ -import {Dropzone} from "../Components/FileUpload/Dropzone"; +import {useSelector} from "react-redux"; + +import {Dropzone} from "../Components/FileUpload/Dropzone"; import {GlobalStats} from "../Components/HomePage/GlobalStats"; import {FooterLinks} from "../Components/HomePage/FooterLinks"; import {MetricsGraph} from "../Components/HomePage/MetricsGraph"; -import {useSelector} from "react-redux"; + +import {RootState} from "Store"; export function HomePage() { - const metrics = useSelector(a => a.info.info); + const metrics = useSelector((s: RootState) => s.info.info); return (
- +
); diff --git a/VoidCat/spa/src/Pages/Profile.js b/VoidCat/spa/src/Pages/Profile.tsx similarity index 54% rename from VoidCat/spa/src/Pages/Profile.js rename to VoidCat/spa/src/Pages/Profile.tsx index 21f0b59..9f61b69 100644 --- a/VoidCat/spa/src/Pages/Profile.js +++ b/VoidCat/spa/src/Pages/Profile.tsx @@ -1,129 +1,105 @@ import "./Profile.css"; import {Fragment, useEffect, useState} from "react"; import {useDispatch, useSelector} from "react-redux"; -import moment from "moment"; +import {default as moment} from "moment"; import {useParams} from "react-router-dom"; -import {useApi} from "../Components/Shared/Api"; -import {ApiHost, DefaultAvatar, UserFlags} from "../Components/Shared/Const"; +import useApi from "Hooks/UseApi"; +import {RootState} from "Store"; +import {Profile} from "Api"; +import {DefaultAvatar} from "Const"; + import {logout, setProfile as setGlobalProfile} from "../LoginState"; -import {DigestAlgo} from "../Components/FileUpload/FileUpload"; -import {buf2hex, hasFlag} from "../Components/Shared/Util"; import {FileList} from "../Components/Shared/FileList"; import {VoidButton} from "../Components/Shared/VoidButton"; import ApiKeyList from "../Components/Profile/ApiKeyList"; -export function Profile() { - const [profile, setProfile] = useState(); - const [noProfile, setNoProfile] = useState(false); +export function ProfilePage() { + const dispatch = useDispatch(); + const params = useParams(); + const Api = useApi(); + + const [profile, setProfile] = useState(); + const [noProfile, setNoProfile] = useState(); const [emailCode, setEmailCode] = useState(""); const [emailCodeError, setEmailCodeError] = useState(""); const [newCodeSent, setNewCodeSent] = useState(false); - const auth = useSelector(state => state.login.jwt); - const localProfile = useSelector(state => state.login.profile); + + const auth = useSelector((s: RootState) => s.login.jwt); + const localProfile = useSelector((s: RootState) => s.login.profile); const canEdit = localProfile?.id === profile?.id; - const needsEmailVerify = canEdit && (profile?.flags & UserFlags.EmailVerified) !== UserFlags.EmailVerified; + const needsEmailVerify = canEdit && profile?.needsVerification === true; const cantEditProfile = canEdit && !needsEmailVerify; - const {Api} = useApi(); - const params = useParams(); - const dispatch = useDispatch(); - async function loadProfile() { - let p = await Api.getUser(params.id); - if (p.ok && p.status === 200) { - setProfile(await p.json()); - } else { + async function loadProfile(id: string) { + try { + let p = await Api.getUser(id); + setProfile(p); + } catch (e) { + console.error(e); setNoProfile(true); } } - function editUsername(v) { - setProfile({ - ...profile, - displayName: v - }); - } - - function toggleFlag(v) { - setProfile({ - ...profile, - flags: (profile.flags ^ v) - }); - } - async function changeAvatar() { - let res = await new Promise((resolve, reject) => { + const res = await new Promise>((resolve) => { let i = document.createElement('input'); i.setAttribute('type', 'file'); i.setAttribute('multiple', ''); i.addEventListener('change', async function (evt) { - resolve(evt.target.files); + resolve((evt.target as any).files); }); i.click(); }); const file = res[0]; - const buf = await file.arrayBuffer(); - const digest = await crypto.subtle.digest(DigestAlgo, buf); - - let req = await fetch(`${ApiHost}/upload`, { - mode: "cors", - method: "POST", - body: buf, - headers: { - "Content-Type": "application/octet-stream", - "V-Content-Type": file.type, - "V-Filename": file.name, - "V-Digest": buf2hex(digest), - "Authorization": `Bearer ${auth}` - } - }); - - if (req.ok) { - let rsp = await req.json(); - if (rsp.ok) { - setProfile({ - ...profile, - avatar: rsp.file.id - }); - } + const noop = (_: any) => { + }; + const uploader = Api.getUploader(file, noop, noop, noop); + const rsp = await uploader.upload(); + if (rsp.ok) { + setProfile({ + ...profile, + avatar: rsp.file?.id + } as Profile); } } - async function saveUser(e) { - let r = await Api.updateUser({ - id: profile.id, - avatar: profile.avatar, - displayName: profile.displayName, - flags: profile.flags - }); - if (r.ok) { - // saved - dispatch(setGlobalProfile(profile)); + async function saveUser(p: Profile) { + try { + await Api.updateUser(p); + dispatch(setGlobalProfile(p)); + } catch (e) { + console.error(e); } } - async function submitCode(e) { - let r = await Api.submitVerifyCode(profile.id, emailCode); - if (r.ok) { - await loadProfile(); - } else { + async function submitCode(id: string, code: string) { + try { + await Api.submitVerifyCode(id, code); + await loadProfile(id); + } catch (e) { + console.error(e); setEmailCodeError("Invalid or expired code."); } } - async function sendNewCode() { + async function sendNewCode(id: string) { setNewCodeSent(true); - let r = await Api.sendNewCode(profile.id); - if (!r.ok) { + try { + await Api.sendNewCode(id); + } catch (e) { + console.error(e); setNewCodeSent(false); } } function renderEmailVerify() { + if (!profile) return; + return (

Please enter email verification code

@@ -132,37 +108,50 @@ export function Profile() {
setEmailCode(e.target.value)}/> - Submit - dispatch(logout())}>Logout + submitCode(profile.id, emailCode)}>Submit + { + dispatch(logout()); + }}>Logout
- {emailCodeError ? {emailCodeError} : null} - {emailCodeError && !newCodeSent ? Send verfication email : null} + {emailCodeError && {emailCodeError}} + {(emailCodeError && !newCodeSent) && + sendNewCode(profile.id)}>Send verification email}
); } function renderProfileEdit() { + if (!profile) return; + return (
Public Profile:
- toggleFlag(UserFlags.PublicProfile)}/> + setProfile({ + ...profile, + publicProfile: e.target.checked + })}/>
Public Uploads:
- toggleFlag(UserFlags.PublicUploads)}/> + setProfile({ + ...profile, + publicUploads: e.target.checked + })}/>
- Save + saveUser(profile)} options={{showSuccess: true}}>Save
- dispatch(logout())}>Logout + { + dispatch(logout()); + }}>Logout
@@ -170,8 +159,10 @@ export function Profile() { } useEffect(() => { - loadProfile(); - }, []); + if (params.id) { + loadProfile(params.id).catch(console.error); + } + }, [params]); if (profile) { let avatarUrl = profile.avatar ?? DefaultAvatar; @@ -187,9 +178,12 @@ export function Profile() {
{cantEditProfile ? - editUsername(e.target.value)}/> - : profile.displayName} + setProfile({ + ...profile, + name: e.target.value + })}/> + : profile.name}
@@ -216,7 +210,7 @@ export function Profile() {
); - } else if (noProfile === true) { + } else if (noProfile) { return (

No profile found :(

diff --git a/VoidCat/spa/src/Pages/UserLogin.js b/VoidCat/spa/src/Pages/UserLogin.tsx similarity index 81% rename from VoidCat/spa/src/Pages/UserLogin.js rename to VoidCat/spa/src/Pages/UserLogin.tsx index 66dd302..d2ca6fd 100644 --- a/VoidCat/spa/src/Pages/UserLogin.js +++ b/VoidCat/spa/src/Pages/UserLogin.tsx @@ -1,10 +1,12 @@ -import {Login} from "../Components/Shared/Login"; import {useSelector} from "react-redux"; import {useNavigate} from "react-router-dom"; import {useEffect} from "react"; +import {Login} from "../Components/Shared/Login"; +import {RootState} from "Store"; + export function UserLogin() { - const auth = useSelector((state) => state.login.jwt); + const auth = useSelector((s: RootState) => s.login.jwt); const navigate = useNavigate(); useEffect(() => { diff --git a/VoidCat/spa/src/SiteInfoStore.js b/VoidCat/spa/src/SiteInfoStore.ts similarity index 53% rename from VoidCat/spa/src/SiteInfoStore.js rename to VoidCat/spa/src/SiteInfoStore.ts index cc8fe9e..e4ab9a7 100644 --- a/VoidCat/spa/src/SiteInfoStore.js +++ b/VoidCat/spa/src/SiteInfoStore.ts @@ -1,12 +1,13 @@ -import {createSlice} from "@reduxjs/toolkit"; +import {createSlice, PayloadAction} from "@reduxjs/toolkit"; +import {SiteInfoResponse} from "Api"; export const SiteInfoState = createSlice({ name: "SiteInfo", initialState: { - info: null + info: null as SiteInfoResponse | null }, reducers: { - setInfo: (state, action) => { + setInfo: (state, action: PayloadAction) => { state.info = action.payload; }, } diff --git a/VoidCat/spa/src/Store.js b/VoidCat/spa/src/Store.ts similarity index 57% rename from VoidCat/spa/src/Store.js rename to VoidCat/spa/src/Store.ts index ad55b26..7ccb6d0 100644 --- a/VoidCat/spa/src/Store.js +++ b/VoidCat/spa/src/Store.ts @@ -2,9 +2,13 @@ import loginReducer from "./LoginState"; import siteInfoReducer from "./SiteInfoStore"; -export default configureStore({ +const store = configureStore({ reducer: { login: loginReducer, info: siteInfoReducer } -}); \ No newline at end of file +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; +export default store; \ No newline at end of file diff --git a/VoidCat/spa/src/Components/Shared/Util.js b/VoidCat/spa/src/Util.ts similarity index 76% rename from VoidCat/spa/src/Components/Shared/Util.js rename to VoidCat/spa/src/Util.ts index 74b45d0..3b08d9a 100644 --- a/VoidCat/spa/src/Components/Shared/Util.js +++ b/VoidCat/spa/src/Util.ts @@ -1,13 +1,13 @@ -import * as Const from "./Const"; +import * as Const from "Const"; /** * Formats bytes into binary notation - * @param {number} b - The value in bytes - * @param {number} [f=2] - The number of decimal places to use - * @returns {string} Bytes formatted in binary notation + * @param b The value in bytes + * @param f The number of decimal places to use + * @returns Bytes formatted in binary notation */ -export function FormatBytes(b, f) { - f = typeof f === 'number' ? 2 : f; +export function FormatBytes(b: number, f?: number) { + f ??= 2; if (b >= Const.YiB) return (b / Const.YiB).toFixed(f) + ' YiB'; if (b >= Const.ZiB) @@ -27,11 +27,11 @@ export function FormatBytes(b, f) { return b.toFixed(f) + ' B' } -export function buf2hex(buffer) { +export function buf2hex(buffer: number[] | ArrayBuffer) { return [...new Uint8Array(buffer)].map(x => x.toString(16).padStart(2, '0')).join(''); } -export function ConstName(type, val) { +export function ConstName(type: object, val: any) { for (let [k, v] of Object.entries(type)) { if (v === val) { return k; @@ -39,10 +39,7 @@ export function ConstName(type, val) { } } -export function FormatCurrency(value, currency) { - if (typeof value !== "number") { - value = parseFloat(value); - } +export function FormatCurrency(value: number, currency: string | number) { switch (currency) { case 0: case "BTC": { @@ -75,8 +72,4 @@ export function FormatCurrency(value, currency) { } } return value.toString(); -} - -export function hasFlag(value, flag) { - return (value & flag) === flag; } \ No newline at end of file diff --git a/VoidCat/spa/src/index.js b/VoidCat/spa/src/index.js deleted file mode 100644 index d7a2cad..0000000 --- a/VoidCat/spa/src/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; -import './index.css'; - -ReactDOM.render( - - - , - document.getElementById('root') -); \ No newline at end of file diff --git a/VoidCat/spa/src/index.tsx b/VoidCat/spa/src/index.tsx new file mode 100644 index 0000000..2eb28d2 --- /dev/null +++ b/VoidCat/spa/src/index.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; + +import './index.css'; +import App from './App'; + +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); +root.render( + + + +); \ No newline at end of file diff --git a/VoidCat/spa/tsconfig.json b/VoidCat/spa/tsconfig.json new file mode 100644 index 0000000..1e1e06d --- /dev/null +++ b/VoidCat/spa/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "baseUrl": "src", + "target": "es2020", + "jsx": "react-jsx", + "moduleResolution": "node", + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "allowJs": true + } +} diff --git a/VoidCat/spa/yarn.lock b/VoidCat/spa/yarn.lock index 1968208..e72a305 100644 --- a/VoidCat/spa/yarn.lock +++ b/VoidCat/spa/yarn.lock @@ -2,12 +2,17 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" "@apideck/better-ajv-errors@^0.3.1": @@ -19,55 +24,56 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.8.3": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4", "@babel/code-frame@^7.8.3": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" + integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.0.tgz#2a592fd89bacb1fcde68de31bee4f2f2dacb0e86" - integrity sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw== +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5": + version "7.21.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.7.tgz#61caffb60776e49a57ba61a88f02bedd8714f6bc" + integrity sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA== "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.0.tgz#d2f5f4f2033c00de8096be3c9f45772563e150c3" - integrity sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ== + version "7.21.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.8.tgz#2a8c7f0f53d60100ba4c32470ba0281c92aa9aa4" + integrity sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ== dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" - "@babel/helper-compilation-targets" "^7.19.0" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.5" + "@babel/helper-compilation-targets" "^7.21.5" + "@babel/helper-module-transforms" "^7.21.5" + "@babel/helpers" "^7.21.5" + "@babel/parser" "^7.21.8" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.1" + json5 "^2.2.2" semver "^6.3.0" "@babel/eslint-parser@^7.16.3": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.18.9.tgz#255a63796819a97b7578751bb08ab9f2a375a031" - integrity sha512-KzSGpMBggz4fKbRbWLNyPVTuQr6cmCcBhOyXTw/fieOVaw5oYAwcAj4a7UKcDYCPxQq+CG1NCDZH9e2JTXquiQ== + version "7.21.8" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz#59fb6fc4f3b017ab86987c076226ceef7b2b2ef2" + integrity sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ== dependencies: - eslint-scope "^5.1.1" + "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" semver "^6.3.0" -"@babel/generator@^7.19.0", "@babel/generator@^7.7.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a" - integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg== +"@babel/generator@^7.21.5", "@babel/generator@^7.7.2": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.5.tgz#c0c0e5449504c7b7de8236d99338c3e2a340745f" + integrity sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w== dependencies: - "@babel/types" "^7.19.0" + "@babel/types" "^7.21.5" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" "@babel/helper-annotate-as-pure@^7.18.6": @@ -78,48 +84,51 @@ "@babel/types" "^7.18.6" "@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz#817f73b6c59726ab39f6ba18c234268a519e5abb" + integrity sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g== dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" + "@babel/types" "^7.21.5" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz#537ec8339d53e806ed422f1e06c8f17d55b96bb0" - integrity sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA== +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz#631e6cc784c7b660417421349aac304c94115366" + integrity sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w== dependencies: - "@babel/compat-data" "^7.19.0" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.20.2" + "@babel/compat-data" "^7.21.5" + "@babel/helper-validator-option" "^7.21.0" + browserslist "^4.21.3" + lru-cache "^5.1.1" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b" - integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": + version "7.21.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz#205b26330258625ef8869672ebca1e0dee5a0f02" + integrity sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-environment-visitor" "^7.21.5" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-member-expression-to-functions" "^7.21.5" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-replace-supers" "^7.21.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/helper-split-export-declaration" "^7.18.6" + semver "^6.3.0" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" - integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": + version "7.21.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz#a7886f61c2e29e21fd4aaeaf1e473deba6b571dc" + integrity sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.1.0" + regexpu-core "^5.3.1" + semver "^6.3.0" -"@babel/helper-define-polyfill-provider@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz#bd10d0aca18e8ce012755395b05a79f45eca5073" - integrity sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg== +"@babel/helper-define-polyfill-provider@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" + integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== dependencies: "@babel/helper-compilation-targets" "^7.17.7" "@babel/helper-plugin-utils" "^7.16.7" @@ -128,25 +137,18 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== +"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz#c769afefd41d171836f7cb63e295bedf689d48ba" + integrity sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ== -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== +"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" + "@babel/template" "^7.20.7" + "@babel/types" "^7.21.0" "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" @@ -155,33 +157,33 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-member-expression-to-functions@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" - integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== +"@babel/helper-member-expression-to-functions@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz#3b1a009af932e586af77c1030fba9ee0bde396c0" + integrity sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.21.5" -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" + integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.21.4" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" - integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz#d937c82e9af68d31ab49039136a222b17ac0b420" + integrity sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-environment-visitor" "^7.21.5" + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-simple-access" "^7.21.5" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.18.6" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" @@ -190,12 +192,12 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" - integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.21.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56" + integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg== -"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": +"@babel/helper-remap-async-to-generator@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== @@ -205,30 +207,31 @@ "@babel/helper-wrap-function" "^7.18.9" "@babel/types" "^7.18.9" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" - integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7", "@babel/helper-replace-supers@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz#a6ad005ba1c7d9bc2973dfde05a1bba7065dde3c" + integrity sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-environment-visitor" "^7.21.5" + "@babel/helper-member-expression-to-functions" "^7.21.5" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" -"@babel/helper-simple-access@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" - integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== +"@babel/helper-simple-access@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz#d697a7971a5c39eac32c7e63c0921c06c8a249ee" + integrity sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.21.5" -"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" - integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" + integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.20.0" "@babel/helper-split-export-declaration@^7.18.6": version "7.18.6" @@ -237,39 +240,39 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-string-parser@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" - integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== +"@babel/helper-string-parser@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd" + integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w== -"@babel/helper-validator-identifier@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" - integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== +"@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" + integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== "@babel/helper-wrap-function@^7.18.9": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1" - integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3" + integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== dependencies: "@babel/helper-function-name" "^7.19.0" "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" -"@babel/helpers@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" - integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== +"@babel/helpers@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.5.tgz#5bac66e084d7a4d2d9696bdf0175a93f7fb63c08" + integrity sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA== dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" "@babel/highlight@^7.18.6": version "7.18.6" @@ -280,10 +283,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c" - integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8": + version "7.21.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8" + integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -292,22 +295,22 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" - integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz#d9c85589258539a22a901033853101a6198d4ef1" + integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/plugin-proposal-optional-chaining" "^7.20.7" -"@babel/plugin-proposal-async-generator-functions@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.0.tgz#cf5740194f170467df20581712400487efc79ff1" - integrity sha512-nhEByMUTx3uZueJ/QkJuSlCfN4FGg+xy+vRsfGQGzSauq5ks2Deid2+05Q3KhfaUjvec1IGhw/Zm3cFm8JigTQ== +"@babel/plugin-proposal-async-generator-functions@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326" + integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== dependencies: "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-syntax-async-generators" "^7.8.4" @@ -319,25 +322,25 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" - integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== +"@babel/plugin-proposal-class-static-block@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz#77bdd66fb7b605f3a61302d224bdfacf5547977d" + integrity sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-proposal-decorators@^7.16.4": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.0.tgz#5a3bc0699ee34117c73c960a5396ffce104c4eaa" - integrity sha512-Bo5nOSjiJccjv00+BrDkmfeBLBi2B0qe8ygj24KdL8VdwtZz+710NCwehF+x/Ng+0mkHx5za2eAofmvVFLF4Fg== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz#70e0c89fdcd7465c97593edb8f628ba6e4199d63" + integrity sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.20.7" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/plugin-syntax-decorators" "^7.19.0" + "@babel/plugin-syntax-decorators" "^7.21.0" "@babel/plugin-proposal-dynamic-import@^7.18.6": version "7.18.6" @@ -363,12 +366,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" - integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== +"@babel/plugin-proposal-logical-assignment-operators@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz#dfbcaa8f7b4d37b51e8bfb46d94a5aea2bb89d83" + integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": @@ -387,16 +390,16 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" - integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== +"@babel/plugin-proposal-object-rest-spread@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-parameters" "^7.20.7" "@babel/plugin-proposal-optional-catch-binding@^7.18.6": version "7.18.6" @@ -406,13 +409,13 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.16.0", "@babel/plugin-proposal-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" - integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== +"@babel/plugin-proposal-optional-chaining@^7.16.0", "@babel/plugin-proposal-optional-chaining@^7.20.7", "@babel/plugin-proposal-optional-chaining@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-proposal-private-methods@^7.16.0", "@babel/plugin-proposal-private-methods@^7.18.6": @@ -423,14 +426,14 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" - integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== +"@babel/plugin-proposal-private-property-in-object@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz#19496bd9883dd83c23c7d7fc45dcd9ad02dfa1dc" + integrity sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": @@ -469,12 +472,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599" - integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ== +"@babel/plugin-syntax-decorators@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz#d2b3f31c3e86fa86e16bb540b7660c55bd7d0e78" + integrity sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" @@ -491,20 +494,20 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-flow@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz#774d825256f2379d06139be0c723c4dd444f3ca1" - integrity sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A== + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz#3e37fca4f06d93567c1cd9b75156422e90a67107" + integrity sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-syntax-import-assertions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" - integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== +"@babel/plugin-syntax-import-assertions@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" + integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -518,12 +521,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== +"@babel/plugin-syntax-jsx@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" + integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -581,28 +584,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.18.6", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" - integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== +"@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz#2751948e9b7c6d771a8efa59340c15d4a2891ff8" + integrity sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-arrow-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" - integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== +"@babel/plugin-transform-arrow-functions@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz#9bb42a53de447936a57ba256fbf537fc312b6929" + integrity sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.21.5" -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" - integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== +"@babel/plugin-transform-async-to-generator@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz#dfee18623c8cb31deb796aa3ca84dda9cea94354" + integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== dependencies: "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-transform-block-scoped-functions@^7.18.6": version "7.18.6" @@ -611,41 +614,42 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoping@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" - integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== +"@babel/plugin-transform-block-scoping@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02" + integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-classes@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" - integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A== +"@babel/plugin-transform-classes@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz#f469d0b07a4c5a7dbb21afad9e27e57b47031665" + integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.19.0" + "@babel/helper-compilation-targets" "^7.20.7" "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" + "@babel/helper-function-name" "^7.21.0" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.20.7" "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" - integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== +"@babel/plugin-transform-computed-properties@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz#3a2d8bb771cd2ef1cd736435f6552fe502e11b44" + integrity sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/template" "^7.20.7" -"@babel/plugin-transform-destructuring@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" - integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== +"@babel/plugin-transform-destructuring@^7.21.3": + version "7.21.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz#73b46d0fd11cd6ef57dea8a381b1215f4959d401" + integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.18.6" @@ -671,19 +675,19 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-flow-strip-types@^7.16.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz#e9e8606633287488216028719638cbbb2f2dde8f" - integrity sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz#6aeca0adcb81dc627c8986e770bfaa4d9812aff5" + integrity sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-flow" "^7.18.6" -"@babel/plugin-transform-for-of@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== +"@babel/plugin-transform-for-of@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz#e890032b535f5a2e237a18535f56a9fdaa7b83fc" + integrity sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.21.5" "@babel/plugin-transform-function-name@^7.18.9": version "7.18.9" @@ -708,35 +712,32 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-modules-amd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" - integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== +"@babel/plugin-transform-modules-amd@^7.20.11": + version "7.20.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz#3daccca8e4cc309f03c3a0c4b41dc4b26f55214a" + integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.20.11" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-modules-commonjs@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" - integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== +"@babel/plugin-transform-modules-commonjs@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz#d69fb947eed51af91de82e4708f676864e5e47bc" + integrity sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.21.5" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-simple-access" "^7.21.5" -"@babel/plugin-transform-modules-systemjs@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f" - integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A== +"@babel/plugin-transform-modules-systemjs@^7.20.11": + version "7.20.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz#467ec6bba6b6a50634eea61c9c232654d8a4696e" + integrity sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw== dependencies: "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.20.11" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-validator-identifier" "^7.19.1" "@babel/plugin-transform-modules-umd@^7.18.6": version "7.18.6" @@ -746,13 +747,13 @@ "@babel/helper-module-transforms" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.0.tgz#58c52422e4f91a381727faed7d513c89d7f41ada" - integrity sha512-HDSuqOQzkU//kfGdiHBt71/hkDTApw4U/cMVgKgX7PqfB3LOaK+2GtCEsBu1dL9CkswDm0Gwehht1dCr421ULQ== +"@babel/plugin-transform-named-capturing-groups-regex@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8" + integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-create-regexp-features-plugin" "^7.20.5" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-new-target@^7.18.6": version "7.18.6" @@ -769,12 +770,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/helper-replace-supers" "^7.18.6" -"@babel/plugin-transform-parameters@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" - integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== +"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.21.3": + version "7.21.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz#18fc4e797cf6d6d972cb8c411dbe8a809fa157db" + integrity sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-property-literals@^7.18.6": version "7.18.6" @@ -784,11 +785,11 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-react-constant-elements@^7.12.1": - version "7.18.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.18.12.tgz#edf3bec47eb98f14e84fa0af137fcc6aad8e0443" - integrity sha512-Q99U9/ttiu+LMnRU8psd23HhvwXmKWDQIpocm0JKaICcZHnw+mdQbHm6xnSy7dOl8I5PELakYtNBubNQlBXbZw== + version "7.21.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.21.3.tgz#b32a5556100d424b25e388dd689050d78396884d" + integrity sha512-4DVcFeWe/yDYBLp0kBmOGFJ6N2UYg7coGid1gdxb4co62dy/xISDMaYBXBVXEDhfgMk7qkbcYiGtwd5Q/hwDDQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-react-display-name@^7.16.0", "@babel/plugin-transform-react-display-name@^7.18.6": version "7.18.6" @@ -805,15 +806,15 @@ "@babel/plugin-transform-react-jsx" "^7.18.6" "@babel/plugin-transform-react-jsx@^7.18.6": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9" - integrity sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg== + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.5.tgz#bd98f3b429688243e4fa131fe1cbb2ef31ce6f38" + integrity sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-jsx" "^7.18.6" - "@babel/types" "^7.19.0" + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/plugin-syntax-jsx" "^7.21.4" + "@babel/types" "^7.21.5" "@babel/plugin-transform-react-pure-annotations@^7.18.6": version "7.18.6" @@ -823,13 +824,13 @@ "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" - integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== +"@babel/plugin-transform-regenerator@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz#576c62f9923f94bcb1c855adc53561fd7913724e" + integrity sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - regenerator-transform "^0.15.0" + "@babel/helper-plugin-utils" "^7.21.5" + regenerator-transform "^0.15.1" "@babel/plugin-transform-reserved-words@^7.18.6": version "7.18.6" @@ -839,15 +840,15 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-runtime@^7.16.4": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.10.tgz#37d14d1fa810a368fd635d4d1476c0154144a96f" - integrity sha512-q5mMeYAdfEbpBAgzl7tBre/la3LeCxmDO1+wMXRdPWbcoMjR3GiXlCLk7JBZVVye0bqTGNMbt0yYVXX1B1jEWQ== + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz#2e1da21ca597a7d01fc96b699b21d8d2023191aa" + integrity sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.9" - babel-plugin-polyfill-corejs2 "^0.3.2" - babel-plugin-polyfill-corejs3 "^0.5.3" - babel-plugin-polyfill-regenerator "^0.4.0" + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-plugin-utils" "^7.20.2" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" semver "^6.3.0" "@babel/plugin-transform-shorthand-properties@^7.18.6": @@ -857,13 +858,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-spread@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" - integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== +"@babel/plugin-transform-spread@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz#c2d83e0b99d3bf83e07b11995ee24bf7ca09401e" + integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-transform-sticky-regex@^7.18.6": version "7.18.6" @@ -886,21 +887,22 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-typescript@^7.18.6": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.0.tgz#50c3a68ec8efd5e040bde2cd764e8e16bc0cbeaf" - integrity sha512-DOOIywxPpkQHXijXv+s9MDAyZcLp12oYRl3CMWZ6u7TjSoCBq/KqHR/nNFR3+i2xqheZxoF0H2XyL7B6xeSRuA== +"@babel/plugin-transform-typescript@^7.21.3": + version "7.21.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz#316c5be579856ea890a57ebc5116c5d064658f2b" + integrity sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-typescript" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.21.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-typescript" "^7.20.0" -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== +"@babel/plugin-transform-unicode-escapes@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz#1e55ed6195259b0e9061d81f5ef45a9b009fb7f2" + integrity sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.21.5" "@babel/plugin-transform-unicode-regex@^7.18.6": version "7.18.6" @@ -911,37 +913,38 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.0.tgz#fd18caf499a67d6411b9ded68dc70d01ed1e5da7" - integrity sha512-1YUju1TAFuzjIQqNM9WsF4U6VbD/8t3wEAlw3LFYuuEr+ywqLRcSXxFKz4DCEj+sN94l/XTDiUXYRrsvMpz9WQ== + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.21.5.tgz#db2089d99efd2297716f018aeead815ac3decffb" + integrity sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg== dependencies: - "@babel/compat-data" "^7.19.0" - "@babel/helper-compilation-targets" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-option" "^7.18.6" + "@babel/compat-data" "^7.21.5" + "@babel/helper-compilation-targets" "^7.21.5" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-validator-option" "^7.21.0" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.19.0" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.20.7" + "@babel/plugin-proposal-async-generator-functions" "^7.20.7" "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.21.0" "@babel/plugin-proposal-dynamic-import" "^7.18.6" "@babel/plugin-proposal-export-namespace-from" "^7.18.9" "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" + "@babel/plugin-proposal-logical-assignment-operators" "^7.20.7" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.18.9" + "@babel/plugin-proposal-object-rest-spread" "^7.20.7" "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-optional-chaining" "^7.21.0" "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.21.0" "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.18.6" + "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -951,44 +954,44 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.21.5" + "@babel/plugin-transform-async-to-generator" "^7.20.7" "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.18.9" - "@babel/plugin-transform-classes" "^7.19.0" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.18.13" + "@babel/plugin-transform-block-scoping" "^7.21.0" + "@babel/plugin-transform-classes" "^7.21.0" + "@babel/plugin-transform-computed-properties" "^7.21.5" + "@babel/plugin-transform-destructuring" "^7.21.3" "@babel/plugin-transform-dotall-regex" "^7.18.6" "@babel/plugin-transform-duplicate-keys" "^7.18.9" "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" + "@babel/plugin-transform-for-of" "^7.21.5" "@babel/plugin-transform-function-name" "^7.18.9" "@babel/plugin-transform-literals" "^7.18.9" "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.18.6" - "@babel/plugin-transform-modules-commonjs" "^7.18.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.0" + "@babel/plugin-transform-modules-amd" "^7.20.11" + "@babel/plugin-transform-modules-commonjs" "^7.21.5" + "@babel/plugin-transform-modules-systemjs" "^7.20.11" "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.20.5" "@babel/plugin-transform-new-target" "^7.18.6" "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-parameters" "^7.21.3" "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.21.5" "@babel/plugin-transform-reserved-words" "^7.18.6" "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" + "@babel/plugin-transform-spread" "^7.20.7" "@babel/plugin-transform-sticky-regex" "^7.18.6" "@babel/plugin-transform-template-literals" "^7.18.9" "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" + "@babel/plugin-transform-unicode-escapes" "^7.21.5" "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.19.0" - babel-plugin-polyfill-corejs2 "^0.3.2" - babel-plugin-polyfill-corejs3 "^0.5.3" - babel-plugin-polyfill-regenerator "^0.4.0" - core-js-compat "^3.22.1" + "@babel/types" "^7.21.5" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + core-js-compat "^3.25.1" semver "^6.3.0" "@babel/preset-modules@^0.1.5": @@ -1015,61 +1018,60 @@ "@babel/plugin-transform-react-pure-annotations" "^7.18.6" "@babel/preset-typescript@^7.16.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" - integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.21.5.tgz#68292c884b0e26070b4d66b202072d391358395f" + integrity sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-typescript" "^7.18.6" + "@babel/helper-plugin-utils" "^7.21.5" + "@babel/helper-validator-option" "^7.21.0" + "@babel/plugin-syntax-jsx" "^7.21.4" + "@babel/plugin-transform-modules-commonjs" "^7.21.5" + "@babel/plugin-transform-typescript" "^7.21.3" -"@babel/runtime-corejs3@^7.10.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.19.0.tgz#0df75cb8e5ecba3ca9e658898694e5326d52397f" - integrity sha512-JyXXoCu1N8GLuKc2ii8y5RGma5FMpFeO2nAQIe0Yzrbq+rQnN+sFj47auLblR5ka6aHNGPDgv8G/iI2Grb0ldQ== +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.9", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" + integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== dependencies: - core-js-pure "^3.20.2" - regenerator-runtime "^0.13.4" + regenerator-runtime "^0.13.11" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.9", "@babel/runtime@^7.18.9", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" - integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.18.10", "@babel/template@^7.3.3": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== +"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" -"@babel/traverse@^7.18.9", "@babel/traverse@^7.19.0", "@babel/traverse@^7.7.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.0.tgz#eb9c561c7360005c592cc645abafe0c3c4548eed" - integrity sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA== +"@babel/traverse@^7.20.5", "@babel/traverse@^7.21.5", "@babel/traverse@^7.7.2": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.5.tgz#ad22361d352a5154b498299d523cf72998a4b133" + integrity sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.5" + "@babel/helper-environment-visitor" "^7.21.5" + "@babel/helper-function-name" "^7.21.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/parser" "^7.21.5" + "@babel/types" "^7.21.5" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" - integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== +"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.5.tgz#18dfbd47c39d3904d5db3d3dc2cc80bedb60e5b6" + integrity sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q== dependencies: - "@babel/helper-string-parser" "^7.18.10" - "@babel/helper-validator-identifier" "^7.18.6" + "@babel/helper-string-parser" "^7.21.5" + "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -1101,10 +1103,10 @@ resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4" integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg== -"@csstools/postcss-cascade-layers@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.0.6.tgz#a52da13b91fc184a52337b4e938c3d3188e537b0" - integrity sha512-ei4Vh4AJwTCXTNj7uzwduoZDO7nLPksQ0TI7OzUlyFq4P4Uhu6hU7R4AlLimDP/s6D3PQdHmRL4f7UOy370UHA== +"@csstools/postcss-cascade-layers@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz#8a997edf97d34071dd2e37ea6022447dd9e795ad" + integrity sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA== dependencies: "@csstools/selector-specificity" "^2.0.2" postcss-selector-parser "^6.0.10" @@ -1203,45 +1205,57 @@ integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== "@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" - integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" + integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== -"@eslint/eslintrc@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d" - integrity sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.2.tgz#01575e38707add677cf73ca1589abba8da899a02" + integrity sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.4.0" - globals "^13.15.0" + espree "^9.5.1" + globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/js@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" + integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng== + "@hcaptcha/react-hcaptcha@^1.1.1": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.4.4.tgz#529c55369160995115735b5fe5453daef4670f04" - integrity sha512-Aen217LDnf5ywbPSwBG5CsoqBLIHIAS9lhj3zQjXJuO13doQ6/ubkCWNuY8jmwYLefoFt3V3MrZmCdKDaFoTuQ== + version "1.8.1" + resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.8.1.tgz#3e6e0423100158bae089e4ef6507db0d4c62ec3f" + integrity sha512-33tIl77HgeahiQ6R0+JPDA8cGBBv95cIVcdOcFVwiGCJhrOxyiOQetCdEUNTDS13xrkvIP29K/PrqLXXSbKl6Q== dependencies: "@babel/runtime" "^7.17.9" -"@humanwhocodes/config-array@^0.10.4": - version "0.10.4" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" - integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== +"@humanwhocodes/config-array@^0.11.8": + version "0.11.8" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" + integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/gitignore-to-minimatch@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" - integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== + minimatch "^3.0.5" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" @@ -1479,46 +1493,48 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== "@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@1.4.14": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" @@ -1527,19 +1543,26 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== +"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": + version "5.1.1-v1" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" + integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== + dependencies: + eslint-scope "5.1.1" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1553,7 +1576,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -1562,29 +1585,34 @@ fastq "^1.6.0" "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.7.tgz#58f8217ba70069cc6a73f5d7e05e85b458c150e2" - integrity sha512-bcKCAzF0DV2IIROp9ZHkRJa6O4jy7NlnHdWL3GmcUxYWNjLXkK5kfELELwEfSP5hXPfVL/qOGMAROuMQb9GG8Q== + version "0.5.10" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8" + integrity sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA== dependencies: ansi-html-community "^0.0.8" common-path-prefix "^3.0.0" - core-js-pure "^3.8.1" + core-js-pure "^3.23.3" error-stack-parser "^2.0.6" find-up "^5.0.0" html-entities "^2.1.0" - loader-utils "^2.0.0" + loader-utils "^2.0.4" schema-utils "^3.0.0" source-map "^0.7.3" "@reduxjs/toolkit@^1.7.2": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.8.5.tgz#c14bece03ee08be88467f22dc0ecf9cf875527cd" - integrity sha512-f4D5EXO7A7Xq35T0zRbWq5kJQyXzzscnHKmjnu2+37B3rwHU6mX9PYlbfXdnxcY6P/7zfmjhgan0Z+yuOfeBmA== + version "1.9.5" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.9.5.tgz#d3987849c24189ca483baa7aa59386c8e52077c4" + integrity sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ== dependencies: - immer "^9.0.7" - redux "^4.1.2" - redux-thunk "^2.4.1" - reselect "^4.1.5" + immer "^9.0.21" + redux "^4.2.1" + redux-thunk "^2.4.2" + reselect "^4.1.8" + +"@remix-run/router@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.6.1.tgz#3a3a408481a3796f45223a549c2571517bc8af2d" + integrity sha512-YUkWj+xs0oOzBe74OgErsuR3wVn+efrFhXBWrit50kOiED+pvQe2r6MWY0iJMQU/mSVKxvNzL4ZaYvjdX+G7ZA== "@rollup/plugin-babel@^5.2.0": version "5.3.1" @@ -1624,19 +1652,19 @@ picomatch "^2.2.2" "@rushstack/eslint-patch@^1.1.0": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz#0c8b74c50f29ee44f423f7416829c0bf8bb5eb27" - integrity sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA== + version "1.2.0" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" + integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== "@sinclair/typebox@^0.24.1": - version "0.24.40" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.40.tgz#00ee9b48537b147f6ffc80ebc28ab16d6016ed5c" - integrity sha512-Xint60L8rF0+nRy+6fCjW9jQMmu7fTpbwTBrXZiK6eq/RHDJS7LvWX/0oXC8O7fCePmrY/XdfaTv2HiUDeCq4g== + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== "@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== dependencies: type-detect "4.0.8" @@ -1791,12 +1819,12 @@ integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.12", "@types/babel__core@^7.1.14": - version "7.1.19" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" - integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + version "7.20.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" + integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" @@ -1817,9 +1845,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.18.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.1.tgz#ce5e2c8c272b99b7a9fd69fa39f0b4cd85028bd9" - integrity sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA== + version "7.18.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.5.tgz#c107216842905afafd3b6e774f6f935da6f5db80" + integrity sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q== dependencies: "@babel/types" "^7.3.0" @@ -1839,9 +1867,9 @@ "@types/node" "*" "@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + version "1.5.0" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#9fd20b3974bdc2bcd4ac6567e2e0f6885cb2cf41" + integrity sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" @@ -1853,11 +1881,21 @@ dependencies: "@types/node" "*" +"@types/d3-array@^3.0.3": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.4.tgz#44eebe40be57476cad6a0cd6a85b0f57d54185a2" + integrity sha512-nwvEkG9vYOc0Ic7G7kwgviY4AQlTfYGIZ0fqB7CQHXGyYM6nO7kJh5EguSNA3jfh4rq7Sb7eMVq8isuvg2/miQ== + "@types/d3-color@*": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.0.tgz#6594da178ded6c7c3842f3cc0ac84b156f12f2d4" integrity sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA== +"@types/d3-ease@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.0.tgz#c29926f8b596f9dadaeca062a32a45365681eae0" + integrity sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA== + "@types/d3-interpolate@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz#e7d17fa4a5830ad56fe22ce3b4fac8541a9572dc" @@ -1871,24 +1909,29 @@ integrity sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg== "@types/d3-scale@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.2.tgz#41be241126af4630524ead9cb1008ab2f0f26e69" - integrity sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA== + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.3.tgz#7a5780e934e52b6f63ad9c24b105e33dd58102b5" + integrity sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ== dependencies: "@types/d3-time" "*" "@types/d3-shape@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.0.tgz#1d87a6ddcf28285ef1e5c278ca4bdbc0658f3505" - integrity sha512-jYIYxFFA9vrJ8Hd4Se83YI6XF+gzDL1aC5DCsldai4XYYiVNdhtpGbA/GM6iyQ8ayhSp3a148LY34hy7A4TxZA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.1.tgz#15cc497751dac31192d7aef4e67a8d2c62354b95" + integrity sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A== dependencies: "@types/d3-path" "*" -"@types/d3-time@*": +"@types/d3-time@*", "@types/d3-time@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.0.tgz#e1ac0f3e9e195135361fa1a1d62f795d87e6e819" integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg== +"@types/d3-timer@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.0.tgz#e2505f1c21ec08bda8915238e397fb71d2fc54ce" + integrity sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g== + "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -1898,51 +1941,47 @@ "@types/estree" "*" "@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": - version "8.4.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" - integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== + version "8.37.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.37.0.tgz#29cebc6c2a3ac7fea7113207bf5a828fdf4d7ef1" + integrity sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.30" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" - integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.34" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.34.tgz#c119e85b75215178bc127de588e93100698ab4cc" + integrity sha512-fvr49XlCGoUj2Pp730AItckfjat4WNb0lb3kfrLWffd+RLeoGAMsq7UOy04PAPtoL01uKwcp6u8nhzpgpDYr3w== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" + "@types/send" "*" "@types/express@*", "@types/express@^4.17.13": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" - integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== dependencies: "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" + "@types/express-serve-static-core" "^4.17.33" "@types/qs" "*" "@types/serve-static" "*" "@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" @@ -1960,9 +1999,9 @@ integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== "@types/http-proxy@^1.17.8": - version "1.17.9" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" - integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== + version "1.17.11" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.11.tgz#0ca21949a5588d55ac2b659b69035c84bd5da293" + integrity sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA== dependencies: "@types/node" "*" @@ -2000,10 +2039,15 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== -"@types/node@*": - version "18.7.16" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.16.tgz#0eb3cce1e37c79619943d2fd903919fc30850601" - integrity sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg== +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node@*", "@types/node@^18.16.3": + version "18.16.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.3.tgz#6bda7819aae6ea0b386ebc5b24bdf602f1b42b01" + integrity sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q== "@types/parse-json@^4.0.0": version "4.0.0" @@ -2011,9 +2055,14 @@ integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/prettier@^2.1.5": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc" - integrity sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A== + version "2.7.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" + integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + +"@types/preval.macro@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/preval.macro/-/preval.macro-3.0.0.tgz#c348162024c8ea22ea3d330d2497a1a21be64e38" + integrity sha512-mm7qx+Aj9bhMcK9Y3UHNy6zCQneRj+GBFlCi+cxtx66iLU4yarOupVLrFadlG+Cd4TEsdo4og0REhzUQQ7m3fg== "@types/prop-types@*": version "15.7.5" @@ -2025,6 +2074,13 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df" integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ== +"@types/qrcode.react@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.2.tgz#f892432cc41b5dac52e3ca8873b717c8bfea6002" + integrity sha512-I9Oq5Cjlkgy3Tw7krCnCXLw2/zMhizkTere49OOcta23tkvH0xBTP0yInimTh0gstLRtb8Ki9NZVujE5UI6ffQ== + dependencies: + "@types/react" "*" + "@types/qs@*": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" @@ -2035,20 +2091,34 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/react-dom@^18.2.1": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.3.tgz#2fe492bb0e67047b7b43e18166d8f50d44e0525e" + integrity sha512-hxXEXWxFJXbY0LMj/T69mznqOZJXNtQMqVxIiirVAZnnpeYiD4zt+lPsgcr/cfWg2VLsxZ1y26vigG03prYB+Q== + dependencies: + "@types/react" "*" + +"@types/react-helmet@^6.1.6": + version "6.1.6" + resolved "https://registry.yarnpkg.com/@types/react-helmet/-/react-helmet-6.1.6.tgz#7d1afd8cbf099616894e8240e9ef70e3c6d7506d" + integrity sha512-ZKcoOdW/Tg+kiUbkFCBtvDw0k3nD4HJ/h/B9yWxN4uDO8OkRksWTO+EL+z/Qu3aHTeTll3Ro0Cc/8UhwBCMG5A== + dependencies: + "@types/react" "*" + "@types/react-redux@^7.1.20": - version "7.1.24" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.24.tgz#6caaff1603aba17b27d20f8ad073e4c077e975c0" - integrity sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ== + version "7.1.25" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.25.tgz#de841631205b24f9dfb4967dd4a7901e048f9a88" + integrity sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg== dependencies: "@types/hoist-non-react-statics" "^3.3.0" "@types/react" "*" hoist-non-react-statics "^3.3.0" redux "^4.0.0" -"@types/react@*": - version "18.0.19" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.19.tgz#269a5f35b9a73c69dfb0c7189017013ab02acbaa" - integrity sha512-BDc3Q+4Q3zsn7k9xZrKfjWyJsSlEDMs38gD1qp2eDazLCdcPqAT+vq1ND+Z8AGel/UiwzNUk8ptpywgNQcJ1MQ== +"@types/react@*", "@types/react@^18.2.0": + version "18.2.5" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.5.tgz#f9403e1113b12b53f7edcdd9a900c10dd4b49a59" + integrity sha512-RuoMedzJ5AOh23Dvws13LU9jpZHIc/k90AgmK7CecAYeWmSr3553L4u5rk4sWAPBuQosfT7HmTfG4Rg5o4nGEA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -2067,9 +2137,22 @@ integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/scheduler@*": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" - integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + +"@types/semver@^7.3.12": + version "7.3.13" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" + integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== + +"@types/send@*": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + dependencies: + "@types/mime" "^1" + "@types/node" "*" "@types/serve-index@^1.9.1": version "1.9.1" @@ -2079,13 +2162,18 @@ "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" - integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + version "1.15.1" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" + integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== dependencies: "@types/mime" "*" "@types/node" "*" +"@types/sjcl@^1.0.30": + version "1.0.30" + resolved "https://registry.yarnpkg.com/@types/sjcl/-/sjcl-1.0.30.tgz#c1db866622ef4da56af081fa2e258d76fb255b89" + integrity sha512-4ebBtj1rx3Kh3To5RnPua+U4JzVwH2MxUmHQvAlxWpzmfmupBRyyXAIEQceon+e5tW9aBeOApTYA6EXfBysRyQ== + "@types/sockjs@^0.3.33": version "0.3.33" resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" @@ -2099,14 +2187,14 @@ integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/trusted-types@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" - integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" + integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== "@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + version "8.5.4" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5" + integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg== dependencies: "@types/node" "*" @@ -2116,226 +2204,229 @@ integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + version "16.0.5" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" + integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.12.tgz#0745ff3e4872b4ace98616d4b7e37ccbd75f9526" - integrity sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ== + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.5.0": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.2.tgz#6df092a20e0f9ec748b27f293a12cb39d0c1fe4d" - integrity sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw== + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz#684a2ce7182f3b4dac342eef7caa1c2bae476abd" + integrity sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A== dependencies: - "@typescript-eslint/scope-manager" "5.36.2" - "@typescript-eslint/type-utils" "5.36.2" - "@typescript-eslint/utils" "5.36.2" + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.59.2" + "@typescript-eslint/type-utils" "5.59.2" + "@typescript-eslint/utils" "5.59.2" debug "^4.3.4" - functional-red-black-tree "^1.0.1" + grapheme-splitter "^1.0.4" ignore "^5.2.0" - regexpp "^3.2.0" + natural-compare-lite "^1.4.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/experimental-utils@^5.0.0": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.36.2.tgz#66a2b07f69595c55e718bf5a0a70a73413daa8e9" - integrity sha512-JtRmWb31KQoxGV6CHz8cI+9ki6cC7ciZepXYpCLxsdAtQlBrRBxh5Qpe/ZHyJFOT9j7gyXE+W0shWzRLPfuAFQ== + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.59.2.tgz#c2785247c4c8929cb6946e46280ea44f54d9cf79" + integrity sha512-JLw2UImsjHDuVukpA8Nt+UK7JKE/LQAeV3tU5f7wJo2/NNYVwcakzkWjoYzu/2qzWY/Z9c7zojngNDfecNt92g== dependencies: - "@typescript-eslint/utils" "5.36.2" + "@typescript-eslint/utils" "5.59.2" "@typescript-eslint/parser@^5.5.0": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.36.2.tgz#3ddf323d3ac85a25295a55fcb9c7a49ab4680ddd" - integrity sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA== + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.2.tgz#c2c443247901d95865b9f77332d9eee7c55655e8" + integrity sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ== dependencies: - "@typescript-eslint/scope-manager" "5.36.2" - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/typescript-estree" "5.36.2" + "@typescript-eslint/scope-manager" "5.59.2" + "@typescript-eslint/types" "5.59.2" + "@typescript-eslint/typescript-estree" "5.59.2" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.36.2.tgz#a75eb588a3879ae659514780831370642505d1cd" - integrity sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw== +"@typescript-eslint/scope-manager@5.59.2": + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz#f699fe936ee4e2c996d14f0fdd3a7da5ba7b9a4c" + integrity sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA== dependencies: - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/visitor-keys" "5.36.2" + "@typescript-eslint/types" "5.59.2" + "@typescript-eslint/visitor-keys" "5.59.2" -"@typescript-eslint/type-utils@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.36.2.tgz#752373f4babf05e993adf2cd543a763632826391" - integrity sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw== +"@typescript-eslint/type-utils@5.59.2": + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz#0729c237503604cd9a7084b5af04c496c9a4cdcf" + integrity sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ== dependencies: - "@typescript-eslint/typescript-estree" "5.36.2" - "@typescript-eslint/utils" "5.36.2" + "@typescript-eslint/typescript-estree" "5.59.2" + "@typescript-eslint/utils" "5.59.2" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.36.2.tgz#a5066e500ebcfcee36694186ccc57b955c05faf9" - integrity sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ== +"@typescript-eslint/types@5.59.2": + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.2.tgz#b511d2b9847fe277c5cb002a2318bd329ef4f655" + integrity sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w== -"@typescript-eslint/typescript-estree@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.2.tgz#0c93418b36c53ba0bc34c61fe9405c4d1d8fe560" - integrity sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w== +"@typescript-eslint/typescript-estree@5.59.2": + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz#6e2fabd3ba01db5d69df44e0b654c0b051fe9936" + integrity sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q== dependencies: - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/visitor-keys" "5.36.2" + "@typescript-eslint/types" "5.59.2" + "@typescript-eslint/visitor-keys" "5.59.2" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.36.2", "@typescript-eslint/utils@^5.13.0": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.36.2.tgz#b01a76f0ab244404c7aefc340c5015d5ce6da74c" - integrity sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg== +"@typescript-eslint/utils@5.59.2", "@typescript-eslint/utils@^5.58.0": + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.2.tgz#0c45178124d10cc986115885688db6abc37939f4" + integrity sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ== dependencies: + "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.36.2" - "@typescript-eslint/types" "5.36.2" - "@typescript-eslint/typescript-estree" "5.36.2" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.59.2" + "@typescript-eslint/types" "5.59.2" + "@typescript-eslint/typescript-estree" "5.59.2" eslint-scope "^5.1.1" - eslint-utils "^3.0.0" + semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.36.2": - version "5.36.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.2.tgz#2f8f78da0a3bad3320d2ac24965791ac39dace5a" - integrity sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A== +"@typescript-eslint/visitor-keys@5.59.2": + version "5.59.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz#37a419dc2723a3eacbf722512b86d6caf7d3b750" + integrity sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig== dependencies: - "@typescript-eslint/types" "5.36.2" + "@typescript-eslint/types" "5.59.2" eslint-visitor-keys "^3.3.0" -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@webassemblyjs/ast@1.11.5", "@webassemblyjs/ast@^1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.5.tgz#6e818036b94548c1fb53b754b5cae3c9b208281c" + integrity sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-numbers" "1.11.5" + "@webassemblyjs/helper-wasm-bytecode" "1.11.5" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.5.tgz#e85dfdb01cad16b812ff166b96806c050555f1b4" + integrity sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.5.tgz#1e82fa7958c681ddcf4eabef756ce09d49d442d1" + integrity sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.5.tgz#91381652ea95bb38bbfd270702351c0c89d69fba" + integrity sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.5.tgz#23380c910d56764957292839006fecbe05e135a9" + integrity sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.5" + "@webassemblyjs/helper-api-error" "1.11.5" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.5.tgz#e258a25251bc69a52ef817da3001863cc1c24b9f" + integrity sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.5.tgz#966e855a6fae04d5570ad4ec87fbcf29b42ba78e" + integrity sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.11.5" + "@webassemblyjs/helper-buffer" "1.11.5" + "@webassemblyjs/helper-wasm-bytecode" "1.11.5" + "@webassemblyjs/wasm-gen" "1.11.5" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.5.tgz#b2db1b33ce9c91e34236194c2b5cba9b25ca9d60" + integrity sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.5.tgz#482e44d26b6b949edf042a8525a66c649e38935a" + integrity sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== +"@webassemblyjs/utf8@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.5.tgz#83bef94856e399f3740e8df9f63bc47a987eae1a" + integrity sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ== -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.5.tgz#93ee10a08037657e21c70de31c47fdad6b522b2d" + integrity sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" + "@webassemblyjs/ast" "1.11.5" + "@webassemblyjs/helper-buffer" "1.11.5" + "@webassemblyjs/helper-wasm-bytecode" "1.11.5" + "@webassemblyjs/helper-wasm-section" "1.11.5" + "@webassemblyjs/wasm-gen" "1.11.5" + "@webassemblyjs/wasm-opt" "1.11.5" + "@webassemblyjs/wasm-parser" "1.11.5" + "@webassemblyjs/wast-printer" "1.11.5" -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== +"@webassemblyjs/wasm-gen@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.5.tgz#ceb1c82b40bf0cf67a492c53381916756ef7f0b1" + integrity sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.11.5" + "@webassemblyjs/helper-wasm-bytecode" "1.11.5" + "@webassemblyjs/ieee754" "1.11.5" + "@webassemblyjs/leb128" "1.11.5" + "@webassemblyjs/utf8" "1.11.5" -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== +"@webassemblyjs/wasm-opt@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.5.tgz#b52bac29681fa62487e16d3bb7f0633d5e62ca0a" + integrity sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/ast" "1.11.5" + "@webassemblyjs/helper-buffer" "1.11.5" + "@webassemblyjs/wasm-gen" "1.11.5" + "@webassemblyjs/wasm-parser" "1.11.5" -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== +"@webassemblyjs/wasm-parser@1.11.5", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.5.tgz#7ba0697ca74c860ea13e3ba226b29617046982e2" + integrity sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.11.5" + "@webassemblyjs/helper-api-error" "1.11.5" + "@webassemblyjs/helper-wasm-bytecode" "1.11.5" + "@webassemblyjs/ieee754" "1.11.5" + "@webassemblyjs/leb128" "1.11.5" + "@webassemblyjs/utf8" "1.11.5" -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== +"@webassemblyjs/wast-printer@1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.5.tgz#7a5e9689043f3eca82d544d7be7a8e6373a6fa98" + integrity sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA== dependencies: - "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/ast" "1.11.5" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -2379,16 +2470,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-node@^1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" - integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== - dependencies: - acorn "^7.0.0" - acorn-walk "^7.0.0" - xtend "^4.0.2" - -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== @@ -2398,20 +2480,20 @@ acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^7.0.0, acorn@^7.1.1: +acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== address@^1.0.1, address@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9" - integrity sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig== + version "1.2.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== adjust-sourcemap-loader@^4.0.0: version "4.0.0" @@ -2440,7 +2522,7 @@ ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0: +ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== @@ -2457,10 +2539,10 @@ ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.6.0, ajv@^8.8.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== +ajv@^8.0.0, ajv@^8.6.0, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -2508,10 +2590,15 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@^3.0.3, anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -2538,13 +2625,20 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== +aria-query@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" + deep-equal "^2.0.5" + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" array-flatten@1.1.1: version "1.1.1" @@ -2556,15 +2650,15 @@ array-flatten@^2.1.2: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-includes@^3.1.4, array-includes@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" - integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== +array-includes@^3.1.5, array-includes@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" - es-abstract "^1.19.5" - get-intrinsic "^1.1.1" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" is-string "^1.0.7" array-union@^2.1.0: @@ -2572,37 +2666,48 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.flat@^1.2.5: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" - integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== +array.prototype.flat@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" -array.prototype.flatmap@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f" - integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg== +array.prototype.flatmap@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" -array.prototype.reduce@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz#8167e80089f78bff70a99e20bd4201d4663b0a6f" - integrity sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw== +array.prototype.reduce@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" + integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" +array.prototype.tosorted@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" + integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.1.3" + asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -2633,27 +2738,34 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -autoprefixer@^10.4.8: - version "10.4.8" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.8.tgz#92c7a0199e1cfb2ad5d9427bd585a3d75895b9e5" - integrity sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw== +autoprefixer@^10.4.13: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== dependencies: - browserslist "^4.21.3" - caniuse-lite "^1.0.30001373" + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" postcss-value-parser "^4.2.0" -axe-core@^4.4.3: - version "4.4.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" - integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== +axe-core@^4.6.2: + version "4.7.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" + integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== + +axobject-query@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" + integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== + dependencies: + deep-equal "^2.0.5" babel-jest@^27.4.2, babel-jest@^27.5.1: version "27.5.1" @@ -2670,22 +2782,15 @@ babel-jest@^27.4.2, babel-jest@^27.5.1: slash "^3.0.0" babel-loader@^8.2.3: - version "8.2.5" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" - integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== + version "8.3.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" + integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== dependencies: find-cache-dir "^3.3.1" loader-utils "^2.0.0" make-dir "^3.1.0" schema-utils "^2.6.5" -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -2721,29 +2826,29 @@ babel-plugin-named-asset-import@^0.3.8: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz#6b7fa43c59229685368683c28bc9734f24524cc2" integrity sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q== -babel-plugin-polyfill-corejs2@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz#e4c31d4c89b56f3cf85b92558954c66b54bd972d" - integrity sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q== +babel-plugin-polyfill-corejs2@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" + integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== dependencies: "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.2" + "@babel/helper-define-polyfill-provider" "^0.3.3" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz#d7e09c9a899079d71a8b670c6181af56ec19c5c7" - integrity sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw== +babel-plugin-polyfill-corejs3@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" + integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.2" - core-js-compat "^3.21.0" + "@babel/helper-define-polyfill-provider" "^0.3.3" + core-js-compat "^3.25.1" -babel-plugin-polyfill-regenerator@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz#8f51809b6d5883e07e71548d75966ff7635527fe" - integrity sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw== +babel-plugin-polyfill-regenerator@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" + integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.2" + "@babel/helper-define-polyfill-provider" "^0.3.3" babel-plugin-preval@^5.0.0: version "5.1.0" @@ -2853,10 +2958,10 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -body-parser@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== dependencies: bytes "3.1.2" content-type "~1.0.4" @@ -2866,15 +2971,15 @@ body-parser@1.20.0: http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.10.3" + qs "6.11.0" raw-body "2.5.1" type-is "~1.6.18" unpipe "1.0.0" bonjour-service@^1.0.11: - version "1.0.14" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" - integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" + integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== dependencies: array-flatten "^2.1.2" dns-equal "^1.0.0" @@ -2913,15 +3018,15 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.20.2, browserslist@^4.20.3, browserslist@^4.21.3: - version "4.21.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.21.5: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" - node-releases "^2.0.6" - update-browserslist-db "^1.0.5" + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" bser@2.1.1: version "2.1.1" @@ -2996,10 +3101,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001373: - version "1.0.30001393" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz#1aa161e24fe6af2e2ccda000fc2b94be0b0db356" - integrity sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: + version "1.0.30001482" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001482.tgz#8b3fad73dc35b2674a5c96df2d4f9f1c561435de" + integrity sha512-F1ZInsg53cegyjroxLNW9DmrEQ1SuGRTO1QlpA0o2/6OpQ0gFeDRoq1yFmnr8Sakn9qwwt9DmbxHB6w167OSuQ== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -3042,9 +3147,9 @@ char-regex@^2.0.0: integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== check-types@^11.1.1: - version "11.1.2" - resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f" - integrity sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ== + version "11.2.2" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.2.tgz#7afc0b6a860d686885062f2dba888ba5710335b4" + integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA== check-types@^8.0.3: version "8.0.3" @@ -3072,9 +3177,9 @@ chrome-trace-event@^1.0.2: integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.4.0.tgz#b28484fd436cbc267900364f096c9dc185efb251" - integrity sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cjs-module-lexer@^1.0.0: version "1.2.2" @@ -3082,14 +3187,14 @@ cjs-module-lexer@^1.0.0: integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== classnames@^2.2.5: - version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== clean-css@^5.2.2: - version "5.3.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" - integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== + version "5.3.2" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" + integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== dependencies: source-map "~0.6.0" @@ -3140,7 +3245,7 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@^1.1.4, color-name@~1.1.4: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== @@ -3151,9 +3256,9 @@ colord@^2.9.1: integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== colorette@^2.0.10: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== combined-stream@^1.0.8: version "1.0.8" @@ -3167,6 +3272,11 @@ commander@^2.18.0, commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" @@ -3235,16 +3345,14 @@ content-disposition@0.5.4: safe-buffer "5.2.1" content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== cookie-signature@1.0.6: version "1.0.6" @@ -3256,22 +3364,22 @@ cookie@0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -core-js-compat@^3.21.0, core-js-compat@^3.22.1: - version "3.25.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.1.tgz#6f13a90de52f89bbe6267e5620a412c7f7ff7e42" - integrity sha512-pOHS7O0i8Qt4zlPW/eIFjwp+NrTPx+wTL0ctgI2fHn31sZOq89rDsmtc/A2vAX7r6shl+bmVI+678He46jgBlw== +core-js-compat@^3.25.1: + version "3.30.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.30.1.tgz#961541e22db9c27fc48bfc13a3cafa8734171dfe" + integrity sha512-d690npR7MC6P0gq4npTl5n2VQeNAmUrJ90n+MHiKS7W2+xno4o3F5GDEuylSdi6EJ3VssibSGXOa1r3YXD3Mhw== dependencies: - browserslist "^4.21.3" + browserslist "^4.21.5" -core-js-pure@^3.20.2, core-js-pure@^3.8.1: - version "3.25.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.1.tgz#79546518ae87cc362c991d9c2d211f45107991ee" - integrity sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A== +core-js-pure@^3.23.3: + version "3.30.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.30.1.tgz#7d93dc89e7d47b8ef05d7e79f507b0e99ea77eec" + integrity sha512-nXBEVpmUnNRhz83cHd9JRQC52cTMcuXAmR56+9dSMpRdpeA4I1PX6yjmhd71Eyc/wXNsdBdUDIj1QTIeZpU5Tg== core-js@^3.19.2: - version "3.25.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.25.1.tgz#5818e09de0db8956e16bf10e2a7141e931b7c69c" - integrity sha512-sr0FY4lnO1hkQ4gLDr24K0DGnweGO1QwSj5BpfQjpSJPdqWalja4cTps29Y/PJVG/P7FYlPDkH3hO+Tr0CvDgQ== + version "3.30.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.30.1.tgz#fc9c5adcc541d8e9fa3e381179433cbf795628ba" + integrity sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ== core-util-is@~1.0.0: version "1.0.3" @@ -3298,9 +3406,9 @@ cosmiconfig@^6.0.0: yaml "^1.7.2" cosmiconfig@^7, cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" import-fresh "^3.2.1" @@ -3343,10 +3451,10 @@ css-blank-pseudo@^3.0.3: dependencies: postcss-selector-parser "^6.0.9" -css-declaration-sorter@^6.3.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" - integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w== +css-declaration-sorter@^6.3.1: + version "6.4.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz#630618adc21724484b3e9505bce812def44000ad" + integrity sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew== css-has-pseudo@^3.0.4: version "3.0.4" @@ -3356,18 +3464,18 @@ css-has-pseudo@^3.0.4: postcss-selector-parser "^6.0.9" css-loader@^6.5.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" - integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== + version "6.7.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.3.tgz#1e8799f3ccc5874fdd55461af51137fcc5befbcd" + integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ== dependencies: icss-utils "^5.1.0" - postcss "^8.4.7" + postcss "^8.4.19" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" - semver "^7.3.5" + semver "^7.3.8" css-minimizer-webpack-plugin@^3.2.0: version "3.4.1" @@ -3443,35 +3551,35 @@ css-what@^6.0.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== -cssdb@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.0.1.tgz#3810a0c67ae06362982dfe965dbedf57a0f26617" - integrity sha512-pT3nzyGM78poCKLAEy2zWIVX2hikq6dIrjuZzLV98MumBg+xMTNYfHx7paUlfiRTgg91O/vR889CIf+qiv79Rw== +cssdb@^7.1.0: + version "7.5.4" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.5.4.tgz#e34dafee5184d67634604e345e389ca79ac179ea" + integrity sha512-fGD+J6Jlq+aurfE1VDXlLS4Pt0VtNlu2+YgfGOdMxRyl/HQ9bDiHTwSck1Yz8A97Dt/82izSK6Bp/4nVqacOsg== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^5.2.12: - version "5.2.12" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" - integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== +cssnano-preset-default@^5.2.14: + version "5.2.14" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" + integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== dependencies: - css-declaration-sorter "^6.3.0" + css-declaration-sorter "^6.3.1" cssnano-utils "^3.1.0" postcss-calc "^8.2.3" - postcss-colormin "^5.3.0" - postcss-convert-values "^5.1.2" + postcss-colormin "^5.3.1" + postcss-convert-values "^5.1.3" postcss-discard-comments "^5.1.2" postcss-discard-duplicates "^5.1.0" postcss-discard-empty "^5.1.1" postcss-discard-overridden "^5.1.0" - postcss-merge-longhand "^5.1.6" - postcss-merge-rules "^5.1.2" + postcss-merge-longhand "^5.1.7" + postcss-merge-rules "^5.1.4" postcss-minify-font-values "^5.1.0" postcss-minify-gradients "^5.1.1" - postcss-minify-params "^5.1.3" + postcss-minify-params "^5.1.4" postcss-minify-selectors "^5.2.1" postcss-normalize-charset "^5.1.0" postcss-normalize-display-values "^5.1.0" @@ -3479,11 +3587,11 @@ cssnano-preset-default@^5.2.12: postcss-normalize-repeat-style "^5.1.1" postcss-normalize-string "^5.1.0" postcss-normalize-timing-functions "^5.1.0" - postcss-normalize-unicode "^5.1.0" + postcss-normalize-unicode "^5.1.1" postcss-normalize-url "^5.1.0" postcss-normalize-whitespace "^5.1.1" postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.0" + postcss-reduce-initial "^5.1.2" postcss-reduce-transforms "^5.1.0" postcss-svgo "^5.1.0" postcss-unique-selectors "^5.1.1" @@ -3494,11 +3602,11 @@ cssnano-utils@^3.1.0: integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== cssnano@^5.0.6: - version "5.1.13" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.13.tgz#83d0926e72955332dc4802a7070296e6258efc0a" - integrity sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ== + version "5.1.15" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" + integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== dependencies: - cssnano-preset-default "^5.2.12" + cssnano-preset-default "^5.2.14" lilconfig "^2.0.3" yaml "^1.10.2" @@ -3527,14 +3635,14 @@ cssstyle@^2.3.0: cssom "~0.3.6" csstype@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" - integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== -"d3-array@2 - 3", "d3-array@2.10.0 - 3": - version "3.2.0" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.0.tgz#15bf96cd9b7333e02eb8de8053d78962eafcff14" - integrity sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g== +"d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6: + version "3.2.3" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.3.tgz#39f1f4954e4a09ff69ac597c2d61906b04e84740" + integrity sha512-JRHwbQQ84XuAESWhvIPaUV4/1UYTBOLiOPGWqgFDHZS1D5QN9c57FbH3QpEnQMYiOXNzKUQyGTZf+EVO7RT5TQ== dependencies: internmap "1 - 2" @@ -3543,6 +3651,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== +d3-ease@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + "d3-format@1 - 3": version "3.1.0" resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" @@ -3555,10 +3668,10 @@ csstype@^3.0.2: dependencies: d3-color "1 - 3" -"d3-path@1 - 3": - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.0.1.tgz#f09dec0aaffd770b7995f1a399152bf93052321e" - integrity sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w== +d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== d3-scale@^4.0.2: version "4.0.2" @@ -3572,11 +3685,11 @@ d3-scale@^4.0.2: d3-time-format "2 - 4" d3-shape@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.1.0.tgz#c8a495652d83ea6f524e482fca57aa3f8bc32556" - integrity sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ== + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== dependencies: - d3-path "1 - 3" + d3-path "^3.1.0" "d3-time-format@2 - 4": version "4.1.0" @@ -3585,13 +3698,18 @@ d3-shape@^3.1.0: dependencies: d3-time "1 - 3" -"d3-time@1 - 3", "d3-time@2.1.1 - 3": - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.0.0.tgz#65972cb98ae2d4954ef5c932e8704061335d4975" - integrity sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ== +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== dependencies: d3-array "2 - 3" +d3-timer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" @@ -3606,7 +3724,7 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -debug@2.6.9, debug@^2.6.0, debug@^2.6.9: +debug@2.6.9, debug@^2.6.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -3633,24 +3751,48 @@ decimal.js-light@^2.4.1: integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== decimal.js@^10.2.1: - version "10.4.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.0.tgz#97a7448873b01e92e5ff9117d89a7bca8e63e0fe" - integrity sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg== + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-equal@^2.0.5: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.1.tgz#c72ab22f3a7d3503a4ca87dde976fe9978816739" + integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.0" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== default-gateway@^6.0.3: version "6.0.3" @@ -3664,19 +3806,14 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -3715,15 +3852,6 @@ detect-port-alt@^1.1.6: address "^1.0.1" debug "^2.6.0" -detective@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034" - integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw== - dependencies: - acorn-node "^1.8.2" - defined "^1.0.0" - minimist "^1.2.6" - didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" @@ -3757,9 +3885,9 @@ dns-equal@^1.0.0: integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== dns-packet@^5.2.2: - version "5.4.0" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" - integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + version "5.6.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.0.tgz#2202c947845c7a63c23ece58f2f70ff6ab4c2f7d" + integrity sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ== dependencies: "@leichtgewicht/ip-codec" "^2.0.1" @@ -3883,16 +4011,16 @@ ejs@^2.6.1: integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== ejs@^3.1.6: - version "3.1.8" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" - integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.202: - version "1.4.247" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.247.tgz#cc93859bc5fc521f611656e65ce17eae26a0fd3d" - integrity sha512-FLs6R4FQE+1JHM0hh3sfdxnYjKvJpHZyhQDjc2qFq/xFvmmRt/TATNToZhrcGUFzpF2XjeiuozrA8lI0PZmYYw== +electron-to-chromium@^1.4.284: + version "1.4.382" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.382.tgz#87e659b0f0d5f7b19759038871bac0a327191f82" + integrity sha512-czMavlW52VIPgutbVL9JnZIZuFijzsG1ww/1z2Otu1r1q+9Qe2bTsH3My3sZarlvwyqHM6+mnZfEnt2Vr4dsIg== emittery@^0.10.2: version "0.10.2" @@ -3924,10 +4052,10 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enhanced-resolve@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== +enhanced-resolve@^5.13.0: + version "5.13.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz#26d1ecc448c02de997133217b5c1053f34a0a275" + integrity sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3951,44 +4079,79 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.3.4" -es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.1: - version "1.20.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3" - integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ== +es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: + version "1.21.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" + integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== dependencies: + array-buffer-byte-length "^1.0.0" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" - function-bind "^1.1.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.1.2" + get-intrinsic "^1.2.0" get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" has "^1.0.3" has-property-descriptors "^1.0.0" + has-proto "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.4" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" is-string "^1.0.7" + is-typed-array "^1.1.10" is-weakref "^1.0.2" - object-inspect "^1.12.2" + object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.4.3" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" es-array-method-boxes-properly@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + +es-module-lexer@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.2.1.tgz#ba303831f63e6a394983fde2f97ad77b22324527" + integrity sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg== + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" es-shim-unscopables@^1.0.0: version "1.0.0" @@ -4063,18 +4226,19 @@ eslint-config-react-app@^7.0.0: eslint-plugin-react-hooks "^4.3.0" eslint-plugin-testing-library "^5.0.1" -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== +eslint-import-resolver-node@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" + integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== dependencies: debug "^3.2.7" - resolve "^1.20.0" + is-core-module "^2.11.0" + resolve "^1.22.1" -eslint-module-utils@^2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== +eslint-module-utils@^2.7.4: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" @@ -4087,22 +4251,24 @@ eslint-plugin-flowtype@^8.0.3: string-natural-compare "^3.0.1" eslint-plugin-import@^2.25.3: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== + version "2.27.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" + integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + array.prototype.flatmap "^1.3.1" + debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" + eslint-import-resolver-node "^0.3.7" + eslint-module-utils "^2.7.4" has "^1.0.3" - is-core-module "^2.8.1" + is-core-module "^2.11.0" is-glob "^4.0.3" minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" + object.values "^1.1.6" + resolve "^1.22.1" + semver "^6.3.0" tsconfig-paths "^3.14.1" eslint-plugin-jest@^25.3.0: @@ -4113,22 +4279,25 @@ eslint-plugin-jest@^25.3.0: "@typescript-eslint/experimental-utils" "^5.0.0" eslint-plugin-jsx-a11y@^6.5.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" - integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== + version "6.7.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" + integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== dependencies: - "@babel/runtime" "^7.18.9" - aria-query "^4.2.2" - array-includes "^3.1.5" + "@babel/runtime" "^7.20.7" + aria-query "^5.1.3" + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" ast-types-flow "^0.0.7" - axe-core "^4.4.3" - axobject-query "^2.2.0" + axe-core "^4.6.2" + axobject-query "^3.1.1" damerau-levenshtein "^1.0.8" emoji-regex "^9.2.2" has "^1.0.3" - jsx-ast-utils "^3.3.2" - language-tags "^1.0.5" + jsx-ast-utils "^3.3.3" + language-tags "=1.0.5" minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" semver "^6.3.0" eslint-plugin-react-hooks@^4.3.0: @@ -4137,31 +4306,32 @@ eslint-plugin-react-hooks@^4.3.0: integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== eslint-plugin-react@^7.27.1: - version "7.31.8" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.8.tgz#3a4f80c10be1bcbc8197be9e8b641b2a3ef219bf" - integrity sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw== + version "7.32.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" + integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== dependencies: - array-includes "^3.1.5" - array.prototype.flatmap "^1.3.0" + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" doctrine "^2.1.0" estraverse "^5.3.0" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" - object.entries "^1.1.5" - object.fromentries "^2.0.5" - object.hasown "^1.1.1" - object.values "^1.1.5" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" prop-types "^15.8.1" - resolve "^2.0.0-next.3" + resolve "^2.0.0-next.4" semver "^6.3.0" - string.prototype.matchall "^4.0.7" + string.prototype.matchall "^4.0.8" eslint-plugin-testing-library@^5.0.1: - version "5.6.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.6.3.tgz#98878d3dbf4910f175d1ec0a3417ede147f3fc6e" - integrity sha512-//fhmCzopr8UDv5X2M3XMGxQ0j6KjKYZ+6PGqdV0woLiXTSTOAzuNsiTELGv883iCeUrYrnHhtObPXyiTMytVQ== + version "5.10.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.3.tgz#e613fbaf9a145e9eef115d080b32cb488fae622e" + integrity sha512-0yhsKFsjHLud5PM+f2dWr9K3rqYzMy4cSHs3lcmFYMa1CdSzRvHGgXvsFarBjZ41gU8jhTdMIkg8jHLxGJqLqw== dependencies: - "@typescript-eslint/utils" "^5.13.0" + "@typescript-eslint/utils" "^5.58.0" eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" @@ -4171,30 +4341,23 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: +eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz#c7f0f956124ce677047ddbc192a68f999454dedc" + integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== eslint-webpack-plugin@^3.1.1: version "3.2.0" @@ -4208,38 +4371,40 @@ eslint-webpack-plugin@^3.1.1: schema-utils "^4.0.0" eslint@^8.3.0: - version "8.23.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040" - integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA== + version "8.39.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.39.0.tgz#7fd20a295ef92d43809e914b70c39fd5a23cf3f1" + integrity sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og== dependencies: - "@eslint/eslintrc" "^1.3.1" - "@humanwhocodes/config-array" "^0.10.4" - "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.2" + "@eslint/js" "8.39.0" + "@humanwhocodes/config-array" "^0.11.8" "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.4.0" - esquery "^1.4.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.0" + espree "^9.5.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" find-up "^5.0.0" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.15.0" - globby "^11.1.0" + glob-parent "^6.0.2" + globals "^13.19.0" grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -4247,29 +4412,28 @@ eslint@^8.3.0: minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.1" - regexpp "^3.2.0" strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.4.0: - version "9.4.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" - integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== +espree@^9.5.1: + version "9.5.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.1.tgz#4f26a4d5f18905bf4f2e0bd99002aab807e96dd4" + integrity sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg== dependencies: acorn "^8.8.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.0" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -4346,13 +4510,13 @@ expect@^27.5.1: jest-message-util "^27.5.1" express@^4.16.3, express@^4.17.3: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.0" + body-parser "1.20.1" content-disposition "0.5.4" content-type "~1.0.4" cookie "0.5.0" @@ -4371,7 +4535,7 @@ express@^4.16.3, express@^4.17.3: parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.10.3" + qs "6.11.0" range-parser "~1.2.1" safe-buffer "5.2.1" send "0.18.0" @@ -4387,12 +4551,12 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-equals@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.4.tgz#3add9410585e2d7364c2deeb6a707beadb24b927" - integrity sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w== +fast-equals@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-4.0.3.tgz#72884cc805ec3c6679b99875f6b7654f39f0e8c7" + integrity sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg== -fast-glob@^3.2.11, fast-glob@^3.2.9: +fast-glob@^3.2.12, fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -4414,9 +4578,9 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" @@ -4428,17 +4592,12 @@ faye-websocket@^0.11.3: websocket-driver ">=0.5.1" fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" -feather-icons-react@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/feather-icons-react/-/feather-icons-react-0.5.0.tgz#74f8b398f4031491901aa47ff470899e408df159" - integrity sha512-k7y6JnghcwLi3uo5SaSnnngfHOE+IPpAFzlsmNhlXwbP8jev2rOYbEq1g5lhMglbV934KhcaSbo3DYV32I3/Ug== - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4537,14 +4696,21 @@ flatted@^3.1.0: integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== follow-redirects@^1.0.0: - version "1.15.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" - integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" - integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== + version "6.5.3" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" + integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== dependencies: "@babel/code-frame" "^7.8.3" "@types/json-schema" "^7.0.5" @@ -4633,12 +4799,7 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -functions-have-names@^1.2.2: +functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -4653,10 +4814,10 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" - integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -4692,7 +4853,7 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1, glob-parent@^6.0.2: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -4704,6 +4865,18 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -4737,13 +4910,20 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.15.0: - version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== dependencies: type-fest "^0.20.2" +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + globby@^11.0.4, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -4756,10 +4936,17 @@ globby@^11.0.4, globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== grapheme-splitter@^1.0.4: version "1.0.4" @@ -4813,6 +5000,11 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -4837,13 +5029,6 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -history@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" - integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== - dependencies: - "@babel/runtime" "^7.7.6" - hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -4897,9 +5082,9 @@ html-minifier-terser@^6.0.2: terser "^5.10.0" html-webpack-plugin@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" - integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== + version "5.5.1" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz#826838e31b427f5f7f30971f8d8fa2422dfa6763" + integrity sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA== dependencies: "@types/html-minifier-terser" "^6.0.0" html-minifier-terser "^6.0.2" @@ -5010,9 +5195,9 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== idb@^7.0.1: - version "7.0.2" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.2.tgz#7a067e20dd16539938e456814b7d714ba8db3892" - integrity sha512-jjKrT1EnyZewQ/gCBb/eyiYrhGzws2FeY92Yx8qT9S9GeQAmo4JFVIiWRIfKW/6Ob9A+UDAOW9j9jn58fy2HIg== + version "7.1.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" + integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== identity-obj-proxy@^3.0.0: version "3.0.0" @@ -5022,14 +5207,14 @@ identity-obj-proxy@^3.0.0: harmony-reflect "^1.4.6" ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== -immer@^9.0.7: - version "9.0.15" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.15.tgz#0b9169e5b1d22137aba7d43f8a81a495dd1b62dc" - integrity sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ== +immer@^9.0.21, immer@^9.0.7: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" @@ -5075,12 +5260,12 @@ ini@^1.3.5: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== +internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: - get-intrinsic "^1.1.0" + get-intrinsic "^1.2.0" has "^1.0.3" side-channel "^1.0.4" @@ -5099,6 +5284,23 @@ ipaddr.js@^2.0.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== +is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -5126,19 +5328,19 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== +is-core-module@^2.11.0, is-core-module@^2.9.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" + integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== dependencies: has "^1.0.3" -is-date-object@^1.0.1: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -5172,6 +5374,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" @@ -5199,6 +5406,11 @@ is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" @@ -5227,6 +5439,11 @@ is-root@^2.1.0: resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -5253,11 +5470,27 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -5265,6 +5498,14 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -5272,6 +5513,11 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -5288,9 +5534,9 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" - integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -5574,9 +5820,9 @@ jest-mock@^27.5.1: "@types/node" "*" jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== jest-regex-util@^27.5.1: version "27.5.1" @@ -5816,6 +6062,16 @@ jest@^27.4.3: import-local "^3.0.2" jest-cli "^27.5.1" +jiti@^1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd" + integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== + +js-sdsl@^4.1.4: + version "4.4.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.0.tgz#8b437dbe642daa95760400b602378ed8ffea8430" + integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -5904,17 +6160,17 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@^1.0.1: +json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.2.0, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.1.2, json5@^2.2.0, json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^6.0.1: version "6.1.0" @@ -5930,7 +6186,7 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== @@ -5949,22 +6205,30 @@ kleur@^3.0.3: integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== klona@^2.0.4, klona@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" - integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== language-subtag-registry@~0.3.2: version "0.3.22" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== -language-tags@^1.0.5: +language-tags@=1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== dependencies: language-subtag-registry "~0.3.2" +launch-editor@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.0.tgz#4c0c1a6ac126c572bd9ff9a30da1d2cae66defd7" + integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.7.3" + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -5986,10 +6250,10 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lilconfig@^2.0.3, lilconfig@^2.0.5, lilconfig@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== +lilconfig@^2.0.3, lilconfig@^2.0.5, lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lines-and-columns@^1.1.6: version "1.2.4" @@ -6001,7 +6265,7 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^2.0.0: +loader-utils@^2.0.0, loader-utils@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -6011,9 +6275,9 @@ loader-utils@^2.0.0: json5 "^2.1.2" loader-utils@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f" - integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== + version "3.2.1" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" + integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== locate-path@^3.0.0: version "3.0.0" @@ -6081,6 +6345,13 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -6130,9 +6401,9 @@ media-typer@0.3.0: integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== memfs@^3.1.2, memfs@^3.4.3: - version "3.4.7" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" - integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== + version "3.5.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.5.1.tgz#f0cd1e2bfaef58f6fe09bfb9c2288f07fea099ec" + integrity sha512-UWbFJKvj5k+nETdteFndTpYxdeTMox/ULeqX5k/dpaQJCCFmj5EeKv3dBcyO2xmkRAx2vppRu5dVG7SOtsGOzA== dependencies: fs-monkey "^1.0.3" @@ -6187,9 +6458,9 @@ mimic-fn@^2.1.0: integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mini-css-extract-plugin@^2.4.5: - version "2.6.1" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e" - integrity sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg== + version "2.7.5" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.5.tgz#afbb344977659ec0f1f6e050c7aea456b121cfc5" + integrity sha512-9HaR++0mlgom81s95vvNjxkg52n2b5s//3ZTI1EtzFb98awsLSivs2LMsVqnQ3ay0PVhqWcGNyDaTE961FOcjQ== dependencies: schema-utils "^4.0.0" @@ -6198,14 +6469,7 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -6213,16 +6477,16 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: brace-expansion "^1.1.7" minimatch@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.6" @@ -6259,10 +6523,24 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== natural-compare@^1.4.0: version "1.4.0" @@ -6297,10 +6575,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -6339,11 +6617,11 @@ nth-check@^2.0.1: boolbase "^1.0.0" nwsapi@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== + version "2.2.4" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.4.tgz#fd59d5e904e8e1f03c25a7d5a15cfa16c714a1e5" + integrity sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g== -object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -6353,17 +6631,25 @@ object-hash@^3.0.0: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.0, object.assign@^4.1.3, object.assign@^4.1.4: +object.assign@^4.1.3, object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -6373,50 +6659,51 @@ object.assign@^4.1.0, object.assign@^4.1.3, object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.entries@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== +object.entries@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" + integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" + define-properties "^1.1.4" + es-abstract "^1.20.4" -object.fromentries@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" - integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== +object.fromentries@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" + define-properties "^1.1.4" + es-abstract "^1.20.4" object.getownpropertydescriptors@^2.1.0: - version "2.1.4" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz#7965e6437a57278b587383831a9b829455a4bc37" - integrity sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ== + version "2.1.6" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz#5e5c384dd209fa4efffead39e3a0512770ccc312" + integrity sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ== dependencies: - array.prototype.reduce "^1.0.4" + array.prototype.reduce "^1.0.5" call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.1" + define-properties "^1.2.0" + es-abstract "^1.21.2" + safe-array-concat "^1.0.0" -object.hasown@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3" - integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A== +object.hasown@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" + integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== dependencies: define-properties "^1.1.4" - es-abstract "^1.19.5" + es-abstract "^1.20.4" -object.values@^1.1.0, object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== +object.values@^1.1.0, object.values@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" + define-properties "^1.1.4" + es-abstract "^1.20.4" obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" @@ -6450,9 +6737,9 @@ onetime@^5.1.2: mimic-fn "^2.1.0" open@^8.0.9, open@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== dependencies: define-lazy-prop "^2.0.0" is-docker "^2.1.1" @@ -6643,7 +6930,7 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pirates@^4.0.4: +pirates@^4.0.1, pirates@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== @@ -6710,22 +6997,22 @@ postcss-color-rebeccapurple@^7.1.1: dependencies: postcss-value-parser "^4.2.0" -postcss-colormin@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" - integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== +postcss-colormin@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" + integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" colord "^2.9.1" postcss-value-parser "^4.2.0" -postcss-convert-values@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz#31586df4e184c2e8890e8b34a0b9355313f503ab" - integrity sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g== +postcss-convert-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" + integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== dependencies: - browserslist "^4.20.3" + browserslist "^4.21.4" postcss-value-parser "^4.2.0" postcss-custom-media@^8.0.2: @@ -6735,10 +7022,10 @@ postcss-custom-media@^8.0.2: dependencies: postcss-value-parser "^4.2.0" -postcss-custom-properties@^12.1.8: - version "12.1.8" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.8.tgz#aa003e1885c5bd28e2e32496cd597e389ca889e4" - integrity sha512-8rbj8kVu00RQh2fQF81oBqtduiANu4MIxhyf0HbbStgPtnFlWn0yiaYTpLHrPnJbffVY1s9apWsIoVZcc68FxA== +postcss-custom-properties@^12.1.10: + version "12.1.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz#d14bb9b3989ac4d40aaa0e110b43be67ac7845cf" + integrity sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ== dependencies: postcss-value-parser "^4.2.0" @@ -6827,10 +7114,10 @@ postcss-image-set-function@^4.0.7: dependencies: postcss-value-parser "^4.2.0" -postcss-import@^14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" - integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== dependencies: postcss-value-parser "^4.0.0" read-cache "^1.0.0" @@ -6841,10 +7128,10 @@ postcss-initial@^4.0.1: resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== -postcss-js@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00" - integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ== +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== dependencies: camelcase-css "^2.0.1" @@ -6856,13 +7143,13 @@ postcss-lab-function@^4.2.1: "@csstools/postcss-progressive-custom-properties" "^1.1.0" postcss-value-parser "^4.2.0" -postcss-load-config@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" - integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== +postcss-load-config@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" + integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== dependencies: lilconfig "^2.0.5" - yaml "^1.10.2" + yaml "^2.1.1" postcss-loader@^6.2.1: version "6.2.1" @@ -6883,20 +7170,20 @@ postcss-media-minmax@^5.0.0: resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== -postcss-merge-longhand@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" - integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== +postcss-merge-longhand@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" + integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== dependencies: postcss-value-parser "^4.2.0" - stylehacks "^5.1.0" + stylehacks "^5.1.1" -postcss-merge-rules@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" - integrity sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ== +postcss-merge-rules@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" + integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" cssnano-utils "^3.1.0" postcss-selector-parser "^6.0.5" @@ -6917,12 +7204,12 @@ postcss-minify-gradients@^5.1.1: cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" -postcss-minify-params@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz#ac41a6465be2db735099bbd1798d85079a6dc1f9" - integrity sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg== +postcss-minify-params@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" + integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" @@ -6961,17 +7248,17 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nested@5.0.6: - version "5.0.6" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc" - integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA== +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== dependencies: - postcss-selector-parser "^6.0.6" + postcss-selector-parser "^6.0.11" -postcss-nesting@^10.1.10: - version "10.1.10" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.10.tgz#9c396df3d8232cbedfa95baaac6b765b8fd2a817" - integrity sha512-lqd7LXCq0gWc0wKXtoKDru5wEUNjm3OryLVNRZ8OnW8km6fSNUuFrjEhU3nklxXE2jvd4qrox566acgh+xQt8w== +postcss-nesting@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz#0b12ce0db8edfd2d8ae0aaf86427370b898890be" + integrity sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA== dependencies: "@csstools/selector-specificity" "^2.0.0" postcss-selector-parser "^6.0.10" @@ -7016,12 +7303,12 @@ postcss-normalize-timing-functions@^5.1.0: dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-unicode@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" - integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== +postcss-normalize-unicode@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" + integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" postcss-value-parser "^4.2.0" postcss-normalize-url@^5.1.0: @@ -7049,9 +7336,9 @@ postcss-normalize@^10.0.1: sanitize.css "*" postcss-opacity-percentage@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz#bd698bb3670a0a27f6d657cc16744b3ebf3b1145" - integrity sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w== + version "1.1.3" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz#5b89b35551a556e20c5d23eb5260fbfcf5245da6" + integrity sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A== postcss-ordered-values@^5.1.3: version "5.1.3" @@ -7081,11 +7368,11 @@ postcss-place@^7.0.5: postcss-value-parser "^4.2.0" postcss-preset-env@^7.0.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.1.tgz#2bfe935736727ab601a5c718bf24fc9f858eceb0" - integrity sha512-8884CHxQaoN1i4iEK+JvzOe8emODb5R4p/0dw4yEdo7QM4RdUk2sBx0fnzFyJt8BLfZSCGeVkKZ4HC564waBpQ== + version "7.8.3" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz#2a50f5e612c3149cc7af75634e202a5b2ad4f1e2" + integrity sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag== dependencies: - "@csstools/postcss-cascade-layers" "^1.0.6" + "@csstools/postcss-cascade-layers" "^1.1.1" "@csstools/postcss-color-function" "^1.1.1" "@csstools/postcss-font-format-keywords" "^1.0.1" "@csstools/postcss-hwb-function" "^1.0.2" @@ -7099,19 +7386,19 @@ postcss-preset-env@^7.0.1: "@csstools/postcss-text-decoration-shorthand" "^1.0.0" "@csstools/postcss-trigonometric-functions" "^1.0.2" "@csstools/postcss-unset-value" "^1.0.2" - autoprefixer "^10.4.8" - browserslist "^4.21.3" + autoprefixer "^10.4.13" + browserslist "^4.21.4" css-blank-pseudo "^3.0.3" css-has-pseudo "^3.0.4" css-prefers-color-scheme "^6.0.3" - cssdb "^7.0.1" + cssdb "^7.1.0" postcss-attribute-case-insensitive "^5.0.2" postcss-clamp "^4.1.0" postcss-color-functional-notation "^4.2.4" postcss-color-hex-alpha "^8.0.4" postcss-color-rebeccapurple "^7.1.1" postcss-custom-media "^8.0.2" - postcss-custom-properties "^12.1.8" + postcss-custom-properties "^12.1.10" postcss-custom-selectors "^6.0.3" postcss-dir-pseudo-class "^6.0.5" postcss-double-position-gradients "^3.1.2" @@ -7125,7 +7412,7 @@ postcss-preset-env@^7.0.1: postcss-lab-function "^4.2.1" postcss-logical "^5.0.4" postcss-media-minmax "^5.0.0" - postcss-nesting "^10.1.10" + postcss-nesting "^10.2.0" postcss-opacity-percentage "^1.1.2" postcss-overflow-shorthand "^3.0.4" postcss-page-break "^3.0.4" @@ -7142,12 +7429,12 @@ postcss-pseudo-class-any-link@^7.1.6: dependencies: postcss-selector-parser "^6.0.10" -postcss-reduce-initial@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" - integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== +postcss-reduce-initial@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" + integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" postcss-reduce-transforms@^5.1.0: @@ -7169,10 +7456,10 @@ postcss-selector-not@^6.0.1: dependencies: postcss-selector-parser "^6.0.10" -postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9: - version "6.0.10" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: + version "6.0.12" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz#2efae5ffab3c8bfb2b7fbf0c426e3bca616c4abb" + integrity sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -7210,12 +7497,12 @@ postcss@^7.0.35: picocolors "^0.2.1" source-map "^0.6.1" -postcss@^8.3.5, postcss@^8.4.14, postcss@^8.4.4, postcss@^8.4.7: - version "8.4.16" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" - integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== +postcss@^8.3.5, postcss@^8.4.19, postcss@^8.4.23, postcss@^8.4.4: + version "8.4.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab" + integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA== dependencies: - nanoid "^3.3.4" + nanoid "^3.3.6" picocolors "^1.0.0" source-map-js "^1.0.2" @@ -7287,9 +7574,9 @@ progress@^2.0.3: integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise@^8.1.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.2.0.tgz#a1f6280ab67457fbfc8aad2b198c9497e9e5c806" - integrity sha512-+CMAlLHqwRYwBMXKCP+o8ns7DN+xHDUiI+0nArsiJ9y+kJVPLFxEaSw6Ha9s9H0tftxg2Yzl25wqj9G7m5wLZg== + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" + integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== dependencies: asap "~2.0.6" @@ -7324,9 +7611,9 @@ psl@^1.1.33: integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== q@^1.1.2: version "1.5.1" @@ -7347,10 +7634,10 @@ qrcode.react@^1.0.1: prop-types "^15.6.0" qr.js "0.0.0" -qs@6.10.3: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" @@ -7364,11 +7651,6 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - raf@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" @@ -7440,14 +7722,13 @@ react-dev-utils@^12.0.0: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" + scheduler "^0.23.0" react-error-overlay@^6.0.11: version "6.0.11" @@ -7455,9 +7736,9 @@ react-error-overlay@^6.0.11: integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== react-fast-compare@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" - integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== + version "3.2.1" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.1.tgz#53933d9e14f364281d6cba24bfed7a4afb808b5f" + integrity sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg== react-helmet@^6.1.0: version "6.1.0" @@ -7490,9 +7771,9 @@ react-lifecycles-compat@^3.0.4: integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== react-redux@^7.2.6: - version "7.2.8" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.8.tgz#a894068315e65de5b1b68899f9c6ee0923dd28de" - integrity sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw== + version "7.2.9" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" + integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ== dependencies: "@babel/runtime" "^7.15.4" "@types/react-redux" "^7.1.20" @@ -7506,27 +7787,27 @@ react-refresh@^0.11.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== -react-resize-detector@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-7.1.2.tgz#8ef975dd8c3d56f9a5160ac382ef7136dcd2d86c" - integrity sha512-zXnPJ2m8+6oq9Nn8zsep/orts9vQv3elrpA+R8XTcW7DVVUJ9vwDwMXaBtykAYjMnkCIaOoK9vObyR7ZgFNlOw== +react-resize-detector@^8.0.4: + version "8.1.0" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-8.1.0.tgz#1c7817db8bc886e2dbd3fbe3b26ea8e56be0524a" + integrity sha512-S7szxlaIuiy5UqLhLL1KY3aoyGHbZzsTpYal9eYMwCyKqoqoVLCmIgAgNyIM1FhnP2KyBygASJxdhejrzjMb+w== dependencies: lodash "^4.17.21" react-router-dom@^6.2.1: - version "6.3.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d" - integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw== + version "6.11.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.11.1.tgz#af226bae950deb437208a606a47cf5c2d72c55dc" + integrity sha512-dPC2MhoPeTQ1YUOt5uIK376SMNWbwUxYRWk2ZmTT4fZfwlOvabF8uduRKKJIyfkCZvMgiF0GSCQckmkGGijIrg== dependencies: - history "^5.2.0" - react-router "6.3.0" + "@remix-run/router" "1.6.1" + react-router "6.11.1" -react-router@6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" - integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== +react-router@6.11.1: + version "6.11.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.11.1.tgz#6e58458c03e16834dda2b433c6adb9e7c2b1d7a8" + integrity sha512-OZINSdjJ2WgvAi7hgNLazrEV8SGn6xrKA+MkJe9wVDMZ3zQ6fdJocUjpCUCI0cNrelWjcvon0S/QK/j0NzL3KA== dependencies: - history "^5.2.0" + "@remix-run/router" "1.6.1" react-scripts@5.0.0: version "5.0.0" @@ -7588,12 +7869,12 @@ react-side-effect@^2.1.0: resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a" integrity sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw== -react-smooth@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.1.tgz#74c7309916d6ccca182c4b30c8992f179e6c5a05" - integrity sha512-Own9TA0GPPf3as4vSwFhDouVfXP15ie/wIHklhyKBH5AN6NFtdk0UpHBnonV11BtqDkAWlt40MOUc+5srmW7NA== +react-smooth@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.2.tgz#0ef24213628cb13bf4305194a050e1db4302a3a1" + integrity sha512-pgqSp1q8rAGtF1bXQE0m3CHGLNfZZh5oA5o1tsPLXRHnKtkujMIJ8Ws5nO1mTySZf1c4vgwlEk+pHi3Ln6eYLw== dependencies: - fast-equals "^2.0.0" + fast-equals "^4.0.3" react-transition-group "2.9.0" react-transition-group@2.9.0: @@ -7606,13 +7887,12 @@ react-transition-group@2.9.0: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" -react@^17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" read-cache@^1.0.0: version "1.0.0" @@ -7622,9 +7902,9 @@ read-cache@^1.0.0: pify "^2.3.0" readable-stream@^2.0.1: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -7635,9 +7915,9 @@ readable-stream@^2.0.1: util-deprecate "~1.0.1" readable-stream@^3.0.6: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -7658,31 +7938,26 @@ recharts-scale@^0.4.4: decimal.js-light "^2.4.1" recharts@^2.1.10: - version "2.1.14" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.1.14.tgz#177259b4d423a287a9284420fe2208bdb45311e7" - integrity sha512-GDmDDPEmRhGb6O41OfJUKh/RFYh3QMtEdaNuXOnVtJN8wiifo41MvIHHzrjf7Vp7/yJYFsGaXnCElzM5H7SPmQ== + version "2.5.0" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.5.0.tgz#34452852509099502690f9d2a72bde1d4cd65648" + integrity sha512-0EQYz3iA18r1Uq8VqGZ4dABW52AKBnio37kJgnztIqprELJXpOEsa0SzkqU1vjAhpCXCv52Dx1hiL9119xsqsQ== dependencies: - "@types/d3-interpolate" "^3.0.1" - "@types/d3-scale" "^4.0.2" - "@types/d3-shape" "^3.1.0" classnames "^2.2.5" - d3-interpolate "^3.0.1" - d3-scale "^4.0.2" - d3-shape "^3.1.0" eventemitter3 "^4.0.1" lodash "^4.17.19" react-is "^16.10.2" - react-resize-detector "^7.1.2" - react-smooth "^2.0.1" + react-resize-detector "^8.0.4" + react-smooth "^2.0.2" recharts-scale "^0.4.4" reduce-css-calc "^2.1.8" + victory-vendor "^36.6.8" recursive-readdir@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" - integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + version "2.2.3" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== dependencies: - minimatch "3.0.4" + minimatch "^3.0.5" reduce-css-calc@^2.1.8: version "2.1.8" @@ -7692,22 +7967,22 @@ reduce-css-calc@^2.1.8: css-unit-converter "^1.1.1" postcss-value-parser "^3.3.0" -redux-thunk@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" - integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== +redux-thunk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" + integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== -redux@^4.0.0, redux@^4.1.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13" - integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA== +redux@^4.0.0, redux@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" + integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== dependencies: "@babel/runtime" "^7.9.2" -regenerate-unicode-properties@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" - integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== dependencies: regenerate "^1.4.2" @@ -7716,15 +7991,15 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.9: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== dependencies: "@babel/runtime" "^7.8.4" @@ -7733,41 +8008,31 @@ regex-parser@^2.2.11: resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== -regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== +regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -regexpu-core@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" - integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== dependencies: + "@babel/regjsgen" "^0.8.0" regenerate "^1.4.2" - regenerate-unicode-properties "^10.0.1" - regjsgen "^0.6.0" - regjsparser "^0.8.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" -regjsgen@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" - integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== - -regjsparser@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" - integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== dependencies: jsesc "~0.5.0" @@ -7802,10 +8067,10 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -reselect@^4.1.5: - version "4.1.6" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.6.tgz#19ca2d3d0b35373a74dc1c98692cdaffb6602656" - integrity sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ== +reselect@^4.1.8: + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== resolve-cwd@^3.0.0: version "3.0.0" @@ -7836,20 +8101,20 @@ resolve-url-loader@^4.0.0: source-map "0.6.1" resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== -resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.2: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.11.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.3: +resolve@^2.0.0-next.4: version "2.0.0-next.4" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== @@ -7886,9 +8151,9 @@ rollup-plugin-terser@^7.0.0: terser "^5.0.0" rollup@^2.43.1: - version "2.79.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.0.tgz#9177992c9f09eb58c5e56cbfa641607a12b57ce2" - integrity sha512-x4KsrCgwQ7ZJPcFA/SUu6QVcYlO7uRLfLAy0DSA4NS2eG8japdbpM50ToH7z4iObodRYOJ0soneF0iaQRJ6zhA== + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== optionalDependencies: fsevents "~2.3.2" @@ -7899,6 +8164,16 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -7909,6 +8184,15 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -7939,13 +8223,12 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" schema-utils@2.7.0: version "2.7.0" @@ -7965,31 +8248,31 @@ schema-utils@^2.6.5: ajv "^6.12.4" ajv-keywords "^3.5.2" -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.2.tgz#36c10abca6f7577aeae136c804b0c741edeadc99" + integrity sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg== dependencies: "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + version "4.0.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.1.tgz#eb2d042df8b01f4b5c276a2dfd41ba0faab72e8d" + integrity sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ== dependencies: "@types/json-schema" "^7.0.9" - ajv "^8.8.0" + ajv "^8.9.0" ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" + ajv-keywords "^5.1.0" select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== -selfsigned@^2.0.1: +selfsigned@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== @@ -8001,10 +8284,10 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: + version "7.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" + integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== dependencies: lru-cache "^6.0.0" @@ -8034,10 +8317,10 @@ serialize-javascript@^4.0.0: dependencies: randombytes "^2.1.0" -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== dependencies: randombytes "^2.1.0" @@ -8087,9 +8370,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" - integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== side-channel@^1.0.4: version "1.0.4" @@ -8145,9 +8428,9 @@ source-map-js@^1.0.1, source-map-js@^1.0.2: integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== source-map-loader@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d" - integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.2.tgz#af23192f9b344daa729f6772933194cc5fa54fee" + integrity sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg== dependencies: abab "^2.0.5" iconv-lite "^0.6.3" @@ -8217,9 +8500,9 @@ stable@^0.1.8: integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" @@ -8238,6 +8521,13 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -8268,37 +8558,46 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d" - integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg== +string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" + integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" has-symbols "^1.0.3" internal-slot "^1.0.3" - regexp.prototype.flags "^1.4.1" + regexp.prototype.flags "^1.4.3" side-channel "^1.0.4" -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== +string.prototype.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" - es-abstract "^1.19.5" + es-abstract "^1.20.4" -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" - es-abstract "^1.19.5" + es-abstract "^1.20.4" + +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" string_decoder@^1.1.1: version "1.3.0" @@ -8363,18 +8662,31 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== style-loader@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + version "3.3.2" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.2.tgz#eaebca714d9e462c19aa1e3599057bc363924899" + integrity sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw== -stylehacks@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" - integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== +stylehacks@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" postcss-selector-parser "^6.0.4" +sucrase@^3.32.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7" + integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -8452,32 +8764,33 @@ symbol-tree@^3.2.4: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== tailwindcss@^3.0.2: - version "3.1.8" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.8.tgz#4f8520550d67a835d32f2f4021580f9fddb7b741" - integrity sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g== + version "3.3.2" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.2.tgz#2f9e35d715fdf0bbf674d90147a0684d7054a2d3" + integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w== dependencies: + "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" chokidar "^3.5.3" - color-name "^1.1.4" - detective "^5.2.1" didyoumean "^1.2.2" dlv "^1.1.3" - fast-glob "^3.2.11" + fast-glob "^3.2.12" glob-parent "^6.0.2" is-glob "^4.0.3" - lilconfig "^2.0.6" + jiti "^1.18.2" + lilconfig "^2.1.0" + micromatch "^4.0.5" normalize-path "^3.0.0" object-hash "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.14" - postcss-import "^14.1.0" - postcss-js "^4.0.0" - postcss-load-config "^3.1.4" - postcss-nested "5.0.6" - postcss-selector-parser "^6.0.10" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" postcss-value-parser "^4.2.0" - quick-lru "^5.1.1" - resolve "^1.22.1" + resolve "^1.22.2" + sucrase "^3.32.0" tapable@^1.0.0: version "1.1.3" @@ -8512,21 +8825,21 @@ terminal-link@^2.0.0: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" -terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5: - version "5.3.6" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" - integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== +terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.7: + version "5.3.7" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz#ef760632d24991760f339fe9290deb936ad1ffc7" + integrity sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw== dependencies: - "@jridgewell/trace-mapping" "^0.3.14" + "@jridgewell/trace-mapping" "^0.3.17" jest-worker "^27.4.5" schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" + serialize-javascript "^6.0.1" + terser "^5.16.5" -terser@^5.0.0, terser@^5.10.0, terser@^5.14.1: - version "5.15.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" - integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== +terser@^5.0.0, terser@^5.10.0, terser@^5.16.5: + version "5.17.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.17.1.tgz#948f10830454761e2eeedc6debe45c532c83fd69" + integrity sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -8547,10 +8860,24 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + version "6.0.2" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" + integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== thunky@^1.0.2: version "1.1.0" @@ -8608,6 +8935,11 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + ts-node@^10.7.0: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -8628,12 +8960,12 @@ ts-node@^10.7.0: yn "3.1.1" tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== dependencies: "@types/json5" "^0.0.29" - json5 "^1.0.1" + json5 "^1.0.2" minimist "^1.2.6" strip-bom "^3.0.0" @@ -8643,9 +8975,9 @@ tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.3: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== tsutils@^3.21.0: version "3.21.0" @@ -8696,6 +9028,15 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -8703,6 +9044,11 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -8726,15 +9072,15 @@ unicode-match-property-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript "^2.0.0" unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== unique-string@^2.0.0: version "2.0.0" @@ -8768,10 +9114,10 @@ upath@^1.2.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz#16279639cff1d0f800b14792de43d97df2d11b7d" - integrity sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg== +update-browserslist-db@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -8840,6 +9186,26 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +victory-vendor@^36.6.8: + version "36.6.10" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.6.10.tgz#e7e3646deaf0e850bc60dffdad6d7a4abee40632" + integrity sha512-7YqYGtsA4mByokBhCjk+ewwPhUfzhR1I3Da6/ZsZUv/31ceT77RKoaqrxRq5Ki+9we4uzf7+A+7aG2sfYhm7nA== + dependencies: + "@types/d3-array" "^3.0.3" + "@types/d3-ease" "^3.0.0" + "@types/d3-interpolate" "^3.0.1" + "@types/d3-scale" "^4.0.2" + "@types/d3-shape" "^3.1.0" + "@types/d3-time" "^3.0.0" + "@types/d3-timer" "^3.0.0" + d3-array "^3.1.6" + d3-ease "^3.0.1" + d3-interpolate "^3.0.1" + d3-scale "^4.0.2" + d3-shape "^3.1.0" + d3-time "^3.0.0" + d3-timer "^3.0.1" + w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" @@ -8922,9 +9288,9 @@ webpack-dev-middleware@^5.3.1: schema-utils "^4.0.0" webpack-dev-server@^4.6.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.0.tgz#290ee594765cd8260adfe83b2d18115ea04484e7" - integrity sha512-L5S4Q2zT57SK7tazgzjMiSMBdsw+rGYIX27MgPgx7LDhWO0lViPrHKoLS7jo5In06PWYAhlYu3PbyoC6yAThbw== + version "4.13.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.13.3.tgz#9feb740b8b56b886260bae1360286818a221bae8" + integrity sha512-KqqzrzMRSRy5ePz10VhjyL27K2dxqwXQLP5rAKwRJBPUahe7Z2bBWzHw37jeb8GCPKxZRO79ZdQUAPesMh/Nug== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -8945,16 +9311,17 @@ webpack-dev-server@^4.6.0: html-entities "^2.3.2" http-proxy-middleware "^2.0.3" ipaddr.js "^2.0.1" + launch-editor "^2.6.0" open "^8.0.9" p-retry "^4.5.0" rimraf "^3.0.2" schema-utils "^4.0.0" - selfsigned "^2.0.1" + selfsigned "^2.1.1" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" webpack-dev-middleware "^5.3.1" - ws "^8.4.2" + ws "^8.13.0" webpack-manifest-plugin@^4.0.2: version "4.1.1" @@ -8993,21 +9360,21 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.64.4: - version "5.76.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.1.tgz#7773de017e988bccb0f13c7d75ec245f377d295c" - integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ== + version "5.82.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.82.0.tgz#3c0d074dec79401db026b4ba0fb23d6333f88e7d" + integrity sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" acorn "^8.7.1" acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.13.0" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" @@ -9016,9 +9383,9 @@ webpack@^5.64.4: loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.1.2" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" + terser-webpack-plugin "^5.3.7" watchpack "^2.4.0" webpack-sources "^3.2.3" @@ -9082,6 +9449,28 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -9306,10 +9695,10 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.4.2: - version "8.8.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" - integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== +ws@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== xml-name-validator@^3.0.0: version "3.0.0" @@ -9321,16 +9710,16 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -9341,6 +9730,11 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.1.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073" + integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA== + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"