Browse Source

Merge branch 'dev' into Issue-#23643

pull/23666/head
Ahmet Çelik 5 months ago
parent
commit
5dfbae2acf
  1. 18
      Directory.Packages.props
  2. 2
      docs/en/Community-Articles/2025-09-02-training-campaign/post.md
  3. 173
      docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/Post.md
  4. BIN
      docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/cover.png
  5. BIN
      docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/image-1.png
  6. BIN
      docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/image-2.png
  7. BIN
      docs/en/Community-Articles/2025-09-10-Truly-Layering-a-NET-Application-Based-on-DDD-Principles/coverimage.png
  8. 191
      docs/en/Community-Articles/2025-09-10-Truly-Layering-a-NET-Application-Based-on-DDD-Principles/post.md
  9. 333
      docs/en/Community-Articles/2025-09-11-Best-Practices-Guide-for-REST-API-Design/post.md
  10. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/BenchmarkDotnet.png
  11. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/Disruptor.png
  12. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/MemoryPack.png
  13. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/MessagePack.png
  14. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/Polly.png
  15. 157
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/Post.md
  16. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/cliwrap.png
  17. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/cover.png
  18. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/wolverine-logo.png
  19. BIN
      docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/wolverine.png
  20. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_1.png
  21. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_2.png
  22. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_3.png
  23. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_4.png
  24. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_5.png
  25. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_6.png
  26. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_7.png
  27. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_8.png
  28. BIN
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_9.png
  29. 282
      docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/post.md
  30. 803
      docs/en/Community-Articles/2025-09-11-aws-secrets-manager-in-abp-framework/article.md
  31. BIN
      docs/en/Community-Articles/2025-09-11-aws-secrets-manager-in-abp-framework/cover.png
  32. 316
      docs/en/Community-Articles/2025-09-12-Demystified-Aggregates-in-DDD-&-.NET/post.md
  33. 4
      docs/en/docs-nav.json
  34. 7
      docs/en/dynamic-proxying-interceptors.md
  35. 13
      docs/en/framework/api-development/standard-apis/configuration.md
  36. 45
      docs/en/framework/data/entity-framework-core/oracle-official.md
  37. 28
      docs/en/framework/fundamentals/localization.md
  38. 10
      docs/en/framework/infrastructure/blob-storing/google.md
  39. 5
      docs/en/framework/infrastructure/event-bus/distributed/index.md
  40. 213
      docs/en/framework/infrastructure/interceptors.md
  41. 2
      docs/en/framework/infrastructure/object-to-object-mapping.md
  42. 208
      docs/en/framework/ui/angular/form-validation.md
  43. 5
      docs/en/framework/ui/angular/modifying-the-menu.md
  44. 183
      docs/en/release-info/migration-guides/AutoMapper-To-Mapperly.md
  45. 9
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs
  46. 4
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs
  47. 12
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs
  48. 14
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs
  49. 8
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs
  50. 6
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs
  51. 10
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
  52. 26
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/DbContextEventInbox.cs
  53. 2
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EventInboxDbContextModelBuilderExtensions.cs
  54. 31
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IncomingEventRecord.cs
  55. 4
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IEventInbox.cs
  56. 18
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs
  57. 10
      framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventStatus.cs
  58. 17
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs
  59. 82
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs
  60. 22
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessorFailurePolicy.cs
  61. 28
      framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs
  62. 14
      framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs
  63. 72
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs
  64. 7
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationFile.cs
  65. 23
      framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/AbpMapperlyModule.cs
  66. 60
      framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs
  67. 2
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs
  68. 8
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  69. 31
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpBsonSerializer.cs
  70. 3
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs
  71. 36
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/IncomingEventRecord.cs
  72. 46
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbContextEventInbox.cs
  73. 54
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ObjectToInferredTypesConverter_Tests.cs
  74. 25
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs
  75. 24
      framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/en.json
  76. 13
      framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs
  77. 158
      framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/ExtraProperties_Dictionary_Reference_Tests.cs
  78. 43
      framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/SampleClasses/MapperlyMappers.cs
  79. 4
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityCache_Tests.cs
  80. 4
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs
  81. 9
      latest-versions.json
  82. 1
      modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Bundling/BasicThemeGlobalStyleContributor.cs
  83. 1
      modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/googlefonts.css
  84. 74
      modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.css
  85. 6
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
  86. 264
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
  87. 4
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
  88. 268
      modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
  89. 4
      modules/blogging/app/Volo.BloggingTestApp/package.json
  90. 306
      modules/blogging/app/Volo.BloggingTestApp/yarn.lock
  91. 2
      modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json
  92. 240
      modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock
  93. 10
      modules/cms-kit/angular/package.json
  94. 4
      modules/cms-kit/angular/projects/cms-kit/package.json
  95. 2
      modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json
  96. 240
      modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock
  97. 2
      modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json
  98. 240
      modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock
  99. 4
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json
  100. 392
      modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock

18
Directory.Packages.props

@ -113,10 +113,10 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.12.0" />
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.12.0" />
<PackageVersion Include="Microsoft.IdentityModel.Tokens" Version="8.12.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.12.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.14.0" />
<PackageVersion Include="Microsoft.IdentityModel.Tokens" Version="8.14.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.14.0" />
<PackageVersion Include="Minio" Version="6.0.4" />
<PackageVersion Include="MongoDB.Driver" Version="3.3.0" />
<PackageVersion Include="NEST" Version="7.17.5" />
@ -128,11 +128,11 @@
<PackageVersion Include="NUglify" Version="1.21.15" />
<PackageVersion Include="Nullable" Version="1.3.1" />
<PackageVersion Include="Octokit" Version="14.0.0" />
<PackageVersion Include="OpenIddict.Abstractions" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Core" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Server.AspNetCore" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Validation.AspNetCore" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Validation.ServerIntegration" Version="7.0.0" />
<PackageVersion Include="OpenIddict.Abstractions" Version="7.1.0" />
<PackageVersion Include="OpenIddict.Core" Version="7.1.0" />
<PackageVersion Include="OpenIddict.Server.AspNetCore" Version="7.1.0" />
<PackageVersion Include="OpenIddict.Validation.AspNetCore" Version="7.1.0" />
<PackageVersion Include="OpenIddict.Validation.ServerIntegration" Version="7.1.0" />
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.80" />
<PackageVersion Include="Polly" Version="8.5.2" />
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0" />

2
docs/en/Community-Articles/2025-09-02-training-campaign/post.md

@ -25,5 +25,5 @@ Simply visit our training page, select your preferred package, add your note if
Invest in your skills and advance your career with ABP.IO training. This offer won’t last long, so grab your spot now\!
### 🔗[Sign up for training now and start building with ABP](https://abp.io/trainings?utm_source=referral&utm_medium=website&utm_campaign=training_abpblogpost)\!
### 🔗[Pick your package and send your training request now!](https://abp.io/trainings?utm_source=referral&utm_medium=website&utm_campaign=training_abpblogpost)

173
docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/Post.md

@ -0,0 +1,173 @@
# .NET 10: What You Need to Know (LTS Release, Coming November 2025)
The next version of .NET is .NET 10 and it is coming with **Long-Term Support (LTS)**, scheduled for **November 2025**.
On **September 9, 2025**, Microsoft released **.NET 10 Release Candidate 1 (RC1)**, which supports go-live usage and is compatible with [Visual Studio 2026 Insider](https://visualstudio.microsoft.com/insiders/) and [Visual Studio Code Insider](https://code.visualstudio.com/insiders/) via the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) extension.
------
## .NET 10 Runtime Enhancements
- **JIT Speed-ups**: Enhanced struct argument handling—members now go directly into registers, reducing memory load/store operations.
- **Advanced Loop Optimization**: New graph-based loop inversion improves precision and boosts further optimizations.
- **Array Interface De-virtualization**: Critical for performance, now array-based enumerations inline and skip virtual calls including de-abstraction of array enumeration and small-array stack allocation.
- **General JIT Improvements**: Better code layout and branch reduction support overall efficiency.
------
## Language & Library Upgrades
### C# 14 Enhancements
- Field-backed properties: easier custom getters/setters.
- `nameof` for unbound generics like `List<>`.
- Implicit conversions for `Span<T>` and `ReadOnlySpan<T>`.
- Lambda parameter modifiers (`ref`, `in`, `out`).
- Partial constructors/events.
- `extension` blocks for static extension members.
- Null-conditional assignment (`?.=`) and custom compound/increment operators.
### F# & Visual Basic Enhancements
- F# improvements via `<LangVersion>preview</LangVersion>`, updated `FSharp.Core`, and compiler fixes.
- VB compiler supports `unmanaged` generics and respects `OverloadResolutionPriorityAttribute` for performance and overload clarity.
## .NET Libraries & SDK
### Libraries:
- Better ZipArchive performance (lazy entry loading).
- JSON improvements, including `JsonSourceGenerationOptions` and reference-handling tweaks.
- Enhanced `OrderedDictionary`, ISOWeek date APIs, PEM data and certificate handling, `CompareOptions.NumericOrdering`
### SDK & CLI:
- No major new SDK features in RC1—you should expect stability fixes rather than additions.
- Earlier previews brought JSON support improvements (e.g., `PipeReader` for JSON, WebSocketStream, ML-DSA crypto, AES KeyWrap), TLS 1.3 for macOS
------
## ASP.NET Core & Blazor
### Blazor & Web App Security:
Enhanced OIDC and Microsoft Entra ID integration, including encrypted token caching and Key Vault use.
### UI Enhancements:
- `QuickGrid` gains `RowClass` for conditional styling.
- Scripts now served as static assets with compression and fingerprinting.
- NavigationManager no longer scrolls to top for same-page updates.
### API Improvements:
Full support for OpenAPI 3.1 (JSON Schema draft 2020-12), and metrics for authentication/authorization events (e.g., sign-ins, logins) .
------
## .NET MAUI
Updates include multiple file selection, image compression, WebView request interception, and support for Android API 35/36.
## EF Core
LINQ enhancements, performance boosts, better Azure Cosmos DB support, and more flexible named query filters.
## Breaking Changes in .NET 10
### ASP.NET Core - Breaking Changes in .NET 10:
.NET 10 Preview 7 brings **several deprecations + behavior changes**, while **RC1 removes the old WebHost model**.
- **[Cookie login redirects disabled](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/cookie-authentication-api-endpoints)** → Redirects no longer occur for API endpoints; APIs now return `401`/`403`. *(Behavioral change)*
- **[WithOpenApi deprecated](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/withopenapi-deprecated)** → Extension method removed; use updated OpenAPI generator features. *(Source incompatible)*
- **[Exception diagnostics suppressed](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/exception-handler-diagnostics-suppressed)** → When `TryHandleAsync` returns true, exception details aren’t logged. *(Behavioral change)*
- **[IActionContextAccessor obsolete](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/iactioncontextaccessor-obsolete)** → Marked obsolete; may break code depending on it. *(Source/behavioral change)*
- **[IncludeOpenAPIAnalyzers deprecated](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/openapi-analyzers-deprecated)** → Property and MVC API analyzers removed. *(Source incompatible)*
- **[IPNetwork & KnownNetworks obsolete](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/ipnetwork-knownnetworks-obsolete)** → Old networking APIs removed in favor of new ones. *(Source incompatible)*
- **[ApiDescription.Client package deprecated](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/apidescription-client-deprecated)** → No longer maintained; migrate to other tools. *(Source incompatible)*
- **[Razor run-time compilation obsolete](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/razor-runtime-compilation-obsolete)** → Disabled at runtime; precompilation required. *(Source incompatible)*
- **[WebHostBuilder, IWebHost, WebHost obsolete](https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/10/webhostbuilder-deprecated)** → Legacy hosting model deprecated; use `WebApplicationBuilder`. *(Source incompatible, RC1)*
### EF Core - Breaking Changes in .NET 10:
You can find the complete list at [Microsoft EF Core 10 Breaking Changes page](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-10.0/breaking-changes). Here's the brief summary:
#### EF Core - SQL Server
- **JSON column type by default (Azure SQL / compat level ≥170).** Primitive collections and owned types mapped to JSON now use SQL Server’s native `json` type instead of `nvarchar(max)`. A migration may alter existing columns. Mitigate by setting compat level <170 or explicitly forcing `nvarchar(max)`.
- **`ExecuteUpdateAsync` signature change.** Column setters now take a regular `Func<…>` (not an expression). Dynamic expression-tree code won’t compile; replace with imperative setters inside the lambda.
#### Microsoft.Data.Sqlite
- **`GetDateTimeOffset` (no offset) assumes UTC.** Previously assumed local time. You can temporarily revert via `AppContext.SetSwitch("Microsoft.Data.Sqlite.Pre10TimeZoneHandling", true)`.
- **Writing `DateTimeOffset` to REAL stores UTC.** Conversion now happens before writing; revertable with the same switch.
- **`GetDateTime` (with offset) returns UTC `DateTime` (`DateTimeKind.Utc`).** Was `Local` before. Same temporary switch if needed.
#### Who’s most affected
- Apps on **Azure SQL / SQL Server 2025** using JSON mapping.
- Codebases building **expression trees** for bulk updates.
- Apps using **SQLite** with date/time parsing or REAL timestamp storage.
#### Quick mitigations
- Set SQL Server compatibility <170 or force column type.
- Rewrite `ExecuteUpdateAsync` callers to use the new delegate form.
- For SQLite, update handling to UTC or use the temporary AppContext switch while transitioning.
### Containers - Breaking Changes in .NET 10:
Default .NET images now use [Ubuntu](https://learn.microsoft.com/en-us/dotnet/core/compatibility/containers/10.0/default-images-use-ubuntu).
### Core Libraries - Breaking Changes in .NET 10:
[ActivitySource](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/activity-sampling) behavior tweaks; [generic math](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/generic-math) shift behavior aligned; W3C trace context is [default](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/default-trace-context-propagator); [DriveInfo](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/driveinfo-driveformat-linux) reports Linux FS types; InlineArray size rules tightened; [System.Linq.AsyncEnumerable](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/asyncenumerable) included in core libs...
### Cryptography - Breaking Changes in .NET 10:
[Stricter X500](https://learn.microsoft.com/en-us/dotnet/core/compatibility/cryptography/10.0/x500distinguishedname-validation) name validation; [OpenSSL](https://learn.microsoft.com/en-us/dotnet/core/compatibility/cryptography/10.0/openssl-macos-unsupported) primitives unsupported on macOS; [some key members](https://learn.microsoft.com/en-us/dotnet/core/compatibility/cryptography/10.0/mldsa-slhdsa-secretkey-to-privatekey) nullable/renamed; env var [rename to](https://learn.microsoft.com/en-us/dotnet/core/compatibility/cryptography/10.0/version-override) `DOTNET_OPENSSL_VERSION_OVERRIDE`.
### Extensions - Breaking Changes in .NET 10:
[Config preserves](https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/10.0/configuration-null-values-preserved) nulls; [logging](https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/10.0/console-json-logging-duplicate-messages)/[package](https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/10.0/provideraliasattribute-moved-assembly)/trim annotations changes; some [trim-unsafe](https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/10.0/dynamically-accessed-members-configuration) code annotations removed.
### Globalization & Interop - Breaking Changes in .NET 10:
[ICU](https://learn.microsoft.com/en-us/dotnet/core/compatibility/globalization/10.0/version-override) env var renamed; single-file apps stop probing executable dir for native libs; [DllImport](https://learn.microsoft.com/en-us/dotnet/core/compatibility/interop/10.0/search-assembly-directory) search path tightened.
Networking:
[HTTP/3 disabled ](https://learn.microsoft.com/en-us/dotnet/core/compatibility/networking/10.0/http3-disabled-with-publishtrimmed) by default when trimming; [default cert revocation](https://learn.microsoft.com/en-us/dotnet/core/compatibility/networking/10.0/ssl-certificate-revocation-check-default) check now Online; [browser clients](https://learn.microsoft.com/en-us/dotnet/core/compatibility/networking/10.0/default-http-streaming) stream responses by default; [URI length limits](https://learn.microsoft.com/en-us/dotnet/core/compatibility/networking/10.0/uri-length-limits-removed) removed.
### SDK & MSBuild/NuGet - Breaking Changes in .NET 10:
`dotnet --interactive` [defaults to true](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/dotnet-cli-interactive); tool packages are [RID-specific](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/dotnet-tool-pack-publish); [workload](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/default-workload-config) sets default; `dotnet new sln` uses [SLNX](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/dotnet-new-sln-slnx-default); restore audits transitives; [local tool](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/dotnet-tool-install-local-manifest) install creates manifest by default; `project.json` [not supported](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/dotnet-restore-project-json-unsupported); stricter NuGet [validation](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/nuget-packageid-validation)/[errors](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/http-warnings-to-errors).
WinForms/WPF:
Multiple [API obsoletions](https://learn.microsoft.com/en-us/dotnet/core/compatibility/windows-forms/10.0/obsolete-apis)/parameter [renames](https://learn.microsoft.com/en-us/dotnet/core/compatibility/windows-forms/10.0/insertadjacentelement-orientation); [rendering](https://learn.microsoft.com/en-us/dotnet/core/compatibility/windows-forms/10.0/statusstrip-renderer)/behavior tweaks; stricter XAML rules (e.g., [disallow empty row](https://learn.microsoft.com/en-us/dotnet/core/compatibility/wpf/10.0/empty-grid-definitions)/column definitions or incorrect usage of [DynamicResource](https://learn.microsoft.com/en-us/dotnet/core/compatibility/wpf/10.0/dynamicresource-crash) will crash).
------
## Support Policy for .NET 10
As you can see from the picture below, **.NET 10 has long term support** therefore it will be maintained for 3 years **until November 2028**.
[![.NET 10 Support Policy](image-2.png)](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core)
## Download .NET10
Click 👉 https://dotnet.microsoft.com/en-us/download/dotnet/10.0 to download the latest release candidate (currently RC.1).
[![Download .NET 10](image-1.png)](https://dotnet.microsoft.com/en-us/download/dotnet/10.0)
Also to use the latest features, download/update your Visual Studio to the latest 👉 https://visualstudio.microsoft.com/downloads/

BIN
docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/cover.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

BIN
docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/image-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
docs/en/Community-Articles/2025-09-10-NET10-What-You-Need-To-Know/image-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
docs/en/Community-Articles/2025-09-10-Truly-Layering-a-NET-Application-Based-on-DDD-Principles/coverimage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

191
docs/en/Community-Articles/2025-09-10-Truly-Layering-a-NET-Application-Based-on-DDD-Principles/post.md

@ -0,0 +1,191 @@
# **Truly Layering a .NET Application Based on DDD Principles**
Okay, so we ALL been there, right? You start new project thinking "this time will be different" - clean code, perfect architecture, everything organized. Fast forward 3 months and your codebase look like someone throw grenade into bowl of spaghetti. Business logic everywhere, your controllers doing database work, and every new feature feel like defusing bomb.
I been there too many times, and honestly, it suck. But here thing - there actually way to build .NET apps that not turn into maintenance nightmare. It called **Layered Architecture** + **Domain-Driven Design (DDD)**, and once you get it, it game changer.
Let me walk you through this step by step, no fluff, just practical stuff that actually work.
### **Layered Architecture 101 (The Foundation)**
So layered architecture basically about keeping your code organized. Instead of having everything mixed together like bad smoothie, you separate concerns into different layers. Think like organizing your room - clothes go in closet, books on shelf, etc.
Here how it typically break down:
* **Presentation Layer (UI):** This what users actually see and click on - your ASP.NET Core MVC stuff, Razor Pages, Blazor, whatever float your boat.
* **Application Layer:** The conductor of orchestra. It not do heavy lifting itself, but tell everyone else what to do. It like middle manager of your code.
* **Domain Layer:** The VIP section. This where all your business rules live - entities, value objects, whole nine yards. This layer pure and not give damn about databases or UI.
* **Infrastructure Layer:** The "how-to" guy. Database stuff, email sending, API calls - basically all technical plumbing that make everything work.
The golden rule? **Dependency Rule**: Layers can only talk to layers below them (or more central). UI talk to Application, Application talk to Domain, but Domain? Domain not talk to anyone. It the cool kid that everyone want to hang out with.
### **DDD: Where Magic Happen**
Alright, so DDD not some fancy framework you install from NuGet. It more like mindset - basically saying "hey, let make our code actually reflect business we building for." Instead of having bunch of random classes, we organize everything around actual business domain.
Think like this: if you building e-commerce app, your code should scream "I'M E-COMMERCE APP" not "I'M BUNCH OF RANDOM CLASSES."
Here toolkit DDD give you (all living in your Domain Layer):
* **Entity:** This something that have identity. Like `Customer` - two customers with same name still different people because they have different IDs. It like having two friends named John - they not same person.
* **Value Object:** Opposite of entity. It defined by what it contain, not who it is. `Address` perfect for this - if two addresses have same street, city, and zip code, they same address. Usually immutable too.
* **Aggregate & Aggregate Root:** This where it get interesting. Aggregate like family of related objects that stick together. **Aggregate Root** head of family - only one you talk to when you want change something. Like `Order` that contain `OrderItem`s. You not mess with `OrderItem` directly, you tell `Order` to handle it.
* **Repository (Interface):** Think like your data access contract. It say "here how you can get and save stuff" without caring about whether it SQL Server, MongoDB, or file on your desktop. Interface live in Domain, implementation go in Infrastructure.
* **Domain Service:** When business logic too complex for single entity or value object, this your go-to. It like utility class but for business rules.
### **Putting It All Together: Real C# Code**
Alright, enough theory. Let see what this actually look like in real .NET solution. You typically have projects like:
* `MyProject.Domain` (or `.Core`) - The VIP section
* `MyProject.Application` - The middle manager
* `MyProject.Infrastructure` - The technical guy
* `MyProject.Web` (or whatever UI you using) - The pretty face
**1. The Domain Layer (`MyProject.Domain`) - The Heart**
This where magic happen. Zero dependencies on other projects (maybe some basic utility libraries, but that it). Pure business logic, no database nonsense, no UI concerns.
```csharp
// In MyProject.Domain/Orders/Order.cs
public class Order : AggregateRoot<Guid>
{
public Address ShippingAddress { get; private set; }
private readonly List<OrderItem> _orderItems = new();
public IReadOnlyCollection<OrderItem> OrderItems => _orderItems.AsReadOnly();
// Private constructor for ORM
private Order() { }
public Order(Guid id, Address shippingAddress) : base(id)
{
ShippingAddress = shippingAddress;
}
public void AddOrderItem(Guid productId, int quantity, decimal price)
{
if (quantity <= 0)
{
throw new BusinessException("Quantity must be greater than zero.");
}
// More business rules...
_orderItems.Add(new OrderItem(productId, quantity, price));
}
}
// In MyProject.Domain/Orders/IOrderRepository.cs
public interface IOrderRepository
{
Task<Order> GetAsync(Guid id);
Task AddAsync(Order order);
Task UpdateAsync(Order order);
}
```
See what I mean? The `Order` class all about business rules (`AddOrderItem` with validation and all that jazz). It not give damn about databases or how it get saved. That someone else problem.
**2. The Application Layer (`MyProject.Application`) - The Conductor**
This where we orchestrate everything. It talk to domain objects and use repositories to get/save data. Think like middle manager that coordinate work but not do heavy lifting.
```csharp
// In MyProject.Application/Orders/OrderAppService.cs
public class OrderAppService
{
private readonly IOrderRepository _orderRepository;
public OrderAppService(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task CreateOrderAsync(CreateOrderDto input)
{
var shippingAddress = new Address(input.Street, input.City, input.ZipCode);
var order = new Order(Guid.NewGuid(), shippingAddress);
foreach (var item in input.Items)
{
order.AddOrderItem(item.ProductId, item.Quantity, item.Price);
}
await _orderRepository.AddAsync(order);
}
}
```
The application service coordinate everything but let domain objects handle actual business rules. Clean separation!
**3. The Infrastructure Layer (`MyProject.Infrastructure`) - The Technical Guy**
This where we implement all interfaces we defined in domain. Entity Framework Core, email services, API clients - all technical plumbing live here.
```csharp
// In MyProject.Infrastructure/Orders/EfCoreOrderRepository.cs
public class EfCoreOrderRepository : IOrderRepository
{
private readonly MyDbContext _dbContext;
public EfCoreOrderRepository(MyDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<Order> GetAsync(Guid id)
{
// EF Core logic to get the order
return await _dbContext.Orders.FindAsync(id);
}
public async Task AddAsync(Order order)
{
await _dbContext.Orders.AddAsync(order);
}
// ... other implementations
}
```
### **ABP Framework: The Shortcut (Because We Lazy)**
Look, setting all this up from scratch pain. That where **ABP Framework** come in clutch. It basically DDD and layered architecture on steroids, and it do all boring setup work for you.
ABP not just talk talk - it walk walk. When you create new ABP solution, boom! Perfect project structure, all layered and DDD-compliant, ready to go.
Here what you get out of box:
* **Base Classes:** `AggregateRoot`, `Entity`, `ValueObject` - all with good stuff like optimistic concurrency and domain events. No more writing boilerplate.
* **Generic Repositories:** No more writing `IRepository` interfaces for every single entity. ABP give you `IRepository<TEntity, TKey>` with all standard CRUD methods. Just inject it and go.
* **Application Services:** Inherit from `ApplicationService` and boom - you done. It handle validation, authorization, exception handling, all that cross-cutting concern stuff without cluttering your actual business logic.
With ABP, our `OrderAppService` become way cleaner:
```csharp
// In ABP project, this much cleaner
public class OrderAppService : ApplicationService, IOrderAppService
{
private readonly IRepository<Order, Guid> _orderRepository;
public OrderAppService(IRepository<Order, Guid> orderRepository)
{
_orderRepository = orderRepository;
}
public async Task CreateAsync(CreateOrderDto input)
{
// ... same logic as before, but using ABP generic repository
var order = new Order(...);
await _orderRepository.InsertAsync(order);
}
}
```
### **Wrapping Up**
Look, I get it - this stuff take discipline and it not always fastest way to get features out door. But here thing: when you actually layer your app properly and put solid Domain Model at center, you end up with software that not suck to maintain.
Your code start speaking language of business instead of some random technical jargon. That whole point of DDD - make your code reflect what you actually building for.
Yeah, it take work upfront, but payoff huge. And frameworks like ABP make journey way less painful. Trust me, your future self will thank you when you not debugging spaghetti code at 2 AM.
What you think? You try this approach before, or you still stuck in spaghetti code phase? Let me know in comments!

333
docs/en/Community-Articles/2025-09-11-Best-Practices-Guide-for-REST-API-Design/post.md

@ -0,0 +1,333 @@
# Best Practices Guide for REST API Design
This guide compiles best practices for building robust, scalable, and sustainable RESTful APIs, based on information gathered from various sources.
## 1. Fundamentals of REST Architecture
REST is based on specific constraints and principles that support features like simplicity, scalability, and statelessness. The six core principles of RESTful architecture are:
- **Uniform Interface**: This is about consistency. You use standard HTTP methods (GET, POST, PUT, DELETE) and URIs to interact with resources. The client knows how to talk to the server without needing some custom instruction manual.
- **Client-Server**: The client (e.g., a frontend app) and the server are separate. The server handles data and logic, the client handles the user interface. They can evolve independently as long as the API contract doesn't change.
- **Stateless**: This is a big one. The server doesn't remember anything about the client between requests. Every single request must contain all the info needed to process it (like an auth token). This is key for scalability.
- **Cacheable**: Responses should declare whether they can be cached or not. Good caching can massively improve performance and reduce server load.
- **Layered System**: You can have things like proxies or load balancers between the client and the server without the client knowing. It just talks to one endpoint, and the layers in between handle the rest.
- **Code on Demand (Optional)**: This is the only optional one. It means the server can send back executable code (like JavaScript) to the client. Less common in the world of modern SPAs, but it's part of the spec.
## 2. URI Design and Naming Conventions
The URI structure is critical for making your API understandable and intuitive.
### Use Nouns Instead of Verbs
Your URIs should represent things (resources), not actions. The HTTP method already tells you what the action is.
- **Good:** `/api/users`
- **Bad:** `/api/getUsers`
### Use Plural Nouns for Resource Names
Stick with plural nouns for collections. It keeps things consistent, even when you're accessing a single item from that collection.
- **Get all users:** `GET /api/users`
- **Get a single user:** `GET /api/users/{id}`
### Use Nested Routes to Show Relationships
If a resource only exists in the context of another (like a user's orders), reflect that in the URL.
- **Good:** `/api/users/{userId}/orders` (All orders for a user)
- **Bad:** `/api/orders?userId={userId}`
- **Good:** `/api/users/{userId}/orders/{orderId}` (A specific order for a user)
**Note:** Use this structure only if the child resource is tightly coupled to the parent. Avoid nesting deeper than two or three levels, as this can complicate the URIs.
### Path Parameters vs. Query Parameters
Use the correct parameter type based on its function.
- **Path Parameters (`/users/{id}`):** Use these to identify a specific resource or a collection. They are mandatory for the endpoint to resolve.
- *Example:* `GET /api/users/123` uniquely identifies user 123.
- **Query Parameters (`?key=value`):** Use these for optional actions like filtering, sorting, or pagination on a collection.
- *Example:* `GET /api/users?role=admin&sort=lastName` filters the user collection.
### Keep the URL Structure Consistent
- **Use lowercase letters:** Since some systems are case-sensitive, always use lowercase in URIs for consistency.
- *Example:* Use `/api/product-offers` instead of `/api/Product-Offers`.
- **Use special characters correctly:** Use characters like `/`, `?`, and `#` only for their defined purposes.
- *Example:* To get comments for a specific post, use the path `/posts/123/comments`. To filter those comments, use a query parameter: `/posts/123/comments?authorId=45`.
## 3. Correct Usage of HTTP Methods
Each HTTP method has a specific purpose. Sticking to these standards makes your API predictable.
| **HTTP Method** | **Description** | **Idempotent*** | **Safe**** |
| --------------- | --------------------------------------------------------------------------- | --------------- | ---------- |
| **GET** | Retrieves a resource or a collection of resources. | Yes | Yes |
| **POST** | Creates a new resource. | No | No |
| **PUT** | Updates an existing resource completely or creates it if it does not exist. | Yes | No |
| **PATCH** | Partially updates an existing resource. | No | No |
| **DELETE** | Deletes a resource. | Yes | No |
- **Idempotent:** Doing it once has the same effect as doing it 100 times. Deleting a user is idempotent; once it's gone, it's gone.
- **Safe:** The request doesn't change anything on the server. GET is safe.
**Example in practice:**
Let's consider a resource endpoint for a collection of articles: `/api/articles`.
- **`GET /api/articles`**: Retrieves a list of all articles.
- **`GET /api/articles/123`**: Retrieves the specific article with ID 123.
- **`POST /api/articles`**: Creates a new article. The data for the new article is sent in the request body.
- **`PUT /api/articles/123`**: Replaces the entire article with ID 123 using the new data sent in the request body.
- **`PATCH /api/articles/123`**: Partially updates the article with ID 123. For example, you could send only the `{"title": "New Title"}` in the request body to update just the title.
- **`DELETE /api/articles/123`**: Deletes the article with ID 123.
## 4. Data Exchange and Responses
### Prefer the JSON Format
It's the standard. It's lightweight, human-readable, and every language can parse it easily. Send and receive your data as JSON.
- *Example Request Body:*
```
{
"title": "Best Practices for APIs",
"authorId": 5,
"content": "An article about designing great APIs..."
}
```
### Use Appropriate HTTP Status Codes
Use standard HTTP status codes to provide clear information to the client about the outcome of their request.
- **2xx (Success):**
- `200 OK`: The request was successful. (For GET, PUT, PATCH)
- `201 Created`: The resource was successfully created. (For POST) The response should include a `Location` header with the URI of the new resource.
- *Example:* `POST /api/articles` responds with `201 Created` and the header `Location: /api/articles/124`.
- `204 No Content`: The request was successful, but there is no response body. (For DELETE)
- **4xx (Client Error):**
- `400 Bad Request`: Invalid request (e.g., missing or incorrect data).
- `401 Unauthorized`: Authentication is required.
- `403 Forbidden`: No permission.
- `404 Not Found`: The requested resource could not be found.
- **5xx (Server Error):**
- `500 Internal Server Error`: An unexpected error occurred on the server.
### Provide Clear and Consistent Error Responses
When something goes wrong, give back a useful JSON error message. Your future self and any developer using your API will thank you.
- *Example of a detailed error response:*
```
{
"type": "[https://---.com/probs/validation-error](https://example.com/probs/validation-error)",
"title": "Your request parameters didn't validate.",
"status": 400,
"detail": "The 'email' field must be a valid email address.",
"instance": "/api/users"
}
```
## 5. Performance Optimization
Optimizing API performance is crucial for providing a good user experience and ensuring the scalability of your service. Key strategies include caching, efficient data retrieval, and controlling traffic.
### Caching
Caching is one of the most effective ways to improve performance. By storing and reusing frequently accessed data, you can significantly reduce latency and server load.
- **How it works:** Caching can be implemented at various levels (client-side, CDN, server-side). REST APIs can facilitate this by using standard HTTP caching headers.
- **Key Headers:**
- `Cache-Control`: Tells the client how long to cache something (e.g., `public, max-age=600`).
- `ETag`: A unique version identifier for a resource. The client can send this back in an `If-None-Match` header. If the data hasn't changed, you can just return `304 Not Modified` with an empty body, saving bandwidth.
- `Last-Modified`: Indicates when the resource was last changed. Similar to `ETag`, it can be used for conditional requests with the `If-Modified-Since` header.
- *Example Response Header for Caching:*
```
Cache-Control: public, max-age=600
ETag: "x234dff"
```
### Filtering, Sorting, and Pagination
For endpoints that return lists of resources, it's inefficient to return the entire dataset at once, especially if it's large. Implementing these features gives clients more control over the data they receive.
- **Filtering:** Allows clients to narrow down the result set based on specific criteria. This reduces the amount of data transferred and makes it easier for the client to find what it needs.
- *Example:* `GET /api/orders?status=shipped&customer_id=123`
- **Sorting:** Enables clients to request the data in a specific order. A common convention is to specify the field to sort by and the direction (ascending or descending).
- *Example:* `GET /api/users?sort=lastName_asc` or `GET /api/products?sort=-price` (the `-` indicates descending order).
- **Pagination:** Breaks down a large result set into smaller, manageable chunks called "pages". This prevents overloading the server and client with massive amounts of data in a single response.
- *Example:* `GET /api/articles?page=2&pageSize=20` (retrieves the second page, with 20 articles per page).
### Rate Limiting
Protect your API from abuse by limiting how many requests a client can make in a given time. If they exceed the limit, return a `429 Too Many Requests`.
It's also super helpful to return these headers so the client knows what's going on:
- `X-RateLimit-Limit`: Total requests allowed.
- `X-RateLimit-Remaining`: How many requests they have left.
- `Retry-After`: How many seconds they should wait before trying again.
## 6. Security
Security is not an optional feature; it must be a core part of your API design.
- **Always Use HTTPS (TLS):** Encrypt all traffic to prevent man-in-the-middle attacks. There are no exceptions to this rule for production APIs.
- **Authentication & Authorization:**
- **Authentication** (Who are you?): Use a standard like OAuth 2.0 or JWT Bearer Tokens.
- **Authorization** (What are you allowed to do?): Check permissions for every request. Just because a user is logged in doesn't mean they can delete another user's data.
- **Input Validation**: Always validate and sanitize data coming from the client to prevent injection attacks. If the data is bad, reject it with a `400 Bad Request`.
- **Use Security Headers**: Add headers like `Strict-Transport-Security` and `Content-Security-Policy` to add extra layers of browser-level protection.
## 7. API Lifecycle Management
### Versioning
Your API will change. Versioning lets you make breaking changes without messing up existing clients. The most common way is in the URI.
- **URI Versioning (Most Common):** `https://api.example.com/v1/users`
- **Pros:** Simple, explicit, and easy to explore in a browser.
- **Header Versioning:** The client requests a version via a custom HTTP header.
- *Example:* `Accept-Version: v1`
- **Pros:** Keeps the URI clean.
- **Media Type Versioning (Content Negotiation):** The version is included in the `Accept` header.
- *Example:* `Accept: application/vnd.example.v1+json`
- **Pros:** Technically the "purest" REST approach.
### Backward Compatibility & Deprecation
When you release v2, don't just kill v1. Keep it running for a while and communicate a clear shutdown schedule to your users.
### Documentation
An API is only as good as its documentation. Use tools like the **OpenAPI Specification (formerly Swagger)** to generate interactive, machine-readable documentation. Good docs should include:
- Authentication instructions.
- Clear explanations of each endpoint.
- Request/response examples.
- Error code definitions.
## 8. Monitoring and Testing
### Monitoring and Logging
To ensure your API is reliable, you must monitor its health and log important events.
- **Structured Logging:** Log in a machine-readable format like JSON. Include a `correlationId` to track a single request across multiple services.
- **Monitoring:** Track key metrics like latency (response time), error rate, and requests per second. Use tools like Prometheus, Grafana, or Datadog to visualize these metrics and set up alerts.
### API Testing
Thorough testing is essential to prevent bugs and regressions.
- **Unit Tests:** Test individual components and business logic in isolation.
- **Integration Tests:** Test the interaction between different parts of your API, including the database.
- **Contract Tests:** Verify that your API adheres to its documented contract (e.g., the OpenAPI spec).
## 9. Advanced Level: HATEOAS
**HATEOAS (Hypermedia as the Engine of Application State)** is a REST principle that allows your API to be self-documenting and more discoverable. It involves including hyperlinks in responses for actions that can be performed on the relevant resource.
For example, a response for a user resource might look like this:
```
{
"id": 1,
"name": "Deo Steel",
"links": [
{ "rel": "self", "href": "/users/1", "method": "GET" },
{ "rel": "update", "href": "/users/1", "method": "PUT" },
{ "rel": "delete", "href": "/users/1", "method": "DELETE" }
]
}
```
This way, the client can follow the links in the response to take the next step, rather than manually constructing the URIs.
## 10. A Practical Shortcut: Leveraging Frameworks like ABP.IO
Okay, that was a lot. While it's crucial to understand all these principles, you don't have to build everything from scratch. Modern frameworks can handle a ton of this for you. I work a lot in the .NET space, and **ABP Framework** is a great example of this.
Here’s how it automates many of the things we just talked about:
- **Automatic API Controllers**: You write your business logic in an "Application Service," and ABP automatically creates the REST API endpoints for you, following all the correct naming and HTTP method conventions. (Covers sections 2 & 3).
- **Built-in Best Practices**:
- **Standardized Error Responses**: It has a built-in exception handling system that automatically generates clean, consistent JSON error responses. (Covers section 4).
- **Input Validation**: It has automatic validation for your DTOs. If a request is invalid, it returns a detailed `400 Bad Request` without you writing a single line of code for it. (Covers section 6).
- **Paging, Sorting, Filtering**: You get these out of the box by just using their predefined interfaces. (Covers section 5).
- **Integrated Security**: It comes with a full auth system. You just add an `[Authorize]` attribute to a method, and it handles the rest. It also automatically manages database transactions per API request (Unit of Work) to ensure data consistency. (Covers section 6).
- **Automatic Documentation**: It automatically generates an OpenAPI/Swagger UI for your API, which is a massive help for anyone who needs to use it. (Covers section 7).
Using a framework like this lets you focus on your core business logic, confident that the foundation is built on solid, established best practices.

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/BenchmarkDotnet.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 KiB

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/Disruptor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/MemoryPack.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/MessagePack.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/Polly.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

157
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/Post.md

@ -0,0 +1,157 @@
# High-Performance .NET Libraries You Didn’t Know You Needed
Whether you’re building enterprise apps, microservices, or SaaS platforms, using the right libraries can help you ship faster and scale effortlessly.
Here are some **high-performance .NET libraries** you might not know but definitely should.
## 1. BenchmarkDotNet – Measure before you optimize
![BenchmarkDotnet](BenchmarkDotnet.png)
BenchmarkDotNet makes it simple to **benchmark .NET code with precision**.
- Easy setup with `[Benchmark]` attributes
- Generates detailed performance reports
- Works with .NET Core, .NET Framework, and Mono
Perfect for spotting bottlenecks in APIs, background services, or CPU-bound operations.
- **NuGet** (40M downloads) 🔗 https://www.nuget.org/packages/BenchmarkDotNet
- **GitHub** (11k stars) 🔗 https://github.com/dotnet/BenchmarkDotNet
## 2. MessagePack – Fastest JSON serializer
Need speed beyond System.Text.Json or Newtonsoft.Json? MessagePack is the fastest serializer for C# (.NET, .NET Core, Unity, Xamarin). MessagePack has a compact binary size and a full set of general-purpose expressive data types. Ideal for high-traffic APIs, IoT data processing, and microservices.
![MessagePack Benchmark](MessagePack.png)
- **NuGet** (204M downloads) 🔗 https://www.nuget.org/packages/messagepack
- **GitHub** (6.4K stars) 🔗 https://github.com/MessagePack-CSharp/MessagePack-CSharp
## 3. Polly – Resilience at scale
![Polly](Polly.png)
In distributed systems, failures are inevitable. **Polly** provides a fluent way to add **retry, circuit-breaker, and fallback** strategies.
- Handle transient faults gracefully
- Improve uptime and user experience
- Works seamlessly with HttpClient and gRPC
A must-have for cloud-native .NET applications.
- **NuGet** (1B downloads) 🔗 https://www.nuget.org/packages/polly/
- **GitHub** (14K stars) 🔗 https://github.com/App-vNext/Polly
## 4. MemoryPack – Zero-cost binary serialization
If you need **blazing-fast serialization** for in-memory caching or network transport, **MemoryPack** is a game-changer.
- Zero-copy, zero-alloc serialization
- Perfect for high-performance caching or game servers
- Strongly typed and version-tolerant
![MemoryPack](MemoryPack.png)
Great for real-time multiplayer games, chat apps, or financial systems.
- **NuGet** (5.3M downloads) 🔗 https://www.nuget.org/packages/MemoryPack
- **GitHub** (4K stars) 🔗 https://github.com/Cysharp/MemoryPack
## 5. WolverineFx – Ultra-low latency messaging
![wolverine](wolverine-logo.png)
MediatR was one of the best mediator libraries, but now it's a paid library. Wolverine is a toolset for command execution and message handling within .NET applications. The killer feature of Wolverine is its very efficient command execution pipeline that can be used as:
- An [inline "mediator" pipeline](https://wolverinefx.net/tutorials/mediator.html) for executing commands
- A [local message bus](https://wolverinefx.net/guide/messaging/transports/local.html) for in-application communication
- A full-fledged [asynchronous messaging framework](https://wolverinefx.net/guide/messaging/introduction.html) for robust communication and interaction between services when used in conjunction with low-level messaging infrastructure tools like RabbitMQ
- With the [WolverineFx.Http](https://wolverinefx.net/guide/http/) library, Wolverine's execution pipeline can be used directly as an alternative ASP.NET Core Endpoint provider
*image below is from [codecrash.net](https://www.codecrash.net/2024/02/06/Mediatr-versus-Wolverine-performance.html)*
![WolverineFx](wolverine.png)
WolverineFx is great for cleanly separating business logic from controllers while unifying in-process mediator patterns with powerful distributed messaging in a single, high-performance .NET library.
- **NuGet** (1.5M downloads) 🔗 https://www.nuget.org/packages/WolverineFx
- **GitHub** (1.7K stars) 🔗 https://github.com/JasperFx/wolverine
## 6. Disruptor-net – Next generation free .NET mediator
The Disruptor is a high-performance inter-thread message passing framework. A lock-free ring buffer for ultra-low latency messaging.
Features are:
- Zero memory allocation after initial setup (the events are pre-allocated).
- Push-based consumers.
- Optionally lock-free.
- Configurable wait strategies.
![Disruptor](Disruptor.png)
- **NuGet** (1.2M downloads) 🔗 https://www.nuget.org/packages/Disruptor/
- **GitHub** (1.3K stars) 🔗 https://github.com/disruptor-net/Disruptor-net
## 7. CliWrap - Running command-line processes
![CLIWrap](cliwrap.png)
CliWrap makes it easy to **run and manage external CLI processes in .NET**.
- Fluent, task-based API for starting commands
- Streams standard input/output and error in real time
- Supports cancellation, timeouts, and piping between processes
Ideal for automation, build tools, and integrating external executables.
- **NuGet** (14.1M downloads) 🔗 https://www.nuget.org/packages/CliWrap
- **GitHub** (4.7K stars) 🔗 https://github.com/Tyrrrz/CliWrap
---
## Hidden Libs from the Community
### Sylvan.Csv & **Sep**
- **Sylvan.Csv**: Up to *10× faster* and *100× less memory allocations* than `CsvHelper`, making CSV processing lightning-fast. ([Reddit](https://www.reddit.com/r/csharp/comments/191rwgt/extremely_highperformance_libraries_for_common/?utm_source=chatgpt.com))
- **Sep**: Even faster than Sylvan, but trades off some flexibility. Great when performance matters more than API richness. ([Reddit](https://www.reddit.com/r/csharp/comments/191rwgt/extremely_highperformance_libraries_for_common/?utm_source=chatgpt.com))
### String Parsing: **csFastFloat**
- Parses `float` and `double` around *8–9× faster* than `.Parse` methods—perfect for high-volume parsing tasks. ([Reddit](https://www.reddit.com/r/csharp/comments/191rwgt/extremely_highperformance_libraries_for_common/?utm_source=chatgpt.com))
### CySharp’s Suite: MemoryPack, MasterMemory, SimdLinq
- **MemoryPack**: One of the fastest serializers available, with low allocations and high throughput. Ideal for Web APIs or microservices. ([Reddit](https://www.reddit.com/r/csharp/comments/191rwgt/extremely_highperformance_libraries_for_common/?utm_source=chatgpt.com))
- **MasterMemory**: Designed for databases or config storage. Claims *4,700× faster than SQLite* with zero-allocations per query. ([Reddit](https://www.reddit.com/r/csharp/comments/191rwgt/extremely_highperformance_libraries_for_common/?utm_source=chatgpt.com))
- **SimdLinq**: SIMD-accelerated LINQ operations supporting a broader set of methods than .NET's built-in SIMD. Works when slight floating-point differences are acceptable. ([Reddit](https://www.reddit.com/r/csharp/comments/191rwgt/extremely_highperformance_libraries_for_common/?utm_source=chatgpt.com))
### Jil – JSON Deserializer
- Ultra-fast JSON (de)serializer with low memory overhead, used in high-scale systems. ([Performance is a Feature!](https://www.mattwarren.org/2014/09/05/stack-overflow-performance-lessons-part-2/?utm_source=chatgpt.com))
### StackExchange.NetGain – WebSocket Efficiency
- High-performance WebSocket server library designed for low-latency IO scenarios. (Now mostly replaced by Kestrel's built-in support, but worth knowing.) ([GitHub](https://github.com/StackExchange/NetGain?utm_source=chatgpt.com))
### Math Libraries: Math.NET Numerics & ILNumerics
- **Math.NET Numerics**: Core numerical methods and matrix math, similar to BLAS/LAPACK. ([Wikipedia](https://en.wikipedia.org/wiki/Math.NET_Numerics?utm_source=chatgpt.com))
- **ILNumerics**: Efficient numerical arrays with parallelized processing, loop unrolling and cache optimizations. Great for scientific computing. ([Wikipedia](https://en.wikipedia.org/wiki/ILNumerics?utm_source=chatgpt.com))

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/cliwrap.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/cover.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/wolverine-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

BIN
docs/en/Community-Articles/2025-09-11-High-Perf-DotNet-Libs/wolverine.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/images/img_9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

282
docs/en/Community-Articles/2025-09-11-Web-Design-Basics-for-Graphic-Designers-Who-Dont-Code/post.md

@ -0,0 +1,282 @@
# Web Design Basics for Graphic Designers Who Don't Code
## Introduction
As a **designer**, I have been working on **logos**, **posters**, and **social media announcement** **visuals** for years. However, when it comes to the web, I used to hold back saying “I **don’t know how to code**.” We have all thought about this at some point and unfortunately, we still think about it from time to time.
🚀 **Good news**: We can learn **web design** without writing code and design **user-friendly**, **aesthetic, and functional web interfaces** using basic knowledge.
In this article, we will talk about the **basics of web design**, its **differences from graphic design**, and whether it is possible to do **web design without knowing how to code**.
## Differences Between Graphic Design & Web Design
![](images/img_2.png)
### What is Graphic Design?
Graphic design is creating **visual content** that conveys a message to a **specific audience**. Graphic designers use various **visual elements** such as **color**, **typography**, **imagery**, and **layout** to communicate a message effectively. They work on a wide range of projects, including **logos**, **websites**, **packaging**, **advertisements, and branding**.
### What is Web Design?
Web design is the process of creating a website that can be viewed on computers or mobile devices. Like graphic design, web design also involves creating **graphics**, **typography**, **and visuals**, but they use the **internet** as the communication channel.
### Graphic Design
* Graphic Design is concerned with **visuals** and **appearance**.
* Graphic design focuses on visually conveying specific messages or ideas through **typography**, **visuals**, **colors**, and i**llustrations**.
* Graphic design focuses on how objects **look**.
* Graphic designers **do not need coding knowledge**.
* Graphic design is **static**.
### Web Design
* Web design is user experience–focused.
* Web design aims to create **functional** and **user-friendly** **websites** that provide the **best experience** for users.
* Web design considers **search engine optimization** when creating websites.
* Web designers need to have **knowledge of HTML**, **CSS**, and other web development languages to create **functional and responsive designs**.
* Web design is **dynamic**.
## Fundamental Principles of Web Design (Applicable Without Coding)
Companies and **brands** from almost every sector request the **creation of their own websites**. This way, they gain the opportunity to introduce their **services**, **prices**, and themselves to their **target audiences**. However, for this to have the desired effect, the website must be **designed properly**. What are the **fundamental principles** to pay attention to when designing a website? Now, it’s time to answer this question by introducing the basics. Here are the **indispensable principles in web design**.
### 1\) User-Centered Designs:
Users always value **ease and practicality** when receiving a service. For this reason, it is important for websites to be designed in a user-centered way. **Easy to find menus**, **fast usage**, and the **easy to locate any information** are very important. With **user centered design**, it is possible to create websites that are **easy to use** and also **satisfy users**.
### 2\) Responsive Designs:
It is very important for the website and its design to be **usable on every digital platform**. Therefore, the designed sites must have a **responsive design**. This means easy access to the site on a **phone**, **tablet**, or **computer**. This also ensures that users continue to prefer the site.
### 3\) Visual Hierarchy:
The page must have **visuals related to itself**, and **product content** should be matched with the **correct visuals**. It is also very important for visual elements to be placed according to their order of importance. On web pages, content compatible with visuals must be provided with **sufficient and accurate information**.
### 4\) Color and Typography Selection:
Color and typography selection is very important for handling visuals, colors, and text in a certain **harmony**. For the site to **attract attention** or for the relevant pages to achieve the expected interaction, the use of color and the chosen font style and font color must be harmonious. A design that is both **easy to read** and **eye catching** without causing any disturbance should be preferred.
### 5\) Content and Layout Structure:
One of the most desired features on web pages is **content organization**. Content that is **unrelated to the pages, creates confusion while reading**, or **lacks simplicity**, such as overly frequent paragraphs, incorrect fonts, and similar factors, causes web pages to have less impact. **Content structure** also includes **placing related topics sequentially** and **adding them to the menu**. For example, on a website created for shoes, if shoe types are grouped separately, users find it easier. Options like high heels, sandals, and sneakers help users find what they are looking for more easily, which in turn ensures positive site feedback.
### 6\) Speed Optimization:
As with every type of service, speed is very important for services provided through web pages. Easy navigation between pages, error-free performance, and ease of use are very important for users. No one wants to shop or use a service on a website that takes a long time to load, because everyone prefers websites to save time.
### 7\) Consistency:
For a service to be preferred, it must first be reliable. This is directly related to the information, visuals, and everything on the website. The information in the content, visuals, and content details must be consistent and should not raise any questions in visitors’ minds. Otherwise, negative feedback can later affect customer preferences and damage the brand image.
## Is It Possible to Do Web Design Without Coding?
In the past, it was not possible to create a website without at least some basic coding knowledge. However, today, almost anyone can build a website. Even if you have not written a **single line of code**.
The biggest helpers for those who want to do **web development without coding** are **No-Code** and **Low-Code** platforms. These tools help users **design websites** without dealing with **technical details**.
Systems like **Wix**, **Webflow**, **Shopify**, and **WordPress** are very common in this area.
![](images/img_3.png)
The web development process on these platforms is carried out through practical methods such as **drag-and-drop**, selecting **ready-made templates**, and filling out forms.
### **No Code**
As the name suggests, it allows you to create websites, mobile applications, automations, and workflows **without writing a single line of code**.
* **How Does It Work**? They usually have a visual editor. You create the skeleton of your application by dragging and dropping ready “building blocks” such as buttons, forms, and visuals onto your canvas. Then, you determine what these elements will do (for example, “go to this page when this button is clicked”) by selecting options from the menus.
* **Who Uses It**? It is perfect for entrepreneurs, marketers, product managers, designers, and anyone who wants to quickly test an idea.
* **Examples**: Platforms like Webflow, Bubble, Adalo, and Glide allow you to create a wide range of products, from complex web applications to mobile apps.
### **Low Code**
Low-Code systems require a bit more **technical knowledge** but still **do not require learning full-scale programming**.
* **How Does It Work**? You handle 80% of the work with drag-and-drop, and for the remaining 20% that requires customization, you add small code snippets.
* **Who Uses It**? It is generally preferred by IT departments of corporate companies and technical teams that want to develop more complex, scalable applications.
* **Examples**: Platforms like OutSystems and Mendix are used to build large, integrated systems that manage a company’s internal processes.
## What Should the Web Design Process be Like?
![](images/img_4.png)
**Web design** is a passionate field but can be **overwhelming** at times. When starting out, coming up with a plan on how to tackle your website or a web app idea often feels daunting: Where should you begin?Web designers often think about the **web design process** with a focus on **technical matters** such as wireframes, code, and content management. But great
design isn’t about how you integrate the social media buttons or even slick visuals. **Great design** is actually about having **a website creation process** that aligns with an **overarching strategy.**
Doing all the thinking beforehand ensures that you don’t forget anything crucial. It also frees up headspace for doing the actual work, avoids overwhelm, improves efficiency, and allows you to build better websites on repeat.
But how do you achieve that harmonious synthesis of elements? Through a **holistic web design** process that takes both **form and function** into account.
We have already covered the fundamentals, now, I'll share the steps to an **effective web design process.**
Let's get started.
### 1\) Goal Identification
In this **initial stage**, the designer needs to identify the end goal of the website design, usually in close collaboration with the client or other stakeholders. Questions to explore and answer in this stage of the design and website development process include:
* Who is the site for?
* What do they hope to find or do there?
* Is the main purpose of this website to inform, to sell (e-commerce, for everyone?), or to entertain?
* Does the website need to clearly convey the **brand's core message**, or is it part of a broader **brand strategy** with its own unique focus?
* If there are any, which **competitor sites** exist, and how should this site be **inspired by them** / how should it differ from them?
To have clear answers to above questions will lead to the **successful execution** of the project.
### What Purpose Will the Website Serve?
Whatever the project you’re taking on, you always want each and every initiative you take to achieve the goals you’ve set for it. **Goal setting is critical** because it will be key in making decisions throughout the project by asking yourself the right questions and **prioritizing tasks and efforts**.
As basic as it may seem, following the **SMART framework** is always a great idea when setting your goals, to **ensure effectiveness:**
**S \- SPECIFIC**
Your goal is direct, detailed, and meaningful.
**M \- MEASURABLE**
Your goal is quantifiable to track progress or success.
**A \- ATTAINABLE**
Your goal is realistic and you have the tools and/or resources to attain it.
**R \- RELEVANT**
Your goal aligns with your company mission.
**T \- TIME-BASED**
Your goal has a deadline.
### 2\) Scope Definition
This is easier said than done when starting out, so it is best to approach it with caution : Everyone has once been guilty of saying a project “will be done by next week” before realizing they dramatically **underestimated** how hard it would be.
Nevertheless, **setting** a timeline will help a lot with **accountability**, both internal and external, and will help **break down the project in distinct stages**.
You don’t have to reinvent anything from scratch, as a lot of tools such as Airtable’s timeline view will help you put the timeline together.
![](images/img_5.png)
Source: [Airtable](https://blog.airtable.com/introducing-airtables-new-timeline-view/)
### 3\) Sitemap and Wireframe Creation
The site map forms the foundation of a well-designed website. It gives web designers a clear idea of the **information architecture** of the website and explains the **relationships** between various **pages and content elements**.
![](images/img_6.png)
Building a web site without a site map is like building a house without a plan. And it rarely ends well.
Time to start building the first iteration of your project\! To put it shortly, **wireframes** serve as a blueprint, a visual guide representing the skeletal framework of a website or application. It will be a raw version of your project, a great way to get your **initial idea down** in its first “physical” form.
![](images/img_7.png)
Source: [Afolayan Daniel](https://medium.com/fbdevclagos/4-reasons-why-wire-frame-is-important-during-website-or-mobile-app-development-46fabdf47190)
While it won’t be functional yet, it’ll be a major web design step to share with your team, potential leads or even investors, and will highlight issues that you might not have thought about previously. Wireframes are a great opportunity to move fast, once they’re ready, you’ll be able to:
* Gather early feedback;
* Run UX testing groups;
* Iterate on your timeline if necessary;
* Get concept validation.
There are different ways to create wireframes. You can of course sketch them out on paper to start with, but creating a digital version will eventually be much more practical to share them.
#### Tools for sitemapping and wireframing;
* Pen/pencil and paper.
* Balsamiq.
* Moqups.
* Sketch.
* Axure.
* Webflow.
* Slickplan.
* Writemaps.
* Mindnode.
* Figma.
* Sketch.
### 4\) Content Creation
A website should offer more than just a simple design and attractive graphics. An effective content strategy is essential to capture users’ interest and to make the site stand out in search engines.
![](images/img_8.png)
When it comes to content, search engine optimization is only
half of the battle.
There are two main goals that you need to focus on while creating content.
#### **Goal 1 Content encourages engagement and action:**
First of all, content drives readers to take action and encourages them to perform the actions necessary to achieve a site's goals. This is influenced both by the content itself (writing) and by the way it is presented (typography and structural elements).
Boring, lifeless, and lengthy writing rarely holds visitors' attention for long enough. Short, fluent, and engaging content captures them and makes them click through to other pages. Even if your pages need a lot of content (which they often do), properly "breaking it up" into short paragraphs supported by visuals can help create a light and engaging feel.
#### **Goal 2 Search Engine Optimization**:
Content also increases a site's visibility in the eyes of search engines. The practice of creating and developing content to achieve a good ranking in search results is called search engine optimization or SEO.
Identifying your keywords and key phrases correctly is very important for the success of any website.
### 5\) Visual Elements
![](images/img_9.png)
Style Tile: a free style tile / moodboard template built by Mat Vogels.
It is time to create the **visual style** of the site. This part of the design process is usually shaped by **existing brand elements, color choices**, and **logos** specified by the client. However, it is also the stage of the web design process where a **good web designer can truly shine**.
**Visuals play a more important** **role** in web design than ever before. High quality visuals not only give a website a professional look and feel, but also convey a message, are mobile friendly, and help build trust.
**Visual design is a way of communicating** with the web site users to make the site as **appealing to them** as possible. When done right, it can determine the site’s being one of the major successes amongst competitors. On the other hand, any mistake might put it in risk of becoming just another ordinary web site.
**Tools for visual elements**:
* (Sketch, Illustrator, Photoshop, Figma, vb.)
* Visual Style Guides.
### 6\) Development & Platforms
**Front-End Development**: The parts that users interact with (HTML, CSS, JavaScript).
**Back-End Developmen**t: Database and server-side processes (PHP, Python, Node.js).
**No-Code Platforms**: Publishing on platforms like Webflow, Bubble, Adalo, Glide.
### 7\) Testing
When your site has all the visuals and content, you are ready to test.
Once the **first iteration** of your website/web app is ready, it’s time for some **testing** to make sure it **runs smoothly**.
A website should undergo a detailed testing process before going live.
Items to check during the testing process:
* Mobile Compatibility.
* Functionality across different browsers.
* Functionality of forms and buttons.
Alongside these steps, setting up website uptime monitoring is essential to ensure the site remains functional after launch, providing immediate alerts if any downtime occurs. Ultimately, while testing is an important part of the web design process, it’s not worth losing sleep over. **Done is always better than perfect** and when in doubt, keep this quote in mind.
*“If you are not embarrassed by the first version of your product, you've launched too late.” \- Reid Hoffman, founder of LinkedIn*
### 8\) Website Launch
Now it’s time for everyone’s favorite part of the website design process: When everything has been thoroughly tested and you’re happy with the site, you can start.
Don’t expect this to go perfectly. There may still be some elements that need fixing. Web design is a fluid and ongoing process that requires constant maintenance.
Web design and design in general is about finding the right balance between form and function. You need to use the right fonts, colors, and design motifs. But the way users navigate and experience your site is just as important.
## Conclusion
Previously, when we wanted to turn our designs into reality, the barrier of learning and using a programming language tool stood in our way. This barrier has now been removed thanks to **No-Code tools**. With these tools, even without coding knowledge, there is now a way to bring your designs to life.
## Resources
* Bulut, B. (2025, July 20). *Kod yazmayı bilmeden yazılımcı olmak nasıl mümkün oldu?* Webtekno. [https://www.webtekno.com/kod-bilmeden-yazilimci-olmak-nasil-mumkun-oldu-h159799.html](https://www.webtekno.com/kod-bilmeden-yazilimci-olmak-nasil-mumkun-oldu-h159799.html)
* Ectasarim. (2024, Kasım 10). *Web tasarım ilkeleri nelerdir? Önemli hususlar*. [https://www.ectasarim.com/web-tasarim-ilkeleri/](https://www.ectasarim.com/web-tasarim-ilkeleri/?utm_source=chatgpt.com)
* Meazey, M. (2020, February 12). *The web design process in 7 simple steps*. *Webflow Blog*. [https://webflow.com/blog/the-web-design-process-in-7-simple-steps](https://webflow.com/blog/the-web-design-process-in-7-simple-steps)
* University of California Office of the President. (2016). *How to write SMART goals: A how-to guide.* University of California. [https://www.ucop.edu/local-human-resources/\_files/performance-appraisal/How+to+write+SMART+Goals+v2.pdf](https://www.ucop.edu/local-human-resources/_files/performance-appraisal/How+to+write+SMART+Goals+v2.pdf)

803
docs/en/Community-Articles/2025-09-11-aws-secrets-manager-in-abp-framework/article.md

@ -0,0 +1,803 @@
# Step-by-Step AWS Secrets Manager Integration in ABP Framework Projects
## Introduction
In this article, we are going to discuss how to secure sensitive data in ABP Framework projects using AWS Secrets Manager and explain various aspects and concepts of _secret_ data management. We will explain step-by-step AWS Secrets Manager integration.
## What is the Problem?
Modern applications must store sensitive data such as API keys, database connection strings, OAuth client credentials, and other similar sensitive data. These are at the center of functionality but if stored in the wrong place can be massive security issues.
At build time, the first place that comes to mind is usually **appsettings.json**. This is a configuration file; it is not a secure place to store secret information, especially in production.
### Common Security Risks:
- **Plain text storage**: Plain text storage of passwords
- **Exposure to version control**: Secrets are rendered encrypted in Git repositories
- **No access control**: Anyone who has file access can see the secrets
- **No rotation**: We must change them manually
- **No audit trail**: Who accessed which secret when is not known
## .NET User Secrets Tool vs AWS Secrets Manager
**User Secrets (.NET Secret Manager Tools)** is a dev environment only, local file-based solution that keeps sensitive information out of the repository.
**AWS Secrets Manager** is production. It's a centralized, encrypted, and audited secret management service.
| Feature | User Secrets (Dev) | AWS Secrets Manager (Prod) |
| ---------------------- | ---------------------------- | ------------------------------ |
| Scope | Local developer machine | All environments (dev/stage/prod) |
| Storage | JSON in user profile | Managed service (centralized) |
| Encryption | None (plain text file) | Encrypted with KMS |
| Access Control | OS file permissions | IAM policies |
| Rotation | None | Yes (automatic) |
| Audit / Traceability | None | Yes (CloudTrail) |
| Typical Usage | Quick dev outside repo | Production secret management |
---
## AWS Secrets Manager
Especially designed to securely store and handle sensitive and confidential data for our applications. It even supports features such as secret rotation, replication, and many more.
AWS Secrets Manager offers a trial of 30 days. After that, there is a $0.40 USD/month charge per stored secret. There is also a $0.05 USD fee per 10,000 API requests.
### Key Features:
- **Automatic encryption**: KMS automatic encryption
- **Automatic rotation**: Scheduled secret rotation
- **Fine-grained access control**: IAM fine-grained access control
- **Audit logging**: Full audit logging with CloudTrail
- **Cross-region replication**: Cross-region replication
- **API integration**: Programmatic access support
---
## Step 1: AWS Secrets Manager Setup
### 1.1 Creating a Secret in AWS Console
First, search for the Secrets Manager service in the AWS Management Console.
1. **AWS Console****Secrets Manager** → **Store a new secret**
2. Select **Secret type**:
- **Other type of secret** (For custom key-value pairs)
- **Credentials for RDS database** (For databases)
- **Credentials for DocumentDB database**
- **Credentials for Redshift cluster**
3. Enter **Secret value**:
```json
{
"ConnectionString": "Server=myserver;Database=mydb;User Id=myuser;Password=mypassword;"
}
```
4. Set **Secret name**: `prod/ABPAWSTest/ConnectionString`
5. Add **Description**: "ABP Framework connection string for production"
6. Choose **Encryption key** (default KMS key is sufficient)
7. Configure **Automatic rotation** settings (optional)
### 1.2 IAM Permissions
Create an IAM policy for secret access:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "arn:aws:secretsmanager:eu-north-1:588118819172:secret:prod/ABPAWSTest/ConnectionString-*"
}
]
}
```
---
## Step 2: ABP Framework Project Setup
### 2.1 NuGet Packages
Add the required AWS packages to your project:
```bash
dotnet add package AWSSDK.SecretsManager
dotnet add package AWSSDK.Extensions.NETCore.Setup
```
### 2.2 Configuration Files
**appsettings.json** (Development):
```json
{
"AWS": {
"Profile": "default",
"Region": "eu-north-1",
"AccessKey": "YOUR_ACCESS_KEY",
"SecretKey": "YOUR_SECRET_KEY"
},
"SecretsManager": {
"SecretName": "prod/ABPAWSTest/ConnectionString",
"SecretArn": "arn:aws:secretsmanager:eu-north-1:588118819172:secret:prod/ABPAWSTest/ConnectionString-xtYQxv"
}
}
```
**appsettings.Production.json** (Production):
```json
{
"AWS": {
"Region": "eu-north-1"
// Use environment variables or IAM roles in production
},
"SecretsManager": {
"SecretName": "prod/ABPAWSTest/ConnectionString"
}
}
```
### 2.3 Environment Variables (Production)
```bash
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_DEFAULT_REGION=eu-north-1
```
---
## Step 3: AWS Integration Implementation
### 3.1 Program.cs Configuration
```csharp
using Amazon;
using Amazon.SecretsManager;
public class Program
{
public async static Task<int> Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// AWS Secrets Manager configuration
var awsOptions = builder.Configuration.GetAWSOptions();
// Read AWS credentials from appsettings
var accessKey = builder.Configuration["AWS:AccessKey"];
var secretKey = builder.Configuration["AWS:SecretKey"];
var region = builder.Configuration["AWS:Region"];
if (!string.IsNullOrEmpty(accessKey) && !string.IsNullOrEmpty(secretKey))
{
awsOptions.Credentials = new Amazon.Runtime.BasicAWSCredentials(accessKey, secretKey);
}
if (!string.IsNullOrEmpty(region))
{
awsOptions.Region = RegionEndpoint.GetBySystemName(region);
}
builder.Services.AddDefaultAWSOptions(awsOptions);
builder.Services.AddAWSService<IAmazonSecretsManager>();
// ... ABP configuration
await builder.AddApplicationAsync<YourAppModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
}
}
```
### 3.2 Secrets Manager Service
**Interface:**
```csharp
public interface ISecretsManagerService
{
Task<string> GetSecretAsync(string secretName);
Task<T> GetSecretAsync<T>(string secretName) where T : class;
Task<string> GetConnectionStringAsync();
}
```
**Implementation:**
```csharp
using Amazon.SecretsManager;
using Amazon.SecretsManager.Model;
using Volo.Abp.DependencyInjection;
using System.Text.Json;
public class SecretsManagerService : ISecretsManagerService, IScopedDependency
{
private readonly IAmazonSecretsManager _secretsManager;
private readonly IConfiguration _configuration;
private readonly ILogger<SecretsManagerService> _logger;
public SecretsManagerService(
IAmazonSecretsManager secretsManager,
IConfiguration configuration,
ILogger<SecretsManagerService> logger)
{
_secretsManager = secretsManager;
_configuration = configuration;
_logger = logger;
}
public async Task<string> GetSecretAsync(string secretName)
{
try
{
var request = new GetSecretValueRequest
{
SecretId = secretName
};
var response = await _secretsManager.GetSecretValueAsync(request);
_logger.LogInformation("Successfully retrieved secret: {SecretName}", secretName);
return response.SecretString;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to retrieve secret: {SecretName}", secretName);
throw;
}
}
public async Task<T> GetSecretAsync<T>(string secretName) where T : class
{
var secretValue = await GetSecretAsync(secretName);
try
{
return JsonSerializer.Deserialize<T>(secretValue)
?? throw new InvalidOperationException($"Failed to deserialize secret {secretName}");
}
catch (JsonException ex)
{
_logger.LogError(ex, "Failed to deserialize secret {SecretName}", secretName);
throw;
}
}
public async Task<string> GetConnectionStringAsync()
{
var secretName = _configuration["SecretsManager:SecretName"]
?? throw new InvalidOperationException("SecretsManager:SecretName configuration is missing");
return await GetSecretAsync(secretName);
}
}
```
---
## Step 4: Usage Examples
### 4.1 Using in Application Service
```csharp
[RemoteService(false)]
public class DatabaseService : ApplicationService
{
private readonly ISecretsManagerService _secretsManager;
public DatabaseService(ISecretsManagerService secretsManager)
{
_secretsManager = secretsManager;
}
public async Task<string> GetDatabaseConnectionAsync()
{
// Get connection string from AWS Secrets Manager
var connectionString = await _secretsManager.GetConnectionStringAsync();
// Use the connection string
return connectionString;
}
public async Task<ApiConfiguration> GetApiConfigAsync()
{
// Deserialize JSON secret
var config = await _secretsManager.GetSecretAsync<ApiConfiguration>("prod/MyApp/ApiConfig");
return config;
}
}
```
### 4.2 DbContext Configuration
```csharp
public class YourDbContextConfigurer
{
public static void Configure(DbContextOptionsBuilder<YourDbContext> builder, string connectionString)
{
builder.UseSqlServer(connectionString);
}
public static void Configure(DbContextOptionsBuilder<YourDbContext> builder, DbConnection connection)
{
builder.UseSqlServer(connection);
}
}
// Usage in Module
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var secretsManager = context.Services.GetRequiredService<ISecretsManagerService>();
// Get secret at startup and pass to DbContext
var connectionString = await secretsManager.GetConnectionStringAsync();
context.Services.AddAbpDbContext<YourDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
options.DbContextOptions.UseSqlServer(connectionString);
});
}
```
---
## Step 5: Best Practices & Security
### 5.1 Security Best Practices
1. **Environment-based Configuration:**
- Development: appsettings.json
- Production: Environment variables or IAM roles
2. **Principle of Least Privilege:**
```json
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:region:account:secret:specific-secret-*"
}
```
3. **Secret Rotation:**
- Set up automatic rotation
- Custom rotation logic with Lambda functions
4. **Caching Strategy:**
```csharp
public class CachedSecretsManagerService : ISecretsManagerService
{
private readonly IMemoryCache _cache;
private readonly SecretsManagerService _secretsManager;
public async Task<string> GetSecretAsync(string secretName)
{
var cacheKey = $"secret:{secretName}";
if (_cache.TryGetValue(cacheKey, out string cachedValue))
{
return cachedValue;
}
var value = await _secretsManager.GetSecretAsync(secretName);
_cache.Set(cacheKey, value, TimeSpan.FromMinutes(30));
return value;
}
}
```
### 5.2 Error Handling
```csharp
public async Task<string> GetSecretWithRetryAsync(string secretName)
{
const int maxRetries = 3;
var delay = TimeSpan.FromSeconds(1);
for (int i = 0; i < maxRetries; i++)
{
try
{
return await GetSecretAsync(secretName);
}
catch (AmazonSecretsManagerException ex) when (i < maxRetries - 1)
{
_logger.LogWarning(ex, "Retry {Attempt} for secret {SecretName}", i + 1, secretName);
await Task.Delay(delay);
delay = TimeSpan.FromMilliseconds(delay.TotalMilliseconds * 2); // Exponential backoff
}
}
throw new InvalidOperationException($"Failed to retrieve secret {secretName} after {maxRetries} attempts");
}
```
### 5.3 Performance Optimization
```csharp
public class PerformantSecretsManagerService : ISecretsManagerService
{
private readonly IAmazonSecretsManager _secretsManager;
private readonly IMemoryCache _cache;
private readonly ILogger<PerformantSecretsManagerService> _logger;
private readonly SemaphoreSlim _semaphore = new(1, 1);
public async Task<string> GetSecretAsync(string secretName)
{
var cacheKey = $"secret:{secretName}";
// Try to get from cache first
if (_cache.TryGetValue(cacheKey, out string cachedValue))
{
return cachedValue;
}
// Use semaphore to prevent multiple concurrent requests for the same secret
await _semaphore.WaitAsync();
try
{
// Double-check pattern
if (_cache.TryGetValue(cacheKey, out cachedValue))
{
return cachedValue;
}
// Fetch from AWS
var value = await GetSecretFromAwsAsync(secretName);
// Cache for 30 minutes
_cache.Set(cacheKey, value, TimeSpan.FromMinutes(30));
return value;
}
finally
{
_semaphore.Release();
}
}
}
```
---
## Step 6: Testing & Debugging
### 6.1 Unit Testing
```csharp
public class SecretsManagerServiceTests : AbpIntegratedTest<TestModule>
{
private readonly ISecretsManagerService _secretsManager;
public SecretsManagerServiceTests()
{
_secretsManager = GetRequiredService<ISecretsManagerService>();
}
[Fact]
public async Task Should_Get_Connection_String()
{
// Act
var connectionString = await _secretsManager.GetConnectionStringAsync();
// Assert
connectionString.ShouldNotBeNullOrEmpty();
connectionString.ShouldContain("Server=");
}
[Fact]
public async Task Should_Deserialize_Json_Secret()
{
// Arrange
var secretName = "test/json/config";
// Act
var config = await _secretsManager.GetSecretAsync<TestConfig>(secretName);
// Assert
config.ShouldNotBeNull();
config.ApiKey.ShouldNotBeNullOrEmpty();
}
}
```
### 6.2 Mock Implementation for Testing
```csharp
public class MockSecretsManagerService : ISecretsManagerService, ISingletonDependency
{
private readonly Dictionary<string, string> _secrets = new()
{
["prod/ABPAWSTest/ConnectionString"] = "Server=localhost;Database=TestDb;Trusted_Connection=true;",
["prod/MyApp/ApiKey"] = "test-api-key",
["prod/MyApp/Config"] = """{"ApiUrl": "https://api.test.com", "Timeout": 30}"""
};
public Task<string> GetSecretAsync(string secretName)
{
if (_secrets.TryGetValue(secretName, out var secret))
{
return Task.FromResult(secret);
}
throw new ArgumentException($"Unknown secret: {secretName}");
}
public async Task<T> GetSecretAsync<T>(string secretName) where T : class
{
var json = await GetSecretAsync(secretName);
return JsonSerializer.Deserialize<T>(json)
?? throw new InvalidOperationException($"Failed to deserialize {secretName}");
}
public Task<string> GetConnectionStringAsync()
{
return GetSecretAsync("prod/ABPAWSTest/ConnectionString");
}
}
```
### 6.3 Integration Testing
```csharp
public class SecretsManagerIntegrationTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
private readonly HttpClient _client;
public SecretsManagerIntegrationTests(WebApplicationFactory<Program> factory)
{
_factory = factory;
_client = _factory.CreateClient();
}
[Fact]
public async Task Should_Connect_To_Database_With_Secret()
{
// Arrange & Act
var response = await _client.GetAsync("/api/health");
// Assert
response.EnsureSuccessStatusCode();
}
}
```
---
## Step 7: Monitoring & Observability
### 7.1 CloudWatch Metrics
```csharp
public class MonitoredSecretsManagerService : ISecretsManagerService
{
private readonly ISecretsManagerService _inner;
private readonly IMetrics _metrics;
private readonly ILogger<MonitoredSecretsManagerService> _logger;
public async Task<string> GetSecretAsync(string secretName)
{
using var activity = Activity.StartActivity("SecretsManager.GetSecret");
activity?.SetTag("secret.name", secretName);
var stopwatch = Stopwatch.StartNew();
try
{
var result = await _inner.GetSecretAsync(secretName);
_metrics.Counter("secrets_manager.requests")
.WithTag("secret_name", secretName)
.WithTag("status", "success")
.Increment();
_metrics.Timer("secrets_manager.duration")
.WithTag("secret_name", secretName)
.Record(stopwatch.ElapsedMilliseconds);
return result;
}
catch (Exception ex)
{
_metrics.Counter("secrets_manager.requests")
.WithTag("secret_name", secretName)
.WithTag("status", "error")
.WithTag("error_type", ex.GetType().Name)
.Increment();
_logger.LogError(ex, "Failed to retrieve secret {SecretName}", secretName);
throw;
}
}
}
```
### 7.2 Health Checks
```csharp
public class SecretsManagerHealthCheck : IHealthCheck
{
private readonly IAmazonSecretsManager _secretsManager;
private readonly ILogger<SecretsManagerHealthCheck> _logger;
public SecretsManagerHealthCheck(
IAmazonSecretsManager secretsManager,
ILogger<SecretsManagerHealthCheck> logger)
{
_secretsManager = secretsManager;
_logger = logger;
}
public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
try
{
// Try to list secrets to verify connection
var request = new ListSecretsRequest { MaxResults = 1 };
await _secretsManager.ListSecretsAsync(request, cancellationToken);
return HealthCheckResult.Healthy("AWS Secrets Manager is accessible");
}
catch (Exception ex)
{
_logger.LogError(ex, "AWS Secrets Manager health check failed");
return HealthCheckResult.Unhealthy("AWS Secrets Manager is not accessible", ex);
}
}
}
// Register in Program.cs
builder.Services.AddHealthChecks()
.AddCheck<SecretsManagerHealthCheck>("secrets-manager");
```
---
## Step 8: Advanced Scenarios
### 8.1 Dynamic Configuration Reload
```csharp
public class DynamicSecretsConfigurationProvider : ConfigurationProvider, IDisposable
{
private readonly ISecretsManagerService _secretsManager;
private readonly Timer _reloadTimer;
private readonly string _secretName;
public DynamicSecretsConfigurationProvider(
ISecretsManagerService secretsManager,
string secretName)
{
_secretsManager = secretsManager;
_secretName = secretName;
// Reload every 5 minutes
_reloadTimer = new Timer(ReloadSecrets, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));
}
private async void ReloadSecrets(object state)
{
try
{
var secretValue = await _secretsManager.GetSecretAsync(_secretName);
var config = JsonSerializer.Deserialize<Dictionary<string, string>>(secretValue);
Data.Clear();
foreach (var kvp in config)
{
Data[kvp.Key] = kvp.Value;
}
OnReload();
}
catch (Exception ex)
{
// Log error but don't throw to avoid crashing the timer
Console.WriteLine($"Failed to reload secrets: {ex.Message}");
}
}
public void Dispose()
{
_reloadTimer?.Dispose();
}
}
```
### 8.2 Multi-Region Failover
```csharp
public class MultiRegionSecretsManagerService : ISecretsManagerService
{
private readonly List<IAmazonSecretsManager> _clients;
private readonly ILogger<MultiRegionSecretsManagerService> _logger;
public MultiRegionSecretsManagerService(
IConfiguration configuration,
ILogger<MultiRegionSecretsManagerService> logger)
{
_logger = logger;
_clients = new List<IAmazonSecretsManager>();
// Create clients for multiple regions
var regions = new[] { "us-east-1", "us-west-2", "eu-west-1" };
foreach (var region in regions)
{
var config = new AmazonSecretsManagerConfig
{
RegionEndpoint = RegionEndpoint.GetBySystemName(region)
};
_clients.Add(new AmazonSecretsManagerClient(config));
}
}
public async Task<string> GetSecretAsync(string secretName)
{
Exception lastException = null;
foreach (var client in _clients)
{
try
{
var request = new GetSecretValueRequest { SecretId = secretName };
var response = await client.GetSecretValueAsync(request);
_logger.LogInformation("Retrieved secret from region {Region}",
client.Config.RegionEndpoint.SystemName);
return response.SecretString;
}
catch (Exception ex)
{
lastException = ex;
_logger.LogWarning(ex, "Failed to retrieve secret from region {Region}",
client.Config.RegionEndpoint.SystemName);
}
}
throw new InvalidOperationException(
"Failed to retrieve secret from all regions", lastException);
}
}
```
---
## Conclusion
AWS Secrets Manager integration with ABP Framework significantly enhances the security of your applications. With this integration:
**Centralized Secret Management**: All secrets are managed centrally
**Better Security**: Encryption through KMS and access control through IAM
**Audit Trail**: Complete recording of who accessed which secret when
**Automatic Rotation**: Secrets can be rotated automatically
**High Availability**: AWS high availability guarantee
**Easy Integration**: Native integration with ABP Framework
**Cost Effective**: Pay only for what you use
**Scalable**: Scales with your application needs
With this post, you can securely utilize AWS Secrets Manager in your ABP Framework applications and bid farewell to secret management concerns in production.
### Key Benefits:
- **Developer Productivity**: No hardcoded secrets in config files
- **Operational Excellence**: Automation of rotation and monitoring
- **Security Compliance**: Meet enterprise security requirements
- **Peace of Mind**: Professional-grade secret management
---
## Additional Resources
- [AWS Secrets Manager Documentation](https://docs.aws.amazon.com/secretsmanager/)
- [ABP Framework Documentation](https://docs.abp.io/)
- [AWS SDK for .NET](https://docs.aws.amazon.com/sdk-for-net/)
- [AWS Security Best Practices](https://aws.amazon.com/architecture/security-identity-compliance/)
- [Sample Project Repository](https://github.com/fahrigedik/AWSIntegrationABP)

BIN
docs/en/Community-Articles/2025-09-11-aws-secrets-manager-in-abp-framework/cover.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

316
docs/en/Community-Articles/2025-09-12-Demystified-Aggregates-in-DDD-&-.NET/post.md

@ -0,0 +1,316 @@
# Demystified Aggregates in DDD & .NET: From Theory to Practice
## Introduction
Domain-Driven Design (DDD) is one of the key foundations of modern software architecture and has taken a strong place in the .NET world. At the center of DDD are Aggregates, which protect the consistency of business rules. While they are one of DDD’s biggest strengths, they’re also one of the most commonly misunderstood ideas. Trying to follow “pure” DDD rules to the letter often clashes with the complexity and performance needs of real-world projects, leaving developers in tough situations. The goal of this article is to take a fresh, practical look at Aggregates and show how they can be applied in a way that works in real life.
----------
### **Chapter 1: Laying the Groundwork: What Is a Classic Aggregate?**
Before jumping into pragmatic shortcuts, let’s make sure we’re all on the same page. To do that, we’ll start with the classic “by the book” definition of an Aggregate and the rules that make it tick.
#### **What Exactly Is an Aggregate?**
At its simplest, an **Aggregate** is a group of related objects (Entities and Value Objects) that are treated as **one unit of change**. And this group has a leader: the **Aggregate Root**.
- **Aggregate Root** → Think of it as the gatekeeper. All outside commands (like “add a product to the order”) must go through the root. You can’t just poke around and change stuff inside.
- **Entity** → Objects within the Aggregate that have their own identity (ID). Example: an `OrderLine` inside an `Order`.
- **Value Object** → Objects without an identity. They’re defined entirely by their values, like an `Address` or `Money`.
The Aggregate’s main purpose isn’t just grouping things together—it’s about **protecting business rules (invariants).** For example: _“an order’s total amount can never be negative.”_ The Aggregate Root makes sure rules like this are never broken.
#### **The Role of Aggregates: Transaction Boundaries**
The most important job of an Aggregate is defining the **transactional consistency boundary**. In other words:
👉 Any change you make inside an Aggregate either **fully succeeds** or **fully fails**. There’s no half-done state.
From a database perspective, when you call `SaveChanges()` or `Commit()`, everything within one Aggregate gets saved in a single transaction. If you add a product and update the total price, those two actions are atomic—they succeed together. Thanks to Aggregates, you’ll never end up in weird states like _“product was added but total wasn’t updated.”_
#### **The Golden Rules of Aggregates**
Classic DDD lays out three golden rules for working with Aggregates:
1. **Talk Only to the Root**
You can’t directly update something like an `OrderLine`. You must go through the root: `Order.AddOrderLine(...)` or `Order.RemoveOrderLine(...)`. That way, the root always enforces the rules.
2. **Reference Other Aggregates by ID Only**
An `Order` shouldn’t hold a `Customer` object directly. Instead, it should just store `CustomerId`. This keeps Aggregates independent and avoids loading massive object graphs.
3. **Change Only One Aggregate per Transaction**
Need to create an order _and_ update loyalty points? Classic DDD says: do it in two steps. First, save the `Order`. Then publish a **domain event** to update the `Customer`. This enables scalability but introduces **eventual consistency**.
#### **A Classic Example: The Order Aggregate in .NET**
Here’s a simple example showing an `Order` Aggregate that enforces a business rule:
```csharp
// Aggregate Root: The entry point and rule enforcer
public class Order
{
public Guid Id { get; private set; }
public Guid CustomerId { get; private set; }
private readonly List<OrderLine> _orderLines = new();
public IReadOnlyCollection<OrderLine> OrderLines => _orderLines.AsReadOnly();
public decimal TotalPrice { get; private set; }
public Order(Guid id, Guid customerId)
{
Id = id;
CustomerId = customerId;
}
public void AddOrderLine(Guid productId, int quantity, decimal price)
{
// Rule 1: Max 10 order lines
if (_orderLines.Count >= 10)
throw new InvalidOperationException("An order can contain at most 10 products.");
// Rule 2: No duplicate products
var existingLine = _orderLines.FirstOrDefault(ol => ol.ProductId == productId);
if (existingLine != null)
throw new InvalidOperationException("This product is already in the order.");
var orderLine = new OrderLine(productId, quantity, price);
_orderLines.Add(orderLine);
RecalculateTotalPrice();
}
private void RecalculateTotalPrice()
{
TotalPrice = _orderLines.Sum(ol => ol.TotalPrice);
}
}
public class OrderLine
{
public Guid Id { get; private set; }
public Guid ProductId { get; private set; }
public int Quantity { get; private set; }
public decimal UnitPrice { get; private set; }
public decimal TotalPrice => Quantity * UnitPrice;
public OrderLine(Guid productId, int quantity, decimal unitPrice)
{
Id = Guid.NewGuid();
ProductId = productId;
Quantity = quantity;
UnitPrice = unitPrice;
}
}
```
Here, the `Order` enforces the rule _“an order can have at most 10 items”_ inside its `AddOrderLine` method. Nobody outside the class can bypass this, because `_orderLines` is private.
👉 That’s the real strength of a classic Aggregate: **business rules are always protected at the boundary.**
----------
### **Chapter 2: Theory in Books vs. Reality in Code — Why Classic Aggregates Struggle**
In Chapter 1, we painted the “ideal” world of DDD. Aggregates were like fortresses guarding our business rules…
But what happens when we try to build that fortress in a real project with tools like Entity Framework Core? That’s when the gap between theory and practice starts to show up.
#### **1. That `.Include()` Chain — Do We Really Need It? The Performance Trap**
DDD books tell us: _“To validate a business rule, you must load the entire aggregate into memory.”_
Sounds reasonable if consistency is the goal.
But let’s picture a scenario: we have an `Order` aggregate with **500 order lines** inside it. And all we want to do is change its status to `Confirmed`.
```csharp
// Just to update a single field...
var order = await _context.Orders
.Include(o => o.OrderLines) // <-- 500 rows pulled in!
.SingleOrDefaultAsync(o => o.Id == orderId);
order.Confirm(); // Just sets order.Status = "Confirmed";
await _context.SaveChangesAsync();
```
This query pulls **all 500 order lines into memory** just so we can flip a single `Status` field. Even in small projects, this is a silent performance killer. As the system grows, it will drag your app down.
#### **2. The Abandoned Fortress — Sliding into Anemic Domain Models**
Now, what’s a developer’s natural reaction to this? Something like:
_“Pulling this much data is expensive. Maybe I should strip down the aggregate into a plain POCO with properties only, and move the logic into an `OrderService` class.”_
This is how we slip straight into the **Anemic Domain Model** trap. Our classes lose their behavior, becoming nothing more than data bags.
The whole DDD principle of _“keep behavior close to data”_ evaporates. Business logic leaks out of the aggregate and spreads across services. We think we’re doing DDD, but in reality, we’ve fallen back into classic transaction-script style coding.
#### **3. One Model Doesn’t Fit All — The Clash of Command and Query**
Aggregates are designed for **commands** — write operations where business rules must be enforced.
But what about **queries**? Imagine a dashboard where we just want to list the last 10 orders. All we need is `OrderId`, `CustomerName`, and `TotalAmount`.
Loading 10 fully-hydrated `Order` aggregates (with all their order lines) just for that list? That’s like using a cannon to hunt a sparrow. Wasteful, slow, and clumsy.
Aggregates simply aren’t built for reporting or read-heavy scenarios.
And there you have it — the three usual suspects that make developers doubt DDD in real life:
- Performance headaches
- The risk of falling into an Anemic Model
- Aggregates being too heavy for read operations
So, should we give up on DDD? Absolutely not!
The key is to stop following the rules blindly and instead focus on their **real intent**. In the next chapter, we’ll explore the pragmatic approach — **Demystified Aggregates** — and how they can actually help us solve these problems.
----------
### **Chapter 3: Enter the Solution — What Exactly Is a "Demystified Aggregate"?**
The issues we listed in the last chapter don’t mean DDD is bad. They just show that blindly applying textbook rules without considering the realities of your project creates friction.
A **Demystified Aggregate** isn’t a library or a framework. It’s a **way of thinking**. Its philosophy is simple: focus on the Aggregate’s real job, and make sure it does that job **as efficiently as possible.**
#### **1. Philosophy: Focus on Purpose, Not Rules**
What’s the Aggregate’s most sacred duty?
**To protect business rules (invariants) during a data change (command).**
Here’s the key: an Aggregate’s job isn’t to always hold all data in memory. Its job is to **ensure consistency while performing an operation**.
Think of it like a security guard at a bank vault. Their job is to make sure transfers are done correctly. They don’t need to memorize the serial number of every single banknote. They just need the critical info for the current operation: the balance and the transfer amount.
The Demystified Aggregate says the same thing: when running a method, you **only load the data that method actually needs**, not the entire Aggregate.
#### **2. The Core Idea: What “State” Does a Behavior Actually Need?**
To apply this idea in code, ask yourself:
_“What data does the `Confirm()` method on my `Order` Aggregate actually need?”_
- Maybe just the order’s current `Status`. (`"Pending"` can become `"Confirmed"`, `"Cancelled"` throws an error.)
- What about `AddItem(product, quantity)`?
- It needs the `Status` (can’t add items to a cancelled order).
- And maybe the existing `OrderLines` (to increase quantity if the item already exists).
See the pattern? Each behavior needs different data. So why load everything every single time?
#### **3. How Do We Do This in .NET & EF Core? Practical Solutions**
Putting this philosophy into code is easier than you might think.
**The Approach: Purpose-Built Repository Methods**
Instead of a generic `GetByIdAsync()`, create methods tailored to the operation at hand. Let’s revisit our classic **Order Confirmation** scenario in a “Before & After” style.
**BEFORE (Classic & Inefficient Approach)**
```csharp
// Repository Layer
public async Task<Order> GetByIdAsync(Guid id)
{
// LOAD EVERYTHING!
return await _context.Orders
.Include(o => o.OrderLines)
.SingleOrDefaultAsync(o => o.Id == id);
}
// Application Service Layer
public async Task ConfirmOrderAsync(Guid orderId)
{
var order = await _orderRepository.GetByIdAsync(orderId);
order.Confirm(); // This method might not even care about OrderLines!
await _unitOfWork.SaveChangesAsync();
}
```
**AFTER (Demystified & Focused Approach)**
```csharp
// Repository Layer
public async Task<Order> GetForConfirmationAsync(Guid id)
{
// LOAD ONLY WHAT WE NEED! (No OrderLines needed)
return await _context.Orders
.SingleOrDefaultAsync(o => o.Id == id);
}
// Application Service Layer
public async Task ConfirmOrderAsync(Guid orderId)
{
// Intent is crystal clear in the code!
var order = await _orderRepository.GetForConfirmationAsync(orderId);
// Aggregate still protects the business rule.
// Confirm() checks status, etc.
order.Confirm();
await _unitOfWork.SaveChangesAsync();
}
```
**What Do We Gain?**
1. **Awesome Performance:** We avoid unnecessary JOINs and data transfer.
2. **Clear Intent:** Anyone reading `GetForConfirmationAsync` immediately knows this operation only cares about the order itself, not its items. Code documents itself.
3. **No Compromise:** Our Aggregate still enforces the business rules via `Confirm()`. DDD’s spirit remains intact.
For **read/query operations**, the answer is even simpler: skip Aggregates altogether! Use optimized queries that return DTOs via `Select` projections, or even raw SQL with Dapper.
That’s the essence of a Demystified Aggregate: **using the right tool for the right job.**
In the next chapter, we’ll wrap everything up and tie all the concepts together.
----------
### **Conclusion: Pragmatism Beats Dogmatism in DDD**
We’ve reached the finish line. We started with the “pure” textbook definition of Aggregates in the ideal world of Domain-Driven Design. Then we hit the real-world walls of performance and complexity. Finally, we learned how to break through those walls.
The biggest lesson from the **Demystified Aggregates** approach is simple:
**DDD isn’t a rigid rulebook — it’s a way of thinking.**
Our goal isn’t to implement the “most pure DDD ever written in a book.” It’s to make our domain logic clean, solid, understandable, and performant. In this journey, patterns and rules should serve us, not the other way around.
### **Key Takeaways**
1. **Focus on the Core Purpose:**
The primary reason an Aggregate exists is to enforce business rules (invariants) and ensure consistency while handling a command. Every design decision should revolve around this purpose.
2. **Load Only What You Need:**
You don’t have to load the entire Aggregate to execute a behavior. Use purpose-built repository methods (`GetForX()`) to fetch just the data needed for the operation. This can drastically improve both performance and readability.
3. **Separate Writing from Reading:**
Use rich, protected Aggregates for commands (write operations). For queries (read operations), don’t burden your Aggregates. Instead, rely on projections, DTOs, or optimized queries. This is one of the simplest, most practical ways to embrace CQRS principles.
Don’t be afraid to shape your Aggregates based on your project and the realities of your tools (like Entity Framework Core). The power of DDD lies in its **flexibility and pragmatism**.

4
docs/en/docs-nav.json

@ -745,6 +745,10 @@
"text": "Image Manipulation",
"path": "framework/infrastructure/image-manipulation.md"
},
{
"text": "Interceptors",
"path": "framework/infrastructure/interceptors.md"
},
{
"text": "JSON",
"path": "framework/infrastructure/json.md"

7
docs/en/dynamic-proxying-interceptors.md

@ -1,7 +0,0 @@
# Dynamic Proxying / Interceptors
This document is planned to be written later.
## See Also
* [Video tutorial](https://abp.io/video-courses/essentials/interception)

13
docs/en/framework/api-development/standard-apis/configuration.md

@ -55,7 +55,16 @@ namespace Acme.BookStore.Web
}
```
Add your contributor instance to the `AbpApplicationConfigurationOptions`
```csharp
Configure<AbpApplicationConfigurationOptions>(options =>
{
options.Contributors.AddIfNotContains(new MyApplicationConfigurationContributor());
});
```
* `IApplicationConfigurationContributor` defines the `ContributeAsync` method to extend the **application-configuration** endpoint with the specified additional data.
* You can inject services and perform any logic needed to extend the endpoint as you wish.
* You can get services from `context.ServiceProvider` and perform any logic needed to extend the endpoint as you wish.
> Application configuration contributors are automatically discovered by the ABP and executed as a part of the application configuration initialization process.
> Application configuration contributors are executed as a part of the application configuration initialization process.

45
docs/en/framework/data/entity-framework-core/oracle-official.md

@ -59,6 +59,51 @@ Run the `.DbMigrator` project to create the database, apply the changes and seed
Oracle limits strings to `NVARCHAR2(2000)` when the migration is created. Some of the entity properties may extend it. You can check the known and reported properties of ABP modules entities that can extend this limit. To prevent this problem, you need to convert the `string` type to `long` type first and generate a new migration. Then convert the `long` type to `clob` type with maximum length.
## ORA-00904: "FALSE": invalid identifier
In the 23ai release, Oracle has added new `OracleSQLCompatibility` enumeration values:
- `OracleSQLCompatibility.DatabaseVersion19`
- `OracleSQLCompatibility.DatabaseVersion21`
- `OracleSQLCompatibility.DatabaseVersion23`
By default, the enumeration value will match the ODP.NET version number. In the case of ODP.NET 23, the enumeration is `OracleSQLCompatibility.DatabaseVersion23`.
In DB 23ai, BOOLEAN columns and native JSON columns are supported. Thus, Oracle EF Core 8.23.40 use these in its SQL when `OracleSQLCompatibility.DatabaseVersion23` or no value is set. If you'd like to revert to 19c compatible behavior, use the `OracleSQLCompatibility.DatabaseVersion19` value.
See the following issue for more details:
https://github.com/oracle/dotnet-db-samples/issues/377#issuecomment-2096419703
If you want to change the `OracleSQLCompatibility` value, you need to change it at `AbpDbContextOptions` and `MyProjectNameDbContextFactory` files.
```csharp
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDbContextOptions>(options =>
{
options.UseOracle(x => x.UseOracleSQLCompatibility(OracleSQLCompatibility.DatabaseVersion19));
});
}
```
```csharp
public MyProjectNameDbContext CreateDbContext(string[] args)
{
var configuration = BuildConfiguration();
AbpSolution4EfCoreEntityExtensionMappings.Configure();
var builder = new DbContextOptionsBuilder<MyProjectNameDbContext>()
.UseOracle(configuration.GetConnectionString("Default"), x =>
{
x.UseOracleSQLCompatibility(OracleSQLCompatibility.DatabaseVersion19);
});
return new MyProjectNameDbContext(builder.Options);
}
```
### First Migration
Update you application DbContext `OnModelCreating` method:

28
docs/en/framework/fundamentals/localization.md

@ -91,6 +91,34 @@ A JSON localization file content is shown below:
> ABP will ignore (skip) the JSON file if the `culture` section is missing.
You can also use nesting or array in localization files, like this:
````json
{
"culture": "en",
"texts": {
"HelloWorld": "Hello World!",
"Hello": {
"World": "Hello World!"
},
"Hi":[
"Bye": "Bye World!"
"Hello": "Hello World!"
]
}
}
````
Then you can use it like this:
> The double underscore (`__`) is used to separate the parent key from the child key.
````csharp
var str = L["Hello__World"]; // Hello World!
var str2 = L["Hi__0"]; // Bye World!
var str3 = L["Hi__1"]; // Hello World!
````
### Default Resource
`AbpLocalizationOptions.DefaultResourceType` can be set to a resource type, so it is used when the localization resource was not specified:

10
docs/en/framework/infrastructure/blob-storing/google.md

@ -27,11 +27,11 @@ Configure<AbpBlobStoringOptions>(options =>
{
container.UseGoogle(google =>
{
google.ClientEmail = "your coogle client email";
google.ProjectId = "your coogle project id";
google.PrivateKey = "your coogle private key";
google.Scopes = "your coogle scopes";
google.ContainerName = "your coogle container name";
google.ClientEmail = "your google client email";
google.ProjectId = "your google project id";
google.PrivateKey = "your google private key";
google.Scopes = "your google scopes";
google.ContainerName = "your google container name";
google.CreateContainerIfNotExists = true;
//google.UseApplicationDefaultCredentials = true; // If you want to use application default credentials
});

5
docs/en/framework/infrastructure/event-bus/distributed/index.md

@ -643,6 +643,11 @@ Configure<AbpEventBusBoxesOptions>(options =>
* `InboxWaitingEventMaxCount`: The maximum number of events to query at once from the inbox in the database. Default value is 1000.
* `OutboxWaitingEventMaxCount`: The maximum number of events to query at once from the outbox in the database. Default value is 1000.
* `DistributedLockWaitDuration`: ABP uses [distributed locking](../../distributed-locking.md) to prevent concurrent access to the inbox and outbox messages in the database, when running multiple instance of the same application. If an instance of the application can not obtain the lock, it tries after a duration. This is the configuration of that duration. Default value is 15 seconds (`TimeSpan.FromSeconds(15)`).
* `InboxProcessorFailurePolicy`: The policy to handle the failure of the inbox processor. Default value is `Retry`. Possible values are:
* `Retry`: The current exception and subsequent events will continue to be processed in order in the next cycle.
* `RetryLater`: Skip the event that caused the exception and continue with the following events. The failed event will be retried after a delay that doubles with each retry, starting from the configured `InboxProcessorRetryBackoffFactor` (e.g., 10, 20, 40, 80 seconds). The default maximum retry count is 10 (configurable). Discard the event if it still fails after reaching the maximum retry count.
* `Discard`: The event that caused the exception will be discarded and will not be retried.
* `InboxProcessorRetryBackoffFactor`: The initial retry delay factor (double) used when `InboxProcessorFailurePolicy` is `RetryLater`. The retry delay is calculated as: `delay = InboxProcessorRetryBackoffFactor × 2^retryCount`. Default value is `10`.
### Skipping Outbox

213
docs/en/framework/infrastructure/interceptors.md

@ -0,0 +1,213 @@
# Interceptors
ABP provides a powerful interception system that allows you to execute custom logic before and after method calls without modifying the original method code. This is achieved through **dynamic proxying** and is extensively used throughout the ABP framework to implement cross-cutting concerns. ABP's interception is implemented on top of the [Castle DynamicProxy](https://www.castleproject.org/projects/dynamicproxy/) library.
## What is Dynamic Proxying / Interception?
**Interception** is a technique that allows executing additional logic before or after a method call without directly modifying the method's code. This is achieved through **dynamic proxying**, where the runtime generates proxy classes that wrap the original class.
When a method is called on a proxied object:
1. The call is intercepted by the proxy
2. Custom behaviors (like logging, validation, or authorization) can be executed
3. The original method is called
4. Additional logic can be executed after the method completes
This enables **cross-cutting concerns** (logic that applies across many parts of an application) to be handled in a clean, reusable way without code duplication.
## Similarities and Differences with MVC Action/Page Filters
If you are familiar with ASP.NET Core MVC, you've likely used **action filters** or **page filters**. Interceptors are conceptually similar but have some key differences:
### Similarities
* Both allow executing code before and after method execution
* Both are used to implement cross-cutting concerns like validation, logging, caching, or exception handling
* Both support asynchronous operations
### Differences
* **Scope**: Filters are tied to MVC's request pipeline, while interceptors can be applied to **any class or service** in the application
* **Configuration**: Filters are configured via attributes or middleware in MVC, while interceptors in ABP are applied through **dependency injection and dynamic proxies**
* **Target**: Interceptors can target application services, domain services, repositories, and virtually any service resolved from the IoC container—not just web controllers
## How ABP Uses Interceptors
ABP Framework extensively leverages interception to provide built-in features without requiring boilerplate code. Here are some key examples:
### [Unit of Work (UOW)](../architecture/domain-driven-design/unit-of-work.md)
Automatically begins and commits/rolls back a database transaction when entering or exiting an application service method. This ensures data consistency without manual transaction management.
### [Input Validation](../fundamentals/validation.md)
Input DTOs are automatically validated against data annotation attributes and custom validation rules before executing the service logic, providing consistent validation behavior across all services.
### [Authorization](../fundamentals/authorization.md)
Checks user permissions before allowing the execution of application service methods, ensuring security policies are enforced consistently.
### [Feature](./features.md) & [Global Feature](./global-features.md) Checking
Checks if a feature is enabled before executing the service logic, allowing you to conditionally enable or restrict functionality for tenants or the application.
### [Auditing](./audit-logging.md)
Automatically logs who performed an action, when it happened, what parameters were used, and what data was involved, providing comprehensive audit trails.
## Building Your Own Interceptor
You can create custom interceptors in ABP to implement your own cross-cutting concerns.
### Creating an Interceptor
Create a class that inherits from `AbpInterceptor`:
````csharp
using System.Threading.Tasks;
using Volo.Abp.Aspects;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
public class ExecutionTimeLogInterceptor : AbpInterceptor, ITransientDependency
{
private readonly ILogger<ExecutionTimeLogInterceptor> _logger;
public ExecutionTimeLogInterceptor(ILogger<ExecutionTimeLogInterceptor> logger)
{
_logger = logger;
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
var sw = Stopwatch.StartNew();
_logger.LogInformation($"Executing {invocation.TargetObject.GetType().Name}.{invocation.Method.Name}");
// Proceed to the actual target method
await invocation.ProceedAsync();
sw.Stop();
_logger.LogInformation($"Executed {invocation.TargetObject.GetType().Name}.{invocation.Method.Name} in {sw.ElapsedMilliseconds} ms");
}
}
````
### Register Interceptors
Create a static class that contains the `RegisterIfNeeded` method and register the interceptor in the `PreConfigureServices` method of your module.
The `ShouldIntercept` method is used to determine if the interceptor should be registered for the given type. You can add an `IExecutionTimeLogEnabled` interface and implement it in the classes that you want to intercept.
> `DynamicProxyIgnoreTypes` is static class that contains the types that should be ignored by the interceptor. See [Performance Considerations](#performance-considerations) for more information.
````csharp
// Define an interface to mark the classes that should be intercepted
public interface IExecutionTimeLogEnabled
{
}
````
````csharp
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
// A simple service that added to the DI container and will be intercepted since it implements the `IExecutionTimeLogEnabled` interface
public class SampleExecutionTimeService : IExecutionTimeLogEnabled, ITransientDependency
{
public virtual async Task DoWorkAsync()
{
// Simulate a long-running task to test the interceptor
await Task.Delay(1000);
}
}
````
````csharp
using System;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
public static class ExecutionTimeLogInterceptorRegistrar
{
public static void RegisterIfNeeded(IOnServiceRegistredContext context)
{
if (ShouldIntercept(context.ImplementationType))
{
context.Interceptors.TryAdd<ExecutionTimeLogInterceptor>();
}
}
private static bool ShouldIntercept(Type type)
{
return !DynamicProxyIgnoreTypes.Contains(type) && typeof(IExecutionTimeLogEnabled).IsAssignableFrom(type);
}
}
````
````csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.OnRegistered(ExecutionTimeLogInterceptorRegistrar.RegisterIfNeeded);
}
````
## Restrictions and Important Notes
### Always use asynchronous methods
For best performance and reliability, implement your service methods as asynchronous to avoid **async over sync**, that can cause unexpected problems, For more information, see [Should I expose synchronous wrappers for asynchronous methods?](https://devblogs.microsoft.com/dotnet/should-i-expose-synchronous-wrappers-for-asynchronous-methods/)
### Virtual Methods Requirement
For **class proxies**, methods need to be marked as `virtual` so that they can be overridden by the proxy. Otherwise, interception will not occur.
````csharp
public class MyService : IExecutionTimeLogEnabled, ITransientDependency
{
// This method CANNOT be intercepted (not virtual)
public void CannotBeIntercepted()
{
}
// This method CAN be intercepted (virtual)
public virtual void CanBeIntercepted()
{
}
}
````
> This restriction does **not** apply to interface-based proxies. If your service implements an interface and is injected via that interface, all methods can be intercepted regardless of the `virtual` keyword.
### Dependency Injection Scope
Interceptors only work when services are resolved from the dependency injection container. Direct instantiation with `new` bypasses interception:
````csharp
// This will NOT be intercepted
var service = new MyService();
service.CannotBeIntercepted();
// This WILL be intercepted (if MyService is registered with DI)
var service = serviceProvider.GetService<MyService>();
service.CanBeIntercepted();
````
### Performance Considerations
Interceptors are generally efficient, but each one adds method-call overhead. Keep the number of interceptors minimal on hot paths.
Castle DynamicProxy can negatively impact performance for certain components, notably ASP.NET Core MVC controllers. See the discussions in [castleproject/Core#486](https://github.com/castleproject/Core/issues/486) and [abpframework/abp#3180](https://github.com/abpframework/abp/issues/3180).
ABP uses interceptors for features like UOW, auditing, and authorization, which rely on dynamic proxy classes. For controllers, prefer implementing cross-cutting concerns with middleware or MVC/Page filters instead of dynamic proxies.
To avoid generating dynamic proxies for specific types, use the static class `DynamicProxyIgnoreTypes` and add the base classes of the types to the list. Subclasses of any listed base class are also ignored. ABP framework already adds some base classes to the list (`ComponentBase, ControllerBase, PageModel, ViewComponent`); you can add more base classes if needed.
> Always use interface-based proxies instead of class-based proxies for better performance.
## See Also
* [Video tutorial: Interceptors in ABP Framework](https://abp.io/video-courses/essentials/interception)
* [Castle DynamicProxy](https://www.castleproject.org/projects/dynamicproxy/)
* [Castle.Core.AsyncInterceptor](https://github.com/JSkimming/Castle.Core.AsyncInterceptor)
* [ASP.NET Core Filters](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters)

2
docs/en/framework/infrastructure/object-to-object-mapping.md

@ -337,6 +337,8 @@ var users = await _userRepository.GetListAsync(); // returns List<User>
var dtos = ObjectMapper.Map<List<User>, List<UserDto>>(users); // creates List<UserDto>
````
> When mapping a collection property, if the source value is null Mapperly will keep the destination value as null. This is different from AutoMapper, which will map the destination field to an empty collection.
### Nested Mapping
When working with nested object mapping, there's an important limitation to be aware of. If you have separate mappers for nested types like in the example below, the parent mapper (`SourceTypeToDestinationTypeMapper`) will not automatically use the nested mapper (`SourceNestedTypeToDestinationNestedTypeMapper`) to handle the mapping of nested properties. This means that configurations like the `MapperIgnoreTarget` attribute on the nested mapper will be ignored during the parent mapping operation.

208
docs/en/framework/ui/angular/form-validation.md

@ -170,3 +170,211 @@ export const appConfig: ApplicationConfig = {
The error message will be bold and italic now:
<img alt="A required field is cleared and a bold and italic error message appears." src="./images/form-validation---custom-error-template.gif" width="990px" style="max-width:100%">
## How to Validate Nested Form Groups
There are multiple ways to validate nested form groups in ABP Angular UI. Below is the first and most common approach, using automatic validation and error messages with nested reactive forms. (A second method will be described in the next section.)
### 1st Way: Automatic Validation and Error Message Using Nested Reactive Forms
ABP Angular UI leverages Angular's reactive forms and the [ngx-validate](https://www.npmjs.com/package/@ngx-validate/core) library to provide a robust, flexible, and user-friendly form validation experience. Whether you build your forms manually or use ABP’s dynamic form generation features, validation and error messages are handled automatically.
#### Key Features
- **Automatic Validation:**
All validation rules defined in your DTOs (such as `[Required]`, `[StringLength]`, `[EmailAddress]`, etc.) are automatically reflected in the Angular form. Error messages are shown under each field without any extra markup.
- **Nested Form Groups and Dynamic Fields:**
For complex data structures, you can group fields or manage dynamic lists using nested `FormGroup` and `FormArray` structures. Validation and error display work seamlessly for both parent and child controls.
- **Dynamic and Extensible Forms:**
With ABP’s extensibility system, you can generate forms dynamically using helpers like `generateFormFromProps` and display them with the `abp-extensible-form` component. This ensures all entity properties (including extension properties) are included in the form and their validation rules are applied.
- **No Extra Boilerplate:**
You do not need to add custom error components or directives for validation. The system works out of the box, including for nested and dynamically generated controls.
#### Real-World Example: Nested Form Groups in the Users Form
Below is a real example from the Users management form in ABP Angular UI, showing how nested form structures and validation are implemented. This example includes both dynamically generated fields (with `abp-extensible-form`) and a dynamic list of roles using `FormArray` and `FormGroup`.
**TypeScript: Building the Form**
```ts
buildForm() {
const data = new FormPropData(this.injector, this.selected);
this.form = generateFormFromProps(data); // Automatically creates form controls from entity and extension properties
this.service.getAssignableRoles().subscribe(({ items }) => {
this.roles = items;
if (this.roles) {
// Dynamic roles list: nested FormArray and FormGroup
this.form.addControl(
'roleNames',
this.fb.array(
this.roles.map(role =>
this.fb.group({
[role.name as string]: [
this.selected?.id
? !!this.selectedUserRoles?.find(userRole => userRole.id === role.id)
: role.isDefault,
],
}),
),
),
);
}
});
}
```
**HTML: Displaying the Form**
```html
<abp-modal [(visible)]="isModalVisible" [busy]="modalBusy">
<ng-template #abpHeader>
<h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}</h3>
</ng-template>
<ng-template #abpBody>
@if (form) {
<form [formGroup]="form" (ngSubmit)="save()">
<ul ngbNav #nav="ngbNav" class="nav-tabs">
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>
<ng-template ngbNavContent>
<!-- Automatically displays all entity fields and their validation -->
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
</ng-template>
</li>
<li ngbNavItem>
<a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a>
<ng-template ngbNavContent>
<!-- Dynamic roles list: nested FormArray and FormGroup -->
@for (roleGroup of roleGroups; track $index; let i = $index) {
<div class="form-check mb-2">
<abp-checkbox
[formControl]="roleGroup.controls[roles[i].name]"
[label]="roles[i].name"
></abp-checkbox>
</div>
}
</ng-template>
</li>
</ul>
<div class="mt-2 fade-in-top" [ngbNavOutlet]="nav"></div>
</form>
} @else {
<div class="text-center"><i class="fa fa-pulse fa-spinner" aria-hidden="true"></i></div>
}
</ng-template>
</abp-modal>
```
**Explanation:**
- `abp-extensible-form` automatically generates and displays all entity fields and their validation.
- In the Roles tab, each role is represented by a checkbox, and these checkboxes are managed in a `FormArray`, with each as a `FormGroup`. This is a real-world example of a nested form structure.
- All validation and error messages are shown automatically for both the main form and nested groups.
### 2nd Way: Manual Nested Reactive Forms Without abp-extensible-form
You can also build and validate nested form groups manually, without using `abp-extensible-form` or dynamic helpers. This approach gives you full control over the form structure and is useful for custom or non-entity-based forms.
#### Example: Simple Manual Nested FormGroup
Below is a simple, generic example of a nested reactive form. This form includes a nested `FormGroup` for profile information and demonstrates how to apply validation rules.
**TypeScript: Building the Form**
```ts
import { Component, OnInit, inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NgxValidateCoreModule } from '@ngx-validate/core';
@Component({
selector: 'app-nested-form',
templateUrl: './nested-form.component.html',
standalone: true,
imports: [NgxValidateCoreModule],
})
export class NestedFormComponent implements OnInit {
form: FormGroup;
private fb = inject(FormBuilder);
ngOnInit() {
this.buildForm();
}
buildForm() {
this.form = this.fb.group({
userName: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
profile: this.fb.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
}),
});
}
submit() {
if (this.form.invalid) {
return;
}
// handle submit
}
}
```
**HTML: Displaying the Form**
```html
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="mb-3">
<label class="form-label">User Name</label>
<input type="text" class="form-control" formControlName="userName" />
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" formControlName="email" />
</div>
<div formGroupName="profile" class="card mt-3">
<div class="card-header">
<strong>Profile Details</strong>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">First Name</label>
<input type="text" class="form-control" formControlName="firstName" />
</div>
<div class="mb-3">
<label class="form-label">Last Name</label>
<input type="text" class="form-control" formControlName="lastName" />
</div>
</div>
</div>
<hr class="my-3" />
<div>
<abp-button buttonType="submit" iconClass="fa fa-save" [disabled]="form.invalid">
Save
</abp-button>
</div>
</form>
```
**How it works:**
- The form contains main fields (`userName`, `email`) and a nested `FormGroup` (`profile`).
- The `profile` group includes `firstName` and `lastName` fields, each with their own validation rules.
- Validation rules are defined directly in the form builder.
- Error messages and validation feedback are handled automatically by ngx-validate and ABP Angular UI, just like with dynamic forms.
- This structure ensures that validation works automatically for both the main form and nested groups.
> **Note:** This approach is ideal for custom forms or when you want full control over the form structure. It provides a user experience and validation behavior similar to ABP's dynamic forms, but with manual control over the form layout and logic.
---

5
docs/en/framework/ui/angular/modifying-the-menu.md

@ -269,7 +269,12 @@ this.routes.remove(['Your navigation']);
// or
this.routes.removeByParam({ name: 'Your navigation' });
```
**Method Parameters:**
- `remove(routeNames: string[])`: Takes an array of route names to remove.
- `removeByParam(routeProperty: Partial<ABP.Route>)`: Takes any route property (name, path, parentName, etc.) to match and remove routes.
<br>
**Results of the operations above:**
- Moved the _Home_ navigation under the _Administration_ dropdown based on given `parentName`.
- Added an icon to _Home_.
- Specified the order and made _Home_ the first item in list.

183
docs/en/release-info/migration-guides/AutoMapper-To-Mapperly.md

@ -56,7 +56,7 @@ public class ExampleAutoMapper : Profile
And the Mapperly mapping class:
```csharp
[Mapper]
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[MapExtraProperties]
public partial class IdentityUserToIdentityUserDtoMapper : MapperBase<IdentityUser, IdentityUserDto>
{
@ -71,7 +71,7 @@ public partial class IdentityUserToIdentityUserDtoMapper : MapperBase<IdentityUs
public override partial void Map(IdentityUser source, IdentityUserDto destination);
}
[Mapper]
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class IdentityUserClaimToIdentityUserClaimDtoMapper : MapperBase<IdentityUserClaim, IdentityUserClaimDto>
{
public override partial IdentityUserClaimDto Map(IdentityUserClaim source);
@ -79,7 +79,7 @@ public partial class IdentityUserClaimToIdentityUserClaimDtoMapper : MapperBase<
public override partial void Map(IdentityUserClaim source, IdentityUserClaimDto destination);
}
[Mapper]
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[MapExtraProperties]
public partial class OrganizationUnitToOrganizationUnitDtoMapper : MapperBase<OrganizationUnit, OrganizationUnitDto>
{
@ -87,7 +87,7 @@ public partial class OrganizationUnitToOrganizationUnitDtoMapper : MapperBase<Or
public override partial void Map(OrganizationUnit source, OrganizationUnitDto destination);
}
[Mapper]
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class OrganizationUnitRoleToOrganizationUnitRoleDtoMapper : TwoWayMapperBase<OrganizationUnitRole, OrganizationUnitRoleDto>
{
public override partial OrganizationUnitRoleDto Map(OrganizationUnitRole source);
@ -97,7 +97,7 @@ public partial class OrganizationUnitRoleToOrganizationUnitRoleDtoMapper : TwoWa
public override partial void ReverseMap(OrganizationUnitRoleDto destination, OrganizationUnitRole source);
}
[Mapper]
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[MapExtraProperties]
public partial class OrganizationUnitToOrganizationUnitWithDetailsDtoMapper : MapperBase<OrganizationUnit, OrganizationUnitWithDetailsDto>
{
@ -110,7 +110,7 @@ public partial class OrganizationUnitToOrganizationUnitWithDetailsDtoMapper : Ma
public override partial void Map(OrganizationUnit source, OrganizationUnitWithDetailsDto destination);
}
[Mapper]
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class IdentityRoleToOrganizationUnitRoleDtoMapper : MapperBase<IdentityRole, OrganizationUnitRoleDto>
{
[MapProperty(nameof(IdentityRole.Id), nameof(OrganizationUnitRoleDto.RoleId))]
@ -120,7 +120,7 @@ public partial class IdentityRoleToOrganizationUnitRoleDtoMapper : MapperBase<Id
public override partial void Map(IdentityRole source, OrganizationUnitRoleDto destination);
}
[Mapper]
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class IdentityUserToIdentityUserExportDtoMapper : MapperBase<IdentityUser, IdentityUserExportDto>
{
[MapperIgnoreTarget(nameof(IdentityUserExportDto.Roles))]
@ -143,7 +143,7 @@ public partial class IdentityUserToIdentityUserExportDtoMapper : MapperBase<Iden
To use Mapperly, you'll need to create a dedicated mapping class for each source and destination types.
* Use the `[Mapper]` attribute to designate the class as a Mapperly mapper.
* Use the `[Mapper]` attribute to designate the class as a Mapperly mapper. The `RequiredMappingStrategy` is set to `Target` by default.
* Replace AutoMapper's `Ignore()` method with the `[MapperIgnoreTarget]` attribute.
* Replace the `MapExtraProperties()` method with the `[MapExtraProperties]` attribute.
* Use the `TwoWayMapperBase` class as an alternative to AutoMapper’s `ReverseMap()` functionality.
@ -151,11 +151,12 @@ To use Mapperly, you'll need to create a dedicated mapping class for each source
### Dependency Injection in Mapper Class
All Mapperly mapping classes automatically registered in the the [dependency injection (DI)](../../framework/fundamentals/dependency-injection.md) container. To use a service within a Mapper class, simply add it to the constructor, Mapperly will inject it automatically.
All Mapperly mapping classes automatically registered in the [dependency injection (DI)](../../framework/fundamentals/dependency-injection.md) container. To use a service within a Mapper class, simply add it to the constructor; Mapperly will inject it automatically.
**Example:**
```csharp
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class IdentityUserToIdentityUserDtoMapper : MapperBase<IdentityUser, IdentityUserDto>
{
public IdentityUserToIdentityUserDtoMapper(MyService myService)
@ -173,6 +174,170 @@ public partial class IdentityUserToIdentityUserDtoMapper : MapperBase<IdentityUs
}
```
## AI Prompt for Migrating AutoMapper to Mapperly
If you have AI tools like Cursor, you can use the following prompt to migrate your AutoMapper mappings to Mapperly automatically:
> AI may generate some code that is not correct. Please check the code carefully.
```
Please help me migrate AutoMapper Profile classes to Mapperly. I have AutoMapper Profile files in my current workspace/context that need to be converted.
**Conversion Requirements:**
1. **Convert AutoMapper Profile to Mapperly Mappers**: Transform each `CreateMap` into a separate Mapperly mapper class
2. **Rename the file**: Change from `XXXAutoMapperProfile.cs` to `XXXMappers.cs`
3. **Use proper Mapperly attributes**:
- `[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]` for each mapper class
- `[MapExtraProperties]` for classes that need extra properties mapping
- `[MapperIgnoreTarget]` for ignored properties
- `[MapProperty]` for custom property mappings
4. **Inherit from appropriate base classes**:
- `MapperBase<TSource, TDestination>` for one-way mapping
- `TwoWayMapperBase<TSource, TDestination>` for reverse mapping
5. **Handle complex mappings**: Use `AfterMap` method for complex transformations
**Note:** The code below contains two parts - both are reference examples for you to understand the conversion pattern:
1. **AutoMapper Profile example** - shows the original AutoMapper code structure
2. **Mapperly Mappers example** - shows the expected converted Mapperly code structure
Please convert the actual AutoMapper Profile files that exist in your current context/workspace, following the same conversion pattern as shown in these examples.
**Reference Examples:**
**1. AutoMapper Profile (original code):**
using System;
using AutoMapper;
using System.Linq;
using Volo.Abp.AutoMapper;
namespace Volo.Abp.Identity;
public class ExampleAutoMapperProfile : Profile
{
public ExampleAutoMapperProfile()
{
CreateMap<IdentityUser, IdentityUserDto>()
.MapExtraProperties()
.Ignore(x => x.IsLockedOut)
.Ignore(x => x.SupportTwoFactor)
.Ignore(x => x.RoleNames);
CreateMap<IdentityUserClaim, IdentityUserClaimDto>();
CreateMap<OrganizationUnit, OrganizationUnitDto>()
.MapExtraProperties();
CreateMap<OrganizationUnitRole, OrganizationUnitRoleDto>()
.ReverseMap();
CreateMap<IdentityRole, OrganizationUnitRoleDto>()
.ForMember(dest => dest.RoleId, src => src.MapFrom(r => r.Id));
CreateMap<IdentityUser, IdentityUserExportDto>()
.ForMember(dest => dest.Active, src => src.MapFrom(r => r.IsActive ? "Yes" : "No"))
.ForMember(dest => dest.EmailConfirmed, src => src.MapFrom(r => r.EmailConfirmed ? "Yes" : "No"))
.ForMember(dest => dest.TwoFactorEnabled, src => src.MapFrom(r => r.TwoFactorEnabled ? "Yes" : "No"))
.ForMember(dest => dest.AccountLookout, src => src.MapFrom(r => r.LockoutEnd != null && r.LockoutEnd > DateTime.UtcNow ? "Yes" : "No"))
.Ignore(x => x.Roles);
}
}
---
**2. Mapperly Mappers (converted code):**
using System;
using System.Linq;
using Riok.Mapperly.Abstractions;
using Volo.Abp.Mapperly;
namespace Volo.Abp.Identity;
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[MapExtraProperties]
public partial class IdentityUserToIdentityUserDtoMapper : MapperBase<IdentityUser, IdentityUserDto>
{
[MapperIgnoreTarget(nameof(IdentityUserDto.IsLockedOut))]
[MapperIgnoreTarget(nameof(IdentityUserDto.SupportTwoFactor))]
[MapperIgnoreTarget(nameof(IdentityUserDto.RoleNames))]
public override partial IdentityUserDto Map(IdentityUser source);
[MapperIgnoreTarget(nameof(IdentityUserDto.IsLockedOut))]
[MapperIgnoreTarget(nameof(IdentityUserDto.SupportTwoFactor))]
[MapperIgnoreTarget(nameof(IdentityUserDto.RoleNames))]
public override partial void Map(IdentityUser source, IdentityUserDto destination);
}
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class IdentityUserClaimToIdentityUserClaimDtoMapper : MapperBase<IdentityUserClaim, IdentityUserClaimDto>
{
public override partial IdentityUserClaimDto Map(IdentityUserClaim source);
public override partial void Map(IdentityUserClaim source, IdentityUserClaimDto destination);
}
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[MapExtraProperties]
public partial class OrganizationUnitToOrganizationUnitDtoMapper : MapperBase<OrganizationUnit, OrganizationUnitDto>
{
public override partial OrganizationUnitDto Map(OrganizationUnit source);
public override partial void Map(OrganizationUnit source, OrganizationUnitDto destination);
}
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class OrganizationUnitRoleToOrganizationUnitRoleDtoMapper : TwoWayMapperBase<OrganizationUnitRole, OrganizationUnitRoleDto>
{
public override partial OrganizationUnitRoleDto Map(OrganizationUnitRole source);
public override partial void Map(OrganizationUnitRole source, OrganizationUnitRoleDto destination);
public override partial OrganizationUnitRole ReverseMap(OrganizationUnitRoleDto destination);
public override partial void ReverseMap(OrganizationUnitRoleDto destination, OrganizationUnitRole source);
}
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[MapExtraProperties]
public partial class OrganizationUnitToOrganizationUnitWithDetailsDtoMapper : MapperBase<OrganizationUnit, OrganizationUnitWithDetailsDto>
{
[MapperIgnoreTarget(nameof(OrganizationUnitWithDetailsDto.Roles))]
[MapperIgnoreTarget(nameof(OrganizationUnitWithDetailsDto.UserCount))]
public override partial OrganizationUnitWithDetailsDto Map(OrganizationUnit source);
[MapperIgnoreTarget(nameof(OrganizationUnitWithDetailsDto.Roles))]
[MapperIgnoreTarget(nameof(OrganizationUnitWithDetailsDto.UserCount))]
public override partial void Map(OrganizationUnit source, OrganizationUnitWithDetailsDto destination);
}
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class IdentityRoleToOrganizationUnitRoleDtoMapper : MapperBase<IdentityRole, OrganizationUnitRoleDto>
{
[MapProperty(nameof(IdentityRole.Id), nameof(OrganizationUnitRoleDto.RoleId))]
public override partial OrganizationUnitRoleDto Map(IdentityRole source);
[MapProperty(nameof(IdentityRole.Id), nameof(OrganizationUnitRoleDto.RoleId))]
public override partial void Map(IdentityRole source, OrganizationUnitRoleDto destination);
}
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
public partial class IdentityUserToIdentityUserExportDtoMapper : MapperBase<IdentityUser, IdentityUserExportDto>
{
[MapperIgnoreTarget(nameof(IdentityUserExportDto.Roles))]
public override partial IdentityUserExportDto Map(IdentityUser source);
[MapperIgnoreTarget(nameof(IdentityUserExportDto.Roles))]
public override partial void Map(IdentityUser source, IdentityUserExportDto destination);
public override void AfterMap(IdentityUser source, IdentityUserExportDto destination)
{
destination.Active = source.IsActive ? "Yes" : "No";
destination.EmailConfirmed = source.EmailConfirmed ? "Yes" : "No";
destination.TwoFactorEnabled = source.TwoFactorEnabled ? "Yes" : "No";
destination.AccountLookout = source.LockoutEnd != null && source.LockoutEnd > DateTime.UtcNow ? "Yes" : "No";
}
}
```
## Mapperly Documentation
Please refer to the [Mapperly documentation](https://mapperly.riok.app/docs/intro/) for more details.

9
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs

@ -69,6 +69,7 @@ public class AddModuleCommand : IConsoleCommand, ITransientDependency
var newProTemplate = !string.IsNullOrEmpty(template) && template == ModuleProTemplate.TemplateName;
var withSourceCode = newTemplate || newProTemplate || commandLineArgs.Options.ContainsKey(Options.SourceCode.Long);
var addSourceCodeToSolutionFile = withSourceCode && commandLineArgs.Options.ContainsKey("add-to-solution-file");
var skipOpeningDocumentation = commandLineArgs.Options.ContainsKey(Options.SkipOpeningDocumentation.Long);
var skipDbMigrations = newTemplate || newProTemplate || commandLineArgs.Options.ContainsKey(Options.DbMigrations.Skip);
var solutionFile = GetSolutionFile(commandLineArgs);
@ -98,7 +99,8 @@ public class AddModuleCommand : IConsoleCommand, ITransientDependency
withSourceCode,
addSourceCodeToSolutionFile,
newTemplate,
newProTemplate
newProTemplate,
skipOpeningDocumentation
);
_lastAddedModuleInfo = new AddModuleInfoOutput
@ -223,5 +225,10 @@ public class AddModuleCommand : IConsoleCommand, ITransientDependency
public const string Short = "t";
public const string Long = "template";
}
public class SkipOpeningDocumentation
{
public const string Long = "skip-opening-documentation";
}
}
}

4
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs

@ -14,11 +14,11 @@ namespace Volo.Abp.Cli.ProjectModification;
public class AngularSourceCodeAdder : ITransientDependency
{
public ILogger<SolutionModuleAdder> Logger { get; set; }
public ILogger<AngularSourceCodeAdder> Logger { get; set; }
public AngularSourceCodeAdder()
{
Logger = NullLogger<SolutionModuleAdder>.Instance;
Logger = NullLogger<AngularSourceCodeAdder>.Instance;
}
public async Task AddFromModuleAsync(string solutionFilePath, string angularPath)

12
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs

@ -98,7 +98,8 @@ public class SolutionModuleAdder : ITransientDependency
bool withSourceCode = false,
bool addSourceCodeToSolutionFile = false,
bool newTemplate = false,
bool newProTemplate = false)
bool newProTemplate = false,
bool skipOpeningDocumentation = false)
{
Check.NotNull(solutionFile, nameof(solutionFile));
Check.NotNull(moduleName, nameof(moduleName));
@ -159,10 +160,13 @@ public class SolutionModuleAdder : ITransientDependency
await SetLeptonXAbpVersionsAsync(solutionFile, Path.Combine(modulesFolderInSolution, module.Name));
}
var documentationLink = module.GetFirstDocumentationLinkOrNull();
if (documentationLink != null)
if (!skipOpeningDocumentation)
{
CmdHelper.Open(documentationLink);
var documentationLink = module.GetFirstDocumentationLinkOrNull();
if (documentationLink != null)
{
CmdHelper.Open(documentationLink);
}
}
return module;

14
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs

@ -1,9 +1,9 @@
using JetBrains.Annotations;
using System;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Data;
@ -43,9 +43,9 @@ public abstract class BasicRepositoryBase<TEntity> :
public IEntityChangeTrackingProvider EntityChangeTrackingProvider => LazyServiceProvider.LazyGetRequiredService<IEntityChangeTrackingProvider>();
public bool? IsChangeTrackingEnabled { get; protected set; }
public string? EntityName { get; set; }
public void SetEntityName(string? name)
{
EntityName = name;
@ -148,10 +148,10 @@ public abstract class BasicRepositoryBase<TEntity> :
public abstract class BasicRepositoryBase<TEntity, TKey> : BasicRepositoryBase<TEntity>, IBasicRepository<TEntity, TKey>
where TEntity : class, IEntity<TKey>
{
protected BasicRepositoryBase(string providerName)
protected BasicRepositoryBase(string providerName)
: base(providerName)
{
}
public virtual async Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
@ -160,7 +160,7 @@ public abstract class BasicRepositoryBase<TEntity, TKey> : BasicRepositoryBase<T
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
throw new EntityNotFoundException<TEntity>(id);
}
return entity;

8
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs

@ -1,10 +1,10 @@
using JetBrains.Annotations;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
@ -60,7 +60,7 @@ public abstract class RepositoryBase<TEntity> : BasicRepositoryBase<TEntity>, IR
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity));
throw new EntityNotFoundException<TEntity>();
}
return entity;
@ -101,7 +101,7 @@ public abstract class RepositoryBase<TEntity, TKey> : RepositoryBase<TEntity>, I
: base(providerName)
{
}
public abstract Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);
public abstract Task<TEntity?> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);

6
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs

@ -56,7 +56,7 @@ public static class RepositoryExtensions
{
if (!await repository.AnyAsync(x => x.Id!.Equals(id), cancellationToken))
{
throw new EntityNotFoundException(typeof(TEntity), id);
throw new EntityNotFoundException<TEntity>(id);
}
}
@ -69,7 +69,7 @@ public static class RepositoryExtensions
{
if (!await repository.AnyAsync(expression, cancellationToken))
{
throw new EntityNotFoundException(typeof(TEntity));
throw new EntityNotFoundException<TEntity>();
}
}
@ -250,7 +250,7 @@ public static class RepositoryExtensions
hardDeleteEntities.Add(entity);
await repository.DeleteAsync(entity, autoSave, cancellationToken);
}
public static TRepository SetEntityName<TRepository>(
this TRepository repository,
string name

10
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs

@ -1,6 +1,3 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Data;
@ -8,7 +5,10 @@ using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
@ -468,7 +468,7 @@ public class EfCoreRepository<TDbContext, TEntity, TKey> : EfCoreRepository<TDbC
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
throw new EntityNotFoundException<TEntity>(id);
}
return entity;
@ -480,7 +480,7 @@ public class EfCoreRepository<TDbContext, TEntity, TKey> : EfCoreRepository<TDbC
? await (await WithDetailsAsync()).OrderBy(e => e.Id).FirstOrDefaultAsync(e => e.Id!.Equals(id), GetCancellationToken(cancellationToken))
: !ShouldTrackingEntityChange()
? await (await GetQueryableAsync()).OrderBy(e => e.Id).FirstOrDefaultAsync(e => e.Id!.Equals(id), GetCancellationToken(cancellationToken))
: await (await GetDbSetAsync()).FindAsync(new object[] {id!}, GetCancellationToken(cancellationToken));
: await (await GetDbSetAsync()).FindAsync(new object[] { id! }, GetCancellationToken(cancellationToken));
}
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)

26
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/DbContextEventInbox.cs

@ -47,10 +47,12 @@ public class DbContextEventInbox<TDbContext> : IDbContextEventInbox<TDbContext>
transformedFilter = InboxOutboxFilterExpressionTransformer.Transform<IIncomingEventInfo, IncomingEventRecord>(filter)!;
}
var now = Clock.Now;
var outgoingEventRecords = await dbContext
.IncomingEvents
.AsNoTracking()
.Where(x => !x.Processed)
.Where(x => x.Status == IncomingEventStatus.Pending)
.Where(x => x.NextRetryTime == null || x.NextRetryTime <= now)
.WhereIf(transformedFilter != null, transformedFilter!)
.OrderBy(x => x.CreationTime)
.Take(maxCount)
@ -66,7 +68,25 @@ public class DbContextEventInbox<TDbContext> : IDbContextEventInbox<TDbContext>
{
var dbContext = await DbContextProvider.GetDbContextAsync();
await dbContext.IncomingEvents.Where(x => x.Id == id).ExecuteUpdateAsync(x =>
x.SetProperty(p => p.Processed, _ => true).SetProperty(p => p.ProcessedTime, _ => Clock.Now));
x.SetProperty(p => p.Status, _ => IncomingEventStatus.Processed).SetProperty(p => p.HandledTime, _ => Clock.Now));
}
[UnitOfWork]
public virtual async Task RetryLaterAsync(Guid id, int retryCount, DateTime? nextRetryTime)
{
var dbContext = await DbContextProvider.GetDbContextAsync();
await dbContext.IncomingEvents.Where(x => x.Id == id).ExecuteUpdateAsync(x =>
x.SetProperty(p => p.RetryCount, _ => retryCount)
.SetProperty(p => p.NextRetryTime, _ => nextRetryTime)
.SetProperty(p => p.Status, _ => IncomingEventStatus.Pending));
}
[UnitOfWork]
public virtual async Task MarkAsDiscardAsync(Guid id)
{
var dbContext = await DbContextProvider.GetDbContextAsync();
await dbContext.IncomingEvents.Where(x => x.Id == id).ExecuteUpdateAsync(x =>
x.SetProperty(p => p.Status, _ => IncomingEventStatus.Discarded).SetProperty(p => p.HandledTime, _ => Clock.Now));
}
[UnitOfWork]
@ -82,7 +102,7 @@ public class DbContextEventInbox<TDbContext> : IDbContextEventInbox<TDbContext>
var dbContext = await DbContextProvider.GetDbContextAsync();
var timeToKeepEvents = Clock.Now - EventBusBoxesOptions.WaitTimeToDeleteProcessedInboxEvents;
await dbContext.IncomingEvents
.Where(x => x.Processed && x.CreationTime < timeToKeepEvents)
.Where(x => (x.Status == IncomingEventStatus.Processed || x.Status == IncomingEventStatus.Discarded) && x.CreationTime < timeToKeepEvents)
.ExecuteDeleteAsync();
}
}

2
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EventInboxDbContextModelBuilderExtensions.cs

@ -16,7 +16,7 @@ public static class EventInboxDbContextModelBuilderExtensions
b.Property(x => x.EventName).IsRequired().HasMaxLength(IncomingEventRecord.MaxEventNameLength);
b.Property(x => x.EventData).IsRequired();
b.HasIndex(x => new { x.Processed, x.CreationTime });
b.HasIndex(x => new { x.Status, x.CreationTime });
b.HasIndex(x => x.MessageId);
});
}

31
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IncomingEventRecord.cs

@ -24,9 +24,13 @@ public class IncomingEventRecord :
public DateTime CreationTime { get; private set; }
public bool Processed { get; set; }
public IncomingEventStatus Status { get; set; } = IncomingEventStatus.Pending;
public DateTime? ProcessedTime { get; set; }
public DateTime? HandledTime { get; set; }
public int RetryCount { get; set; } = 0;
public DateTime? NextRetryTime { get; set; } = null;
protected IncomingEventRecord()
{
@ -58,7 +62,11 @@ public class IncomingEventRecord :
MessageId,
EventName,
EventData,
CreationTime
CreationTime,
Status,
HandledTime,
RetryCount,
NextRetryTime
);
foreach (var property in ExtraProperties)
@ -71,7 +79,20 @@ public class IncomingEventRecord :
public void MarkAsProcessed(DateTime processedTime)
{
Processed = true;
ProcessedTime = processedTime;
Status = IncomingEventStatus.Processed;
HandledTime = processedTime;
}
public void MarkAsDiscarded(DateTime discardedTime)
{
Status = IncomingEventStatus.Discarded;
HandledTime = discardedTime;
}
public void RetryLater(int retryCount, DateTime nextRetryTime)
{
Status = IncomingEventStatus.Pending;
NextRetryTime = nextRetryTime;
RetryCount = retryCount;
}
}

4
framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IEventInbox.cs

@ -14,6 +14,10 @@ public interface IEventInbox
Task MarkAsProcessedAsync(Guid id);
Task RetryLaterAsync(Guid id, int retryCount, DateTime? nextRetryTime);
Task MarkAsDiscardAsync(Guid id);
Task<bool> ExistsByMessageIdAsync(string messageId);
Task DeleteOldEventsAsync();

18
framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventInfo.cs

@ -20,6 +20,14 @@ public class IncomingEventInfo : IIncomingEventInfo
public DateTime CreationTime { get; }
public IncomingEventStatus Status { get; set; } = IncomingEventStatus.Pending;
public DateTime? HandledTime { get; set; }
public int RetryCount { get; set; } = 0;
public DateTime? NextRetryTime { get; set; } = null;
protected IncomingEventInfo()
{
ExtraProperties = new ExtraPropertyDictionary();
@ -31,13 +39,21 @@ public class IncomingEventInfo : IIncomingEventInfo
string messageId,
string eventName,
byte[] eventData,
DateTime creationTime)
DateTime creationTime,
IncomingEventStatus status = IncomingEventStatus.Pending,
DateTime? handledTime = null,
int retryCount = 0,
DateTime? nextRetryTime = null)
{
Id = id;
MessageId = messageId;
EventName = Check.NotNullOrWhiteSpace(eventName, nameof(eventName), MaxEventNameLength);
EventData = eventData;
CreationTime = creationTime;
Status = status;
HandledTime = handledTime;
RetryCount = retryCount;
NextRetryTime = nextRetryTime;
ExtraProperties = new ExtraPropertyDictionary();
this.SetDefaultsForExtraProperties();
}

10
framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/IncomingEventStatus.cs

@ -0,0 +1,10 @@
namespace Volo.Abp.EventBus.Distributed;
public enum IncomingEventStatus
{
Pending = 0,
Discarded = 1,
Processed = 2
}

17
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs

@ -36,6 +36,23 @@ public class AbpEventBusBoxesOptions
/// </summary>
public TimeSpan PeriodTimeSpan { get; set; }
/// <summary>
/// Default: <see cref="InboxProcessorFailurePolicy.Retry"/>
/// </summary>
public InboxProcessorFailurePolicy InboxProcessorFailurePolicy { get; set; } = InboxProcessorFailurePolicy.Retry;
/// <summary>
/// Default: 10
/// </summary>
public int InboxProcessorMaxRetryCount { get; set; } = 10;
/// <summary>
/// Default value is 10
/// The initial retry delay factor (double) when `InboxProcessorFailurePolicy` is `RetryLater`.
/// The delay is calculated as: `delay = InboxProcessorRetryBackoffFactor × 2^retryCount`
/// </summary>
public double InboxProcessorRetryBackoffFactor { get; set; } = 10;
/// <summary>
/// Default: 15 seconds
/// </summary>

82
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
@ -25,7 +26,6 @@ public class InboxProcessor : IInboxProcessor, ITransientDependency
protected IEventInbox Inbox { get; private set; } = default!;
protected InboxConfig InboxConfig { get; private set; } = default!;
protected AbpEventBusBoxesOptions EventBusBoxesOptions { get; }
protected DateTime? LastCleanTime { get; set; }
protected string DistributedLockName { get; set; } = default!;
@ -103,18 +103,76 @@ public class InboxProcessor : IInboxProcessor, ITransientDependency
foreach (var waitingEvent in waitingEvents)
{
using (var uow = UnitOfWorkManager.Begin(isTransactional: true, requiresNew: true))
Logger.LogInformation($"Start processing the incoming event with id = {waitingEvent.Id:N}");
try
{
await DistributedEventBus
.AsSupportsEventBoxes()
.ProcessFromInboxAsync(waitingEvent, InboxConfig);
using (var uow = UnitOfWorkManager.Begin(isTransactional: true, requiresNew: true))
{
await DistributedEventBus
.AsSupportsEventBoxes()
.ProcessFromInboxAsync(waitingEvent, InboxConfig);
await Inbox.MarkAsProcessedAsync(waitingEvent.Id);
await Inbox.MarkAsProcessedAsync(waitingEvent.Id);
await uow.CompleteAsync(StoppingToken);
}
await uow.CompleteAsync(StoppingToken);
}
Logger.LogInformation($"Processed the incoming event with id = {waitingEvent.Id:N}");
Logger.LogInformation($"Processed the incoming event with id = {waitingEvent.Id:N}");
}
catch (Exception e)
{
Logger.LogError(e, $"Event with id = {waitingEvent.Id:N} processing failed.");
if (EventBusBoxesOptions.InboxProcessorFailurePolicy == InboxProcessorFailurePolicy.Retry)
{
throw;
}
if (EventBusBoxesOptions.InboxProcessorFailurePolicy == InboxProcessorFailurePolicy.RetryLater)
{
using (var uow = UnitOfWorkManager.Begin(isTransactional: true, requiresNew: true))
{
if (waitingEvent.NextRetryTime != null)
{
waitingEvent.RetryCount++;
}
if (waitingEvent.RetryCount >= EventBusBoxesOptions.InboxProcessorMaxRetryCount)
{
Logger.LogWarning($"Event with id = {waitingEvent.Id:N} has exceeded the maximum retry count. Marking it as discarded.");
await Inbox.RetryLaterAsync(waitingEvent.Id, waitingEvent.RetryCount, null);
await Inbox.MarkAsDiscardAsync(waitingEvent.Id);
await uow.CompleteAsync(StoppingToken);
continue;
}
waitingEvent.NextRetryTime = GetNextRetryTime(waitingEvent.RetryCount, EventBusBoxesOptions.InboxProcessorRetryBackoffFactor);
Logger.LogInformation($"Event with id = {waitingEvent.Id:N} will retry later. " +
$"Current retry count: {waitingEvent.RetryCount}, " +
$"Next retry time: {waitingEvent.NextRetryTime}, " +
$"Max retry count: {EventBusBoxesOptions.InboxProcessorMaxRetryCount}.");
await Inbox.RetryLaterAsync(waitingEvent.Id, waitingEvent.RetryCount, GetNextRetryTime(waitingEvent.RetryCount, EventBusBoxesOptions.InboxProcessorRetryBackoffFactor));
await uow.CompleteAsync(StoppingToken);
}
continue;
}
if (EventBusBoxesOptions.InboxProcessorFailurePolicy == InboxProcessorFailurePolicy.Discard)
{
using (var uow = UnitOfWorkManager.Begin(isTransactional: true, requiresNew: true))
{
Logger.LogInformation($"Event with id = {waitingEvent.Id:N} will be discarded.");
await Inbox.MarkAsDiscardAsync(waitingEvent.Id);
await uow.CompleteAsync(StoppingToken);
}
continue;
}
}
}
}
}
@ -130,6 +188,12 @@ public class InboxProcessor : IInboxProcessor, ITransientDependency
}
}
protected virtual DateTime? GetNextRetryTime(int retryCount, double factor)
{
var delaySeconds = factor * Math.Pow(2, retryCount);
return DateTime.Now.AddSeconds(delaySeconds);
}
protected virtual async Task<List<IncomingEventInfo>> GetWaitingEventsAsync()
{
return await Inbox.GetWaitingEventsAsync(EventBusBoxesOptions.InboxWaitingEventMaxCount, EventBusBoxesOptions.InboxProcessorFilter, StoppingToken);

22
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessorFailurePolicy.cs

@ -0,0 +1,22 @@
namespace Volo.Abp.EventBus.Distributed;
public enum InboxProcessorFailurePolicy
{
/// <summary>
/// Default behavior, retry the following event in next period time.
/// </summary>
Retry,
/// <summary>
/// Skip the failed event and retry it after a delay.
/// The delay doubles with each retry, starting from the configured InboxProcessorRetryBackoffFactor
/// (e.g., 10, 20, 40, 80 seconds, etc.).
/// The event is discarded if it still fails after reaching the maximum retry count.
/// </summary>
RetryLater,
/// <summary>
/// Skip the event and do not retry it.
/// </summary>
Discard,
}

28
framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/Domain/Entities/EntityNotFoundException.cs

@ -2,6 +2,34 @@
namespace Volo.Abp.Domain.Entities;
/// <summary>
/// This exception is thrown if an entity is expected to be found but not found.
/// </summary>
public class EntityNotFoundException<TEntityType> : EntityNotFoundException
{
/// <summary>
/// Creates a new <see cref="EntityNotFoundException{TEntityType}"/> object.
/// </summary>
public EntityNotFoundException()
: base(typeof(TEntityType))
{
}
/// <summary>
/// Creates a new <see cref="EntityNotFoundException{TEntityType}"/> object.
/// </summary>
public EntityNotFoundException(object? id)
: base(typeof(TEntityType), id)
{
}
/// <summary>
/// Creates a new <see cref="EntityNotFoundException{TEntityType}"/> object.
/// </summary>
public EntityNotFoundException(object? id, Exception? innerException)
: base(typeof(TEntityType), id, innerException)
{
}
}
/// <summary>
/// This exception is thrown if an entity is expected to be found but not found.
/// </summary>

14
framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/ObjectToInferredTypesConverter.cs

@ -26,6 +26,16 @@ public class ObjectToInferredTypesConverter : JsonConverter<object>
public override void Write(
Utf8JsonWriter writer,
object objectToWrite,
JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options);
JsonSerializerOptions options)
{
var runtimeType = objectToWrite.GetType();
if (runtimeType == typeof(object))
{
writer.WriteStartObject();
writer.WriteEndObject();
return;
}
JsonSerializer.Serialize(writer, objectToWrite, runtimeType, options);
}
}

72
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using Microsoft.Extensions.Localization;
@ -47,12 +48,11 @@ public static class JsonLocalizationDictionaryBuilder
{
throw new AbpException("Can not parse json string. " + ex.Message);
}
if (jsonFile == null)
{
return null;
}
var cultureCode = jsonFile.Culture;
if (string.IsNullOrEmpty(cultureCode))
{
@ -61,18 +61,17 @@ public static class JsonLocalizationDictionaryBuilder
var dictionary = new Dictionary<string, LocalizedString>();
var dublicateNames = new List<string>();
foreach (var item in jsonFile.Texts)
foreach (var item in FlattenTexts(jsonFile.Texts))
{
if (string.IsNullOrEmpty(item.Key))
{
throw new AbpException("The key is empty in given json string.");
}
if (dictionary.GetOrDefault(item.Key) != null)
{
dublicateNames.Add(item.Key);
}
dictionary[item.Key] = new LocalizedString(item.Key, item.Value.NormalizeLineEndings());
}
@ -85,4 +84,67 @@ public static class JsonLocalizationDictionaryBuilder
return new StaticLocalizationDictionary(cultureCode, dictionary);
}
private static Dictionary<string, string> FlattenTexts(Dictionary<string, object> texts, string prefix = "")
{
var result = new Dictionary<string, string>();
foreach (var text in texts)
{
var currentKey = string.IsNullOrEmpty(prefix) ? text.Key : $"{prefix}__{text.Key}";
switch (text.Value)
{
case JsonElement jsonElement:
foreach (var item in FlattenJsonElement(jsonElement, currentKey))
{
result[item.Key] = item.Value;
}
break;
case string str:
result[currentKey] = str;
break;
case null:
result[currentKey] = "";
break;
default:
result[currentKey] = text.Value.ToString() ?? "";
break;
}
}
return result;
}
private static IEnumerable<KeyValuePair<string, string>> FlattenJsonElement(JsonElement element, string prefix)
{
switch (element.ValueKind)
{
case JsonValueKind.String:
yield return new KeyValuePair<string, string>(prefix, element.GetString() ?? "");
break;
case JsonValueKind.Object:
foreach (var prop in element.EnumerateObject())
{
var newKey = $"{prefix}__{prop.Name}";
foreach (var item in FlattenJsonElement(prop.Value, newKey))
{
yield return item;
}
}
break;
case JsonValueKind.Array:
var i = 0;
foreach (var prop in element.EnumerateArray())
{
var newKey = $"{prefix}__{i}";
foreach (var item in FlattenJsonElement(prop, newKey))
{
yield return item;
}
i++;
}
break;
default:
yield return new KeyValuePair<string, string>(prefix, element.ToString());
break;
}
}
}

7
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationFile.cs

@ -9,10 +9,5 @@ public class JsonLocalizationFile
/// </summary>
public string Culture { get; set; } = default!;
public Dictionary<string, string> Texts { get; set; }
public JsonLocalizationFile()
{
Texts = new Dictionary<string, string>();
}
public Dictionary<string, object> Texts { get; set; } = [];
}

23
framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/AbpMapperlyModule.cs

@ -1,6 +1,4 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Auditing;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectExtending;
@ -22,23 +20,6 @@ public class AbpMapperlyModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
// This is the temporary solution, We will remove it in when all apps are migrated to Mapperly.
var disableMapperlyAutoObjectMappingProvider = false;
var modules = context.Services.GetSingletonInstance<IAbpApplication>().Modules.ToList();
var autoMapperModuleIndex = modules.FindIndex(x => x.Type.FullName!.Equals("Volo.Abp.AutoMapper.AbpAutoMapperModule", StringComparison.OrdinalIgnoreCase));
if (autoMapperModuleIndex >= 0)
{
var mapperlyModuleIndex = modules.FindIndex(x => x.Type == typeof(AbpMapperlyModule));
if (mapperlyModuleIndex > autoMapperModuleIndex)
{
disableMapperlyAutoObjectMappingProvider = true;
}
}
if (!disableMapperlyAutoObjectMappingProvider)
{
context.Services.AddMapperlyObjectMapper();
}
context.Services.AddMapperlyObjectMapper();
}
}

60
framework/src/Volo.Abp.Mapperly/Volo/Abp/Mapperly/MapperlyAutoObjectMappingProvider.cs

@ -9,7 +9,6 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Reflection;
namespace Volo.Abp.Mapperly;
@ -47,7 +46,7 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
{
mapper.BeforeMap((TSource)source);
var destination = mapper.Map((TSource)source);
TryMapExtraProperties(mapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), (TSource)source, destination, new ExtraPropertyDictionary());
TryMapExtraProperties(mapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), (TSource)source, destination, GetExtraProperties(destination));
mapper.AfterMap((TSource)source, destination);
return destination;
}
@ -62,8 +61,7 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
return destination;
}
throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" +
$" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found");
throw GetNoMapperFoundException<TSource, TDestination>();
}
public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
@ -95,8 +93,34 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
return destination;
}
throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" +
$" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found");
throw GetNoMapperFoundException<TSource, TDestination>();
}
protected virtual AbpException GetNoMapperFoundException<TSource, TDestination>()
{
var newLine = Environment.NewLine;
var message = "No object mapping was found for the specified source and destination types." +
newLine +
newLine +
"Mapping attempted:" +
newLine +
$"{typeof(TSource).Name} -> {typeof(TDestination).Name}" +
newLine +
$"{typeof(TSource).FullName} -> {typeof(TDestination).FullName}" +
newLine +
newLine +
"How to fix:" +
newLine +
"Define a mapping class for these types:" +
newLine +
" - Use MapperBase<TSource, TDestination> for one-way mapping." +
newLine +
" - Use TwoWayMapperBase<TDestination, TSource> for two-way mapping." +
newLine +
newLine +
"For details, see the Mapperly integration document https://abp.io/docs/latest/framework/infrastructure/object-to-object-mapping#mapperly-integration";
return new AbpException(message);
}
protected virtual bool TryToMapCollection<TSource, TDestination>(TSource source, TDestination? destination, out TDestination collectionResult)
@ -212,13 +236,27 @@ public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider
protected virtual void TryMapExtraProperties<TSource, TDestination>(MapExtraPropertiesAttribute? mapExtraPropertiesAttribute, TSource source, TDestination destination, ExtraPropertyDictionary destinationExtraProperty)
{
if (mapExtraPropertiesAttribute != null &&
typeof(IHasExtraProperties).IsAssignableFrom(typeof(TDestination)) &&
typeof(IHasExtraProperties).IsAssignableFrom(typeof(TSource)))
if(source is not IHasExtraProperties sourceHasExtraProperties)
{
return;
}
if (destination is not IHasExtraProperties destinationHasExtraProperties)
{
return;
}
if (sourceHasExtraProperties.ExtraProperties != null && sourceHasExtraProperties.ExtraProperties ==
destinationHasExtraProperties.ExtraProperties)
{
ObjectHelper.TrySetProperty(destinationHasExtraProperties, x => x.ExtraProperties, () => new ExtraPropertyDictionary(destinationHasExtraProperties.ExtraProperties));;
}
if (mapExtraPropertiesAttribute != null)
{
MapExtraProperties<TSource, TDestination>(
source!.As<IHasExtraProperties>(),
destination!.As<IHasExtraProperties>(),
sourceHasExtraProperties,
destinationHasExtraProperties,
destinationExtraProperty,
mapExtraPropertiesAttribute.DefinitionChecks,
mapExtraPropertiesAttribute.IgnoredProperties,

2
framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs

@ -334,7 +334,7 @@ public class MemoryDbRepository<TMemoryDbContext, TEntity, TKey> : MemoryDbRepos
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
throw new EntityNotFoundException<TEntity>(id);
}
return entity;

8
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -1,12 +1,12 @@
using JetBrains.Annotations;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
@ -803,7 +803,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity, TKey>
if (entity == null)
{
throw new EntityNotFoundException(typeof(TEntity), id);
throw new EntityNotFoundException<TEntity>(id);
}
return entity;

31
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpBsonSerializer.cs

@ -0,0 +1,31 @@
using System;
using System.Collections.Concurrent;
using System.Reflection;
using MongoDB.Bson.Serialization;
namespace Volo.Abp.MongoDB;
public static class AbpBsonSerializer
{
private static readonly ConcurrentDictionary<Type, IBsonSerializer> Cache;
static AbpBsonSerializer()
{
var registry = BsonSerializer.SerializerRegistry;
var type = typeof(BsonSerializerRegistry);
var cacheField = type.GetField("_cache", BindingFlags.NonPublic | BindingFlags.Instance) ??
throw new AbpException($"Cannot find _cache field of {type.FullName}.");
Cache = (ConcurrentDictionary<Type, IBsonSerializer>)cacheField.GetValue(registry)!;
}
public static void RemoveSerializer<T>()
{
Cache.TryRemove(typeof(T), out _);
}
public static ConcurrentDictionary<Type, IBsonSerializer> GetSerializerCache()
{
return Cache;
}
}

3
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs

@ -19,7 +19,8 @@ public class AbpMongoDbModule : AbpModule
{
static AbpMongoDbModule()
{
BsonSerializer.TryRegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
AbpBsonSerializer.RemoveSerializer<Guid>();
BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
BsonTypeMapper.RegisterCustomTypeMapper(typeof(Guid), new AbpGuidCustomBsonTypeMapper());
}

36
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/IncomingEventRecord.cs

@ -23,9 +23,13 @@ public class IncomingEventRecord :
public DateTime CreationTime { get; private set; }
public bool Processed { get; set; }
public IncomingEventStatus Status { get; set; } = IncomingEventStatus.Pending;
public DateTime? ProcessedTime { get; set; }
public DateTime? HandledTime { get; set; }
public int RetryCount { get; set; } = 0;
public DateTime? NextRetryTime { get; set; } = null;
protected IncomingEventRecord()
{
@ -41,7 +45,10 @@ public class IncomingEventRecord :
EventName = eventInfo.EventName;
EventData = eventInfo.EventData;
CreationTime = eventInfo.CreationTime;
Status = eventInfo.Status;
HandledTime = eventInfo.HandledTime;
RetryCount = eventInfo.RetryCount;
NextRetryTime = eventInfo.NextRetryTime;
ExtraProperties = new ExtraPropertyDictionary();
this.SetDefaultsForExtraProperties();
foreach (var property in eventInfo.ExtraProperties)
@ -57,7 +64,11 @@ public class IncomingEventRecord :
MessageId,
EventName,
EventData,
CreationTime
CreationTime,
Status,
HandledTime,
RetryCount,
NextRetryTime
);
foreach (var property in ExtraProperties)
@ -70,7 +81,20 @@ public class IncomingEventRecord :
public void MarkAsProcessed(DateTime processedTime)
{
Processed = true;
ProcessedTime = processedTime;
Status = IncomingEventStatus.Processed;
HandledTime = processedTime;
}
public void MarkAsDiscarded(DateTime discardedTime)
{
Status = IncomingEventStatus.Discarded;
HandledTime = discardedTime;
}
public void RetryLater(int retryCount, DateTime nextRetryTime)
{
Status = IncomingEventStatus.Pending;
NextRetryTime = nextRetryTime;
RetryCount = retryCount;
}
}

46
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbContextEventInbox.cs

@ -61,10 +61,12 @@ public class MongoDbContextEventInbox<TMongoDbContext> : IMongoDbContextEventInb
transformedFilter = InboxOutboxFilterExpressionTransformer.Transform<IIncomingEventInfo, IncomingEventRecord>(filter)!;
}
var now = Clock.Now;
var outgoingEventRecords = await dbContext
.IncomingEvents
.AsQueryable()
.Where(x => x.Processed == false)
.Where(x => x.Status == IncomingEventStatus.Pending)
.Where(x => x.NextRetryTime == null || x.NextRetryTime <= now)
.WhereIf(transformedFilter != null, transformedFilter!)
.OrderBy(x => x.CreationTime)
.Take(maxCount)
@ -81,7 +83,43 @@ public class MongoDbContextEventInbox<TMongoDbContext> : IMongoDbContextEventInb
var dbContext = await DbContextProvider.GetDbContextAsync();
var filter = Builders<IncomingEventRecord>.Filter.Eq(x => x.Id, id);
var update = Builders<IncomingEventRecord>.Update.Set(x => x.Processed, true).Set(x => x.ProcessedTime, Clock.Now);
var update = Builders<IncomingEventRecord>.Update.Set(x => x.Status, IncomingEventStatus.Processed).Set(x => x.HandledTime, Clock.Now);
if (dbContext.SessionHandle != null)
{
await dbContext.IncomingEvents.UpdateOneAsync(dbContext.SessionHandle, filter, update);
}
else
{
await dbContext.IncomingEvents.UpdateOneAsync(filter, update);
}
}
[UnitOfWork]
public virtual async Task RetryLaterAsync(Guid id, int retryCount, DateTime? nextRetryTime)
{
var dbContext = await DbContextProvider.GetDbContextAsync();
var filter = Builders<IncomingEventRecord>.Filter.Eq(x => x.Id, id);
var update = Builders<IncomingEventRecord>.Update.Set(x => x.RetryCount, retryCount).Set(x => x.NextRetryTime, nextRetryTime);
if (dbContext.SessionHandle != null)
{
await dbContext.IncomingEvents.UpdateOneAsync(dbContext.SessionHandle, filter, update);
}
else
{
await dbContext.IncomingEvents.UpdateOneAsync(filter, update);
}
}
[UnitOfWork]
public virtual async Task MarkAsDiscardAsync(Guid id)
{
var dbContext = await DbContextProvider.GetDbContextAsync();
var filter = Builders<IncomingEventRecord>.Filter.Eq(x => x.Id, id);
var update = Builders<IncomingEventRecord>.Update.Set(x => x.Status, IncomingEventStatus.Discarded).Set(x => x.HandledTime, Clock.Now);
if (dbContext.SessionHandle != null)
{
@ -108,11 +146,11 @@ public class MongoDbContextEventInbox<TMongoDbContext> : IMongoDbContextEventInb
if (dbContext.SessionHandle != null)
{
await dbContext.IncomingEvents.DeleteManyAsync(dbContext.SessionHandle, x => x.Processed && x.CreationTime < timeToKeepEvents);
await dbContext.IncomingEvents.DeleteManyAsync(dbContext.SessionHandle, x => (x.Status == IncomingEventStatus.Processed || x.Status == IncomingEventStatus.Discarded) && x.CreationTime < timeToKeepEvents);
}
else
{
await dbContext.IncomingEvents.DeleteManyAsync(x => x.Processed && x.CreationTime < timeToKeepEvents);
await dbContext.IncomingEvents.DeleteManyAsync(x => (x.Status == IncomingEventStatus.Processed || x.Status == IncomingEventStatus.Discarded) && x.CreationTime < timeToKeepEvents);
}
}
}

54
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/ObjectToInferredTypesConverter_Tests.cs

@ -0,0 +1,54 @@
using System.Text.Json;
using Shouldly;
using Xunit;
namespace Volo.Abp.Json;
public class ObjectToInferredTypesConverter_Tests : AbpJsonSystemTextJsonTestBase
{
private readonly IJsonSerializer _jsonSerializer;
public ObjectToInferredTypesConverter_Tests()
{
_jsonSerializer = GetRequiredService<IJsonSerializer>();
}
[Fact]
public void Test()
{
var objString = _jsonSerializer.Serialize(new object());
objString.ShouldBe("{}");
var obj = _jsonSerializer.Deserialize<object>(objString);
obj.ShouldBeOfType<JsonElement>();
var booleanString = _jsonSerializer.Serialize(true);
booleanString.ShouldBe("true");
var boolean = _jsonSerializer.Deserialize<bool>(booleanString);
boolean.ShouldBe(true);
var booleanString2 = _jsonSerializer.Serialize(false);
booleanString2.ShouldBe("false");
var boolean2 = _jsonSerializer.Deserialize<bool>(booleanString2);
boolean2.ShouldBe(false);
var numberString = _jsonSerializer.Serialize(1);
numberString.ShouldBe("1");
var number = _jsonSerializer.Deserialize<long>(numberString);
number.ShouldBe(1);
var numberString2 = _jsonSerializer.Serialize(1.1);
numberString2.ShouldBe("1.1");
var number2 = _jsonSerializer.Deserialize<double>(numberString2);
number2.ShouldBe(1.1);
var dateString = _jsonSerializer.Serialize(System.DateTime.Parse("2024-01-01"));
dateString.ShouldBe("\"2024-01-01T00:00:00\"");
var date = _jsonSerializer.Deserialize<System.DateTime>(dateString);
date.ShouldBe(System.DateTime.Parse("2024-01-01"));
var textString = _jsonSerializer.Serialize("text");
textString.ShouldBe("\"text\"");
var text = _jsonSerializer.Deserialize<string>(textString);
text.ShouldBe("text");
}
}

25
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs

@ -196,7 +196,7 @@ public class AbpLocalization_Tests : AbpIntegratedTest<AbpLocalizationTestModule
{
_localizer["CarPlural"].Value.ShouldBe("汽车");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hans-CN")))
{
_localizer["Car"].Value.ShouldBe("汽车");
@ -214,7 +214,7 @@ public class AbpLocalization_Tests : AbpIntegratedTest<AbpLocalizationTestModule
{
_localizer["CarPlural"].Value.ShouldBe("汽車");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-TW")))
{
_localizer["Car"].Value.ShouldBe("汽車");
@ -223,7 +223,7 @@ public class AbpLocalization_Tests : AbpIntegratedTest<AbpLocalizationTestModule
{
_localizer["CarPlural"].Value.ShouldBe("汽車");
}
using (CultureHelper.Use(CultureInfo.GetCultureInfo("zh-Hant-TW")))
{
_localizer["Car"].Value.ShouldBe("汽車");
@ -375,4 +375,21 @@ public class AbpLocalization_Tests : AbpIntegratedTest<AbpLocalizationTestModule
var externalLocalizer = _localizerFactory.CreateByResourceName(TestExternalLocalizationStore.TestExternalResourceNames.ExternalResource1);
externalLocalizer["Car"].Value.ShouldBe("Car");
}
}
[Fact]
public void Should_Get_Nested_Translations()
{
using (CultureHelper.Use("en"))
{
_localizer["MyNestedTranslation__SomeKey"].Value.ShouldBe("Some nested value");
_localizer["MyNestedTranslation__SomeOtherKey"].Value.ShouldBe("Some other nested value");
_localizer["MyNestedTranslation__DeeplyNested__DeepKey"].Value.ShouldBe("A deeply nested value");
_localizer["MyNestedTranslation__DeeplyNestedArray__0"].Value.ShouldBe("First value in array");
_localizer["MyNestedTranslation__DeeplyNestedArray__1"].Value.ShouldBe("Second value in array");
_localizer["MyNestedTranslation__DeeplyNestedArray__2__InnerDeepKey"].Value.ShouldBe("Inner deeply nested value");
_localizer["MyNestedTranslation__DeeplyNestedArray__3__InnerDeepArray__0"].Value.ShouldBe("First inner deep array value");
_localizer["MyNestedTranslation__DeeplyNestedArray__3__InnerDeepArray__1"].Value.ShouldBe("Second inner deep array value");
}
}
}

24
framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/en.json

@ -1,6 +1,26 @@
{
"culture": "en",
"texts": {
"SeeYou": "See you"
"SeeYou": "See you",
"MyNestedTranslation": {
"SomeKey": "Some nested value",
"SomeOtherKey": "Some other nested value",
"DeeplyNested": {
"DeepKey": "A deeply nested value"
},
"DeeplyNestedArray": [
"First value in array",
"Second value in array",
{
"InnerDeepKey": "Inner deeply nested value"
},
{
"InnerDeepArray": [
"First inner deep array value",
"Second inner deep array value"
]
}
]
}
}
}
}

13
framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/AbpMapperlyModule_Basic_Tests.cs

@ -106,9 +106,14 @@ public class AbpMapperlyModule_Basic_Tests : AbpIntegratedTest<MapperlyTestModul
public void Should_Throw_Exception_If_Mapper_Is_Not_Found()
{
var exception = Assert.Throws<AbpException>(() =>_objectMapper.Map<MyEntity, MyClassDto>(new MyEntity()));
exception.Message.ShouldBe("No " +
"Volo.Abp.Mapperly.IAbpMapperlyMapper<Volo.Abp.Mapperly.SampleClasses.MyEntity,Volo.Abp.Mapperly.MyClassDto> or " +
"Volo.Abp.Mapperly.IAbpReverseMapperlyMapper<Volo.Abp.Mapperly.SampleClasses.MyEntity,Volo.Abp.Mapperly.MyClassDto>" +
" was found");
exception.Message.ShouldBe("No object mapping was found for the specified source and destination types.\n\n" +
"Mapping attempted:\n" +
"MyEntity -> MyClassDto\n" +
"Volo.Abp.Mapperly.SampleClasses.MyEntity -> Volo.Abp.Mapperly.MyClassDto\n\n" +
"How to fix:\n" +
"Define a mapping class for these types:" + "\n" +
" - Use MapperBase<TSource, TDestination> for one-way mapping.\n" +
" - Use TwoWayMapperBase<TDestination, TSource> for two-way mapping.\n\n" +
"For details, see the Mapperly integration document https://abp.io/docs/latest/framework/infrastructure/object-to-object-mapping#mapperly-integration");
}
}

158
framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/ExtraProperties_Dictionary_Reference_Tests.cs

@ -0,0 +1,158 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Riok.Mapperly.Abstractions;
using Shouldly;
using Volo.Abp.Data;
using Volo.Abp.Mapperly.SampleClasses;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Testing;
using Xunit;
namespace Volo.Abp.Mapperly;
public class ExtraProperties_Dictionary_Reference_Tests : AbpIntegratedTest<MapperlyTestModule>
{
private readonly IObjectMapper _objectMapper;
public ExtraProperties_Dictionary_Reference_Tests()
{
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper>();
}
[Fact]
public void Should_Create_New_ExtraProperties_Dictionary_When_Same_Reference()
{
// Arrange: Create a shared ExtraProperties dictionary
var sharedExtraProperties = new ExtraPropertyDictionary
{
{"TestProperty", "TestValue"},
{"NumberProperty", 42}
};
var source = new TestEntityWithExtraProperties
{
Id = Guid.NewGuid(),
Name = "Source Entity"
};
var destination = new TestEntityDtoWithExtraProperties
{
Id = Guid.NewGuid(),
Name = "Destination DTO"
};
// Make both source and destination reference the same ExtraProperties dictionary
SetExtraPropertiesReference(source, sharedExtraProperties);
SetExtraPropertiesReference(destination, sharedExtraProperties);
// Verify they have the same reference before mapping
ReferenceEquals(source.ExtraProperties, destination.ExtraProperties).ShouldBeTrue();
source.ExtraProperties.Count.ShouldBe(2);
destination.ExtraProperties.Count.ShouldBe(2);
// Act: Perform mapping
_objectMapper.Map(source, destination);
// Assert: After mapping, they should have different references
// This is the key fix: when ExtraProperties references are the same,
// a new dictionary should be created for the destination
ReferenceEquals(source.ExtraProperties, destination.ExtraProperties).ShouldBeFalse();
// But content should be preserved
destination.ExtraProperties["TestProperty"].ShouldBe("TestValue");
destination.ExtraProperties["NumberProperty"].ShouldBe(42);
destination.ExtraProperties.Count.ShouldBe(source.ExtraProperties.Count);
}
[Fact]
public void Should_Not_Create_New_Dictionary_When_Different_References()
{
// Arrange: Create source and destination with different ExtraProperties references
var source = new TestEntityWithExtraProperties
{
Id = Guid.NewGuid(),
Name = "Source Entity"
};
source.SetProperty("SourceProperty", "SourceValue");
var destination = new TestEntityDtoWithExtraProperties
{
Id = Guid.NewGuid(),
Name = "Destination DTO"
};
destination.SetProperty("DestinationProperty", "DestinationValue");
var originalSourceReference = source.ExtraProperties;
// Verify they have different references before mapping
ReferenceEquals(source.ExtraProperties, destination.ExtraProperties).ShouldBeFalse();
// Act: Perform mapping
_objectMapper.Map(source, destination);
// Assert: Source reference should remain unchanged
ReferenceEquals(source.ExtraProperties, originalSourceReference).ShouldBeTrue();
// Destination reference may change due to normal mapping process, but should not be same as source
ReferenceEquals(source.ExtraProperties, destination.ExtraProperties).ShouldBeFalse();
destination.ExtraProperties["SourceProperty"].ShouldBe("SourceValue");
destination.ExtraProperties["DestinationProperty"].ShouldBe("DestinationValue");
}
[Fact]
public void Should_Handle_Readonly_ExtraProperties_Gracefully()
{
// Arrange: Create entities with readonly ExtraProperties
var source = new TestEntityWithReadonlyExtraProperties
{
Id = Guid.NewGuid(),
Name = "Source Entity"
};
source.ExtraProperties.Add("TestProperty", "TestValue");
var destination = new TestEntityWithReadonlyExtraProperties
{
Id = Guid.NewGuid(),
Name = "Destination Entity"
};
// Make them reference the same ExtraProperties
var sharedExtraProperties = new ExtraPropertyDictionary
{
{"SharedProperty", "SharedValue"}
};
SetReadonlyExtraPropertiesReference(source, sharedExtraProperties);
SetReadonlyExtraPropertiesReference(destination, sharedExtraProperties);
// Verify they have the same reference
ReferenceEquals(source.ExtraProperties, destination.ExtraProperties).ShouldBeTrue();
// Act & Assert: Should not throw exception even if setter is not available
Should.NotThrow(() => _objectMapper.Map(source, destination));
}
private static void SetExtraPropertiesReference(TestEntityWithExtraProperties entity, ExtraPropertyDictionary extraProperties)
{
// Use reflection to set the protected setter from ExtensibleObject
var propertyInfo = typeof(ExtensibleObject).GetProperty(nameof(ExtensibleObject.ExtraProperties));
propertyInfo?.SetValue(entity, extraProperties);
}
private static void SetExtraPropertiesReference(TestEntityDtoWithExtraProperties entity, ExtraPropertyDictionary extraProperties)
{
// Use reflection to set the protected setter from ExtensibleObject
var propertyInfo = typeof(ExtensibleObject).GetProperty(nameof(ExtensibleObject.ExtraProperties));
propertyInfo?.SetValue(entity, extraProperties);
}
private static void SetReadonlyExtraPropertiesReference(TestEntityWithReadonlyExtraProperties entity, ExtraPropertyDictionary extraProperties)
{
// Use reflection to set the private field
var fieldInfo = typeof(TestEntityWithReadonlyExtraProperties).GetField("_extraProperties",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
fieldInfo?.SetValue(entity, extraProperties);
}
}

43
framework/test/Volo.Abp.Mapperly.Tests/Volo/Abp/Mapperly/SampleClasses/MapperlyMappers.cs

@ -1,6 +1,9 @@
using Riok.Mapperly.Abstractions;
using System;
using Riok.Mapperly.Abstractions;
using Volo.Abp.Data;
using Volo.Abp.Mapperly;
using Volo.Abp.Mapperly.SampleClasses;
using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.TestObjects;
[Mapper]
@ -42,3 +45,41 @@ public partial class ExtensibleTestPersonWithRegularPropertiesDtoMapper : Mapper
public override partial void Map(ExtensibleTestPerson source, ExtensibleTestPersonWithRegularPropertiesDto destination);
}
// Test entities for ExtraProperties dictionary reference tests
public class TestEntityWithExtraProperties : ExtensibleObject
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
}
public class TestEntityDtoWithExtraProperties : ExtensibleObject
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
}
public class TestEntityWithReadonlyExtraProperties : IHasExtraProperties
{
private readonly ExtraPropertyDictionary _extraProperties = new();
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public ExtraPropertyDictionary ExtraProperties => _extraProperties;
}
[Mapper]
public partial class TestEntityWithExtraPropertiesMapper : MapperBase<TestEntityWithExtraProperties, TestEntityDtoWithExtraProperties>
{
public override partial TestEntityDtoWithExtraProperties Map(TestEntityWithExtraProperties source);
public override partial void Map(TestEntityWithExtraProperties source, TestEntityDtoWithExtraProperties destination);
}
[Mapper]
public partial class TestEntityWithReadonlyExtraPropertiesMapper : MapperBase<TestEntityWithReadonlyExtraProperties, TestEntityWithReadonlyExtraProperties>
{
public override partial TestEntityWithReadonlyExtraProperties Map(TestEntityWithReadonlyExtraProperties source);
public override partial void Map(TestEntityWithReadonlyExtraProperties source, TestEntityWithReadonlyExtraProperties destination);
}

4
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityCache_Tests.cs

@ -37,8 +37,8 @@ public abstract class EntityCache_Tests<TStartupModule> : TestAppTestBase<TStart
public async Task Should_Throw_EntityNotFoundException_IF_Entity_Not_Exist()
{
var notExistId = Guid.NewGuid();
await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductEntityCache.GetAsync(notExistId));
await Assert.ThrowsAsync<EntityNotFoundException>(() => ProductCacheItem.GetAsync(notExistId));
await Assert.ThrowsAsync<EntityNotFoundException<Product>>(() => ProductEntityCache.GetAsync(notExistId));
await Assert.ThrowsAsync<EntityNotFoundException<Product>>(() => ProductCacheItem.GetAsync(notExistId));
}
[Fact]

4
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs

@ -24,10 +24,10 @@ public abstract class RepositoryExtensions_Tests<TStartupModule> : TestAppTestBa
await WithUnitOfWorkAsync(async () =>
{
var id = Guid.NewGuid();
await Assert.ThrowsAsync<EntityNotFoundException>(async () =>
await Assert.ThrowsAsync<EntityNotFoundException<Person>>(async () =>
await PersonRepository.EnsureExistsAsync(Guid.NewGuid())
);
await Assert.ThrowsAsync<EntityNotFoundException>(async () =>
await Assert.ThrowsAsync<EntityNotFoundException<Person>>(async () =>
await PersonRepository.EnsureExistsAsync(x => x.Id == id)
);

9
latest-versions.json

@ -1,4 +1,13 @@
[
{
"version": "9.3.3",
"releaseDate": "",
"type": "stable",
"message": "",
"leptonx": {
"version": "4.3.3"
}
},
{
"version": "9.3.2",
"releaseDate": "",

1
modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Bundling/BasicThemeGlobalStyleContributor.cs

@ -6,6 +6,7 @@ public class BasicThemeGlobalStyleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add(new BundleFile("/themes/basic/googlefonts.css", true));
context.Files.Add("/themes/basic/layout.css");
}
}

1
modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/googlefonts.css

@ -0,0 +1 @@
@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');

74
modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/wwwroot/themes/basic/layout.css

@ -1,60 +1,65 @@
@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
#main-navbar-tools a.dropdown-toggle {
text-decoration: none;
color: #fff;
}
.navbar .dropdown-submenu {
position: relative;
}
.navbar .dropdown-menu {
margin: 0;
padding: 0;
}
.navbar .dropdown-menu a {
font-size: .9em;
padding: 10px 15px;
display: block;
min-width: 210px;
text-align: left;
border-radius: 0.25rem;
min-height: 44px;
}
.navbar .dropdown-menu a {
font-size: .9em;
padding: 10px 15px;
display: block;
min-width: 210px;
text-align: left;
border-radius: 0.25rem;
min-height: 44px;
}
.navbar .dropdown-submenu a::after {
transform: rotate(-90deg);
position: absolute;
right: 16px;
top: 18px;
}
}
.navbar .dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
}
left: 100%;
}
.card-header .btn {
padding: 2px 6px;
}
}
.card-header h5 {
margin: 0;
}
.container > .card {
}
.container>.card {
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;
}
@media screen and (min-width: 768px) {
.navbar .dropdown:hover > .dropdown-menu {
@media screen and (min-width: 768px) {
.navbar .dropdown:hover>.dropdown-menu {
display: block;
}
.navbar .dropdown-submenu:hover > .dropdown-menu {
.navbar .dropdown-submenu:hover>.dropdown-menu {
display: block;
}
}
.input-validation-error {
border-color: #dc3545;
}
.field-validation-error {
font-size: 0.8em;
}
@ -75,33 +80,40 @@ div.dataTables_wrapper div.dataTables_length label {
.rtl .dropdown-menu-right {
right: auto;
left: 0;
left: 0;
}
.rtl .dropdown-menu-right a {
text-align: right;
}
.rtl .dropdown-menu-right a {
text-align: right;
}
.rtl .navbar .dropdown-menu a {
text-align: right;
}
.rtl .navbar .dropdown-submenu .dropdown-menu {
top: 0;
left: auto;
right: 100%;
}
}
.rtl div.dataTables_wrapper div.dataTables_filter input {
margin-left: auto;
margin-right: 0.5em;
}
.rtl div.dataTables_wrapper div.dataTables_filter {
text-align: left;
}
.rtl table.dataTable thead th, table.dataTable thead td, table.dataTable tfoot th, table.dataTable tfoot td {
.rtl table.dataTable thead th,
table.dataTable thead td,
table.dataTable tfoot th,
table.dataTable tfoot td {
text-align: right;
}
.brand-container{
.brand-container {
text-align: center;
margin-top: 8rem;
}
@ -111,7 +123,7 @@ div.dataTables_wrapper div.dataTables_length label {
}
.brand-text {
color: #292D33;
color: #292D33;
font-family: Lexend;
font-size: 30px;
font-style: normal;
@ -119,4 +131,4 @@ div.dataTables_wrapper div.dataTables_length label {
line-height: 34px;
margin-top: 5px;
margin-bottom: 15px;
}
}

6
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json

@ -3,8 +3,8 @@
"name": "asp.net",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.shared": "~9.3.2",
"@abp/prismjs": "~9.3.2",
"@abp/highlight.js": "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared": "~9.3.3",
"@abp/prismjs": "~9.3.3",
"@abp/highlight.js": "~9.3.3"
}
}

264
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock

@ -2,203 +2,203 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.2.tgz#94089c3dcac4571c5fcb9bdb754e5df28a24e966"
integrity sha512-eRSvhLimwf65KKI1P/DZgQK+l300EwX4r2S4XYL0gJjjXI9aeIDQuPEqGZs2a6P5/zfejFvefqCIcG5EfEH9ew==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.2"
"@abp/bootstrap" "~9.3.2"
"@abp/bootstrap-datepicker" "~9.3.2"
"@abp/bootstrap-daterangepicker" "~9.3.2"
"@abp/datatables.net-bs5" "~9.3.2"
"@abp/font-awesome" "~9.3.2"
"@abp/jquery-form" "~9.3.2"
"@abp/jquery-validation-unobtrusive" "~9.3.2"
"@abp/lodash" "~9.3.2"
"@abp/luxon" "~9.3.2"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.2"
"@abp/moment" "~9.3.2"
"@abp/select2" "~9.3.2"
"@abp/sweetalert2" "~9.3.2"
"@abp/timeago" "~9.3.2"
"@abp/aspnetcore.mvc.ui@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.2.tgz#5cab40d0f17eea2ae97a0d25fa238e52b5e8ef91"
integrity sha512-C73MB6abc531CmYyRctZXtKUY/0t+hhBQg5fIbzdJaR8SCSHEh2v9j2ZAhKFU0kectdrpKrLroOihOWYMfuWdQ==
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.3.tgz#6886575725904f7b8f08234e0057ee851a68735d"
integrity sha512-zv1BL054q3VnqZXjd4fa2E7es/Gs8HsFfp3jWljRwEOytdG1PyHo5++ChM3FlB4+mIXq1On4leST3sDVxa75Sw==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.3"
"@abp/bootstrap" "~9.3.3"
"@abp/bootstrap-datepicker" "~9.3.3"
"@abp/bootstrap-daterangepicker" "~9.3.3"
"@abp/datatables.net-bs5" "~9.3.3"
"@abp/font-awesome" "~9.3.3"
"@abp/jquery-form" "~9.3.3"
"@abp/jquery-validation-unobtrusive" "~9.3.3"
"@abp/lodash" "~9.3.3"
"@abp/luxon" "~9.3.3"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.3"
"@abp/moment" "~9.3.3"
"@abp/select2" "~9.3.3"
"@abp/sweetalert2" "~9.3.3"
"@abp/timeago" "~9.3.3"
"@abp/aspnetcore.mvc.ui@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.3.tgz#16aca3844bccb24317f65f3a419cad34f9aa6387"
integrity sha512-bp1syI3exn3YBSoDertHxF1CVmEUIRHLCPr/+K1DLuBxW6KUPnDIpnJVVhXsO7EmwwzzukJF99utPXNGgQXnIg==
dependencies:
ansi-colors "^4.1.3"
"@abp/bootstrap-datepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.2.tgz#e156b0715b87a182e2cf3132436559e7c47f8987"
integrity sha512-8tDHiFvppm5YlIaLL0IfRd9r/YtyV4+bIp8zuIDeVW6eUvFd1ueuifCzf89vZXRf18PLR8JAiYFdBOx9+8CjZw==
"@abp/bootstrap-datepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.3.tgz#7c2e9f153d4bac45858e0d3dcfe6a382302d9c7f"
integrity sha512-kBjnpD0w2BCzEX3gw1ua+dlioAZ6xQigN4aQNpHumrDamAZ+ULhDiUTMJ8ofwlyM9nEryK9NP2+3Bm42iTSWPw==
dependencies:
bootstrap-datepicker "^1.10.0"
"@abp/bootstrap-daterangepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.2.tgz#19c2f5088ef8cf1cdc4483376f28faa2ca172f18"
integrity sha512-ygyUkiffq5Dry5yuyAzCKnlymbGZZ5f8es9d+dXLjp5lzk8K88LI4jTaIhm/Gc7wzKhFmHMpOIFYIRMzwvMmRQ==
"@abp/bootstrap-daterangepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.3.tgz#6420b359ac440d9d76b1cf47ea28f6ad345a2607"
integrity sha512-l5A2NaBDt5o5mePDoLvrWcDX1wj50o+q3OmFVm6x7lHfjOw+1iCxqv2A2GEye1TZeQ8yxCQOn+aUd7OdLUwE7Q==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.2.tgz#53dc0d68d15c60d36200d711b4f5a0acef15096b"
integrity sha512-vrUux40RDPx7hBXp2u5evRpm2LHRwHmRhmtTXx6ltQ8Aq7BwD9BvqBZEgg5GB5L9MGy5oy5Wm57t9ooQ8qmLgg==
"@abp/bootstrap@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.3.tgz#7fafbe0a6fb6cf051c63943361bcc3ee7159d506"
integrity sha512-O1Nv4cXkChcmlcDmszKGDqDZs1ofcmftkMSSGKYCpdJYEHBuGPhC8v29NDLCE3BLgoZjs8BJd3YpPh/cnJoJrA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
bootstrap "^5.3.3"
"@abp/clipboard@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.2.tgz#4e0d6456e142e552ca3b4ec10159276e096c56bf"
integrity sha512-jorX68Yw/9pWAmt8cOuVx3Cnp7VF9xuvCD/ecvL5eZyHhXt4tDcYIFO5LkF+CaIky79gdzdF3tmYeFSPUE/HzA==
"@abp/clipboard@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.3.tgz#e6fd477a9f6d6c7fb224ea018e8f23d8d303f3ed"
integrity sha512-iR9HUk1JPWHS3LQ5QmH40maCuwi6SFwxPYvqVjNLVTisHsUOGGZLvHJ46aA8Ei3Q4UlUCdISP9Kc4F88JrhRpA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
clipboard "^2.0.11"
"@abp/core@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.2.tgz#10f0a485affb15d51c319bbdf88c1bfa24b5b778"
integrity sha512-y3kkP9+PBG1xxiHDXPk+kYs1BzbAytVRg611vKhCejHntMSD3cD4vCg4NW5oNEtCktNRBYcnQICdgLElAX/koQ==
"@abp/core@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.3.tgz#f87e8de30d0e496eebc6ba4db8ffb2a33ef5b591"
integrity sha512-P/B81S+8jkcRv+QsqczWJq9pk0hQk42mg8bpCnlUif9zyUSq2wsWNwulwC5HJAauLf3UvIcOrarpK8T1X/4cVw==
dependencies:
"@abp/utils" "~9.3.2"
"@abp/utils" "~9.3.3"
"@abp/datatables.net-bs5@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.2.tgz#89a3664c2ee0e98b16a41894f04f12edcf7b7780"
integrity sha512-llju5jfVIppot59cQ4cBGJdl9VA156mDI5V+h5ZHGBmVvwG79R/mUd3D49XmqQGBke95K1Z49R7V/JxYqa6F+Q==
"@abp/datatables.net-bs5@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.3.tgz#12e4011edb151bd8ce8e38f4f83b84062087dbe6"
integrity sha512-+Dn0njWJXdr0g/gMS89njzEHvP4oScUdROZaT40CvFxssN3lIkD3+AYi4QPv+onPGKZQ6D9+K+T1yk9/mrwzDA==
dependencies:
"@abp/datatables.net" "~9.3.2"
"@abp/datatables.net" "~9.3.3"
datatables.net-bs5 "^2.1.8"
"@abp/datatables.net@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.2.tgz#ee5cd8cb286211404d50593b33ea532f1b7cb9f1"
integrity sha512-JK6XgZeP2diBOnC9jSml0kYc1uvbU09yz4GOyPmh/QZiGdS4vonRKfjIXdFd0YbxK0qAPZO+MzZuwqvZSA6nyA==
"@abp/datatables.net@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.3.tgz#ac5281b921e152ae07d73a0061856f4598d33acf"
integrity sha512-4q4gKK3W3x6xXgvj+BYuXMZjSOgU4yecbLvQZkYGvoXk2KJ8PvQUz1ay5W2mJJmX0cvYvIX7ni5uhnEFdKxmZQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
datatables.net "^2.1.8"
"@abp/font-awesome@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.2.tgz#b0659aeec243a4fe3c851a98a79673292c2687b1"
integrity sha512-7esRWpT7PFMPSVhGPKb3DGq1h5n/R2xmusurbGDGhTHckiOfna8tQerZ6A9YdRsM2kIIDisWbuSzBkoM8hqfCQ==
"@abp/font-awesome@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.3.tgz#d9727d6652f419ca0f876a02932d226fa7a39370"
integrity sha512-n8XvR9Xr2u6yH2QEQpiu2RU3Br3hNx+ItSQ0ncp81wjYhR007NbOJvjDoQJFiuzgPKZdPNDbPbiiBv9L0oIgAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@fortawesome/fontawesome-free" "^6.6.0"
"@abp/highlight.js@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-9.3.2.tgz#add22b40f5b412d6c86629a4d6d449d426c9b141"
integrity sha512-EVUCK6Hm3J+sMCuGZDTEEyWxfvAK5mxLuYGRuRrmzZvxXKsnAwqZitMddAvkZVAwN1QiV3gyXgdrz1XUBWZ2kg==
"@abp/highlight.js@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-9.3.3.tgz#fe557c7e3a8d17f3c319d6af8d90de4979f28589"
integrity sha512-sqRynOCoBZAYqqQXU3LEmSupC7HrkmRg+8I8CJJZbfduZJvETbWZyXAISLkyTOzPa9CvOOBXYjnpCkjCWqOxcg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@highlightjs/cdn-assets" "~11.10.0"
"@abp/jquery-form@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.2.tgz#17d0fe0a81d61e2e96131379e82872e5e45a2d5b"
integrity sha512-IwXWBRbtLhdB6/pJwQsWJHqLDHpZfJoA6x48A/GbTQLgWhpt0/OainDZsEUH3o0TWMhgJU+tp274uPENlG3DzQ==
"@abp/jquery-form@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.3.tgz#37d7e1c16b932e439e2127844991496b6557c094"
integrity sha512-B8uDWM13O+fB/TAN7xfMskLC0Qq8327waqpuctiulALz7uM4Ri1txANMp4+ftf25dxMeii/J4k6BSGer8K520Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.2.tgz#f13183ed7108cdea1500f18b1f80aff3037132ce"
integrity sha512-0v0Rhj3bir91cqwhlxDuD0PqwEYceyqLYf6K5eFF1/nE+1wN1VIST/oLN1Xis9x4NswbnnKai+OST0fqagpuhg==
"@abp/jquery-validation-unobtrusive@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.3.tgz#3882d15076fcf4ef6a197648c84b9edd91435235"
integrity sha512-csWL1+h/aRkU71uoxsKCuGZU9zloPdY6WB1uSBCFDTJ4aBy6gkdtAZGwsXHsJZ4AiHwL+d22P9XVSF1MhKB+MQ==
dependencies:
"@abp/jquery-validation" "~9.3.2"
"@abp/jquery-validation" "~9.3.3"
jquery-validation-unobtrusive "^4.0.0"
"@abp/jquery-validation@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.2.tgz#8ec072e2babb5d75aa1088a3754b837b7387df76"
integrity sha512-JCquJcN0FAF+8TQOYgbqeDZqPIwy2mWVDtHKCts2lVj8ol+sQgWCOhZDx11sl1oqVZjkvdOmKMgWHDztdoUojA==
"@abp/jquery-validation@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.3.tgz#daea2a288e8c440051af21ebf519f7e40b4d27d3"
integrity sha512-nU6a04fiaZuHXRnV+J++AwcyZOxEvW6i4yqm2PzFT9OCbDk1E3X5S1ntO7sGlCcppxj0pSp3uL2Jxq5d4gq+qg==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-validation "^1.21.0"
"@abp/jquery@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.2.tgz#edb3d65bdbd3885af72759ce0cd9d813ab41aade"
integrity sha512-i4scUZt6q09jhl8YTtQrPg+GV5Vd1QW57hHesYmgor8pLD87JU7cc5sCEJlmmtzVZsXjDkVuiyD2sOUXSItxMw==
"@abp/jquery@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.3.tgz#5c3ab4dfa820d9f2eb19fecc65194f0211d5bf37"
integrity sha512-5Nfw287+JugPCnm/KK8fjT4e5zHiwnL8w9OSAHVmf9UBcuJ2yBc+b8mklqy5pLt+jObouE5wJUOtENxgkgSkAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
jquery "~3.7.1"
"@abp/lodash@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.2.tgz#d3ca624dd8927d33cf8728403ef591977b9e11f4"
integrity sha512-4XOhLKa/reKB85DyHtz1obC96j2VJs9+xqlO8Pn58hXP396cMEMuC1MfjHMwhPuMVHwgffg0UCfukKKf/UGJ/w==
"@abp/lodash@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.3.tgz#a60a41088288da41fa61b09cd747f1fde3c3ec40"
integrity sha512-GsAJPMGNHZcVHQWJMCEQ7oWSeRwmHx0n2oWLQOQoyFQu1itZeJy2dFE+nSIb2jAQ7sfKZVNw7OrEqN/VqgEoUg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
lodash "^4.17.21"
"@abp/luxon@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.2.tgz#806464e828adf6b99a9620f3c39a16f8621ecd84"
integrity sha512-oP74Q9/FJ8QpB7yVOycFlfsGhPKFUk6NTnoT+cVRNg0wpUkRRjg5WTkZeKLoVxKNk9RwA/9fa6MnBiiNs2z/Pg==
"@abp/luxon@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.3.tgz#5742a90953bf0b24fa129f5a6a4c32dbdc134553"
integrity sha512-+AqTiMhN8Z8Khmv/9aBPwasNVcboJa9BV3WdJ5Nccwo2OEN7Wycw6TkRnb42fbUpzXAvxvwv9cSDHjRBib299A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
luxon "^3.5.0"
"@abp/malihu-custom-scrollbar-plugin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.2.tgz#71069a6abd8a9456f0fc6227ee17b93300ad6030"
integrity sha512-6pFO68hvtbGiGTaxkzTPnzJA2NZkzE+acWlTfBvSVyMvZM1jER5wYJmDpflZO+WPtTTu9CUflTwvYw2TiNKlUg==
"@abp/malihu-custom-scrollbar-plugin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.3.tgz#93a649bb621a47fb50b9b776fb864a07ccdff287"
integrity sha512-w83FD8mqGkhvoAEu0DwzcrmX1wwyKwVRkvfYmxjhokD7+Hq1FyuFDMO51F8hh590I2wzWCX8NvAVUP24viOY+A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.2.tgz#150548dd2b817d586f87113abb40c85f9b1ab406"
integrity sha512-TdHeqPPEPk00/5vKbGHY6D74XlzfRM2Kb4WVvykVx2gjzScp5Sfunpus/A9UCOYls/bWp1MVMT7V0ExBXYPyNg==
"@abp/moment@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.3.tgz#622c424350620e0215a0a04059dfd3e18022fd69"
integrity sha512-m/xV11aWOZKTVVyGsX2mZl9ondcP8pWSmjmUKVNLrFSul4pRNgfM2ZeaKiaOLApkyOSZDzCEMUYbEf+dM2/rcg==
dependencies:
moment "^2.30.1"
"@abp/prismjs@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.2.tgz#2ea48bfa5ebcfd98962029eebeab374d63a4e242"
integrity sha512-q8bdUjk+IuP+nWzN8phgFjvKtOHR94OT5Sth7Rp64L68pVCJopihyth8f4mLZl7hMtwrro/5GFxjpR+KRNRpbg==
"@abp/prismjs@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.3.tgz#e34972d2943403fcfe4f41ec6771405afc553904"
integrity sha512-4LUIMa2elN9wpKJB3ndZz2XrntB4kCCeKZHvqpnwTwALsVsR+K5mVjR5jrsniJu4kJ0H51M+s/EMpgT6b1LQUA==
dependencies:
"@abp/clipboard" "~9.3.2"
"@abp/core" "~9.3.2"
"@abp/clipboard" "~9.3.3"
"@abp/core" "~9.3.3"
prismjs "^1.29.0"
"@abp/select2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.2.tgz#5c069ff7a9fcb9e78bd4a8591d1e5eac6d66f03f"
integrity sha512-/N5bJjyLQnN8zPovRrmrcYhiUxG/RTI6kNaH0QW/QEsryfuX24wdDWrRXacsJ1QKlMxig++IHRnpMBrHhxAKUw==
"@abp/select2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.3.tgz#8ef9bc3d3674d515d7b7f9060d77831246d03b6a"
integrity sha512-2g8LkLBu1Ooaxj6utYne1gPMYG9888l/mEFMJU5iHOPXS0vz4lANw+VjtawapFtP6yRSiD2/qJtOt0C5rQq1yA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
select2 "^4.0.13"
"@abp/sweetalert2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.2.tgz#1ada87b720faef1289aa5fdcf42c0f5c74ff4493"
integrity sha512-PUNbt7O6reTqDelUBGryullFDD5XeZkgQFn/FXbZVp6y0owHUyIlX+Jr7PIesWEB/RHuLa+uZoSywtVPH7fsEw==
"@abp/sweetalert2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.3.tgz#b9d6075d9ede12509f27576f88d54f21598f37df"
integrity sha512-CeX5IWwxAu9M4jqNZBK6o59sVoDuFgxnffhHTMEP7pt8WzH+2uucxGe/21gXT/PW1c3EjSwP3Ri2MhtKOFZuyQ==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
sweetalert2 "^11.14.1"
"@abp/timeago@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.2.tgz#fe4d184aed92dd265e3c9531c53bdc684abb3b52"
integrity sha512-GLimaRixGtZ5oiH3JLEmeUe54gePdSfVZtyJOvGcc0wQjQVOa5JgyTqktszb+pF4QVdeJr+ijz6RZlavwIY0EA==
"@abp/timeago@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.3.tgz#b116a7112c1d53588129587d5572dc0ae55567a5"
integrity sha512-L0X0yc8oS36eDx+8jvzreW4Cr4TnWESMceXihfOfuWbuOm4R58W4Cvx2/74XFiX/0if1WEg31P4Aj3LhpjgEaQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
timeago "^1.6.7"
"@abp/utils@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.2.tgz#f2158e9858c8efcbd3f17bf6e79c41116ac66795"
integrity sha512-DtD07VHsDS5KPfn3jnL6f9WsfXEJVv7xUF+NcgW+HBTHnJTxunnE/OYGf/clTM4xeDb+RWl3AoGYP+kF4H/Snw==
"@abp/utils@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.3.tgz#e8cda12eb1f7432787072c2d5fe9905b7613e2ec"
integrity sha512-X1q9hod+Z6x/QypixI8BVvnMOqncQXM/Vs2Kq2p0jJJsNoerOFqGr+qLqZ5x3e5CoSz0H/38VjaG1yxIoq2exA==
dependencies:
just-compare "^2.3.0"

4
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json

@ -3,8 +3,8 @@
"name": "asp.net",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.2",
"@abp/prismjs": "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.3",
"@abp/prismjs": "~9.3.3"
},
"devDependencies": {}
}

268
modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock

@ -2,202 +2,202 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.2.tgz#92907ca78607515c8fd5696e00ad3b65b42881a7"
integrity sha512-wmXGPoKkbR2sCErFdAT37HxYbCbfN0IAd0CGo8aMaQkFzzenq1b9omnN6l9+xd91Q3WcjUcWhpCJLYurcdbgOA==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.2.tgz#94089c3dcac4571c5fcb9bdb754e5df28a24e966"
integrity sha512-eRSvhLimwf65KKI1P/DZgQK+l300EwX4r2S4XYL0gJjjXI9aeIDQuPEqGZs2a6P5/zfejFvefqCIcG5EfEH9ew==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.2"
"@abp/bootstrap" "~9.3.2"
"@abp/bootstrap-datepicker" "~9.3.2"
"@abp/bootstrap-daterangepicker" "~9.3.2"
"@abp/datatables.net-bs5" "~9.3.2"
"@abp/font-awesome" "~9.3.2"
"@abp/jquery-form" "~9.3.2"
"@abp/jquery-validation-unobtrusive" "~9.3.2"
"@abp/lodash" "~9.3.2"
"@abp/luxon" "~9.3.2"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.2"
"@abp/moment" "~9.3.2"
"@abp/select2" "~9.3.2"
"@abp/sweetalert2" "~9.3.2"
"@abp/timeago" "~9.3.2"
"@abp/aspnetcore.mvc.ui@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.2.tgz#5cab40d0f17eea2ae97a0d25fa238e52b5e8ef91"
integrity sha512-C73MB6abc531CmYyRctZXtKUY/0t+hhBQg5fIbzdJaR8SCSHEh2v9j2ZAhKFU0kectdrpKrLroOihOWYMfuWdQ==
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.3.tgz#71c2003dbc5ccd6d9f78740c28bb52d57452f4d7"
integrity sha512-YqFGHIw/jAQ02jU4FGUay/pQQGWAA/815YoQskFNxc4R0hlGRS6YrR+kSAzRjmMkeRn9gM/KtndLWiygv1fbEQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.3"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.3.tgz#6886575725904f7b8f08234e0057ee851a68735d"
integrity sha512-zv1BL054q3VnqZXjd4fa2E7es/Gs8HsFfp3jWljRwEOytdG1PyHo5++ChM3FlB4+mIXq1On4leST3sDVxa75Sw==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.3"
"@abp/bootstrap" "~9.3.3"
"@abp/bootstrap-datepicker" "~9.3.3"
"@abp/bootstrap-daterangepicker" "~9.3.3"
"@abp/datatables.net-bs5" "~9.3.3"
"@abp/font-awesome" "~9.3.3"
"@abp/jquery-form" "~9.3.3"
"@abp/jquery-validation-unobtrusive" "~9.3.3"
"@abp/lodash" "~9.3.3"
"@abp/luxon" "~9.3.3"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.3"
"@abp/moment" "~9.3.3"
"@abp/select2" "~9.3.3"
"@abp/sweetalert2" "~9.3.3"
"@abp/timeago" "~9.3.3"
"@abp/aspnetcore.mvc.ui@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.3.tgz#16aca3844bccb24317f65f3a419cad34f9aa6387"
integrity sha512-bp1syI3exn3YBSoDertHxF1CVmEUIRHLCPr/+K1DLuBxW6KUPnDIpnJVVhXsO7EmwwzzukJF99utPXNGgQXnIg==
dependencies:
ansi-colors "^4.1.3"
"@abp/bootstrap-datepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.2.tgz#e156b0715b87a182e2cf3132436559e7c47f8987"
integrity sha512-8tDHiFvppm5YlIaLL0IfRd9r/YtyV4+bIp8zuIDeVW6eUvFd1ueuifCzf89vZXRf18PLR8JAiYFdBOx9+8CjZw==
"@abp/bootstrap-datepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.3.tgz#7c2e9f153d4bac45858e0d3dcfe6a382302d9c7f"
integrity sha512-kBjnpD0w2BCzEX3gw1ua+dlioAZ6xQigN4aQNpHumrDamAZ+ULhDiUTMJ8ofwlyM9nEryK9NP2+3Bm42iTSWPw==
dependencies:
bootstrap-datepicker "^1.10.0"
"@abp/bootstrap-daterangepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.2.tgz#19c2f5088ef8cf1cdc4483376f28faa2ca172f18"
integrity sha512-ygyUkiffq5Dry5yuyAzCKnlymbGZZ5f8es9d+dXLjp5lzk8K88LI4jTaIhm/Gc7wzKhFmHMpOIFYIRMzwvMmRQ==
"@abp/bootstrap-daterangepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.3.tgz#6420b359ac440d9d76b1cf47ea28f6ad345a2607"
integrity sha512-l5A2NaBDt5o5mePDoLvrWcDX1wj50o+q3OmFVm6x7lHfjOw+1iCxqv2A2GEye1TZeQ8yxCQOn+aUd7OdLUwE7Q==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.2.tgz#53dc0d68d15c60d36200d711b4f5a0acef15096b"
integrity sha512-vrUux40RDPx7hBXp2u5evRpm2LHRwHmRhmtTXx6ltQ8Aq7BwD9BvqBZEgg5GB5L9MGy5oy5Wm57t9ooQ8qmLgg==
"@abp/bootstrap@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.3.tgz#7fafbe0a6fb6cf051c63943361bcc3ee7159d506"
integrity sha512-O1Nv4cXkChcmlcDmszKGDqDZs1ofcmftkMSSGKYCpdJYEHBuGPhC8v29NDLCE3BLgoZjs8BJd3YpPh/cnJoJrA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
bootstrap "^5.3.3"
"@abp/clipboard@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.2.tgz#4e0d6456e142e552ca3b4ec10159276e096c56bf"
integrity sha512-jorX68Yw/9pWAmt8cOuVx3Cnp7VF9xuvCD/ecvL5eZyHhXt4tDcYIFO5LkF+CaIky79gdzdF3tmYeFSPUE/HzA==
"@abp/clipboard@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.3.tgz#e6fd477a9f6d6c7fb224ea018e8f23d8d303f3ed"
integrity sha512-iR9HUk1JPWHS3LQ5QmH40maCuwi6SFwxPYvqVjNLVTisHsUOGGZLvHJ46aA8Ei3Q4UlUCdISP9Kc4F88JrhRpA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
clipboard "^2.0.11"
"@abp/core@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.2.tgz#10f0a485affb15d51c319bbdf88c1bfa24b5b778"
integrity sha512-y3kkP9+PBG1xxiHDXPk+kYs1BzbAytVRg611vKhCejHntMSD3cD4vCg4NW5oNEtCktNRBYcnQICdgLElAX/koQ==
"@abp/core@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.3.tgz#f87e8de30d0e496eebc6ba4db8ffb2a33ef5b591"
integrity sha512-P/B81S+8jkcRv+QsqczWJq9pk0hQk42mg8bpCnlUif9zyUSq2wsWNwulwC5HJAauLf3UvIcOrarpK8T1X/4cVw==
dependencies:
"@abp/utils" "~9.3.2"
"@abp/utils" "~9.3.3"
"@abp/datatables.net-bs5@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.2.tgz#89a3664c2ee0e98b16a41894f04f12edcf7b7780"
integrity sha512-llju5jfVIppot59cQ4cBGJdl9VA156mDI5V+h5ZHGBmVvwG79R/mUd3D49XmqQGBke95K1Z49R7V/JxYqa6F+Q==
"@abp/datatables.net-bs5@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.3.tgz#12e4011edb151bd8ce8e38f4f83b84062087dbe6"
integrity sha512-+Dn0njWJXdr0g/gMS89njzEHvP4oScUdROZaT40CvFxssN3lIkD3+AYi4QPv+onPGKZQ6D9+K+T1yk9/mrwzDA==
dependencies:
"@abp/datatables.net" "~9.3.2"
"@abp/datatables.net" "~9.3.3"
datatables.net-bs5 "^2.1.8"
"@abp/datatables.net@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.2.tgz#ee5cd8cb286211404d50593b33ea532f1b7cb9f1"
integrity sha512-JK6XgZeP2diBOnC9jSml0kYc1uvbU09yz4GOyPmh/QZiGdS4vonRKfjIXdFd0YbxK0qAPZO+MzZuwqvZSA6nyA==
"@abp/datatables.net@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.3.tgz#ac5281b921e152ae07d73a0061856f4598d33acf"
integrity sha512-4q4gKK3W3x6xXgvj+BYuXMZjSOgU4yecbLvQZkYGvoXk2KJ8PvQUz1ay5W2mJJmX0cvYvIX7ni5uhnEFdKxmZQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
datatables.net "^2.1.8"
"@abp/font-awesome@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.2.tgz#b0659aeec243a4fe3c851a98a79673292c2687b1"
integrity sha512-7esRWpT7PFMPSVhGPKb3DGq1h5n/R2xmusurbGDGhTHckiOfna8tQerZ6A9YdRsM2kIIDisWbuSzBkoM8hqfCQ==
"@abp/font-awesome@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.3.tgz#d9727d6652f419ca0f876a02932d226fa7a39370"
integrity sha512-n8XvR9Xr2u6yH2QEQpiu2RU3Br3hNx+ItSQ0ncp81wjYhR007NbOJvjDoQJFiuzgPKZdPNDbPbiiBv9L0oIgAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@fortawesome/fontawesome-free" "^6.6.0"
"@abp/jquery-form@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.2.tgz#17d0fe0a81d61e2e96131379e82872e5e45a2d5b"
integrity sha512-IwXWBRbtLhdB6/pJwQsWJHqLDHpZfJoA6x48A/GbTQLgWhpt0/OainDZsEUH3o0TWMhgJU+tp274uPENlG3DzQ==
"@abp/jquery-form@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.3.tgz#37d7e1c16b932e439e2127844991496b6557c094"
integrity sha512-B8uDWM13O+fB/TAN7xfMskLC0Qq8327waqpuctiulALz7uM4Ri1txANMp4+ftf25dxMeii/J4k6BSGer8K520Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.2.tgz#f13183ed7108cdea1500f18b1f80aff3037132ce"
integrity sha512-0v0Rhj3bir91cqwhlxDuD0PqwEYceyqLYf6K5eFF1/nE+1wN1VIST/oLN1Xis9x4NswbnnKai+OST0fqagpuhg==
"@abp/jquery-validation-unobtrusive@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.3.tgz#3882d15076fcf4ef6a197648c84b9edd91435235"
integrity sha512-csWL1+h/aRkU71uoxsKCuGZU9zloPdY6WB1uSBCFDTJ4aBy6gkdtAZGwsXHsJZ4AiHwL+d22P9XVSF1MhKB+MQ==
dependencies:
"@abp/jquery-validation" "~9.3.2"
"@abp/jquery-validation" "~9.3.3"
jquery-validation-unobtrusive "^4.0.0"
"@abp/jquery-validation@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.2.tgz#8ec072e2babb5d75aa1088a3754b837b7387df76"
integrity sha512-JCquJcN0FAF+8TQOYgbqeDZqPIwy2mWVDtHKCts2lVj8ol+sQgWCOhZDx11sl1oqVZjkvdOmKMgWHDztdoUojA==
"@abp/jquery-validation@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.3.tgz#daea2a288e8c440051af21ebf519f7e40b4d27d3"
integrity sha512-nU6a04fiaZuHXRnV+J++AwcyZOxEvW6i4yqm2PzFT9OCbDk1E3X5S1ntO7sGlCcppxj0pSp3uL2Jxq5d4gq+qg==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-validation "^1.21.0"
"@abp/jquery@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.2.tgz#edb3d65bdbd3885af72759ce0cd9d813ab41aade"
integrity sha512-i4scUZt6q09jhl8YTtQrPg+GV5Vd1QW57hHesYmgor8pLD87JU7cc5sCEJlmmtzVZsXjDkVuiyD2sOUXSItxMw==
"@abp/jquery@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.3.tgz#5c3ab4dfa820d9f2eb19fecc65194f0211d5bf37"
integrity sha512-5Nfw287+JugPCnm/KK8fjT4e5zHiwnL8w9OSAHVmf9UBcuJ2yBc+b8mklqy5pLt+jObouE5wJUOtENxgkgSkAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
jquery "~3.7.1"
"@abp/lodash@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.2.tgz#d3ca624dd8927d33cf8728403ef591977b9e11f4"
integrity sha512-4XOhLKa/reKB85DyHtz1obC96j2VJs9+xqlO8Pn58hXP396cMEMuC1MfjHMwhPuMVHwgffg0UCfukKKf/UGJ/w==
"@abp/lodash@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.3.tgz#a60a41088288da41fa61b09cd747f1fde3c3ec40"
integrity sha512-GsAJPMGNHZcVHQWJMCEQ7oWSeRwmHx0n2oWLQOQoyFQu1itZeJy2dFE+nSIb2jAQ7sfKZVNw7OrEqN/VqgEoUg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
lodash "^4.17.21"
"@abp/luxon@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.2.tgz#806464e828adf6b99a9620f3c39a16f8621ecd84"
integrity sha512-oP74Q9/FJ8QpB7yVOycFlfsGhPKFUk6NTnoT+cVRNg0wpUkRRjg5WTkZeKLoVxKNk9RwA/9fa6MnBiiNs2z/Pg==
"@abp/luxon@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.3.tgz#5742a90953bf0b24fa129f5a6a4c32dbdc134553"
integrity sha512-+AqTiMhN8Z8Khmv/9aBPwasNVcboJa9BV3WdJ5Nccwo2OEN7Wycw6TkRnb42fbUpzXAvxvwv9cSDHjRBib299A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
luxon "^3.5.0"
"@abp/malihu-custom-scrollbar-plugin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.2.tgz#71069a6abd8a9456f0fc6227ee17b93300ad6030"
integrity sha512-6pFO68hvtbGiGTaxkzTPnzJA2NZkzE+acWlTfBvSVyMvZM1jER5wYJmDpflZO+WPtTTu9CUflTwvYw2TiNKlUg==
"@abp/malihu-custom-scrollbar-plugin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.3.tgz#93a649bb621a47fb50b9b776fb864a07ccdff287"
integrity sha512-w83FD8mqGkhvoAEu0DwzcrmX1wwyKwVRkvfYmxjhokD7+Hq1FyuFDMO51F8hh590I2wzWCX8NvAVUP24viOY+A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.2.tgz#150548dd2b817d586f87113abb40c85f9b1ab406"
integrity sha512-TdHeqPPEPk00/5vKbGHY6D74XlzfRM2Kb4WVvykVx2gjzScp5Sfunpus/A9UCOYls/bWp1MVMT7V0ExBXYPyNg==
"@abp/moment@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.3.tgz#622c424350620e0215a0a04059dfd3e18022fd69"
integrity sha512-m/xV11aWOZKTVVyGsX2mZl9ondcP8pWSmjmUKVNLrFSul4pRNgfM2ZeaKiaOLApkyOSZDzCEMUYbEf+dM2/rcg==
dependencies:
moment "^2.30.1"
"@abp/prismjs@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.2.tgz#2ea48bfa5ebcfd98962029eebeab374d63a4e242"
integrity sha512-q8bdUjk+IuP+nWzN8phgFjvKtOHR94OT5Sth7Rp64L68pVCJopihyth8f4mLZl7hMtwrro/5GFxjpR+KRNRpbg==
"@abp/prismjs@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.3.tgz#e34972d2943403fcfe4f41ec6771405afc553904"
integrity sha512-4LUIMa2elN9wpKJB3ndZz2XrntB4kCCeKZHvqpnwTwALsVsR+K5mVjR5jrsniJu4kJ0H51M+s/EMpgT6b1LQUA==
dependencies:
"@abp/clipboard" "~9.3.2"
"@abp/core" "~9.3.2"
"@abp/clipboard" "~9.3.3"
"@abp/core" "~9.3.3"
prismjs "^1.29.0"
"@abp/select2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.2.tgz#5c069ff7a9fcb9e78bd4a8591d1e5eac6d66f03f"
integrity sha512-/N5bJjyLQnN8zPovRrmrcYhiUxG/RTI6kNaH0QW/QEsryfuX24wdDWrRXacsJ1QKlMxig++IHRnpMBrHhxAKUw==
"@abp/select2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.3.tgz#8ef9bc3d3674d515d7b7f9060d77831246d03b6a"
integrity sha512-2g8LkLBu1Ooaxj6utYne1gPMYG9888l/mEFMJU5iHOPXS0vz4lANw+VjtawapFtP6yRSiD2/qJtOt0C5rQq1yA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
select2 "^4.0.13"
"@abp/sweetalert2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.2.tgz#1ada87b720faef1289aa5fdcf42c0f5c74ff4493"
integrity sha512-PUNbt7O6reTqDelUBGryullFDD5XeZkgQFn/FXbZVp6y0owHUyIlX+Jr7PIesWEB/RHuLa+uZoSywtVPH7fsEw==
"@abp/sweetalert2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.3.tgz#b9d6075d9ede12509f27576f88d54f21598f37df"
integrity sha512-CeX5IWwxAu9M4jqNZBK6o59sVoDuFgxnffhHTMEP7pt8WzH+2uucxGe/21gXT/PW1c3EjSwP3Ri2MhtKOFZuyQ==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
sweetalert2 "^11.14.1"
"@abp/timeago@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.2.tgz#fe4d184aed92dd265e3c9531c53bdc684abb3b52"
integrity sha512-GLimaRixGtZ5oiH3JLEmeUe54gePdSfVZtyJOvGcc0wQjQVOa5JgyTqktszb+pF4QVdeJr+ijz6RZlavwIY0EA==
"@abp/timeago@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.3.tgz#b116a7112c1d53588129587d5572dc0ae55567a5"
integrity sha512-L0X0yc8oS36eDx+8jvzreW4Cr4TnWESMceXihfOfuWbuOm4R58W4Cvx2/74XFiX/0if1WEg31P4Aj3LhpjgEaQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
timeago "^1.6.7"
"@abp/utils@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.2.tgz#f2158e9858c8efcbd3f17bf6e79c41116ac66795"
integrity sha512-DtD07VHsDS5KPfn3jnL6f9WsfXEJVv7xUF+NcgW+HBTHnJTxunnE/OYGf/clTM4xeDb+RWl3AoGYP+kF4H/Snw==
"@abp/utils@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.3.tgz#e8cda12eb1f7432787072c2d5fe9905b7613e2ec"
integrity sha512-X1q9hod+Z6x/QypixI8BVvnMOqncQXM/Vs2Kq2p0jJJsNoerOFqGr+qLqZ5x3e5CoSz0H/38VjaG1yxIoq2exA==
dependencies:
just-compare "^2.3.0"

4
modules/blogging/app/Volo.BloggingTestApp/package.json

@ -3,7 +3,7 @@
"name": "volo.blogtestapp",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.2",
"@abp/blogging": "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.3",
"@abp/blogging": "~9.3.3"
}
}

306
modules/blogging/app/Volo.BloggingTestApp/yarn.lock

@ -2,228 +2,228 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.2.tgz#92907ca78607515c8fd5696e00ad3b65b42881a7"
integrity sha512-wmXGPoKkbR2sCErFdAT37HxYbCbfN0IAd0CGo8aMaQkFzzenq1b9omnN6l9+xd91Q3WcjUcWhpCJLYurcdbgOA==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.2.tgz#94089c3dcac4571c5fcb9bdb754e5df28a24e966"
integrity sha512-eRSvhLimwf65KKI1P/DZgQK+l300EwX4r2S4XYL0gJjjXI9aeIDQuPEqGZs2a6P5/zfejFvefqCIcG5EfEH9ew==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.2"
"@abp/bootstrap" "~9.3.2"
"@abp/bootstrap-datepicker" "~9.3.2"
"@abp/bootstrap-daterangepicker" "~9.3.2"
"@abp/datatables.net-bs5" "~9.3.2"
"@abp/font-awesome" "~9.3.2"
"@abp/jquery-form" "~9.3.2"
"@abp/jquery-validation-unobtrusive" "~9.3.2"
"@abp/lodash" "~9.3.2"
"@abp/luxon" "~9.3.2"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.2"
"@abp/moment" "~9.3.2"
"@abp/select2" "~9.3.2"
"@abp/sweetalert2" "~9.3.2"
"@abp/timeago" "~9.3.2"
"@abp/aspnetcore.mvc.ui@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.2.tgz#5cab40d0f17eea2ae97a0d25fa238e52b5e8ef91"
integrity sha512-C73MB6abc531CmYyRctZXtKUY/0t+hhBQg5fIbzdJaR8SCSHEh2v9j2ZAhKFU0kectdrpKrLroOihOWYMfuWdQ==
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.3.tgz#71c2003dbc5ccd6d9f78740c28bb52d57452f4d7"
integrity sha512-YqFGHIw/jAQ02jU4FGUay/pQQGWAA/815YoQskFNxc4R0hlGRS6YrR+kSAzRjmMkeRn9gM/KtndLWiygv1fbEQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.3"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.3.tgz#6886575725904f7b8f08234e0057ee851a68735d"
integrity sha512-zv1BL054q3VnqZXjd4fa2E7es/Gs8HsFfp3jWljRwEOytdG1PyHo5++ChM3FlB4+mIXq1On4leST3sDVxa75Sw==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.3"
"@abp/bootstrap" "~9.3.3"
"@abp/bootstrap-datepicker" "~9.3.3"
"@abp/bootstrap-daterangepicker" "~9.3.3"
"@abp/datatables.net-bs5" "~9.3.3"
"@abp/font-awesome" "~9.3.3"
"@abp/jquery-form" "~9.3.3"
"@abp/jquery-validation-unobtrusive" "~9.3.3"
"@abp/lodash" "~9.3.3"
"@abp/luxon" "~9.3.3"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.3"
"@abp/moment" "~9.3.3"
"@abp/select2" "~9.3.3"
"@abp/sweetalert2" "~9.3.3"
"@abp/timeago" "~9.3.3"
"@abp/aspnetcore.mvc.ui@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.3.tgz#16aca3844bccb24317f65f3a419cad34f9aa6387"
integrity sha512-bp1syI3exn3YBSoDertHxF1CVmEUIRHLCPr/+K1DLuBxW6KUPnDIpnJVVhXsO7EmwwzzukJF99utPXNGgQXnIg==
dependencies:
ansi-colors "^4.1.3"
"@abp/blogging@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-9.3.2.tgz#52821170874f6d33da4f579abd3323c233abb1ba"
integrity sha512-P7oMpO1o/UEthlkDgYU7uZyFClNJEa5J2EcTFkLzGoQeVbZU/PF2GfVpm8wQb1Fl2EIzpHrslSkVPYiReog/Ww==
"@abp/blogging@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-9.3.3.tgz#16a4433b52f8ec08e8b4ed1d7fef8ee072fe47f7"
integrity sha512-hND79rJkapTEr4bwlh2Bzv2SdwOKXLMHtXv2nrtsmCb/GkPvkBNX07gewvJos/rIupxal0ZKH3aNcUzllH3ccA==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.2"
"@abp/owl.carousel" "~9.3.2"
"@abp/prismjs" "~9.3.2"
"@abp/tui-editor" "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.3"
"@abp/owl.carousel" "~9.3.3"
"@abp/prismjs" "~9.3.3"
"@abp/tui-editor" "~9.3.3"
"@abp/bootstrap-datepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.2.tgz#e156b0715b87a182e2cf3132436559e7c47f8987"
integrity sha512-8tDHiFvppm5YlIaLL0IfRd9r/YtyV4+bIp8zuIDeVW6eUvFd1ueuifCzf89vZXRf18PLR8JAiYFdBOx9+8CjZw==
"@abp/bootstrap-datepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.3.tgz#7c2e9f153d4bac45858e0d3dcfe6a382302d9c7f"
integrity sha512-kBjnpD0w2BCzEX3gw1ua+dlioAZ6xQigN4aQNpHumrDamAZ+ULhDiUTMJ8ofwlyM9nEryK9NP2+3Bm42iTSWPw==
dependencies:
bootstrap-datepicker "^1.10.0"
"@abp/bootstrap-daterangepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.2.tgz#19c2f5088ef8cf1cdc4483376f28faa2ca172f18"
integrity sha512-ygyUkiffq5Dry5yuyAzCKnlymbGZZ5f8es9d+dXLjp5lzk8K88LI4jTaIhm/Gc7wzKhFmHMpOIFYIRMzwvMmRQ==
"@abp/bootstrap-daterangepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.3.tgz#6420b359ac440d9d76b1cf47ea28f6ad345a2607"
integrity sha512-l5A2NaBDt5o5mePDoLvrWcDX1wj50o+q3OmFVm6x7lHfjOw+1iCxqv2A2GEye1TZeQ8yxCQOn+aUd7OdLUwE7Q==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.2.tgz#53dc0d68d15c60d36200d711b4f5a0acef15096b"
integrity sha512-vrUux40RDPx7hBXp2u5evRpm2LHRwHmRhmtTXx6ltQ8Aq7BwD9BvqBZEgg5GB5L9MGy5oy5Wm57t9ooQ8qmLgg==
"@abp/bootstrap@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.3.tgz#7fafbe0a6fb6cf051c63943361bcc3ee7159d506"
integrity sha512-O1Nv4cXkChcmlcDmszKGDqDZs1ofcmftkMSSGKYCpdJYEHBuGPhC8v29NDLCE3BLgoZjs8BJd3YpPh/cnJoJrA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
bootstrap "^5.3.3"
"@abp/clipboard@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.2.tgz#4e0d6456e142e552ca3b4ec10159276e096c56bf"
integrity sha512-jorX68Yw/9pWAmt8cOuVx3Cnp7VF9xuvCD/ecvL5eZyHhXt4tDcYIFO5LkF+CaIky79gdzdF3tmYeFSPUE/HzA==
"@abp/clipboard@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.3.tgz#e6fd477a9f6d6c7fb224ea018e8f23d8d303f3ed"
integrity sha512-iR9HUk1JPWHS3LQ5QmH40maCuwi6SFwxPYvqVjNLVTisHsUOGGZLvHJ46aA8Ei3Q4UlUCdISP9Kc4F88JrhRpA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
clipboard "^2.0.11"
"@abp/core@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.2.tgz#10f0a485affb15d51c319bbdf88c1bfa24b5b778"
integrity sha512-y3kkP9+PBG1xxiHDXPk+kYs1BzbAytVRg611vKhCejHntMSD3cD4vCg4NW5oNEtCktNRBYcnQICdgLElAX/koQ==
"@abp/core@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.3.tgz#f87e8de30d0e496eebc6ba4db8ffb2a33ef5b591"
integrity sha512-P/B81S+8jkcRv+QsqczWJq9pk0hQk42mg8bpCnlUif9zyUSq2wsWNwulwC5HJAauLf3UvIcOrarpK8T1X/4cVw==
dependencies:
"@abp/utils" "~9.3.2"
"@abp/utils" "~9.3.3"
"@abp/datatables.net-bs5@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.2.tgz#89a3664c2ee0e98b16a41894f04f12edcf7b7780"
integrity sha512-llju5jfVIppot59cQ4cBGJdl9VA156mDI5V+h5ZHGBmVvwG79R/mUd3D49XmqQGBke95K1Z49R7V/JxYqa6F+Q==
"@abp/datatables.net-bs5@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.3.tgz#12e4011edb151bd8ce8e38f4f83b84062087dbe6"
integrity sha512-+Dn0njWJXdr0g/gMS89njzEHvP4oScUdROZaT40CvFxssN3lIkD3+AYi4QPv+onPGKZQ6D9+K+T1yk9/mrwzDA==
dependencies:
"@abp/datatables.net" "~9.3.2"
"@abp/datatables.net" "~9.3.3"
datatables.net-bs5 "^2.1.8"
"@abp/datatables.net@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.2.tgz#ee5cd8cb286211404d50593b33ea532f1b7cb9f1"
integrity sha512-JK6XgZeP2diBOnC9jSml0kYc1uvbU09yz4GOyPmh/QZiGdS4vonRKfjIXdFd0YbxK0qAPZO+MzZuwqvZSA6nyA==
"@abp/datatables.net@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.3.tgz#ac5281b921e152ae07d73a0061856f4598d33acf"
integrity sha512-4q4gKK3W3x6xXgvj+BYuXMZjSOgU4yecbLvQZkYGvoXk2KJ8PvQUz1ay5W2mJJmX0cvYvIX7ni5uhnEFdKxmZQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
datatables.net "^2.1.8"
"@abp/font-awesome@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.2.tgz#b0659aeec243a4fe3c851a98a79673292c2687b1"
integrity sha512-7esRWpT7PFMPSVhGPKb3DGq1h5n/R2xmusurbGDGhTHckiOfna8tQerZ6A9YdRsM2kIIDisWbuSzBkoM8hqfCQ==
"@abp/font-awesome@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.3.tgz#d9727d6652f419ca0f876a02932d226fa7a39370"
integrity sha512-n8XvR9Xr2u6yH2QEQpiu2RU3Br3hNx+ItSQ0ncp81wjYhR007NbOJvjDoQJFiuzgPKZdPNDbPbiiBv9L0oIgAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@fortawesome/fontawesome-free" "^6.6.0"
"@abp/jquery-form@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.2.tgz#17d0fe0a81d61e2e96131379e82872e5e45a2d5b"
integrity sha512-IwXWBRbtLhdB6/pJwQsWJHqLDHpZfJoA6x48A/GbTQLgWhpt0/OainDZsEUH3o0TWMhgJU+tp274uPENlG3DzQ==
"@abp/jquery-form@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.3.tgz#37d7e1c16b932e439e2127844991496b6557c094"
integrity sha512-B8uDWM13O+fB/TAN7xfMskLC0Qq8327waqpuctiulALz7uM4Ri1txANMp4+ftf25dxMeii/J4k6BSGer8K520Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.2.tgz#f13183ed7108cdea1500f18b1f80aff3037132ce"
integrity sha512-0v0Rhj3bir91cqwhlxDuD0PqwEYceyqLYf6K5eFF1/nE+1wN1VIST/oLN1Xis9x4NswbnnKai+OST0fqagpuhg==
"@abp/jquery-validation-unobtrusive@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.3.tgz#3882d15076fcf4ef6a197648c84b9edd91435235"
integrity sha512-csWL1+h/aRkU71uoxsKCuGZU9zloPdY6WB1uSBCFDTJ4aBy6gkdtAZGwsXHsJZ4AiHwL+d22P9XVSF1MhKB+MQ==
dependencies:
"@abp/jquery-validation" "~9.3.2"
"@abp/jquery-validation" "~9.3.3"
jquery-validation-unobtrusive "^4.0.0"
"@abp/jquery-validation@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.2.tgz#8ec072e2babb5d75aa1088a3754b837b7387df76"
integrity sha512-JCquJcN0FAF+8TQOYgbqeDZqPIwy2mWVDtHKCts2lVj8ol+sQgWCOhZDx11sl1oqVZjkvdOmKMgWHDztdoUojA==
"@abp/jquery-validation@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.3.tgz#daea2a288e8c440051af21ebf519f7e40b4d27d3"
integrity sha512-nU6a04fiaZuHXRnV+J++AwcyZOxEvW6i4yqm2PzFT9OCbDk1E3X5S1ntO7sGlCcppxj0pSp3uL2Jxq5d4gq+qg==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-validation "^1.21.0"
"@abp/jquery@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.2.tgz#edb3d65bdbd3885af72759ce0cd9d813ab41aade"
integrity sha512-i4scUZt6q09jhl8YTtQrPg+GV5Vd1QW57hHesYmgor8pLD87JU7cc5sCEJlmmtzVZsXjDkVuiyD2sOUXSItxMw==
"@abp/jquery@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.3.tgz#5c3ab4dfa820d9f2eb19fecc65194f0211d5bf37"
integrity sha512-5Nfw287+JugPCnm/KK8fjT4e5zHiwnL8w9OSAHVmf9UBcuJ2yBc+b8mklqy5pLt+jObouE5wJUOtENxgkgSkAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
jquery "~3.7.1"
"@abp/lodash@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.2.tgz#d3ca624dd8927d33cf8728403ef591977b9e11f4"
integrity sha512-4XOhLKa/reKB85DyHtz1obC96j2VJs9+xqlO8Pn58hXP396cMEMuC1MfjHMwhPuMVHwgffg0UCfukKKf/UGJ/w==
"@abp/lodash@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.3.tgz#a60a41088288da41fa61b09cd747f1fde3c3ec40"
integrity sha512-GsAJPMGNHZcVHQWJMCEQ7oWSeRwmHx0n2oWLQOQoyFQu1itZeJy2dFE+nSIb2jAQ7sfKZVNw7OrEqN/VqgEoUg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
lodash "^4.17.21"
"@abp/luxon@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.2.tgz#806464e828adf6b99a9620f3c39a16f8621ecd84"
integrity sha512-oP74Q9/FJ8QpB7yVOycFlfsGhPKFUk6NTnoT+cVRNg0wpUkRRjg5WTkZeKLoVxKNk9RwA/9fa6MnBiiNs2z/Pg==
"@abp/luxon@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.3.tgz#5742a90953bf0b24fa129f5a6a4c32dbdc134553"
integrity sha512-+AqTiMhN8Z8Khmv/9aBPwasNVcboJa9BV3WdJ5Nccwo2OEN7Wycw6TkRnb42fbUpzXAvxvwv9cSDHjRBib299A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
luxon "^3.5.0"
"@abp/malihu-custom-scrollbar-plugin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.2.tgz#71069a6abd8a9456f0fc6227ee17b93300ad6030"
integrity sha512-6pFO68hvtbGiGTaxkzTPnzJA2NZkzE+acWlTfBvSVyMvZM1jER5wYJmDpflZO+WPtTTu9CUflTwvYw2TiNKlUg==
"@abp/malihu-custom-scrollbar-plugin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.3.tgz#93a649bb621a47fb50b9b776fb864a07ccdff287"
integrity sha512-w83FD8mqGkhvoAEu0DwzcrmX1wwyKwVRkvfYmxjhokD7+Hq1FyuFDMO51F8hh590I2wzWCX8NvAVUP24viOY+A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.2.tgz#150548dd2b817d586f87113abb40c85f9b1ab406"
integrity sha512-TdHeqPPEPk00/5vKbGHY6D74XlzfRM2Kb4WVvykVx2gjzScp5Sfunpus/A9UCOYls/bWp1MVMT7V0ExBXYPyNg==
"@abp/moment@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.3.tgz#622c424350620e0215a0a04059dfd3e18022fd69"
integrity sha512-m/xV11aWOZKTVVyGsX2mZl9ondcP8pWSmjmUKVNLrFSul4pRNgfM2ZeaKiaOLApkyOSZDzCEMUYbEf+dM2/rcg==
dependencies:
moment "^2.30.1"
"@abp/owl.carousel@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-9.3.2.tgz#79fbb5bb2dd8d18a7519b0cd7a8cd4e28814907b"
integrity sha512-ETDndGFbyTGWLWiuFChJP6T3rniJgka2hfK3uatg5YmneY9Oqz0X1mwXHHWgD4mBSAB2nCi+PnhSU5Oi3Fj4kQ==
"@abp/owl.carousel@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-9.3.3.tgz#fc94b12ff3c1df59a770a7a4519b9d765a1861ab"
integrity sha512-ZJnWMu9PPAgwMOxtrcE8PcMXOlhVcwfcBF1soIOCcY3eC3lGQ7t8voZr7Iu+WKC1CWeD0qxqHrlqXw+nHbc7Dw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
owl.carousel "^2.3.4"
"@abp/prismjs@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.2.tgz#2ea48bfa5ebcfd98962029eebeab374d63a4e242"
integrity sha512-q8bdUjk+IuP+nWzN8phgFjvKtOHR94OT5Sth7Rp64L68pVCJopihyth8f4mLZl7hMtwrro/5GFxjpR+KRNRpbg==
"@abp/prismjs@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.3.tgz#e34972d2943403fcfe4f41ec6771405afc553904"
integrity sha512-4LUIMa2elN9wpKJB3ndZz2XrntB4kCCeKZHvqpnwTwALsVsR+K5mVjR5jrsniJu4kJ0H51M+s/EMpgT6b1LQUA==
dependencies:
"@abp/clipboard" "~9.3.2"
"@abp/core" "~9.3.2"
"@abp/clipboard" "~9.3.3"
"@abp/core" "~9.3.3"
prismjs "^1.29.0"
"@abp/select2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.2.tgz#5c069ff7a9fcb9e78bd4a8591d1e5eac6d66f03f"
integrity sha512-/N5bJjyLQnN8zPovRrmrcYhiUxG/RTI6kNaH0QW/QEsryfuX24wdDWrRXacsJ1QKlMxig++IHRnpMBrHhxAKUw==
"@abp/select2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.3.tgz#8ef9bc3d3674d515d7b7f9060d77831246d03b6a"
integrity sha512-2g8LkLBu1Ooaxj6utYne1gPMYG9888l/mEFMJU5iHOPXS0vz4lANw+VjtawapFtP6yRSiD2/qJtOt0C5rQq1yA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
select2 "^4.0.13"
"@abp/sweetalert2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.2.tgz#1ada87b720faef1289aa5fdcf42c0f5c74ff4493"
integrity sha512-PUNbt7O6reTqDelUBGryullFDD5XeZkgQFn/FXbZVp6y0owHUyIlX+Jr7PIesWEB/RHuLa+uZoSywtVPH7fsEw==
"@abp/sweetalert2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.3.tgz#b9d6075d9ede12509f27576f88d54f21598f37df"
integrity sha512-CeX5IWwxAu9M4jqNZBK6o59sVoDuFgxnffhHTMEP7pt8WzH+2uucxGe/21gXT/PW1c3EjSwP3Ri2MhtKOFZuyQ==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
sweetalert2 "^11.14.1"
"@abp/timeago@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.2.tgz#fe4d184aed92dd265e3c9531c53bdc684abb3b52"
integrity sha512-GLimaRixGtZ5oiH3JLEmeUe54gePdSfVZtyJOvGcc0wQjQVOa5JgyTqktszb+pF4QVdeJr+ijz6RZlavwIY0EA==
"@abp/timeago@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.3.tgz#b116a7112c1d53588129587d5572dc0ae55567a5"
integrity sha512-L0X0yc8oS36eDx+8jvzreW4Cr4TnWESMceXihfOfuWbuOm4R58W4Cvx2/74XFiX/0if1WEg31P4Aj3LhpjgEaQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
timeago "^1.6.7"
"@abp/tui-editor@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-9.3.2.tgz#7d18d8cf1d6dae3c5072c403dcc85af5ab9792ba"
integrity sha512-JnYCrr4UIZskB4zwNywdk76cXKUzMCXW5v4ec4ClbHC59FTKv34iIRonl1kYC/NkjDTGO8gvmyYG/3UeXrRWmQ==
"@abp/tui-editor@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-9.3.3.tgz#0a4651bb4babc625f4598ebddcb4049eedcff4cc"
integrity sha512-9iHqRRFS6EVqrKwZ75yVW2nkTkZxF5BcVOYnIMTApwrxsRTqzQ95tikt0UNUZ4qgmsgDy4LeOnJAVk1K6MsiQA==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/prismjs" "~9.3.2"
"@abp/jquery" "~9.3.3"
"@abp/prismjs" "~9.3.3"
"@abp/utils@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.2.tgz#f2158e9858c8efcbd3f17bf6e79c41116ac66795"
integrity sha512-DtD07VHsDS5KPfn3jnL6f9WsfXEJVv7xUF+NcgW+HBTHnJTxunnE/OYGf/clTM4xeDb+RWl3AoGYP+kF4H/Snw==
"@abp/utils@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.3.tgz#e8cda12eb1f7432787072c2d5fe9905b7613e2ec"
integrity sha512-X1q9hod+Z6x/QypixI8BVvnMOqncQXM/Vs2Kq2p0jJJsNoerOFqGr+qLqZ5x3e5CoSz0H/38VjaG1yxIoq2exA==
dependencies:
just-compare "^2.3.0"

2
modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json

@ -3,6 +3,6 @@
"name": "client-simulation-web",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.3"
}
}

240
modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock

@ -2,185 +2,185 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.2.tgz#92907ca78607515c8fd5696e00ad3b65b42881a7"
integrity sha512-wmXGPoKkbR2sCErFdAT37HxYbCbfN0IAd0CGo8aMaQkFzzenq1b9omnN6l9+xd91Q3WcjUcWhpCJLYurcdbgOA==
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.3.tgz#71c2003dbc5ccd6d9f78740c28bb52d57452f4d7"
integrity sha512-YqFGHIw/jAQ02jU4FGUay/pQQGWAA/815YoQskFNxc4R0hlGRS6YrR+kSAzRjmMkeRn9gM/KtndLWiygv1fbEQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.3"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.2.tgz#94089c3dcac4571c5fcb9bdb754e5df28a24e966"
integrity sha512-eRSvhLimwf65KKI1P/DZgQK+l300EwX4r2S4XYL0gJjjXI9aeIDQuPEqGZs2a6P5/zfejFvefqCIcG5EfEH9ew==
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.3.tgz#6886575725904f7b8f08234e0057ee851a68735d"
integrity sha512-zv1BL054q3VnqZXjd4fa2E7es/Gs8HsFfp3jWljRwEOytdG1PyHo5++ChM3FlB4+mIXq1On4leST3sDVxa75Sw==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.2"
"@abp/bootstrap" "~9.3.2"
"@abp/bootstrap-datepicker" "~9.3.2"
"@abp/bootstrap-daterangepicker" "~9.3.2"
"@abp/datatables.net-bs5" "~9.3.2"
"@abp/font-awesome" "~9.3.2"
"@abp/jquery-form" "~9.3.2"
"@abp/jquery-validation-unobtrusive" "~9.3.2"
"@abp/lodash" "~9.3.2"
"@abp/luxon" "~9.3.2"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.2"
"@abp/moment" "~9.3.2"
"@abp/select2" "~9.3.2"
"@abp/sweetalert2" "~9.3.2"
"@abp/timeago" "~9.3.2"
"@abp/aspnetcore.mvc.ui@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.2.tgz#5cab40d0f17eea2ae97a0d25fa238e52b5e8ef91"
integrity sha512-C73MB6abc531CmYyRctZXtKUY/0t+hhBQg5fIbzdJaR8SCSHEh2v9j2ZAhKFU0kectdrpKrLroOihOWYMfuWdQ==
"@abp/aspnetcore.mvc.ui" "~9.3.3"
"@abp/bootstrap" "~9.3.3"
"@abp/bootstrap-datepicker" "~9.3.3"
"@abp/bootstrap-daterangepicker" "~9.3.3"
"@abp/datatables.net-bs5" "~9.3.3"
"@abp/font-awesome" "~9.3.3"
"@abp/jquery-form" "~9.3.3"
"@abp/jquery-validation-unobtrusive" "~9.3.3"
"@abp/lodash" "~9.3.3"
"@abp/luxon" "~9.3.3"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.3"
"@abp/moment" "~9.3.3"
"@abp/select2" "~9.3.3"
"@abp/sweetalert2" "~9.3.3"
"@abp/timeago" "~9.3.3"
"@abp/aspnetcore.mvc.ui@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.3.tgz#16aca3844bccb24317f65f3a419cad34f9aa6387"
integrity sha512-bp1syI3exn3YBSoDertHxF1CVmEUIRHLCPr/+K1DLuBxW6KUPnDIpnJVVhXsO7EmwwzzukJF99utPXNGgQXnIg==
dependencies:
ansi-colors "^4.1.3"
"@abp/bootstrap-datepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.2.tgz#e156b0715b87a182e2cf3132436559e7c47f8987"
integrity sha512-8tDHiFvppm5YlIaLL0IfRd9r/YtyV4+bIp8zuIDeVW6eUvFd1ueuifCzf89vZXRf18PLR8JAiYFdBOx9+8CjZw==
"@abp/bootstrap-datepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.3.tgz#7c2e9f153d4bac45858e0d3dcfe6a382302d9c7f"
integrity sha512-kBjnpD0w2BCzEX3gw1ua+dlioAZ6xQigN4aQNpHumrDamAZ+ULhDiUTMJ8ofwlyM9nEryK9NP2+3Bm42iTSWPw==
dependencies:
bootstrap-datepicker "^1.10.0"
"@abp/bootstrap-daterangepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.2.tgz#19c2f5088ef8cf1cdc4483376f28faa2ca172f18"
integrity sha512-ygyUkiffq5Dry5yuyAzCKnlymbGZZ5f8es9d+dXLjp5lzk8K88LI4jTaIhm/Gc7wzKhFmHMpOIFYIRMzwvMmRQ==
"@abp/bootstrap-daterangepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.3.tgz#6420b359ac440d9d76b1cf47ea28f6ad345a2607"
integrity sha512-l5A2NaBDt5o5mePDoLvrWcDX1wj50o+q3OmFVm6x7lHfjOw+1iCxqv2A2GEye1TZeQ8yxCQOn+aUd7OdLUwE7Q==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.2.tgz#53dc0d68d15c60d36200d711b4f5a0acef15096b"
integrity sha512-vrUux40RDPx7hBXp2u5evRpm2LHRwHmRhmtTXx6ltQ8Aq7BwD9BvqBZEgg5GB5L9MGy5oy5Wm57t9ooQ8qmLgg==
"@abp/bootstrap@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.3.tgz#7fafbe0a6fb6cf051c63943361bcc3ee7159d506"
integrity sha512-O1Nv4cXkChcmlcDmszKGDqDZs1ofcmftkMSSGKYCpdJYEHBuGPhC8v29NDLCE3BLgoZjs8BJd3YpPh/cnJoJrA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
bootstrap "^5.3.3"
"@abp/core@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.2.tgz#10f0a485affb15d51c319bbdf88c1bfa24b5b778"
integrity sha512-y3kkP9+PBG1xxiHDXPk+kYs1BzbAytVRg611vKhCejHntMSD3cD4vCg4NW5oNEtCktNRBYcnQICdgLElAX/koQ==
"@abp/core@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.3.tgz#f87e8de30d0e496eebc6ba4db8ffb2a33ef5b591"
integrity sha512-P/B81S+8jkcRv+QsqczWJq9pk0hQk42mg8bpCnlUif9zyUSq2wsWNwulwC5HJAauLf3UvIcOrarpK8T1X/4cVw==
dependencies:
"@abp/utils" "~9.3.2"
"@abp/utils" "~9.3.3"
"@abp/datatables.net-bs5@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.2.tgz#89a3664c2ee0e98b16a41894f04f12edcf7b7780"
integrity sha512-llju5jfVIppot59cQ4cBGJdl9VA156mDI5V+h5ZHGBmVvwG79R/mUd3D49XmqQGBke95K1Z49R7V/JxYqa6F+Q==
"@abp/datatables.net-bs5@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.3.tgz#12e4011edb151bd8ce8e38f4f83b84062087dbe6"
integrity sha512-+Dn0njWJXdr0g/gMS89njzEHvP4oScUdROZaT40CvFxssN3lIkD3+AYi4QPv+onPGKZQ6D9+K+T1yk9/mrwzDA==
dependencies:
"@abp/datatables.net" "~9.3.2"
"@abp/datatables.net" "~9.3.3"
datatables.net-bs5 "^2.1.8"
"@abp/datatables.net@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.2.tgz#ee5cd8cb286211404d50593b33ea532f1b7cb9f1"
integrity sha512-JK6XgZeP2diBOnC9jSml0kYc1uvbU09yz4GOyPmh/QZiGdS4vonRKfjIXdFd0YbxK0qAPZO+MzZuwqvZSA6nyA==
"@abp/datatables.net@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.3.tgz#ac5281b921e152ae07d73a0061856f4598d33acf"
integrity sha512-4q4gKK3W3x6xXgvj+BYuXMZjSOgU4yecbLvQZkYGvoXk2KJ8PvQUz1ay5W2mJJmX0cvYvIX7ni5uhnEFdKxmZQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
datatables.net "^2.1.8"
"@abp/font-awesome@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.2.tgz#b0659aeec243a4fe3c851a98a79673292c2687b1"
integrity sha512-7esRWpT7PFMPSVhGPKb3DGq1h5n/R2xmusurbGDGhTHckiOfna8tQerZ6A9YdRsM2kIIDisWbuSzBkoM8hqfCQ==
"@abp/font-awesome@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.3.tgz#d9727d6652f419ca0f876a02932d226fa7a39370"
integrity sha512-n8XvR9Xr2u6yH2QEQpiu2RU3Br3hNx+ItSQ0ncp81wjYhR007NbOJvjDoQJFiuzgPKZdPNDbPbiiBv9L0oIgAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@fortawesome/fontawesome-free" "^6.6.0"
"@abp/jquery-form@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.2.tgz#17d0fe0a81d61e2e96131379e82872e5e45a2d5b"
integrity sha512-IwXWBRbtLhdB6/pJwQsWJHqLDHpZfJoA6x48A/GbTQLgWhpt0/OainDZsEUH3o0TWMhgJU+tp274uPENlG3DzQ==
"@abp/jquery-form@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.3.tgz#37d7e1c16b932e439e2127844991496b6557c094"
integrity sha512-B8uDWM13O+fB/TAN7xfMskLC0Qq8327waqpuctiulALz7uM4Ri1txANMp4+ftf25dxMeii/J4k6BSGer8K520Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.2.tgz#f13183ed7108cdea1500f18b1f80aff3037132ce"
integrity sha512-0v0Rhj3bir91cqwhlxDuD0PqwEYceyqLYf6K5eFF1/nE+1wN1VIST/oLN1Xis9x4NswbnnKai+OST0fqagpuhg==
"@abp/jquery-validation-unobtrusive@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.3.tgz#3882d15076fcf4ef6a197648c84b9edd91435235"
integrity sha512-csWL1+h/aRkU71uoxsKCuGZU9zloPdY6WB1uSBCFDTJ4aBy6gkdtAZGwsXHsJZ4AiHwL+d22P9XVSF1MhKB+MQ==
dependencies:
"@abp/jquery-validation" "~9.3.2"
"@abp/jquery-validation" "~9.3.3"
jquery-validation-unobtrusive "^4.0.0"
"@abp/jquery-validation@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.2.tgz#8ec072e2babb5d75aa1088a3754b837b7387df76"
integrity sha512-JCquJcN0FAF+8TQOYgbqeDZqPIwy2mWVDtHKCts2lVj8ol+sQgWCOhZDx11sl1oqVZjkvdOmKMgWHDztdoUojA==
"@abp/jquery-validation@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.3.tgz#daea2a288e8c440051af21ebf519f7e40b4d27d3"
integrity sha512-nU6a04fiaZuHXRnV+J++AwcyZOxEvW6i4yqm2PzFT9OCbDk1E3X5S1ntO7sGlCcppxj0pSp3uL2Jxq5d4gq+qg==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-validation "^1.21.0"
"@abp/jquery@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.2.tgz#edb3d65bdbd3885af72759ce0cd9d813ab41aade"
integrity sha512-i4scUZt6q09jhl8YTtQrPg+GV5Vd1QW57hHesYmgor8pLD87JU7cc5sCEJlmmtzVZsXjDkVuiyD2sOUXSItxMw==
"@abp/jquery@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.3.tgz#5c3ab4dfa820d9f2eb19fecc65194f0211d5bf37"
integrity sha512-5Nfw287+JugPCnm/KK8fjT4e5zHiwnL8w9OSAHVmf9UBcuJ2yBc+b8mklqy5pLt+jObouE5wJUOtENxgkgSkAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
jquery "~3.7.1"
"@abp/lodash@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.2.tgz#d3ca624dd8927d33cf8728403ef591977b9e11f4"
integrity sha512-4XOhLKa/reKB85DyHtz1obC96j2VJs9+xqlO8Pn58hXP396cMEMuC1MfjHMwhPuMVHwgffg0UCfukKKf/UGJ/w==
"@abp/lodash@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.3.tgz#a60a41088288da41fa61b09cd747f1fde3c3ec40"
integrity sha512-GsAJPMGNHZcVHQWJMCEQ7oWSeRwmHx0n2oWLQOQoyFQu1itZeJy2dFE+nSIb2jAQ7sfKZVNw7OrEqN/VqgEoUg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
lodash "^4.17.21"
"@abp/luxon@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.2.tgz#806464e828adf6b99a9620f3c39a16f8621ecd84"
integrity sha512-oP74Q9/FJ8QpB7yVOycFlfsGhPKFUk6NTnoT+cVRNg0wpUkRRjg5WTkZeKLoVxKNk9RwA/9fa6MnBiiNs2z/Pg==
"@abp/luxon@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.3.tgz#5742a90953bf0b24fa129f5a6a4c32dbdc134553"
integrity sha512-+AqTiMhN8Z8Khmv/9aBPwasNVcboJa9BV3WdJ5Nccwo2OEN7Wycw6TkRnb42fbUpzXAvxvwv9cSDHjRBib299A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
luxon "^3.5.0"
"@abp/malihu-custom-scrollbar-plugin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.2.tgz#71069a6abd8a9456f0fc6227ee17b93300ad6030"
integrity sha512-6pFO68hvtbGiGTaxkzTPnzJA2NZkzE+acWlTfBvSVyMvZM1jER5wYJmDpflZO+WPtTTu9CUflTwvYw2TiNKlUg==
"@abp/malihu-custom-scrollbar-plugin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.3.tgz#93a649bb621a47fb50b9b776fb864a07ccdff287"
integrity sha512-w83FD8mqGkhvoAEu0DwzcrmX1wwyKwVRkvfYmxjhokD7+Hq1FyuFDMO51F8hh590I2wzWCX8NvAVUP24viOY+A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.2.tgz#150548dd2b817d586f87113abb40c85f9b1ab406"
integrity sha512-TdHeqPPEPk00/5vKbGHY6D74XlzfRM2Kb4WVvykVx2gjzScp5Sfunpus/A9UCOYls/bWp1MVMT7V0ExBXYPyNg==
"@abp/moment@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.3.tgz#622c424350620e0215a0a04059dfd3e18022fd69"
integrity sha512-m/xV11aWOZKTVVyGsX2mZl9ondcP8pWSmjmUKVNLrFSul4pRNgfM2ZeaKiaOLApkyOSZDzCEMUYbEf+dM2/rcg==
dependencies:
moment "^2.30.1"
"@abp/select2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.2.tgz#5c069ff7a9fcb9e78bd4a8591d1e5eac6d66f03f"
integrity sha512-/N5bJjyLQnN8zPovRrmrcYhiUxG/RTI6kNaH0QW/QEsryfuX24wdDWrRXacsJ1QKlMxig++IHRnpMBrHhxAKUw==
"@abp/select2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.3.tgz#8ef9bc3d3674d515d7b7f9060d77831246d03b6a"
integrity sha512-2g8LkLBu1Ooaxj6utYne1gPMYG9888l/mEFMJU5iHOPXS0vz4lANw+VjtawapFtP6yRSiD2/qJtOt0C5rQq1yA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
select2 "^4.0.13"
"@abp/sweetalert2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.2.tgz#1ada87b720faef1289aa5fdcf42c0f5c74ff4493"
integrity sha512-PUNbt7O6reTqDelUBGryullFDD5XeZkgQFn/FXbZVp6y0owHUyIlX+Jr7PIesWEB/RHuLa+uZoSywtVPH7fsEw==
"@abp/sweetalert2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.3.tgz#b9d6075d9ede12509f27576f88d54f21598f37df"
integrity sha512-CeX5IWwxAu9M4jqNZBK6o59sVoDuFgxnffhHTMEP7pt8WzH+2uucxGe/21gXT/PW1c3EjSwP3Ri2MhtKOFZuyQ==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
sweetalert2 "^11.14.1"
"@abp/timeago@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.2.tgz#fe4d184aed92dd265e3c9531c53bdc684abb3b52"
integrity sha512-GLimaRixGtZ5oiH3JLEmeUe54gePdSfVZtyJOvGcc0wQjQVOa5JgyTqktszb+pF4QVdeJr+ijz6RZlavwIY0EA==
"@abp/timeago@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.3.tgz#b116a7112c1d53588129587d5572dc0ae55567a5"
integrity sha512-L0X0yc8oS36eDx+8jvzreW4Cr4TnWESMceXihfOfuWbuOm4R58W4Cvx2/74XFiX/0if1WEg31P4Aj3LhpjgEaQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
timeago "^1.6.7"
"@abp/utils@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.2.tgz#f2158e9858c8efcbd3f17bf6e79c41116ac66795"
integrity sha512-DtD07VHsDS5KPfn3jnL6f9WsfXEJVv7xUF+NcgW+HBTHnJTxunnE/OYGf/clTM4xeDb+RWl3AoGYP+kF4H/Snw==
"@abp/utils@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.3.tgz#e8cda12eb1f7432787072c2d5fe9905b7613e2ec"
integrity sha512-X1q9hod+Z6x/QypixI8BVvnMOqncQXM/Vs2Kq2p0jJJsNoerOFqGr+qLqZ5x3e5CoSz0H/38VjaG1yxIoq2exA==
dependencies:
just-compare "^2.3.0"

10
modules/cms-kit/angular/package.json

@ -15,11 +15,11 @@
},
"private": true,
"dependencies": {
"@abp/ng.account": "~9.3.2",
"@abp/ng.identity": "~9.3.2",
"@abp/ng.setting-management": "~9.3.2",
"@abp/ng.tenant-management": "~9.3.2",
"@abp/ng.theme.basic": "~9.3.2",
"@abp/ng.account": "~9.3.3",
"@abp/ng.identity": "~9.3.3",
"@abp/ng.setting-management": "~9.3.3",
"@abp/ng.tenant-management": "~9.3.3",
"@abp/ng.theme.basic": "~9.3.3",
"@angular/animations": "~10.0.0",
"@angular/common": "~10.0.0",
"@angular/compiler": "~10.0.0",

4
modules/cms-kit/angular/projects/cms-kit/package.json

@ -4,8 +4,8 @@
"peerDependencies": {
"@angular/common": "^9.1.11",
"@angular/core": "^9.1.11",
"@abp/ng.core": ">=9.3.2",
"@abp/ng.theme.shared": ">=9.3.2"
"@abp/ng.core": ">=9.3.3",
"@abp/ng.theme.shared": ">=9.3.3"
},
"dependencies": {
"tslib": "^2.0.0"

2
modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json

@ -3,6 +3,6 @@
"name": "my-app-identityserver",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.3"
}
}

240
modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock

@ -2,185 +2,185 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.2.tgz#92907ca78607515c8fd5696e00ad3b65b42881a7"
integrity sha512-wmXGPoKkbR2sCErFdAT37HxYbCbfN0IAd0CGo8aMaQkFzzenq1b9omnN6l9+xd91Q3WcjUcWhpCJLYurcdbgOA==
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.3.tgz#71c2003dbc5ccd6d9f78740c28bb52d57452f4d7"
integrity sha512-YqFGHIw/jAQ02jU4FGUay/pQQGWAA/815YoQskFNxc4R0hlGRS6YrR+kSAzRjmMkeRn9gM/KtndLWiygv1fbEQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.3"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.2.tgz#94089c3dcac4571c5fcb9bdb754e5df28a24e966"
integrity sha512-eRSvhLimwf65KKI1P/DZgQK+l300EwX4r2S4XYL0gJjjXI9aeIDQuPEqGZs2a6P5/zfejFvefqCIcG5EfEH9ew==
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.3.tgz#6886575725904f7b8f08234e0057ee851a68735d"
integrity sha512-zv1BL054q3VnqZXjd4fa2E7es/Gs8HsFfp3jWljRwEOytdG1PyHo5++ChM3FlB4+mIXq1On4leST3sDVxa75Sw==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.2"
"@abp/bootstrap" "~9.3.2"
"@abp/bootstrap-datepicker" "~9.3.2"
"@abp/bootstrap-daterangepicker" "~9.3.2"
"@abp/datatables.net-bs5" "~9.3.2"
"@abp/font-awesome" "~9.3.2"
"@abp/jquery-form" "~9.3.2"
"@abp/jquery-validation-unobtrusive" "~9.3.2"
"@abp/lodash" "~9.3.2"
"@abp/luxon" "~9.3.2"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.2"
"@abp/moment" "~9.3.2"
"@abp/select2" "~9.3.2"
"@abp/sweetalert2" "~9.3.2"
"@abp/timeago" "~9.3.2"
"@abp/aspnetcore.mvc.ui@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.2.tgz#5cab40d0f17eea2ae97a0d25fa238e52b5e8ef91"
integrity sha512-C73MB6abc531CmYyRctZXtKUY/0t+hhBQg5fIbzdJaR8SCSHEh2v9j2ZAhKFU0kectdrpKrLroOihOWYMfuWdQ==
"@abp/aspnetcore.mvc.ui" "~9.3.3"
"@abp/bootstrap" "~9.3.3"
"@abp/bootstrap-datepicker" "~9.3.3"
"@abp/bootstrap-daterangepicker" "~9.3.3"
"@abp/datatables.net-bs5" "~9.3.3"
"@abp/font-awesome" "~9.3.3"
"@abp/jquery-form" "~9.3.3"
"@abp/jquery-validation-unobtrusive" "~9.3.3"
"@abp/lodash" "~9.3.3"
"@abp/luxon" "~9.3.3"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.3"
"@abp/moment" "~9.3.3"
"@abp/select2" "~9.3.3"
"@abp/sweetalert2" "~9.3.3"
"@abp/timeago" "~9.3.3"
"@abp/aspnetcore.mvc.ui@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.3.tgz#16aca3844bccb24317f65f3a419cad34f9aa6387"
integrity sha512-bp1syI3exn3YBSoDertHxF1CVmEUIRHLCPr/+K1DLuBxW6KUPnDIpnJVVhXsO7EmwwzzukJF99utPXNGgQXnIg==
dependencies:
ansi-colors "^4.1.3"
"@abp/bootstrap-datepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.2.tgz#e156b0715b87a182e2cf3132436559e7c47f8987"
integrity sha512-8tDHiFvppm5YlIaLL0IfRd9r/YtyV4+bIp8zuIDeVW6eUvFd1ueuifCzf89vZXRf18PLR8JAiYFdBOx9+8CjZw==
"@abp/bootstrap-datepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.3.tgz#7c2e9f153d4bac45858e0d3dcfe6a382302d9c7f"
integrity sha512-kBjnpD0w2BCzEX3gw1ua+dlioAZ6xQigN4aQNpHumrDamAZ+ULhDiUTMJ8ofwlyM9nEryK9NP2+3Bm42iTSWPw==
dependencies:
bootstrap-datepicker "^1.10.0"
"@abp/bootstrap-daterangepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.2.tgz#19c2f5088ef8cf1cdc4483376f28faa2ca172f18"
integrity sha512-ygyUkiffq5Dry5yuyAzCKnlymbGZZ5f8es9d+dXLjp5lzk8K88LI4jTaIhm/Gc7wzKhFmHMpOIFYIRMzwvMmRQ==
"@abp/bootstrap-daterangepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.3.tgz#6420b359ac440d9d76b1cf47ea28f6ad345a2607"
integrity sha512-l5A2NaBDt5o5mePDoLvrWcDX1wj50o+q3OmFVm6x7lHfjOw+1iCxqv2A2GEye1TZeQ8yxCQOn+aUd7OdLUwE7Q==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.2.tgz#53dc0d68d15c60d36200d711b4f5a0acef15096b"
integrity sha512-vrUux40RDPx7hBXp2u5evRpm2LHRwHmRhmtTXx6ltQ8Aq7BwD9BvqBZEgg5GB5L9MGy5oy5Wm57t9ooQ8qmLgg==
"@abp/bootstrap@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.3.tgz#7fafbe0a6fb6cf051c63943361bcc3ee7159d506"
integrity sha512-O1Nv4cXkChcmlcDmszKGDqDZs1ofcmftkMSSGKYCpdJYEHBuGPhC8v29NDLCE3BLgoZjs8BJd3YpPh/cnJoJrA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
bootstrap "^5.3.3"
"@abp/core@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.2.tgz#10f0a485affb15d51c319bbdf88c1bfa24b5b778"
integrity sha512-y3kkP9+PBG1xxiHDXPk+kYs1BzbAytVRg611vKhCejHntMSD3cD4vCg4NW5oNEtCktNRBYcnQICdgLElAX/koQ==
"@abp/core@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.3.tgz#f87e8de30d0e496eebc6ba4db8ffb2a33ef5b591"
integrity sha512-P/B81S+8jkcRv+QsqczWJq9pk0hQk42mg8bpCnlUif9zyUSq2wsWNwulwC5HJAauLf3UvIcOrarpK8T1X/4cVw==
dependencies:
"@abp/utils" "~9.3.2"
"@abp/utils" "~9.3.3"
"@abp/datatables.net-bs5@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.2.tgz#89a3664c2ee0e98b16a41894f04f12edcf7b7780"
integrity sha512-llju5jfVIppot59cQ4cBGJdl9VA156mDI5V+h5ZHGBmVvwG79R/mUd3D49XmqQGBke95K1Z49R7V/JxYqa6F+Q==
"@abp/datatables.net-bs5@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.3.tgz#12e4011edb151bd8ce8e38f4f83b84062087dbe6"
integrity sha512-+Dn0njWJXdr0g/gMS89njzEHvP4oScUdROZaT40CvFxssN3lIkD3+AYi4QPv+onPGKZQ6D9+K+T1yk9/mrwzDA==
dependencies:
"@abp/datatables.net" "~9.3.2"
"@abp/datatables.net" "~9.3.3"
datatables.net-bs5 "^2.1.8"
"@abp/datatables.net@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.2.tgz#ee5cd8cb286211404d50593b33ea532f1b7cb9f1"
integrity sha512-JK6XgZeP2diBOnC9jSml0kYc1uvbU09yz4GOyPmh/QZiGdS4vonRKfjIXdFd0YbxK0qAPZO+MzZuwqvZSA6nyA==
"@abp/datatables.net@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.3.tgz#ac5281b921e152ae07d73a0061856f4598d33acf"
integrity sha512-4q4gKK3W3x6xXgvj+BYuXMZjSOgU4yecbLvQZkYGvoXk2KJ8PvQUz1ay5W2mJJmX0cvYvIX7ni5uhnEFdKxmZQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
datatables.net "^2.1.8"
"@abp/font-awesome@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.2.tgz#b0659aeec243a4fe3c851a98a79673292c2687b1"
integrity sha512-7esRWpT7PFMPSVhGPKb3DGq1h5n/R2xmusurbGDGhTHckiOfna8tQerZ6A9YdRsM2kIIDisWbuSzBkoM8hqfCQ==
"@abp/font-awesome@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.3.tgz#d9727d6652f419ca0f876a02932d226fa7a39370"
integrity sha512-n8XvR9Xr2u6yH2QEQpiu2RU3Br3hNx+ItSQ0ncp81wjYhR007NbOJvjDoQJFiuzgPKZdPNDbPbiiBv9L0oIgAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@fortawesome/fontawesome-free" "^6.6.0"
"@abp/jquery-form@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.2.tgz#17d0fe0a81d61e2e96131379e82872e5e45a2d5b"
integrity sha512-IwXWBRbtLhdB6/pJwQsWJHqLDHpZfJoA6x48A/GbTQLgWhpt0/OainDZsEUH3o0TWMhgJU+tp274uPENlG3DzQ==
"@abp/jquery-form@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.3.tgz#37d7e1c16b932e439e2127844991496b6557c094"
integrity sha512-B8uDWM13O+fB/TAN7xfMskLC0Qq8327waqpuctiulALz7uM4Ri1txANMp4+ftf25dxMeii/J4k6BSGer8K520Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.2.tgz#f13183ed7108cdea1500f18b1f80aff3037132ce"
integrity sha512-0v0Rhj3bir91cqwhlxDuD0PqwEYceyqLYf6K5eFF1/nE+1wN1VIST/oLN1Xis9x4NswbnnKai+OST0fqagpuhg==
"@abp/jquery-validation-unobtrusive@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.3.tgz#3882d15076fcf4ef6a197648c84b9edd91435235"
integrity sha512-csWL1+h/aRkU71uoxsKCuGZU9zloPdY6WB1uSBCFDTJ4aBy6gkdtAZGwsXHsJZ4AiHwL+d22P9XVSF1MhKB+MQ==
dependencies:
"@abp/jquery-validation" "~9.3.2"
"@abp/jquery-validation" "~9.3.3"
jquery-validation-unobtrusive "^4.0.0"
"@abp/jquery-validation@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.2.tgz#8ec072e2babb5d75aa1088a3754b837b7387df76"
integrity sha512-JCquJcN0FAF+8TQOYgbqeDZqPIwy2mWVDtHKCts2lVj8ol+sQgWCOhZDx11sl1oqVZjkvdOmKMgWHDztdoUojA==
"@abp/jquery-validation@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.3.tgz#daea2a288e8c440051af21ebf519f7e40b4d27d3"
integrity sha512-nU6a04fiaZuHXRnV+J++AwcyZOxEvW6i4yqm2PzFT9OCbDk1E3X5S1ntO7sGlCcppxj0pSp3uL2Jxq5d4gq+qg==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-validation "^1.21.0"
"@abp/jquery@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.2.tgz#edb3d65bdbd3885af72759ce0cd9d813ab41aade"
integrity sha512-i4scUZt6q09jhl8YTtQrPg+GV5Vd1QW57hHesYmgor8pLD87JU7cc5sCEJlmmtzVZsXjDkVuiyD2sOUXSItxMw==
"@abp/jquery@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.3.tgz#5c3ab4dfa820d9f2eb19fecc65194f0211d5bf37"
integrity sha512-5Nfw287+JugPCnm/KK8fjT4e5zHiwnL8w9OSAHVmf9UBcuJ2yBc+b8mklqy5pLt+jObouE5wJUOtENxgkgSkAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
jquery "~3.7.1"
"@abp/lodash@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.2.tgz#d3ca624dd8927d33cf8728403ef591977b9e11f4"
integrity sha512-4XOhLKa/reKB85DyHtz1obC96j2VJs9+xqlO8Pn58hXP396cMEMuC1MfjHMwhPuMVHwgffg0UCfukKKf/UGJ/w==
"@abp/lodash@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.3.tgz#a60a41088288da41fa61b09cd747f1fde3c3ec40"
integrity sha512-GsAJPMGNHZcVHQWJMCEQ7oWSeRwmHx0n2oWLQOQoyFQu1itZeJy2dFE+nSIb2jAQ7sfKZVNw7OrEqN/VqgEoUg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
lodash "^4.17.21"
"@abp/luxon@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.2.tgz#806464e828adf6b99a9620f3c39a16f8621ecd84"
integrity sha512-oP74Q9/FJ8QpB7yVOycFlfsGhPKFUk6NTnoT+cVRNg0wpUkRRjg5WTkZeKLoVxKNk9RwA/9fa6MnBiiNs2z/Pg==
"@abp/luxon@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.3.tgz#5742a90953bf0b24fa129f5a6a4c32dbdc134553"
integrity sha512-+AqTiMhN8Z8Khmv/9aBPwasNVcboJa9BV3WdJ5Nccwo2OEN7Wycw6TkRnb42fbUpzXAvxvwv9cSDHjRBib299A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
luxon "^3.5.0"
"@abp/malihu-custom-scrollbar-plugin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.2.tgz#71069a6abd8a9456f0fc6227ee17b93300ad6030"
integrity sha512-6pFO68hvtbGiGTaxkzTPnzJA2NZkzE+acWlTfBvSVyMvZM1jER5wYJmDpflZO+WPtTTu9CUflTwvYw2TiNKlUg==
"@abp/malihu-custom-scrollbar-plugin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.3.tgz#93a649bb621a47fb50b9b776fb864a07ccdff287"
integrity sha512-w83FD8mqGkhvoAEu0DwzcrmX1wwyKwVRkvfYmxjhokD7+Hq1FyuFDMO51F8hh590I2wzWCX8NvAVUP24viOY+A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.2.tgz#150548dd2b817d586f87113abb40c85f9b1ab406"
integrity sha512-TdHeqPPEPk00/5vKbGHY6D74XlzfRM2Kb4WVvykVx2gjzScp5Sfunpus/A9UCOYls/bWp1MVMT7V0ExBXYPyNg==
"@abp/moment@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.3.tgz#622c424350620e0215a0a04059dfd3e18022fd69"
integrity sha512-m/xV11aWOZKTVVyGsX2mZl9ondcP8pWSmjmUKVNLrFSul4pRNgfM2ZeaKiaOLApkyOSZDzCEMUYbEf+dM2/rcg==
dependencies:
moment "^2.30.1"
"@abp/select2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.2.tgz#5c069ff7a9fcb9e78bd4a8591d1e5eac6d66f03f"
integrity sha512-/N5bJjyLQnN8zPovRrmrcYhiUxG/RTI6kNaH0QW/QEsryfuX24wdDWrRXacsJ1QKlMxig++IHRnpMBrHhxAKUw==
"@abp/select2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.3.tgz#8ef9bc3d3674d515d7b7f9060d77831246d03b6a"
integrity sha512-2g8LkLBu1Ooaxj6utYne1gPMYG9888l/mEFMJU5iHOPXS0vz4lANw+VjtawapFtP6yRSiD2/qJtOt0C5rQq1yA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
select2 "^4.0.13"
"@abp/sweetalert2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.2.tgz#1ada87b720faef1289aa5fdcf42c0f5c74ff4493"
integrity sha512-PUNbt7O6reTqDelUBGryullFDD5XeZkgQFn/FXbZVp6y0owHUyIlX+Jr7PIesWEB/RHuLa+uZoSywtVPH7fsEw==
"@abp/sweetalert2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.3.tgz#b9d6075d9ede12509f27576f88d54f21598f37df"
integrity sha512-CeX5IWwxAu9M4jqNZBK6o59sVoDuFgxnffhHTMEP7pt8WzH+2uucxGe/21gXT/PW1c3EjSwP3Ri2MhtKOFZuyQ==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
sweetalert2 "^11.14.1"
"@abp/timeago@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.2.tgz#fe4d184aed92dd265e3c9531c53bdc684abb3b52"
integrity sha512-GLimaRixGtZ5oiH3JLEmeUe54gePdSfVZtyJOvGcc0wQjQVOa5JgyTqktszb+pF4QVdeJr+ijz6RZlavwIY0EA==
"@abp/timeago@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.3.tgz#b116a7112c1d53588129587d5572dc0ae55567a5"
integrity sha512-L0X0yc8oS36eDx+8jvzreW4Cr4TnWESMceXihfOfuWbuOm4R58W4Cvx2/74XFiX/0if1WEg31P4Aj3LhpjgEaQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
timeago "^1.6.7"
"@abp/utils@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.2.tgz#f2158e9858c8efcbd3f17bf6e79c41116ac66795"
integrity sha512-DtD07VHsDS5KPfn3jnL6f9WsfXEJVv7xUF+NcgW+HBTHnJTxunnE/OYGf/clTM4xeDb+RWl3AoGYP+kF4H/Snw==
"@abp/utils@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.3.tgz#e8cda12eb1f7432787072c2d5fe9905b7613e2ec"
integrity sha512-X1q9hod+Z6x/QypixI8BVvnMOqncQXM/Vs2Kq2p0jJJsNoerOFqGr+qLqZ5x3e5CoSz0H/38VjaG1yxIoq2exA==
dependencies:
just-compare "^2.3.0"

2
modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json

@ -3,6 +3,6 @@
"name": "my-app",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.3"
}
}

240
modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock

@ -2,185 +2,185 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.2.tgz#92907ca78607515c8fd5696e00ad3b65b42881a7"
integrity sha512-wmXGPoKkbR2sCErFdAT37HxYbCbfN0IAd0CGo8aMaQkFzzenq1b9omnN6l9+xd91Q3WcjUcWhpCJLYurcdbgOA==
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.3.tgz#71c2003dbc5ccd6d9f78740c28bb52d57452f4d7"
integrity sha512-YqFGHIw/jAQ02jU4FGUay/pQQGWAA/815YoQskFNxc4R0hlGRS6YrR+kSAzRjmMkeRn9gM/KtndLWiygv1fbEQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.3"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.2.tgz#94089c3dcac4571c5fcb9bdb754e5df28a24e966"
integrity sha512-eRSvhLimwf65KKI1P/DZgQK+l300EwX4r2S4XYL0gJjjXI9aeIDQuPEqGZs2a6P5/zfejFvefqCIcG5EfEH9ew==
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.3.tgz#6886575725904f7b8f08234e0057ee851a68735d"
integrity sha512-zv1BL054q3VnqZXjd4fa2E7es/Gs8HsFfp3jWljRwEOytdG1PyHo5++ChM3FlB4+mIXq1On4leST3sDVxa75Sw==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.2"
"@abp/bootstrap" "~9.3.2"
"@abp/bootstrap-datepicker" "~9.3.2"
"@abp/bootstrap-daterangepicker" "~9.3.2"
"@abp/datatables.net-bs5" "~9.3.2"
"@abp/font-awesome" "~9.3.2"
"@abp/jquery-form" "~9.3.2"
"@abp/jquery-validation-unobtrusive" "~9.3.2"
"@abp/lodash" "~9.3.2"
"@abp/luxon" "~9.3.2"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.2"
"@abp/moment" "~9.3.2"
"@abp/select2" "~9.3.2"
"@abp/sweetalert2" "~9.3.2"
"@abp/timeago" "~9.3.2"
"@abp/aspnetcore.mvc.ui@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.2.tgz#5cab40d0f17eea2ae97a0d25fa238e52b5e8ef91"
integrity sha512-C73MB6abc531CmYyRctZXtKUY/0t+hhBQg5fIbzdJaR8SCSHEh2v9j2ZAhKFU0kectdrpKrLroOihOWYMfuWdQ==
"@abp/aspnetcore.mvc.ui" "~9.3.3"
"@abp/bootstrap" "~9.3.3"
"@abp/bootstrap-datepicker" "~9.3.3"
"@abp/bootstrap-daterangepicker" "~9.3.3"
"@abp/datatables.net-bs5" "~9.3.3"
"@abp/font-awesome" "~9.3.3"
"@abp/jquery-form" "~9.3.3"
"@abp/jquery-validation-unobtrusive" "~9.3.3"
"@abp/lodash" "~9.3.3"
"@abp/luxon" "~9.3.3"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.3"
"@abp/moment" "~9.3.3"
"@abp/select2" "~9.3.3"
"@abp/sweetalert2" "~9.3.3"
"@abp/timeago" "~9.3.3"
"@abp/aspnetcore.mvc.ui@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.3.tgz#16aca3844bccb24317f65f3a419cad34f9aa6387"
integrity sha512-bp1syI3exn3YBSoDertHxF1CVmEUIRHLCPr/+K1DLuBxW6KUPnDIpnJVVhXsO7EmwwzzukJF99utPXNGgQXnIg==
dependencies:
ansi-colors "^4.1.3"
"@abp/bootstrap-datepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.2.tgz#e156b0715b87a182e2cf3132436559e7c47f8987"
integrity sha512-8tDHiFvppm5YlIaLL0IfRd9r/YtyV4+bIp8zuIDeVW6eUvFd1ueuifCzf89vZXRf18PLR8JAiYFdBOx9+8CjZw==
"@abp/bootstrap-datepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.3.tgz#7c2e9f153d4bac45858e0d3dcfe6a382302d9c7f"
integrity sha512-kBjnpD0w2BCzEX3gw1ua+dlioAZ6xQigN4aQNpHumrDamAZ+ULhDiUTMJ8ofwlyM9nEryK9NP2+3Bm42iTSWPw==
dependencies:
bootstrap-datepicker "^1.10.0"
"@abp/bootstrap-daterangepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.2.tgz#19c2f5088ef8cf1cdc4483376f28faa2ca172f18"
integrity sha512-ygyUkiffq5Dry5yuyAzCKnlymbGZZ5f8es9d+dXLjp5lzk8K88LI4jTaIhm/Gc7wzKhFmHMpOIFYIRMzwvMmRQ==
"@abp/bootstrap-daterangepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.3.tgz#6420b359ac440d9d76b1cf47ea28f6ad345a2607"
integrity sha512-l5A2NaBDt5o5mePDoLvrWcDX1wj50o+q3OmFVm6x7lHfjOw+1iCxqv2A2GEye1TZeQ8yxCQOn+aUd7OdLUwE7Q==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.2.tgz#53dc0d68d15c60d36200d711b4f5a0acef15096b"
integrity sha512-vrUux40RDPx7hBXp2u5evRpm2LHRwHmRhmtTXx6ltQ8Aq7BwD9BvqBZEgg5GB5L9MGy5oy5Wm57t9ooQ8qmLgg==
"@abp/bootstrap@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.3.tgz#7fafbe0a6fb6cf051c63943361bcc3ee7159d506"
integrity sha512-O1Nv4cXkChcmlcDmszKGDqDZs1ofcmftkMSSGKYCpdJYEHBuGPhC8v29NDLCE3BLgoZjs8BJd3YpPh/cnJoJrA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
bootstrap "^5.3.3"
"@abp/core@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.2.tgz#10f0a485affb15d51c319bbdf88c1bfa24b5b778"
integrity sha512-y3kkP9+PBG1xxiHDXPk+kYs1BzbAytVRg611vKhCejHntMSD3cD4vCg4NW5oNEtCktNRBYcnQICdgLElAX/koQ==
"@abp/core@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.3.tgz#f87e8de30d0e496eebc6ba4db8ffb2a33ef5b591"
integrity sha512-P/B81S+8jkcRv+QsqczWJq9pk0hQk42mg8bpCnlUif9zyUSq2wsWNwulwC5HJAauLf3UvIcOrarpK8T1X/4cVw==
dependencies:
"@abp/utils" "~9.3.2"
"@abp/utils" "~9.3.3"
"@abp/datatables.net-bs5@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.2.tgz#89a3664c2ee0e98b16a41894f04f12edcf7b7780"
integrity sha512-llju5jfVIppot59cQ4cBGJdl9VA156mDI5V+h5ZHGBmVvwG79R/mUd3D49XmqQGBke95K1Z49R7V/JxYqa6F+Q==
"@abp/datatables.net-bs5@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.3.tgz#12e4011edb151bd8ce8e38f4f83b84062087dbe6"
integrity sha512-+Dn0njWJXdr0g/gMS89njzEHvP4oScUdROZaT40CvFxssN3lIkD3+AYi4QPv+onPGKZQ6D9+K+T1yk9/mrwzDA==
dependencies:
"@abp/datatables.net" "~9.3.2"
"@abp/datatables.net" "~9.3.3"
datatables.net-bs5 "^2.1.8"
"@abp/datatables.net@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.2.tgz#ee5cd8cb286211404d50593b33ea532f1b7cb9f1"
integrity sha512-JK6XgZeP2diBOnC9jSml0kYc1uvbU09yz4GOyPmh/QZiGdS4vonRKfjIXdFd0YbxK0qAPZO+MzZuwqvZSA6nyA==
"@abp/datatables.net@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.3.tgz#ac5281b921e152ae07d73a0061856f4598d33acf"
integrity sha512-4q4gKK3W3x6xXgvj+BYuXMZjSOgU4yecbLvQZkYGvoXk2KJ8PvQUz1ay5W2mJJmX0cvYvIX7ni5uhnEFdKxmZQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
datatables.net "^2.1.8"
"@abp/font-awesome@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.2.tgz#b0659aeec243a4fe3c851a98a79673292c2687b1"
integrity sha512-7esRWpT7PFMPSVhGPKb3DGq1h5n/R2xmusurbGDGhTHckiOfna8tQerZ6A9YdRsM2kIIDisWbuSzBkoM8hqfCQ==
"@abp/font-awesome@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.3.tgz#d9727d6652f419ca0f876a02932d226fa7a39370"
integrity sha512-n8XvR9Xr2u6yH2QEQpiu2RU3Br3hNx+ItSQ0ncp81wjYhR007NbOJvjDoQJFiuzgPKZdPNDbPbiiBv9L0oIgAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@fortawesome/fontawesome-free" "^6.6.0"
"@abp/jquery-form@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.2.tgz#17d0fe0a81d61e2e96131379e82872e5e45a2d5b"
integrity sha512-IwXWBRbtLhdB6/pJwQsWJHqLDHpZfJoA6x48A/GbTQLgWhpt0/OainDZsEUH3o0TWMhgJU+tp274uPENlG3DzQ==
"@abp/jquery-form@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.3.tgz#37d7e1c16b932e439e2127844991496b6557c094"
integrity sha512-B8uDWM13O+fB/TAN7xfMskLC0Qq8327waqpuctiulALz7uM4Ri1txANMp4+ftf25dxMeii/J4k6BSGer8K520Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.2.tgz#f13183ed7108cdea1500f18b1f80aff3037132ce"
integrity sha512-0v0Rhj3bir91cqwhlxDuD0PqwEYceyqLYf6K5eFF1/nE+1wN1VIST/oLN1Xis9x4NswbnnKai+OST0fqagpuhg==
"@abp/jquery-validation-unobtrusive@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.3.tgz#3882d15076fcf4ef6a197648c84b9edd91435235"
integrity sha512-csWL1+h/aRkU71uoxsKCuGZU9zloPdY6WB1uSBCFDTJ4aBy6gkdtAZGwsXHsJZ4AiHwL+d22P9XVSF1MhKB+MQ==
dependencies:
"@abp/jquery-validation" "~9.3.2"
"@abp/jquery-validation" "~9.3.3"
jquery-validation-unobtrusive "^4.0.0"
"@abp/jquery-validation@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.2.tgz#8ec072e2babb5d75aa1088a3754b837b7387df76"
integrity sha512-JCquJcN0FAF+8TQOYgbqeDZqPIwy2mWVDtHKCts2lVj8ol+sQgWCOhZDx11sl1oqVZjkvdOmKMgWHDztdoUojA==
"@abp/jquery-validation@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.3.tgz#daea2a288e8c440051af21ebf519f7e40b4d27d3"
integrity sha512-nU6a04fiaZuHXRnV+J++AwcyZOxEvW6i4yqm2PzFT9OCbDk1E3X5S1ntO7sGlCcppxj0pSp3uL2Jxq5d4gq+qg==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-validation "^1.21.0"
"@abp/jquery@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.2.tgz#edb3d65bdbd3885af72759ce0cd9d813ab41aade"
integrity sha512-i4scUZt6q09jhl8YTtQrPg+GV5Vd1QW57hHesYmgor8pLD87JU7cc5sCEJlmmtzVZsXjDkVuiyD2sOUXSItxMw==
"@abp/jquery@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.3.tgz#5c3ab4dfa820d9f2eb19fecc65194f0211d5bf37"
integrity sha512-5Nfw287+JugPCnm/KK8fjT4e5zHiwnL8w9OSAHVmf9UBcuJ2yBc+b8mklqy5pLt+jObouE5wJUOtENxgkgSkAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
jquery "~3.7.1"
"@abp/lodash@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.2.tgz#d3ca624dd8927d33cf8728403ef591977b9e11f4"
integrity sha512-4XOhLKa/reKB85DyHtz1obC96j2VJs9+xqlO8Pn58hXP396cMEMuC1MfjHMwhPuMVHwgffg0UCfukKKf/UGJ/w==
"@abp/lodash@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.3.tgz#a60a41088288da41fa61b09cd747f1fde3c3ec40"
integrity sha512-GsAJPMGNHZcVHQWJMCEQ7oWSeRwmHx0n2oWLQOQoyFQu1itZeJy2dFE+nSIb2jAQ7sfKZVNw7OrEqN/VqgEoUg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
lodash "^4.17.21"
"@abp/luxon@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.2.tgz#806464e828adf6b99a9620f3c39a16f8621ecd84"
integrity sha512-oP74Q9/FJ8QpB7yVOycFlfsGhPKFUk6NTnoT+cVRNg0wpUkRRjg5WTkZeKLoVxKNk9RwA/9fa6MnBiiNs2z/Pg==
"@abp/luxon@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.3.tgz#5742a90953bf0b24fa129f5a6a4c32dbdc134553"
integrity sha512-+AqTiMhN8Z8Khmv/9aBPwasNVcboJa9BV3WdJ5Nccwo2OEN7Wycw6TkRnb42fbUpzXAvxvwv9cSDHjRBib299A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
luxon "^3.5.0"
"@abp/malihu-custom-scrollbar-plugin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.2.tgz#71069a6abd8a9456f0fc6227ee17b93300ad6030"
integrity sha512-6pFO68hvtbGiGTaxkzTPnzJA2NZkzE+acWlTfBvSVyMvZM1jER5wYJmDpflZO+WPtTTu9CUflTwvYw2TiNKlUg==
"@abp/malihu-custom-scrollbar-plugin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.3.tgz#93a649bb621a47fb50b9b776fb864a07ccdff287"
integrity sha512-w83FD8mqGkhvoAEu0DwzcrmX1wwyKwVRkvfYmxjhokD7+Hq1FyuFDMO51F8hh590I2wzWCX8NvAVUP24viOY+A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/moment@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.2.tgz#150548dd2b817d586f87113abb40c85f9b1ab406"
integrity sha512-TdHeqPPEPk00/5vKbGHY6D74XlzfRM2Kb4WVvykVx2gjzScp5Sfunpus/A9UCOYls/bWp1MVMT7V0ExBXYPyNg==
"@abp/moment@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.3.tgz#622c424350620e0215a0a04059dfd3e18022fd69"
integrity sha512-m/xV11aWOZKTVVyGsX2mZl9ondcP8pWSmjmUKVNLrFSul4pRNgfM2ZeaKiaOLApkyOSZDzCEMUYbEf+dM2/rcg==
dependencies:
moment "^2.30.1"
"@abp/select2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.2.tgz#5c069ff7a9fcb9e78bd4a8591d1e5eac6d66f03f"
integrity sha512-/N5bJjyLQnN8zPovRrmrcYhiUxG/RTI6kNaH0QW/QEsryfuX24wdDWrRXacsJ1QKlMxig++IHRnpMBrHhxAKUw==
"@abp/select2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.3.tgz#8ef9bc3d3674d515d7b7f9060d77831246d03b6a"
integrity sha512-2g8LkLBu1Ooaxj6utYne1gPMYG9888l/mEFMJU5iHOPXS0vz4lANw+VjtawapFtP6yRSiD2/qJtOt0C5rQq1yA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
select2 "^4.0.13"
"@abp/sweetalert2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.2.tgz#1ada87b720faef1289aa5fdcf42c0f5c74ff4493"
integrity sha512-PUNbt7O6reTqDelUBGryullFDD5XeZkgQFn/FXbZVp6y0owHUyIlX+Jr7PIesWEB/RHuLa+uZoSywtVPH7fsEw==
"@abp/sweetalert2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.3.tgz#b9d6075d9ede12509f27576f88d54f21598f37df"
integrity sha512-CeX5IWwxAu9M4jqNZBK6o59sVoDuFgxnffhHTMEP7pt8WzH+2uucxGe/21gXT/PW1c3EjSwP3Ri2MhtKOFZuyQ==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
sweetalert2 "^11.14.1"
"@abp/timeago@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.2.tgz#fe4d184aed92dd265e3c9531c53bdc684abb3b52"
integrity sha512-GLimaRixGtZ5oiH3JLEmeUe54gePdSfVZtyJOvGcc0wQjQVOa5JgyTqktszb+pF4QVdeJr+ijz6RZlavwIY0EA==
"@abp/timeago@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.3.tgz#b116a7112c1d53588129587d5572dc0ae55567a5"
integrity sha512-L0X0yc8oS36eDx+8jvzreW4Cr4TnWESMceXihfOfuWbuOm4R58W4Cvx2/74XFiX/0if1WEg31P4Aj3LhpjgEaQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
timeago "^1.6.7"
"@abp/utils@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.2.tgz#f2158e9858c8efcbd3f17bf6e79c41116ac66795"
integrity sha512-DtD07VHsDS5KPfn3jnL6f9WsfXEJVv7xUF+NcgW+HBTHnJTxunnE/OYGf/clTM4xeDb+RWl3AoGYP+kF4H/Snw==
"@abp/utils@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.3.tgz#e8cda12eb1f7432787072c2d5fe9905b7613e2ec"
integrity sha512-X1q9hod+Z6x/QypixI8BVvnMOqncQXM/Vs2Kq2p0jJJsNoerOFqGr+qLqZ5x3e5CoSz0H/38VjaG1yxIoq2exA==
dependencies:
just-compare "^2.3.0"

4
modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json

@ -3,7 +3,7 @@
"name": "my-app",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.2",
"@abp/cms-kit": "9.3.2"
"@abp/aspnetcore.mvc.ui.theme.basic": "~9.3.3",
"@abp/cms-kit": "9.3.3"
}
}

392
modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock

@ -2,293 +2,293 @@
# yarn lockfile v1
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.2.tgz#92907ca78607515c8fd5696e00ad3b65b42881a7"
integrity sha512-wmXGPoKkbR2sCErFdAT37HxYbCbfN0IAd0CGo8aMaQkFzzenq1b9omnN6l9+xd91Q3WcjUcWhpCJLYurcdbgOA==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.2"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.2.tgz#94089c3dcac4571c5fcb9bdb754e5df28a24e966"
integrity sha512-eRSvhLimwf65KKI1P/DZgQK+l300EwX4r2S4XYL0gJjjXI9aeIDQuPEqGZs2a6P5/zfejFvefqCIcG5EfEH9ew==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.2"
"@abp/bootstrap" "~9.3.2"
"@abp/bootstrap-datepicker" "~9.3.2"
"@abp/bootstrap-daterangepicker" "~9.3.2"
"@abp/datatables.net-bs5" "~9.3.2"
"@abp/font-awesome" "~9.3.2"
"@abp/jquery-form" "~9.3.2"
"@abp/jquery-validation-unobtrusive" "~9.3.2"
"@abp/lodash" "~9.3.2"
"@abp/luxon" "~9.3.2"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.2"
"@abp/moment" "~9.3.2"
"@abp/select2" "~9.3.2"
"@abp/sweetalert2" "~9.3.2"
"@abp/timeago" "~9.3.2"
"@abp/aspnetcore.mvc.ui@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.2.tgz#5cab40d0f17eea2ae97a0d25fa238e52b5e8ef91"
integrity sha512-C73MB6abc531CmYyRctZXtKUY/0t+hhBQg5fIbzdJaR8SCSHEh2v9j2ZAhKFU0kectdrpKrLroOihOWYMfuWdQ==
"@abp/aspnetcore.mvc.ui.theme.basic@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-9.3.3.tgz#71c2003dbc5ccd6d9f78740c28bb52d57452f4d7"
integrity sha512-YqFGHIw/jAQ02jU4FGUay/pQQGWAA/815YoQskFNxc4R0hlGRS6YrR+kSAzRjmMkeRn9gM/KtndLWiygv1fbEQ==
dependencies:
"@abp/aspnetcore.mvc.ui.theme.shared" "~9.3.3"
"@abp/aspnetcore.mvc.ui.theme.shared@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-9.3.3.tgz#6886575725904f7b8f08234e0057ee851a68735d"
integrity sha512-zv1BL054q3VnqZXjd4fa2E7es/Gs8HsFfp3jWljRwEOytdG1PyHo5++ChM3FlB4+mIXq1On4leST3sDVxa75Sw==
dependencies:
"@abp/aspnetcore.mvc.ui" "~9.3.3"
"@abp/bootstrap" "~9.3.3"
"@abp/bootstrap-datepicker" "~9.3.3"
"@abp/bootstrap-daterangepicker" "~9.3.3"
"@abp/datatables.net-bs5" "~9.3.3"
"@abp/font-awesome" "~9.3.3"
"@abp/jquery-form" "~9.3.3"
"@abp/jquery-validation-unobtrusive" "~9.3.3"
"@abp/lodash" "~9.3.3"
"@abp/luxon" "~9.3.3"
"@abp/malihu-custom-scrollbar-plugin" "~9.3.3"
"@abp/moment" "~9.3.3"
"@abp/select2" "~9.3.3"
"@abp/sweetalert2" "~9.3.3"
"@abp/timeago" "~9.3.3"
"@abp/aspnetcore.mvc.ui@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-9.3.3.tgz#16aca3844bccb24317f65f3a419cad34f9aa6387"
integrity sha512-bp1syI3exn3YBSoDertHxF1CVmEUIRHLCPr/+K1DLuBxW6KUPnDIpnJVVhXsO7EmwwzzukJF99utPXNGgQXnIg==
dependencies:
ansi-colors "^4.1.3"
"@abp/bootstrap-datepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.2.tgz#e156b0715b87a182e2cf3132436559e7c47f8987"
integrity sha512-8tDHiFvppm5YlIaLL0IfRd9r/YtyV4+bIp8zuIDeVW6eUvFd1ueuifCzf89vZXRf18PLR8JAiYFdBOx9+8CjZw==
"@abp/bootstrap-datepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-9.3.3.tgz#7c2e9f153d4bac45858e0d3dcfe6a382302d9c7f"
integrity sha512-kBjnpD0w2BCzEX3gw1ua+dlioAZ6xQigN4aQNpHumrDamAZ+ULhDiUTMJ8ofwlyM9nEryK9NP2+3Bm42iTSWPw==
dependencies:
bootstrap-datepicker "^1.10.0"
"@abp/bootstrap-daterangepicker@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.2.tgz#19c2f5088ef8cf1cdc4483376f28faa2ca172f18"
integrity sha512-ygyUkiffq5Dry5yuyAzCKnlymbGZZ5f8es9d+dXLjp5lzk8K88LI4jTaIhm/Gc7wzKhFmHMpOIFYIRMzwvMmRQ==
"@abp/bootstrap-daterangepicker@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-9.3.3.tgz#6420b359ac440d9d76b1cf47ea28f6ad345a2607"
integrity sha512-l5A2NaBDt5o5mePDoLvrWcDX1wj50o+q3OmFVm6x7lHfjOw+1iCxqv2A2GEye1TZeQ8yxCQOn+aUd7OdLUwE7Q==
dependencies:
bootstrap-daterangepicker "^3.1.0"
"@abp/bootstrap@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.2.tgz#53dc0d68d15c60d36200d711b4f5a0acef15096b"
integrity sha512-vrUux40RDPx7hBXp2u5evRpm2LHRwHmRhmtTXx6ltQ8Aq7BwD9BvqBZEgg5GB5L9MGy5oy5Wm57t9ooQ8qmLgg==
"@abp/bootstrap@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-9.3.3.tgz#7fafbe0a6fb6cf051c63943361bcc3ee7159d506"
integrity sha512-O1Nv4cXkChcmlcDmszKGDqDZs1ofcmftkMSSGKYCpdJYEHBuGPhC8v29NDLCE3BLgoZjs8BJd3YpPh/cnJoJrA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
bootstrap "^5.3.3"
"@abp/clipboard@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.2.tgz#4e0d6456e142e552ca3b4ec10159276e096c56bf"
integrity sha512-jorX68Yw/9pWAmt8cOuVx3Cnp7VF9xuvCD/ecvL5eZyHhXt4tDcYIFO5LkF+CaIky79gdzdF3tmYeFSPUE/HzA==
"@abp/clipboard@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-9.3.3.tgz#e6fd477a9f6d6c7fb224ea018e8f23d8d303f3ed"
integrity sha512-iR9HUk1JPWHS3LQ5QmH40maCuwi6SFwxPYvqVjNLVTisHsUOGGZLvHJ46aA8Ei3Q4UlUCdISP9Kc4F88JrhRpA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
clipboard "^2.0.11"
"@abp/cms-kit.admin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/cms-kit.admin/-/cms-kit.admin-9.3.2.tgz#dd43e879bbfbdeae61fc001026bacc09279e5e7d"
integrity sha512-BsWb6vO+2n0s9aJ+ud1whxST7v/0cwk66CLGfUeWkdiahQGyOx3PsRHDD2k9yZA7H8okgYr+tpN/+hUPUjFw6w==
"@abp/cms-kit.admin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/cms-kit.admin/-/cms-kit.admin-9.3.3.tgz#f3ca6e4ecdda1a70ef8581ad1e302c4dd7b77316"
integrity sha512-cvHYgvtFuM5G2TkkeEIvRgpC7tZDGioVXLKNqovT4T1XzCtqZyuU3AOKBHCZqiqinJZ+9E/FsnKKjp3vlZpvZw==
dependencies:
"@abp/codemirror" "~9.3.2"
"@abp/jstree" "~9.3.2"
"@abp/markdown-it" "~9.3.2"
"@abp/slugify" "~9.3.2"
"@abp/tui-editor" "~9.3.2"
"@abp/uppy" "~9.3.2"
"@abp/codemirror" "~9.3.3"
"@abp/jstree" "~9.3.3"
"@abp/markdown-it" "~9.3.3"
"@abp/slugify" "~9.3.3"
"@abp/tui-editor" "~9.3.3"
"@abp/uppy" "~9.3.3"
"@abp/cms-kit.public@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/cms-kit.public/-/cms-kit.public-9.3.2.tgz#6eeed0407fd70b86aee148c79193403133364213"
integrity sha512-h5Ul5opCApy1wlwp4bARKKMkW+Q43VnPc/4BsKsPpLAB10XU3+DBr8U1vJWNnh+0h0bpRJ44norKfQ/mApscEw==
"@abp/cms-kit.public@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/cms-kit.public/-/cms-kit.public-9.3.3.tgz#b2140e2edc4e78f55ff4d01416685bdc7109f663"
integrity sha512-5xh41EqEwxMdSUMb89XXmlO7c7vbe4XU3kzEMxN70V7jAUtww+bCHKqbw/mqvHhjuSCdXQ0K+IfTjWxZ/kFPVQ==
dependencies:
"@abp/highlight.js" "~9.3.2"
"@abp/star-rating-svg" "~9.3.2"
"@abp/highlight.js" "~9.3.3"
"@abp/star-rating-svg" "~9.3.3"
"@abp/cms-kit@9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-9.3.2.tgz#02f135bb44165b0b687776c5d3b209810a541437"
integrity sha512-UHlFEJAeoKEl3KmuuHf3Hi8UQrUrciTYi4PRHInuS5JdpMT8ZOaTTPZtKxE9ZDuiN19lwc8vsrATbb43dgiX0g==
"@abp/cms-kit@9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-9.3.3.tgz#7b8e67a5391aefb5f563af8a9b0435c008612185"
integrity sha512-+G3SuChVU6apexSCqW7W0Zy4EO/hiKt5cXRWjjx5A8em+SgUOuDB2/nA1TNBe/IGixJJbei6qF4mLlabwnJDTw==
dependencies:
"@abp/cms-kit.admin" "~9.3.2"
"@abp/cms-kit.public" "~9.3.2"
"@abp/cms-kit.admin" "~9.3.3"
"@abp/cms-kit.public" "~9.3.3"
"@abp/codemirror@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-9.3.2.tgz#09de9ce79e6ed542292d12e288f57a58b6a84c98"
integrity sha512-h7yHGeOQRThHAsN1U7Viu0ifafK6m0LpyJOSWvQqAWHQJ44+iXy+gLeZJhJwIpJuwxPwZqQkuRKKjHqHTllf/Q==
"@abp/codemirror@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-9.3.3.tgz#9bb164b214d1969a951f46ee997a69856c25bc26"
integrity sha512-XivrP8v9kztDFWTXkuoHLONFdBQ54dlVUsmwv8WBRVl4QKfVIDhSZs8EmqU8PSIqygS10rcjo6dDLvJYEL3mfg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
codemirror "^5.65.1"
"@abp/core@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.2.tgz#10f0a485affb15d51c319bbdf88c1bfa24b5b778"
integrity sha512-y3kkP9+PBG1xxiHDXPk+kYs1BzbAytVRg611vKhCejHntMSD3cD4vCg4NW5oNEtCktNRBYcnQICdgLElAX/koQ==
"@abp/core@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/core/-/core-9.3.3.tgz#f87e8de30d0e496eebc6ba4db8ffb2a33ef5b591"
integrity sha512-P/B81S+8jkcRv+QsqczWJq9pk0hQk42mg8bpCnlUif9zyUSq2wsWNwulwC5HJAauLf3UvIcOrarpK8T1X/4cVw==
dependencies:
"@abp/utils" "~9.3.2"
"@abp/utils" "~9.3.3"
"@abp/datatables.net-bs5@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.2.tgz#89a3664c2ee0e98b16a41894f04f12edcf7b7780"
integrity sha512-llju5jfVIppot59cQ4cBGJdl9VA156mDI5V+h5ZHGBmVvwG79R/mUd3D49XmqQGBke95K1Z49R7V/JxYqa6F+Q==
"@abp/datatables.net-bs5@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-9.3.3.tgz#12e4011edb151bd8ce8e38f4f83b84062087dbe6"
integrity sha512-+Dn0njWJXdr0g/gMS89njzEHvP4oScUdROZaT40CvFxssN3lIkD3+AYi4QPv+onPGKZQ6D9+K+T1yk9/mrwzDA==
dependencies:
"@abp/datatables.net" "~9.3.2"
"@abp/datatables.net" "~9.3.3"
datatables.net-bs5 "^2.1.8"
"@abp/datatables.net@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.2.tgz#ee5cd8cb286211404d50593b33ea532f1b7cb9f1"
integrity sha512-JK6XgZeP2diBOnC9jSml0kYc1uvbU09yz4GOyPmh/QZiGdS4vonRKfjIXdFd0YbxK0qAPZO+MzZuwqvZSA6nyA==
"@abp/datatables.net@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-9.3.3.tgz#ac5281b921e152ae07d73a0061856f4598d33acf"
integrity sha512-4q4gKK3W3x6xXgvj+BYuXMZjSOgU4yecbLvQZkYGvoXk2KJ8PvQUz1ay5W2mJJmX0cvYvIX7ni5uhnEFdKxmZQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
datatables.net "^2.1.8"
"@abp/font-awesome@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.2.tgz#b0659aeec243a4fe3c851a98a79673292c2687b1"
integrity sha512-7esRWpT7PFMPSVhGPKb3DGq1h5n/R2xmusurbGDGhTHckiOfna8tQerZ6A9YdRsM2kIIDisWbuSzBkoM8hqfCQ==
"@abp/font-awesome@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-9.3.3.tgz#d9727d6652f419ca0f876a02932d226fa7a39370"
integrity sha512-n8XvR9Xr2u6yH2QEQpiu2RU3Br3hNx+ItSQ0ncp81wjYhR007NbOJvjDoQJFiuzgPKZdPNDbPbiiBv9L0oIgAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@fortawesome/fontawesome-free" "^6.6.0"
"@abp/highlight.js@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-9.3.2.tgz#add22b40f5b412d6c86629a4d6d449d426c9b141"
integrity sha512-EVUCK6Hm3J+sMCuGZDTEEyWxfvAK5mxLuYGRuRrmzZvxXKsnAwqZitMddAvkZVAwN1QiV3gyXgdrz1XUBWZ2kg==
"@abp/highlight.js@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-9.3.3.tgz#fe557c7e3a8d17f3c319d6af8d90de4979f28589"
integrity sha512-sqRynOCoBZAYqqQXU3LEmSupC7HrkmRg+8I8CJJZbfduZJvETbWZyXAISLkyTOzPa9CvOOBXYjnpCkjCWqOxcg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
"@highlightjs/cdn-assets" "~11.10.0"
"@abp/jquery-form@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.2.tgz#17d0fe0a81d61e2e96131379e82872e5e45a2d5b"
integrity sha512-IwXWBRbtLhdB6/pJwQsWJHqLDHpZfJoA6x48A/GbTQLgWhpt0/OainDZsEUH3o0TWMhgJU+tp274uPENlG3DzQ==
"@abp/jquery-form@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-9.3.3.tgz#37d7e1c16b932e439e2127844991496b6557c094"
integrity sha512-B8uDWM13O+fB/TAN7xfMskLC0Qq8327waqpuctiulALz7uM4Ri1txANMp4+ftf25dxMeii/J4k6BSGer8K520Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-form "^4.3.0"
"@abp/jquery-validation-unobtrusive@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.2.tgz#f13183ed7108cdea1500f18b1f80aff3037132ce"
integrity sha512-0v0Rhj3bir91cqwhlxDuD0PqwEYceyqLYf6K5eFF1/nE+1wN1VIST/oLN1Xis9x4NswbnnKai+OST0fqagpuhg==
"@abp/jquery-validation-unobtrusive@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-9.3.3.tgz#3882d15076fcf4ef6a197648c84b9edd91435235"
integrity sha512-csWL1+h/aRkU71uoxsKCuGZU9zloPdY6WB1uSBCFDTJ4aBy6gkdtAZGwsXHsJZ4AiHwL+d22P9XVSF1MhKB+MQ==
dependencies:
"@abp/jquery-validation" "~9.3.2"
"@abp/jquery-validation" "~9.3.3"
jquery-validation-unobtrusive "^4.0.0"
"@abp/jquery-validation@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.2.tgz#8ec072e2babb5d75aa1088a3754b837b7387df76"
integrity sha512-JCquJcN0FAF+8TQOYgbqeDZqPIwy2mWVDtHKCts2lVj8ol+sQgWCOhZDx11sl1oqVZjkvdOmKMgWHDztdoUojA==
"@abp/jquery-validation@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-9.3.3.tgz#daea2a288e8c440051af21ebf519f7e40b4d27d3"
integrity sha512-nU6a04fiaZuHXRnV+J++AwcyZOxEvW6i4yqm2PzFT9OCbDk1E3X5S1ntO7sGlCcppxj0pSp3uL2Jxq5d4gq+qg==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jquery-validation "^1.21.0"
"@abp/jquery@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.2.tgz#edb3d65bdbd3885af72759ce0cd9d813ab41aade"
integrity sha512-i4scUZt6q09jhl8YTtQrPg+GV5Vd1QW57hHesYmgor8pLD87JU7cc5sCEJlmmtzVZsXjDkVuiyD2sOUXSItxMw==
"@abp/jquery@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-9.3.3.tgz#5c3ab4dfa820d9f2eb19fecc65194f0211d5bf37"
integrity sha512-5Nfw287+JugPCnm/KK8fjT4e5zHiwnL8w9OSAHVmf9UBcuJ2yBc+b8mklqy5pLt+jObouE5wJUOtENxgkgSkAw==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
jquery "~3.7.1"
"@abp/jstree@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/jstree/-/jstree-9.3.2.tgz#2442e3465fe168e90ffe2d672c1dc6f086c81b4f"
integrity sha512-B0WeKkAmfcwuI7DmS7/V/4neWIK/2RNXnMWVYSQPOZQm89mmSe/blQra4KRMZzlQLPAV76oncIHju01Cn+MV0w==
"@abp/jstree@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/jstree/-/jstree-9.3.3.tgz#6c7ab0049dc033da23617ce9e192fb98b1a0a081"
integrity sha512-HVkL6DtiURnhBhqivBAnVpFSgrAJ5HCsieVBPdciWdrggQ0Y/rPZN6F+HrrI28Asymnj8ayrG/4735yAn2bNZA==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
jstree "^3.3.17"
"@abp/lodash@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.2.tgz#d3ca624dd8927d33cf8728403ef591977b9e11f4"
integrity sha512-4XOhLKa/reKB85DyHtz1obC96j2VJs9+xqlO8Pn58hXP396cMEMuC1MfjHMwhPuMVHwgffg0UCfukKKf/UGJ/w==
"@abp/lodash@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-9.3.3.tgz#a60a41088288da41fa61b09cd747f1fde3c3ec40"
integrity sha512-GsAJPMGNHZcVHQWJMCEQ7oWSeRwmHx0n2oWLQOQoyFQu1itZeJy2dFE+nSIb2jAQ7sfKZVNw7OrEqN/VqgEoUg==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
lodash "^4.17.21"
"@abp/luxon@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.2.tgz#806464e828adf6b99a9620f3c39a16f8621ecd84"
integrity sha512-oP74Q9/FJ8QpB7yVOycFlfsGhPKFUk6NTnoT+cVRNg0wpUkRRjg5WTkZeKLoVxKNk9RwA/9fa6MnBiiNs2z/Pg==
"@abp/luxon@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-9.3.3.tgz#5742a90953bf0b24fa129f5a6a4c32dbdc134553"
integrity sha512-+AqTiMhN8Z8Khmv/9aBPwasNVcboJa9BV3WdJ5Nccwo2OEN7Wycw6TkRnb42fbUpzXAvxvwv9cSDHjRBib299A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
luxon "^3.5.0"
"@abp/malihu-custom-scrollbar-plugin@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.2.tgz#71069a6abd8a9456f0fc6227ee17b93300ad6030"
integrity sha512-6pFO68hvtbGiGTaxkzTPnzJA2NZkzE+acWlTfBvSVyMvZM1jER5wYJmDpflZO+WPtTTu9CUflTwvYw2TiNKlUg==
"@abp/malihu-custom-scrollbar-plugin@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-9.3.3.tgz#93a649bb621a47fb50b9b776fb864a07ccdff287"
integrity sha512-w83FD8mqGkhvoAEu0DwzcrmX1wwyKwVRkvfYmxjhokD7+Hq1FyuFDMO51F8hh590I2wzWCX8NvAVUP24viOY+A==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
malihu-custom-scrollbar-plugin "^3.1.5"
"@abp/markdown-it@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-9.3.2.tgz#1a673991c986eaec7cac5b035e4cbf2eed7c8d59"
integrity sha512-b/yTk312LZOWEF+f13zNHejdBf0dtdrjnd3LGFs9BDPyx2HMDAlDhZ9MiBM160W8ej1h3cIC06sbZBuyxns5Rg==
"@abp/markdown-it@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-9.3.3.tgz#4fc2b4934fe50999e6f20015b7f4e4bdbd185e38"
integrity sha512-6/IZ/2XQQzsnjYNBCcFxTroVenThiridD1oyRmtGK/+q7TGkgxU6x7b89losmvn8n1oGKBOOsqr/f3knEB/+RA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
markdown-it "^14.1.0"
"@abp/moment@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.2.tgz#150548dd2b817d586f87113abb40c85f9b1ab406"
integrity sha512-TdHeqPPEPk00/5vKbGHY6D74XlzfRM2Kb4WVvykVx2gjzScp5Sfunpus/A9UCOYls/bWp1MVMT7V0ExBXYPyNg==
"@abp/moment@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-9.3.3.tgz#622c424350620e0215a0a04059dfd3e18022fd69"
integrity sha512-m/xV11aWOZKTVVyGsX2mZl9ondcP8pWSmjmUKVNLrFSul4pRNgfM2ZeaKiaOLApkyOSZDzCEMUYbEf+dM2/rcg==
dependencies:
moment "^2.30.1"
"@abp/prismjs@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.2.tgz#2ea48bfa5ebcfd98962029eebeab374d63a4e242"
integrity sha512-q8bdUjk+IuP+nWzN8phgFjvKtOHR94OT5Sth7Rp64L68pVCJopihyth8f4mLZl7hMtwrro/5GFxjpR+KRNRpbg==
"@abp/prismjs@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-9.3.3.tgz#e34972d2943403fcfe4f41ec6771405afc553904"
integrity sha512-4LUIMa2elN9wpKJB3ndZz2XrntB4kCCeKZHvqpnwTwALsVsR+K5mVjR5jrsniJu4kJ0H51M+s/EMpgT6b1LQUA==
dependencies:
"@abp/clipboard" "~9.3.2"
"@abp/core" "~9.3.2"
"@abp/clipboard" "~9.3.3"
"@abp/core" "~9.3.3"
prismjs "^1.29.0"
"@abp/select2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.2.tgz#5c069ff7a9fcb9e78bd4a8591d1e5eac6d66f03f"
integrity sha512-/N5bJjyLQnN8zPovRrmrcYhiUxG/RTI6kNaH0QW/QEsryfuX24wdDWrRXacsJ1QKlMxig++IHRnpMBrHhxAKUw==
"@abp/select2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-9.3.3.tgz#8ef9bc3d3674d515d7b7f9060d77831246d03b6a"
integrity sha512-2g8LkLBu1Ooaxj6utYne1gPMYG9888l/mEFMJU5iHOPXS0vz4lANw+VjtawapFtP6yRSiD2/qJtOt0C5rQq1yA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
select2 "^4.0.13"
"@abp/slugify@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/slugify/-/slugify-9.3.2.tgz#dfca463f3750d264fd1ffcc5b14c7e15f3cf12ca"
integrity sha512-ux6j9ojt79g7D5AAODoBRwGeLkccynxEtQQQw+hk55YG5PZFImBL/BxRLEhkBBKBL7YrlHvnO58X2YoCUIG6Ug==
"@abp/slugify@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/slugify/-/slugify-9.3.3.tgz#9cf5b7d924f69a3e75e3cbfa87e0f7ee0e99ad3b"
integrity sha512-9cuT2CgCwcUumuTuMtVq108i65gAgz3SBWq7xy5CW5fS72OenRqi45N1m3yKQxhZ1JIkbvBGI5UlKHmWd9W7mQ==
dependencies:
slugify "^1.6.6"
"@abp/star-rating-svg@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-9.3.2.tgz#9d60ac8bc953e6dae544c2a9961c6905036253b7"
integrity sha512-97n81FqBxnBEQ9jUeXXOtuZ71VHW2mmbaOlroqLl+dE18PR/HIWBNUCEpKK7RCNRBUMMh1saIdv16ApBFVeBFQ==
"@abp/star-rating-svg@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-9.3.3.tgz#3330bcc4635aed05001404cbdf3cb84ef68f211e"
integrity sha512-rSpXtyhL7n21mp7O7GotbyJyBL+Yo/6+UAAXgPjpq0qia8OHB+aRPuZiyBBQwvPfR8nIzRK0wrdwOsaSaFU71Q==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
star-rating-svg "^3.5.0"
"@abp/sweetalert2@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.2.tgz#1ada87b720faef1289aa5fdcf42c0f5c74ff4493"
integrity sha512-PUNbt7O6reTqDelUBGryullFDD5XeZkgQFn/FXbZVp6y0owHUyIlX+Jr7PIesWEB/RHuLa+uZoSywtVPH7fsEw==
"@abp/sweetalert2@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-9.3.3.tgz#b9d6075d9ede12509f27576f88d54f21598f37df"
integrity sha512-CeX5IWwxAu9M4jqNZBK6o59sVoDuFgxnffhHTMEP7pt8WzH+2uucxGe/21gXT/PW1c3EjSwP3Ri2MhtKOFZuyQ==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
sweetalert2 "^11.14.1"
"@abp/timeago@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.2.tgz#fe4d184aed92dd265e3c9531c53bdc684abb3b52"
integrity sha512-GLimaRixGtZ5oiH3JLEmeUe54gePdSfVZtyJOvGcc0wQjQVOa5JgyTqktszb+pF4QVdeJr+ijz6RZlavwIY0EA==
"@abp/timeago@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-9.3.3.tgz#b116a7112c1d53588129587d5572dc0ae55567a5"
integrity sha512-L0X0yc8oS36eDx+8jvzreW4Cr4TnWESMceXihfOfuWbuOm4R58W4Cvx2/74XFiX/0if1WEg31P4Aj3LhpjgEaQ==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/jquery" "~9.3.3"
timeago "^1.6.7"
"@abp/tui-editor@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-9.3.2.tgz#7d18d8cf1d6dae3c5072c403dcc85af5ab9792ba"
integrity sha512-JnYCrr4UIZskB4zwNywdk76cXKUzMCXW5v4ec4ClbHC59FTKv34iIRonl1kYC/NkjDTGO8gvmyYG/3UeXrRWmQ==
"@abp/tui-editor@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-9.3.3.tgz#0a4651bb4babc625f4598ebddcb4049eedcff4cc"
integrity sha512-9iHqRRFS6EVqrKwZ75yVW2nkTkZxF5BcVOYnIMTApwrxsRTqzQ95tikt0UNUZ4qgmsgDy4LeOnJAVk1K6MsiQA==
dependencies:
"@abp/jquery" "~9.3.2"
"@abp/prismjs" "~9.3.2"
"@abp/jquery" "~9.3.3"
"@abp/prismjs" "~9.3.3"
"@abp/uppy@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/uppy/-/uppy-9.3.2.tgz#9e8647bd79c92263f2e8744ec2aa5180db9923b3"
integrity sha512-JXK43liPBifJC/Byq4VA+xWRPyd6ScurbK9FJZQMoD7kWLg/iFVSyLn7D7U4khYmCnmz8nc96SfgE8+CEsCaBQ==
"@abp/uppy@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/uppy/-/uppy-9.3.3.tgz#cb7371e323340021f8de80295f53557df05aeab7"
integrity sha512-/3dBmqlxt/pJ5iQJN6zqoGyCmXN4MSqkKqR+ZVo+z5H807GQiYfZbQ8aqDzTpqIEEF+9NU5Czyelvm5zby6PlA==
dependencies:
"@abp/core" "~9.3.2"
"@abp/core" "~9.3.3"
uppy "^4.4.1"
"@abp/utils@~9.3.2":
version "9.3.2"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.2.tgz#f2158e9858c8efcbd3f17bf6e79c41116ac66795"
integrity sha512-DtD07VHsDS5KPfn3jnL6f9WsfXEJVv7xUF+NcgW+HBTHnJTxunnE/OYGf/clTM4xeDb+RWl3AoGYP+kF4H/Snw==
"@abp/utils@~9.3.3":
version "9.3.3"
resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-9.3.3.tgz#e8cda12eb1f7432787072c2d5fe9905b7613e2ec"
integrity sha512-X1q9hod+Z6x/QypixI8BVvnMOqncQXM/Vs2Kq2p0jJJsNoerOFqGr+qLqZ5x3e5CoSz0H/38VjaG1yxIoq2exA==
dependencies:
just-compare "^2.3.0"

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save