diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml index ec7ba474f0..6f36836d6c 100644 --- a/.github/workflows/auto-pr.yml +++ b/.github/workflows/auto-pr.yml @@ -1,13 +1,13 @@ -name: Merge branch dev with rel-10.2 +name: Merge branch dev with rel-10.3 on: push: branches: - - rel-10.2 + - rel-10.3 permissions: contents: read jobs: - merge-dev-with-rel-10-2: + merge-dev-with-rel-10-3: permissions: contents: write # for peter-evans/create-pull-request to create branch pull-requests: write # for peter-evans/create-pull-request to create a PR @@ -18,14 +18,14 @@ jobs: ref: dev - name: Reset promotion branch run: | - git fetch origin rel-10.2:rel-10.2 - git reset --hard rel-10.2 + git fetch origin rel-10.3:rel-10.3 + git reset --hard rel-10.3 - name: Create Pull Request uses: peter-evans/create-pull-request@v3 with: - branch: auto-merge/rel-10-2/${{github.run_number}} - title: Merge branch dev with rel-10.2 - body: This PR generated automatically to merge dev with rel-10.2. Please review the changed files before merging to prevent any errors that may occur. + branch: auto-merge/rel-10-3/${{github.run_number}} + title: Merge branch dev with rel-10.3 + body: This PR generated automatically to merge dev with rel-10.3. Please review the changed files before merging to prevent any errors that may occur. draft: true token: ${{ github.token }} - name: Merge Pull Request @@ -33,5 +33,5 @@ jobs: GH_TOKEN: ${{ secrets.BOT_SECRET }} run: | gh pr ready - gh pr review auto-merge/rel-10-2/${{github.run_number}} --approve - gh pr merge auto-merge/rel-10-2/${{github.run_number}} --merge --auto --delete-branch + gh pr review auto-merge/rel-10-3/${{github.run_number}} --approve + gh pr merge auto-merge/rel-10-3/${{github.run_number}} --merge --auto --delete-branch diff --git a/.github/workflows/update-studio-docs.yml b/.github/workflows/update-studio-docs.yml index 541ceeaf30..9e16b07280 100644 --- a/.github/workflows/update-studio-docs.yml +++ b/.github/workflows/update-studio-docs.yml @@ -18,9 +18,9 @@ on: description: 'Release URL' required: true target_branch: - description: 'Target branch (default: dev)' + description: 'Target branch (leave empty to auto-detect from latest stable ABP release)' required: false - default: 'dev' + default: '' jobs: update-docs: @@ -41,7 +41,7 @@ jobs: echo "version=${{ github.event.client_payload.version }}" >> $GITHUB_OUTPUT echo "name=${{ github.event.client_payload.name }}" >> $GITHUB_OUTPUT echo "url=${{ github.event.client_payload.url }}" >> $GITHUB_OUTPUT - echo "target_branch=${{ github.event.client_payload.target_branch || 'dev' }}" >> $GITHUB_OUTPUT + echo "target_branch=${{ github.event.client_payload.target_branch }}" >> $GITHUB_OUTPUT # Save notes to environment variable (multiline) { @@ -53,7 +53,7 @@ jobs: echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT echo "name=${{ github.event.inputs.name }}" >> $GITHUB_OUTPUT echo "url=${{ github.event.inputs.url }}" >> $GITHUB_OUTPUT - echo "target_branch=${{ github.event.inputs.target_branch || 'dev' }}" >> $GITHUB_OUTPUT + echo "target_branch=${{ github.event.inputs.target_branch }}" >> $GITHUB_OUTPUT # Save notes to environment variable (multiline) { @@ -63,12 +63,55 @@ jobs: } >> $GITHUB_ENV fi + # ------------------------------------------------- + # Resolve target branch (auto-detect from latest stable ABP if not provided) + # ------------------------------------------------- + - name: Resolve target branch + id: resolve_branch + run: | + TARGET_BRANCH="${{ steps.payload.outputs.target_branch }}" + + if [ -z "$TARGET_BRANCH" ]; then + echo "๐Ÿ” No target_branch provided - fetching latest stable ABP release..." + + RELEASES=$(curl -fsS \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/abpframework/abp/releases?per_page=20") + + ABP_VERSION=$(echo "$RELEASES" | jq -r ' + [.[] | select( + (.prerelease == false) and + (.tag_name | test("preview|rc|beta|dev"; "i") | not) + )] | first | .tag_name + ') + + if [ -z "$ABP_VERSION" ] || [ "$ABP_VERSION" = "null" ]; then + echo "โŒ Could not determine latest stable ABP version" + exit 1 + fi + + # Derive rel-X.Y from X.Y.Z (e.g., 10.1.1 -> rel-10.1) + TARGET_BRANCH=$(echo "$ABP_VERSION" | grep -oE '^[0-9]+\.[0-9]+' | sed 's/^/rel-/') + + if [ -z "$TARGET_BRANCH" ]; then + echo "โŒ Could not derive target branch from version: $ABP_VERSION" + exit 1 + fi + + echo "โœ… Auto-detected target branch: $TARGET_BRANCH (from ABP $ABP_VERSION)" + else + echo "โœ… Using provided target branch: $TARGET_BRANCH" + fi + + echo "target_branch=$TARGET_BRANCH" >> $GITHUB_OUTPUT + - name: Validate payload env: VERSION: ${{ steps.payload.outputs.version }} NAME: ${{ steps.payload.outputs.name }} URL: ${{ steps.payload.outputs.url }} - TARGET_BRANCH: ${{ steps.payload.outputs.target_branch }} + TARGET_BRANCH: ${{ steps.resolve_branch.outputs.target_branch }} run: | if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then echo "โŒ Missing: version" @@ -98,7 +141,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - ref: ${{ steps.payload.outputs.target_branch }} + ref: ${{ steps.resolve_branch.outputs.target_branch }} fetch-depth: 0 - name: Configure git @@ -563,7 +606,7 @@ jobs: VERSION: ${{ steps.payload.outputs.version }} NAME: ${{ steps.payload.outputs.name }} URL: ${{ steps.payload.outputs.url }} - TARGET_BRANCH: ${{ steps.payload.outputs.target_branch }} + TARGET_BRANCH: ${{ steps.resolve_branch.outputs.target_branch }} run: | # Check for existing PR EXISTING_PR=$(gh pr list \ @@ -593,7 +636,8 @@ jobs: gh pr edit "$EXISTING_PR" \ --title "docs(studio): release $VERSION - $NAME" \ - --body "$PR_BODY" + --body "$PR_BODY" \ + --add-reviewer skoc10 echo "PR_NUMBER=$EXISTING_PR" >> $GITHUB_ENV else @@ -605,7 +649,8 @@ jobs: --title "docs(studio): release $VERSION - $NAME" \ --body "$PR_BODY" \ --base "$TARGET_BRANCH" \ - --head "$BRANCH") + --head "$BRANCH" \ + --reviewer skoc10) PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$') echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV @@ -643,7 +688,7 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY echo "**Version**: $VERSION" >> $GITHUB_STEP_SUMMARY echo "**Release**: ${{ steps.payload.outputs.name }}" >> $GITHUB_STEP_SUMMARY - echo "**Target Branch**: ${{ steps.payload.outputs.target_branch }}" >> $GITHUB_STEP_SUMMARY + echo "**Target Branch**: ${{ steps.resolve_branch.outputs.target_branch }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY if [ "${{ steps.changes.outputs.has_changes }}" = "true" ]; then diff --git a/Directory.Packages.props b/Directory.Packages.props index 8a10f5f8c6..d31678a994 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,8 +7,8 @@ - - + + @@ -77,7 +77,7 @@ - + @@ -151,7 +151,7 @@ - + diff --git a/common.props b/common.props index 15fafa9120..f952304d6f 100644 --- a/common.props +++ b/common.props @@ -1,8 +1,8 @@ latest - 10.3.0-preview - 5.3.0-preview + 10.4.0-preview + 5.4.0-preview $(NoWarn);CS1591;CS0436 https://abp.io/assets/abp_nupkg.png https://abp.io/ diff --git a/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/POST.md b/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/POST.md new file mode 100644 index 0000000000..fe0546eef9 --- /dev/null +++ b/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/POST.md @@ -0,0 +1,72 @@ +# ABP.IO Platform 10.2 Final Has Been Released! + +We are glad to announce that [ABP](https://abp.io/) 10.2 stable version has been released. + +## What's New With Version 10.2? + +All the new features were explained in detail in the [10.2 RC Announcement Post](https://abp.io/community/announcements/announcing-abp-10-2-release-candidate-05zatjfq), so there is no need to review them again. You can check it out for more details. + +## Getting Started with 10.2 + +### How to Upgrade an Existing Solution + +You can upgrade your existing solutions with either ABP Studio or ABP CLI. In the following sections, both approaches are explained: + +### Upgrading via ABP Studio + +If you are already using the ABP Studio, you can upgrade it to the latest version. ABP Studio periodically checks for updates in the background, and when a new version of ABP Studio is available, you will be notified through a modal. Then, you can update it by confirming the opened modal. See [the documentation](https://abp.io/docs/latest/studio/installation#upgrading) for more info. + +After upgrading the ABP Studio, then you can open your solution in the application, and simply click the **Upgrade ABP Packages** action button to instantly upgrade your solution: + +![](upgrade-abp-packages.png) + +### Upgrading via ABP CLI + +Alternatively, you can upgrade your existing solution via ABP CLI. First, you need to install the ABP CLI or upgrade it to the latest version. + +If you haven't installed it yet, you can run the following command: + +```bash +dotnet tool install -g Volo.Abp.Studio.Cli +``` + +Or to update the existing CLI, you can run the following command: + +```bash +dotnet tool update -g Volo.Abp.Studio.Cli +``` + +After installing/updating the ABP CLI, you can use the [`update` command](https://abp.io/docs/latest/CLI#update) to update all the ABP related NuGet and NPM packages in your solution as follows: + +```bash +abp update +``` + +You can run this command in the root folder of your solution to update all ABP related packages. + +## Migration Guides + +There are a few breaking changes in this version that may affect your application. Please read the migration guide carefully, if you are upgrading from v10.1 or earlier versions: [ABP Version 10.2 Migration Guide](https://abp.io/docs/10.2/release-info/migration-guides/abp-10-2) + +## Community News + +### New ABP Community Articles + +As always, exciting articles have been contributed by the ABP community. I will highlight some of them here: + +- [Liming Ma](https://abp.io/community/members/maliming) has published 6 new posts: + - [Dynamic Events in ABP](https://abp.io/community/articles/dynamic-events-in-abp-dukq95m1) + - [Dynamic Background Jobs and Workers in ABP](https://abp.io/community/articles/dynamic-background-jobs-and-workers-in-abp-wfdkdsq9) + - [Shared User Accounts in ABP Multi-Tenancy](https://abp.io/community/articles/shared-user-accounts-in-abp-multitenancy-mf3bkg79) + - [Secure Client Authentication with private_key_jwt in ABP 10.3](https://abp.io/community/articles/secure-client-authentication-with-privatekeyjwt-in-abp-b2rf18bc) + - [Operation Rate Limiting in ABP Framework](https://abp.io/community/articles/operation-rate-limiting-in-abp-framework-f4jtd6sn) + - [Resource-Based Authorization in ABP Framework](https://abp.io/community/articles/resourcebased-authorization-in-abp-framework-choku1sn) +- [One Endpoint, Many AI Clients: Turning ABP Workspaces into OpenAI-Compatible Models](https://abp.io/community/articles/turning-abp-workspaces-into-openai-compatible-endpoints-u3ls1gp4) by [Engincan Veske](https://abp.io/community/members/EngincanV) +- [Automatically Validate Your Documentation: How We Built a Tutorial Validator](https://abp.io/community/articles/automatically-validate-your-documentation-m3ozgkhv) by [Mansur Besleney](https://abp.io/community/members/mansur.besleney) +- [Automate Localhost Access for Expo: A Guide to Dynamic Cloudflare Tunnels & Dev Builds](https://abp.io/community/articles/automate-localhost-access-for-expo-a-guide-to-dynamic-7cblqtj3) by [Sumeyye Kurtulus](https://abp.io/community/members/sumeyye.kurtulus) + +Thanks to the ABP Community for all the content they have published. You can also [post your ABP related (text or video) content](https://abp.io/community/posts/create) to the ABP Community. + +## About the Next Version + +The next feature version will be 10.3. You can follow the [release planning here](https://github.com/abpframework/abp/milestones). Please [submit an issue](https://github.com/abpframework/abp/issues/new) if you have any problems with this version. diff --git a/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/cover-image.png b/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/cover-image.png new file mode 100644 index 0000000000..e9fcd305b6 Binary files /dev/null and b/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/cover-image.png differ diff --git a/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/upgrade-abp-packages.png b/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/upgrade-abp-packages.png new file mode 100644 index 0000000000..4ec1d19589 Binary files /dev/null and b/docs/en/Blog-Posts/2026-03-31 v10_2_Release_Stable/upgrade-abp-packages.png differ diff --git a/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/POST.md b/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/POST.md new file mode 100644 index 0000000000..853a7100d4 --- /dev/null +++ b/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/POST.md @@ -0,0 +1,254 @@ +# ABP Platform 10.3 RC Has Been Released + +We are happy to release [ABP](https://abp.io) version **10.3 RC** (Release Candidate). This blog post introduces the new features and important changes in this new version. + +Try this version and provide feedback for a more stable version of ABP v10.3! Thanks to you in advance. + +## Get Started with the 10.3 RC + +You can check the [Get Started page](https://abp.io/get-started) to see how to get started with ABP. You can either download [ABP Studio](https://abp.io/get-started#abp-studio-tab) (**recommended**, if you prefer a user-friendly GUI application - desktop application) or use the [ABP CLI](https://abp.io/docs/latest/cli). + +By default, ABP Studio uses stable versions to create solutions. Therefore, if you want to create a solution with a preview version, first you need to create a solution and then switch your solution to the preview version from the ABP Studio UI: + +![studio-switch-to-preview.png](studio-switch-to-preview.png) + +## Migration Guide + +There are no explicitly marked breaking changes in this version. However, there are still some important migration notes for specific scenarios. Please check the migration guide if you are upgrading from v10.2 or earlier: [ABP Version 10.3 Migration Guide](https://abp.io/docs/10.3/release-info/migration-guides/abp-10-3). + +## What's New with ABP v10.3? + +In this section, I will introduce some major features released in this version. +Here is a brief list of titles explained in the next sections: + +- OpenIddict: `private_key_jwt` Client Authentication + `abp generate-jwks` +- Event Bus: String-Based Event Publishing with Dynamic Payload +- Background Jobs/Workers: String-Based Publishing with Dynamic Payload +- API Definition Endpoint: Descriptions and Documentation Support +- Entity Cache: New Batch APIs (`FindMany*` / `GetMany*`) +- Angular: User/Tenant Sharing and Tenant Switch Experience +- Angular: Upgrade to 21.2 + TypeScript 5.9 +- Introducing the `Volo.Abp.LuckyPenny.AutoMapper` Provider +- Security Improvements (Account Pro Module) + +### OpenIddict: `private_key_jwt` Client Authentication + `abp generate-jwks` + +ABP v10.3 introduces end-to-end support for OpenIddict `private_key_jwt` client authentication. +Instead of using a shared `client_secret`, clients can now authenticate with an asymmetric key pair: keep the private key on the client, and register the public key (JWKS) on the authorization server. + +On the open-source side, ABP CLI now includes the `abp generate-jwks` command (and the OpenIddict demo was updated accordingly). On the Pro side, OpenIddict application management now supports storing and validating JWKS for confidential applications. + +This is especially useful for machine-to-machine and compliance-focused environments where shared secrets are not preferred. + +**Example - Generate a JWKS with ABP CLI:** + +```bash +abp generate-jwks --alg RS256 --key-size 2048 -o ./keys -f my-client +``` +> See the community article [Secure Client Authentication with private_key_jwt in ABP 10.3](https://abp.io/community/articles/secure-client-authentication-with-privatekeyjwt-in-abp-b2rf18bc) for a full walkthrough. +> This approach is especially useful for Pro solutions that manage confidential clients in the administration UI. + +### Event Bus: String-Based Event Publishing with Dynamic Payload + +ABP v10.3 adds string-based publishing and subscription APIs for event-driven integrations. + +When you do not know event types at compile time, you can now publish and handle events by name without introducing extra wrapper contracts up front. This is especially useful for plugin ecosystems, partner integrations, and metadata-driven application flows. + +This is not a separate eventing model. Dynamic events run through the same ABP infrastructure (including outbox/inbox when configured), can be handled through `DynamicEventData`, and can coexist with typed handlers for the same event name. Distributed providers support this approach except Dapr, which requires startup-time topic declarations. + +**Example - Publish by event name:** + +```csharp +await _distributedEventBus.PublishAsync( + "OrderPlaced", + new { OrderId = input.Id, CustomerEmail = input.Email } +); +``` + +**Example - Subscribe dynamically at runtime:** + +```csharp +eventBus.Subscribe("PartnerOrderReceived", + new PartnerOrderHandler(context.ServiceProvider)); + +public class PartnerOrderHandler : IDistributedEventHandler +{ + public Task HandleEventAsync(DynamicEventData eventData) + { + // eventData.EventName + eventData.Data + return Task.CompletedTask; + } +} +``` + +> See the community article [Dynamic Events in ABP](https://abp.io/community/articles/dynamic-events-in-abp-dukq95m1) for details. + +### Background Jobs/Workers: String-Based Publishing with Dynamic Payload + +ABP v10.3 introduces **Dynamic Background Jobs** (`IDynamicBackgroundJobManager`) and **Dynamic Background Workers** (`IDynamicBackgroundWorkerManager`) for runtime registration and execution by name. + +With these APIs, you can enqueue jobs with dynamic payloads, register handler delegates at startup, and add/update/remove recurring workers at runtime. This is especially useful for plugin architectures, metadata-driven workflows, and tenant-specific scheduling scenarios where task types are not known at compile time. + +Dynamic background jobs work through ABP's existing typed job pipeline (including provider integrations), while dynamic workers support runtime schedule management (period/cron depending on provider). + +**Example - Enqueue a job by name with dynamic payload:** + +```csharp +await _dynamicBackgroundJobManager.EnqueueAsync("emails", new +{ + EmailAddress = input.CustomerEmail, + Subject = "Order Confirmed", + Body = $"Your order {input.OrderId} has been placed." +}); +``` + +**Example - Update worker schedule at runtime:** + +```csharp +await workerManager.UpdateScheduleAsync( + "InventorySyncWorker", + new DynamicBackgroundWorkerSchedule { Period = 10000 } // 10s +); +``` + +> See [#25059](https://github.com/abpframework/abp/pull/25059) and the community article [Dynamic Background Jobs and Workers in ABP](https://abp.io/community/articles/dynamic-background-jobs-and-workers-in-abp-wfdkdsq9) for details. + +### API Definition Endpoint: Descriptions and Documentation Support + +The API definition endpoint can now optionally return richer metadata such as summary/description fields for controllers, actions, and parameters. + +This is particularly useful for dynamic client generation, API explorers, and tooling that consumes ABP API metadata directly without requiring OpenAPI parsing. + +> See [#25022](https://github.com/abpframework/abp/pull/25022) for details. + +### Entity Cache: New Batch APIs (`FindMany*` / `GetMany*`) + +ABP v10.3 extends `IEntityCache` with batch retrieval APIs so you can resolve multiple entities in a single cache/database flow instead of looping over `FindAsync`/`GetAsync`. + +It includes both list-based APIs (`FindManyAsync` / `GetManyAsync`) and dictionary-based APIs (`FindManyAsDictionaryAsync` / `GetManyAsDictionaryAsync`) so you can choose the shape that best matches your access pattern. + +**Example - List-based batch retrieval (preserves input order):** + +```csharp +var ids = new List { id1, id2, id1 }; + +var products = await _productCache.GetManyAsync(ids); // throws if any ID is missing +var productsOrNull = await _productCache.FindManyAsync(ids); // null for missing IDs +``` + +**Example - Dictionary-based batch retrieval (fast lookup by ID):** + +```csharp +var productsById = await _productCache.GetManyAsDictionaryAsync(ids); +var nullableProductsById = await _productCache.FindManyAsDictionaryAsync(ids); + +if (nullableProductsById.TryGetValue(id1, out var product) && product != null) +{ + // use product +} +``` + +All of these methods are optimized for bulk scenarios by internally batching cache misses via distributed cache multi-get/multi-add operations. + +> See [#25088](https://github.com/abpframework/abp/pull/25088) and [#25090](https://github.com/abpframework/abp/pull/25090) for details. + +### Angular: User/Tenant Sharing and Tenant Switch Experience + +ABP v10.3 enhances Angular UX for shared-user multi-tenancy scenarios, including invitation flows, tenant switch UX, and related identity/account integrations. + +This improves the out-of-the-box experience for applications using tenant user sharing. + +> See [#25051](https://github.com/abpframework/abp/pull/25051) for details. + +### Angular: Upgrade to 21.2 + TypeScript 5.9 + +ABP v10.3 upgrades Angular to **21.2** and TypeScript to **5.9**, bringing the Angular UI stack to the latest ABP-supported frontend baseline. + +This helps you stay current with the modern Angular and TypeScript ecosystem while benefiting from newer compiler/tooling improvements and maintaining compatibility with the ABP Angular packages in this release. + +> See [#25072](https://github.com/abpframework/abp/pull/25072) for details. + +### Introducing the `Volo.Abp.LuckyPenny.AutoMapper` Provider + +ABP v10.3 introduces `Volo.Abp.LuckyPenny.AutoMapper` as a new optional provider integration for projects that want to use the LuckyPenny-maintained AutoMapper package. + +The existing `Volo.Abp.AutoMapper` package remains unchanged, and migration is straightforward: replace `AbpAutoMapperModule` with `AbpLuckyPennyAutoMapperModule` in your module dependencies while keeping the same ABP-facing namespaces and APIs. + +This update also addresses the AutoMapper 14.x vulnerability context ([GHSA-rvv3-g6hj-g44x](https://github.com/advisories/GHSA-rvv3-g6hj-g44x)), and ABP documentation was expanded with installation, usage, and migration guidance. For more information, see the documentation: [LuckyPenny AutoMapper Integration](https://abp.io/docs/10.3/framework/infrastructure/luckypenny-automapper). + +### Security Improvements (Account Pro Module) + +ABP Commercial v10.3 RC also includes notable account security hardening: + +- Optional CAPTCHA for forgot-password flow +- Operation-based rate limiting policies for account confirmation/token operations (including updated/default policies for reset and token endpoints) +- Session revocation after sensitive credential operations (password change/reset/admin reset) +- Stronger profile picture upload validation (allowed extensions, max size, and magic-bytes checks) + +These changes are security-focused and are designed to be practical for real projects. Here are the key points and how you can tune them: + +- **Forgot-password abuse protection**: You can enable CAPTCHA for forgot-password flows to reduce automated reset attempts. +- **Operation-level rate limiting**: Token/confirmation/reset operations now rely on policy-based limits, so you can centralize and customize limits per operation. +- **Safer session behavior**: Password changes/resets now revoke sessions to reduce risk from stolen or long-lived sessions. +- **Profile picture hardening**: Uploads are checked by extension, size, and file signature (magic bytes), not only by client-provided metadata. + +**Example - Tune profile picture upload restrictions:** + +```csharp +Configure(options => +{ + options.AllowedFileExtensions = new[] { ".jpg", ".jpeg", ".png" }; + options.MaxFileSizeInBytes = 2 * 1024 * 1024; // 2 MB +}); +``` + +**Example - Override account operation rate-limiting policies:** + +```csharp +Configure(options => +{ + options.ConfigurePolicy( + AbpAccountOperationRateLimitPolicies.SendPasswordResetCode, + policy => + { + policy.ClearRules(); + policy.PerHour(5); + policy.PerDay(20); + }); +}); +``` + +> See the community article [Operation Rate Limiting in ABP Framework](https://abp.io/community/articles/operation-rate-limiting-in-abp-framework-f4jtd6sn) for conceptual guidance. + +### Other Improvements and Enhancements + +- **Permission integration endpoint update**: `PermissionIntegrationController.IsGrantedAsync` now uses `HttpPost` for large payload scenarios ([#25177](https://github.com/abpframework/abp/pull/25177)). +- **OpenIddict dependency update**: Upgraded to OpenIddict 7.3.0 ([#25053](https://github.com/abpframework/abp/pull/25053)). +- **Autofac integration update**: Upgraded `Autofac.Extensions.DependencyInjection` to 11.0.0 ([#25190](https://github.com/abpframework/abp/pull/25190)). +- **MongoDB dependency update**: Bumped MongoDB.Driver to 3.7.1 ([#25114](https://github.com/abpframework/abp/pull/25114)). +- **OIDC auth storage options for Angular UI (pro)**: OIDC auth storage is now configurable. + +## Community News + +### New ABP Community Articles + +As always, exciting articles have been contributed by the ABP community. I will highlight some of them here: + +- [Liming Ma](https://abp.io/community/members/maliming) has published 6 new posts: + - [Dynamic Events in ABP](https://abp.io/community/articles/dynamic-events-in-abp-dukq95m1) + - [Dynamic Background Jobs and Workers in ABP](https://abp.io/community/articles/dynamic-background-jobs-and-workers-in-abp-wfdkdsq9) + - [Shared User Accounts in ABP Multi-Tenancy](https://abp.io/community/articles/shared-user-accounts-in-abp-multitenancy-mf3bkg79) + - [Secure Client Authentication with private_key_jwt in ABP 10.3](https://abp.io/community/articles/secure-client-authentication-with-privatekeyjwt-in-abp-b2rf18bc) + - [Operation Rate Limiting in ABP Framework](https://abp.io/community/articles/operation-rate-limiting-in-abp-framework-f4jtd6sn) + - [Resource-Based Authorization in ABP Framework](https://abp.io/community/articles/resourcebased-authorization-in-abp-framework-choku1sn) +- [One Endpoint, Many AI Clients: Turning ABP Workspaces into OpenAI-Compatible Models](https://abp.io/community/articles/turning-abp-workspaces-into-openai-compatible-endpoints-u3ls1gp4) by [Engincan Veske](https://abp.io/community/members/EngincanV) +- [Automatically Validate Your Documentation: How We Built a Tutorial Validator](https://abp.io/community/articles/automatically-validate-your-documentation-m3ozgkhv) by [Mansur Besleney](https://abp.io/community/members/mansur.besleney) +- [Automate Localhost Access for Expo: A Guide to Dynamic Cloudflare Tunnels & Dev Builds](https://abp.io/community/articles/automate-localhost-access-for-expo-a-guide-to-dynamic-7cblqtj3) by [Sumeyye Kurtulus](https://abp.io/community/members/sumeyye.kurtulus) + +Thanks to the ABP Community for all the content they have published. You can also [post your ABP related (text or video) content](https://abp.io/community/posts/create) to the ABP Community. + +## Conclusion + +This version comes with some new features and a lot of enhancements to the existing features. You can see the [Road Map](https://abp.io/docs/10.3/release-info/road-map) documentation to learn about the release schedule and planned features for the next releases. Please try ABP v10.3 RC and provide feedback to help us release a more stable version. + +Thanks for being a part of this community! diff --git a/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/cover-image.png b/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/cover-image.png new file mode 100644 index 0000000000..d51944220d Binary files /dev/null and b/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/cover-image.png differ diff --git a/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/studio-switch-to-preview.png b/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/studio-switch-to-preview.png new file mode 100644 index 0000000000..62fd4d165e Binary files /dev/null and b/docs/en/Blog-Posts/2026-04-01 v10_3_Preview/studio-switch-to-preview.png differ diff --git a/docs/en/Community-Articles/2026-03-10-Tutorial-Validator/article.md b/docs/en/Community-Articles/2026-03-10-Tutorial-Validator/article.md index 43dee7c712..c54b50c881 100644 --- a/docs/en/Community-Articles/2026-03-10-Tutorial-Validator/article.md +++ b/docs/en/Community-Articles/2026-03-10-Tutorial-Validator/article.md @@ -1,4 +1,6 @@ -# Automatically Validate Your Documentation: How We Built a Tutorial Validator +# Automatically Validate Your Documentation: How We Built an AI Tutorial Validator + +> If you're in a hurry and want to quickly check the repository, you can find the source code of the AI Tutorial Validator here ๐Ÿ‘‰ [github.com/abpframework/ai-tutorial-validator](https://github.com/abpframework/ai-tutorial-validator) Writing a tutorial is difficult. Keeping technical documentation accurate over time is even harder. If you maintain developer documentation, you probably know the problem: a tutorial that worked a few months ago can silently break after a framework update, dependency change, or a small missing line in a code snippet. @@ -34,7 +36,7 @@ It treats tutorials like testable workflows, ensuring that every step works exac ## How the Tutorial Validator Works? -the tutorial validator validates tutorials using a three-stage pipeline: +The tutorial validator validates tutorials using a three-stage pipeline: 1. **Analyst**: Scrapes tutorial pages and converts instructions into a structured test plan 2. **Executor**: Follows the plan step by step in a clean environment @@ -43,7 +45,7 @@ the tutorial validator validates tutorials using a three-stage pipeline: ![the tutorial validator Analyst](docs/images/image-1.png) It identifies commands, code edits, HTTP requests, and expected outcomes. -The key idea is simple: if a developer would need to do it, the validator does it too. +The key idea is simple: if a developer needs to do it, the validator does it too. That includes running terminal commands, editing files, checking HTTP responses, and validating build outcomes. ![the tutorial validator Executor](docs/images/image-2.png) @@ -108,6 +110,6 @@ If your team maintains technical tutorials, this project can give you a practica --- -You can find the source-code of the tutorial validator at this repo ๐Ÿ‘‰ https://github.com/abpframework/tutorial-validator +You can find the source code of the tutorial validator at this repo ๐Ÿ‘‰ [github.com/abpframework/ai-tutorial-validator](https://github.com/abpframework/ai-tutorial-validator) We would love to hear your feedback, ideas and waiting PRs to improve this application. diff --git a/docs/en/Community-Articles/2026-03-23-Dynamic-Events-in-ABP/POST.md b/docs/en/Community-Articles/2026-03-23-Dynamic-Events-in-ABP/POST.md index cdc1a03f58..b69d14e1a8 100644 --- a/docs/en/Community-Articles/2026-03-23-Dynamic-Events-in-ABP/POST.md +++ b/docs/en/Community-Articles/2026-03-23-Dynamic-Events-in-ABP/POST.md @@ -72,40 +72,45 @@ Publishing by name with `new { OrderId = ..., CustomerEmail = ... }` triggers th Dynamic subscription lets you register event handlers at runtime, using a string event name. +The recommended approach is to use `IocEventHandlerFactory`, which is the same mechanism ABP uses internally for typed handlers. It creates a new DI scope for each event, resolves a fresh handler instance, calls `HandleEventAsync`, then disposes the scope โ€” so the handler can use normal constructor injection without any manual scope management: + ```csharp -public override async Task OnApplicationInitializationAsync( +public override void ConfigureServices(ServiceConfigurationContext context) +{ + context.Services.AddTransient(); +} + +public override void OnApplicationInitialization( ApplicationInitializationContext context) { var eventBus = context.ServiceProvider .GetRequiredService(); + var scopeFactory = context.ServiceProvider + .GetRequiredService(); // Subscribe to a dynamic event โ€” no event class needed eventBus.Subscribe("PartnerOrderReceived", - new PartnerOrderHandler(context.ServiceProvider)); + new IocEventHandlerFactory(scopeFactory, typeof(PartnerOrderHandler))); } ``` -The handler implements `IDistributedEventHandler`: +The handler implements `IDistributedEventHandler` and injects its dependencies normally: ```csharp public class PartnerOrderHandler : IDistributedEventHandler { - private readonly IServiceProvider _serviceProvider; + private readonly IPartnerOrderProcessor _orderProcessor; - public PartnerOrderHandler(IServiceProvider serviceProvider) + public PartnerOrderHandler(IPartnerOrderProcessor orderProcessor) { - _serviceProvider = serviceProvider; + _orderProcessor = orderProcessor; } public async Task HandleEventAsync(DynamicEventData eventData) { // eventData.EventName = "PartnerOrderReceived" // eventData.Data = the raw payload from the broker - - var orderProcessor = _serviceProvider - .GetRequiredService(); - - await orderProcessor.ProcessAsync(eventData.EventName, eventData.Data); + await _orderProcessor.ProcessAsync(eventData.EventName, eventData.Data); } } ``` @@ -115,18 +120,22 @@ public class PartnerOrderHandler : IDistributedEventHandler - **`EventName`** โ€” the string name that identifies the event - **`Data`** โ€” the raw event data payload (the deserialized `object` from the broker) -> `Subscribe` returns an `IDisposable`. Call `Dispose()` to unsubscribe the handler at runtime. +> `Subscribe` returns an `IDisposable`. Call `Dispose()` to unsubscribe the handler at runtime. For application-lifetime subscriptions, prefer module initialization (`OnApplicationInitialization` / `OnApplicationInitializationAsync`) over subscribing inside an application service. ## Mixed Typed and Dynamic Handlers Typed and dynamic handlers coexist naturally. When both are registered for the same event name, **both are triggered** โ€” the framework automatically converts the data to the appropriate format for each handler. ```csharp +var eventBus = context.ServiceProvider.GetRequiredService(); +var scopeFactory = context.ServiceProvider.GetRequiredService(); + // Typed handler โ€” receives OrderPlacedEto eventBus.Subscribe(); // Dynamic handler โ€” receives DynamicEventData for the same event -eventBus.Subscribe("OrderPlaced", new AuditLogHandler()); +eventBus.Subscribe("OrderPlaced", + new IocEventHandlerFactory(scopeFactory, typeof(AuditLogHandler))); ``` When `OrderPlacedEto` is published (by type or by name), both handlers fire. The typed handler receives a fully deserialized `OrderPlacedEto` object. The dynamic handler receives a `DynamicEventData` wrapping the raw payload. diff --git a/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/POST.md b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/POST.md new file mode 100644 index 0000000000..e8a5d16015 --- /dev/null +++ b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/POST.md @@ -0,0 +1,167 @@ +# SEO-Friendly Localized URLs in ABP with a Single Line of Configuration + +ABP has always supported language switching via the `?culture=en` query string and the culture cookie. That works fine for most applications โ€” but it has a limitation that shows up quickly once SEO or link-sharing matters. + +Consider a book-store app where users browse in their language: + +- A Spanish user shares a product link. The recipient opens it in English because the cookie on *their* machine says `en`. +- Search engines crawl the same URL in every language, making it impossible to create separate sitemaps per locale. +- A user shares a link like `/Books/Detail?id=42&culture=es`. When the server processes the request, it sets the culture cookie and then redirects to `/Books/Detail?id=42` โ€” stripping the `?culture=` parameter. The shared link no longer carries the intended language. + +Embedding the culture in the URL path โ€” `/es/books`, `/zh-Hans/about` โ€” solves all three. Each language has its own stable URL, readable by humans and index-friendly for search engines. + +ABP supports this out of the box. You opt in with a single configuration property, and the framework takes care of routing, URL generation, menu links, and language switching automatically. + +## Enabling URL-Based Localization + +In your ABP module class, add: + +```csharp +Configure(options => +{ + options.UseRouteBasedCulture = true; +}); +``` + +That is the only change you need to make. + +## MVC / Razor Pages + +MVC and Razor Pages have the most complete support โ€” everything works automatically. No code changes needed in your pages or controllers. + +![MVC sample โ€” English](images/mvc-home-en.png) + +![MVC sample โ€” Turkish](images/mvc-home-tr.png) + +## What Happens Automatically + +When you set `UseRouteBasedCulture = true`, ABP automatically: + +- Registers ASP.NET Core's built-in [`RouteDataRequestCultureProvider`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.localization.routing.routedatarequestcultureprovider) to detect culture from the URL path. +- Adds a `{culture}/{controller}/{action}` conventional route for MVC controllers, with a route constraint to prevent non-culture URL segments (like `/enterprise/products`) from matching. +- Adds `{culture}/...` route selectors to all Razor Pages at startup. +- Injects the current culture into all `Url.Page()` and `Url.Action()` calls, so generated URLs automatically include the culture prefix. +- Prepends the culture prefix to navigation menu item URLs. + +You do not need to configure these individually. + +## URL Generation Just Works + +In a Razor Page or view running under a culture-prefixed URL (say, `/zh-Hans/Books`), you do not need to pass a `culture` parameter anywhere: + +```cshtml +@Url.Page("/Books/Detail", new { id = book.Id }) +@* Generates: /zh-Hans/Books/Detail?id=42 *@ + +@Url.Action("About", "Home") +@* Generates: /zh-Hans/Home/About *@ +``` + +If you explicitly pass a different `culture` value, that takes precedence โ€” so cross-language links are also straightforward: + +```cshtml +@Url.Page("/Books/Index", new { culture = "tr" }) +@* Generates: /tr/Books *@ +``` + +## Language Switching + +The built-in ABP language switcher already works with route-based culture. When a user switches language, the culture segment in the URL is automatically replaced: + +| Current URL | Switch to | Redirect to | +|---|---|---| +| `/tr/books` | `en` | `/en/books` | +| `/zh-Hans/about` | `en` | `/en/about` | +| `/tenant-a/zh-Hans/about` | `en` | `/tenant-a/en/about` | + +No theme changes, no language switcher changes โ€” the existing UI component just works. + +## Blazor Support + +Blazor Server and Blazor WebAssembly (WebApp) both support URL-based localization. Culture detection and cookie persistence work automatically on the initial page load (SSR). Menu URLs and language switching also work automatically. + +![Blazor Server sample](images/blazor-server-zh-hans.png) + +![Blazor WebApp sample](images/blazor-webapp-tr.png) + +ABP's built-in module pages (Identity, Settings, etc.) also work with URL-based localization out of the box: + +![Identity module โ€” User Management](images/module-identity-users.png) + +### Manual step: Blazor component routes + +The only manual step for Blazor is adding `@page "/{culture}/..."` routes to your own pages. ASP.NET Core does not support automatically adding route selectors to Blazor components (unlike Razor Pages), so you must add them explicitly: + +```razor +@page "/" +@page "/{culture}" + +@code { + [Parameter] + public string? Culture { get; set; } +} +``` + +```razor +@page "/Products" +@page "/{culture}/Products" + +@code { + [Parameter] + public string? Culture { get; set; } +} +``` + +> **ABP's built-in module pages** (Identity, Tenant Management, Settings, Account, etc.) already ship with `@page "/{culture}/..."` route variants. You only need to add these routes to your own application pages. + +### Blazor WebApp (WASM) configuration + +The WASM client project does not need any `UseRouteBasedCulture` configuration. It reads the setting from the server automatically. + +```csharp +// Server project โ€” the only place you need to configure +Configure(options => +{ + options.UseRouteBasedCulture = true; +}); +``` + +## Multi-Tenancy + +URL-based localization is fully compatible with ABP's multi-tenant routing. Language switching supports tenant-prefixed URLs, so `/tenant-a/zh-Hans/About` correctly switches to `/tenant-a/en/About` without any additional configuration. + +## UI Framework Support Overview + +| UI Framework | Route Registration | URL Generation | Menu URLs | Language Switch | Manual Work | +|---|---|---|---|---|---| +| **MVC / Razor Pages** | Automatic | Automatic | Automatic | Automatic | None | +| **Blazor Server** | Manual `@page` routes | N/A | Automatic | Automatic | Add `{culture}` route to pages | +| **Blazor WebApp (WASM)** | Manual `@page` routes | N/A | Automatic | Automatic | Add `{culture}` route to pages | + +## Running the Sample + +A runnable sample is available at [abp-samples/UrlBasedLocalization](https://github.com/abpframework/abp-samples/tree/master/UrlBasedLocalization), with three projects: + +| Project | UI Type | URL | Command | +|---|---|---|---| +| `BookStore.Mvc` | MVC / Razor Pages | `https://localhost:44335` | `dotnet run --project src/BookStore.Mvc` | +| `BookStore.Blazor.Server` | Blazor Server | `https://localhost:44336` | `dotnet run --project src/BookStore.Blazor.Server` | +| `BookStore.Blazor.WebApp` | Blazor WebApp (InteractiveAuto) | `https://localhost:44337` | `dotnet run --project src/BookStore.Blazor.WebApp` | + +Supported languages: English, Tรผrkรงe, Franรงais, ็ฎ€ไฝ“ไธญๆ–‡. + +## Summary + +To add SEO-friendly localized URL paths to your ABP application: + +1. Set `options.UseRouteBasedCulture = true` in your module. +2. For **Blazor** projects, add `@page "/{culture}/..."` routes to your own pages. + +Everything else โ€” route registration, URL generation, menu links, and language switching โ€” is handled automatically. + +## References + +- [URL-Based Localization โ€” ABP Documentation](https://abp.io/docs/latest/framework/fundamentals/url-based-localization) +- [Localization โ€” ABP Documentation](https://abp.io/docs/latest/framework/fundamentals/localization) +- [abp-samples/UrlBasedLocalization โ€” GitHub](https://github.com/abpframework/abp-samples/tree/master/UrlBasedLocalization) +- [Request Localization in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization/select-language-culture) diff --git a/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/cover.png b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/cover.png new file mode 100644 index 0000000000..fcea11e4d6 Binary files /dev/null and b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/cover.png differ diff --git a/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/blazor-server-zh-hans.png b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/blazor-server-zh-hans.png new file mode 100644 index 0000000000..7db95b4b16 Binary files /dev/null and b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/blazor-server-zh-hans.png differ diff --git a/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/blazor-webapp-tr.png b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/blazor-webapp-tr.png new file mode 100644 index 0000000000..91008fd572 Binary files /dev/null and b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/blazor-webapp-tr.png differ diff --git a/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/module-identity-users.png b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/module-identity-users.png new file mode 100644 index 0000000000..bd4b996df4 Binary files /dev/null and b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/module-identity-users.png differ diff --git a/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/mvc-home-en.png b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/mvc-home-en.png new file mode 100644 index 0000000000..e9bc6a9cbd Binary files /dev/null and b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/mvc-home-en.png differ diff --git a/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/mvc-home-tr.png b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/mvc-home-tr.png new file mode 100644 index 0000000000..01bee42b31 Binary files /dev/null and b/docs/en/Community-Articles/2026-03-29-Url-Based-Localization/images/mvc-home-tr.png differ diff --git a/docs/en/framework/fundamentals/index.md b/docs/en/framework/fundamentals/index.md index 7ffa99fd89..5becda669b 100644 --- a/docs/en/framework/fundamentals/index.md +++ b/docs/en/framework/fundamentals/index.md @@ -17,6 +17,7 @@ The following documents explains the fundamental building blocks to create ABP s * [Dependency Injection](./dependency-injection.md) * [Exception Handling](./exception-handling.md) * [Localization](./localization.md) +* [URL-Based Localization](./url-based-localization.md) * [Logging](./logging.md) * [Object Extensions](./object-extensions.md) * [Options](./options.md) diff --git a/docs/en/framework/fundamentals/localization.md b/docs/en/framework/fundamentals/localization.md index 7a4fcf24ac..562446a892 100644 --- a/docs/en/framework/fundamentals/localization.md +++ b/docs/en/framework/fundamentals/localization.md @@ -294,6 +294,10 @@ Configure(options => }); ``` +## URL-Based Localization + +ABP supports embedding the culture code directly in the URL path (e.g. `/en/products`, `/zh-Hans/about`), which is useful for SEO-friendly and shareable localized URLs. See the [URL-Based Localization](./url-based-localization.md) document for details. + ## The Client Side See the following documents to learn how to reuse the same localization texts in the JavaScript side; diff --git a/docs/en/framework/fundamentals/url-based-localization.md b/docs/en/framework/fundamentals/url-based-localization.md new file mode 100644 index 0000000000..55d29b50a1 --- /dev/null +++ b/docs/en/framework/fundamentals/url-based-localization.md @@ -0,0 +1,173 @@ +````json +//[doc-seo] +{ + "Description": "Learn how to use ABP's URL-based localization to embed culture in the URL path, enabling SEO-friendly and shareable localized URLs." +} +```` + +# URL-Based Localization + +ABP supports embedding the current culture directly in the URL path, for example `/tr/products` or `/en/about`. This approach is widely used by documentation sites, e-commerce platforms, and any site that needs SEO-friendly, shareable localized URLs. + +By default, ABP detects language from QueryString (`?culture=tr`), Cookie, and `Accept-Language` header. URL path detection is **opt-in** and fully backward-compatible. + +## Enabling URL-Based Localization + +Configure the `AbpRequestLocalizationOptions` in your [module class](../architecture/modularity/basics.md): + +````csharp +Configure(options => +{ + options.UseRouteBasedCulture = true; +}); +```` + +That's all you need. The framework automatically handles the rest. + +## What Happens Automatically + +When you set `UseRouteBasedCulture` to `true`, ABP automatically registers the following: + +* **`RouteDataRequestCultureProvider`** โ€” A built-in ASP.NET Core provider that reads `{culture}` from route data. ABP inserts it after `QueryStringRequestCultureProvider` and before `CookieRequestCultureProvider`. +* **`{culture}/{controller}/{action}` route** โ€” A conventional route for MVC controllers. The `{culture}` parameter uses a custom route constraint (`AbpCultureRouteConstraint`) that only matches culture values configured in `AbpLocalizationOptions.Languages`, so URLs like `/enterprise/products` are not mistaken for culture-prefixed routes. +* **`AbpCultureRoutePagesConvention`** โ€” An `IPageRouteModelConvention` that adds `{culture}/...` route selectors to all Razor Pages. +* **`AbpCultureRouteUrlHelperFactory`** โ€” Replaces the default `IUrlHelperFactory` to auto-inject culture into `Url.Page()` and `Url.Action()` calls. +* **`AbpCultureMenuItemUrlProvider`** โ€” Prepends the culture prefix to navigation menu item URLs (MVC / Blazor Server). +* **`AbpWasmCultureMenuItemUrlProvider`** โ€” Prepends the culture prefix to menu item URLs in Blazor WebAssembly (reads the `UseRouteBasedCulture` flag from `/api/abp/application-configuration`). + +You do not need to configure these individually. + +## URL Generation + +When a request has a `{culture}` route value, all URL generation methods automatically include the culture prefix: + +````csharp +// In a Razor Page โ€” culture is auto-injected, no manual parameter needed +@Url.Page("/About") // Generates: /zh-Hans/About +@Url.Action("About", "Home") // Generates: /zh-Hans/Home/About +```` + +Menu items registered via `IMenuContributor` also automatically get the culture prefix. No changes are needed in your menu contributors or theme. + +## Language Switching + +ABP's built-in language switcher (the `/Abp/Languages/Switch` action) automatically replaces the culture segment in the `returnUrl`. The controller reads the culture from the request cookie to identify the current page culture and replaces it with the new one: + +| Before switching | After switching to English | +|---|---| +| `/tr/products` | `/en/products` | +| `/tenant-a/zh-Hans/about` | `/tenant-a/en/about` | +| `/home?culture=tr&ui-culture=tr` | `/home?culture=en&ui-culture=en` | +| `/about` (no prefix) | `/about` (unchanged) | + +No changes are needed in any theme or language switcher component. + +## MVC / Razor Pages + +MVC and Razor Pages have the most complete support. Everything works automatically when `UseRouteBasedCulture = true` โ€” route registration, URL generation, menu links, and language switching. **No code changes are needed in your pages or controllers.** + +## Blazor Server + +Blazor Server uses SignalR (WebSocket) for the interactive circuit. The HTTP middleware pipeline only runs on the **initial page load** โ€” subsequent interactions happen over the WebSocket connection. ABP handles this by persisting the detected URL culture to a **Cookie** on the first request, so the entire Blazor circuit uses the correct language. + +Culture detection, cookie persistence, menu URLs, and language switching all work automatically. No additional configuration is needed beyond the `UseRouteBasedCulture` option. + +### What requires manual changes + +**Blazor component routes**: ASP.NET Core does not provide an `IPageRouteModelConvention` equivalent for Blazor components. You must manually add the `{culture}` route to each page: + +````razor +@page "/" +@page "/{culture}" + +@code { + [Parameter] + public string? Culture { get; set; } +} +```` + +````razor +@page "/About" +@page "/{culture}/About" + +@code { + [Parameter] + public string? Culture { get; set; } +} +```` + +> This applies to your own application pages. ABP built-in module pages (Identity, Tenant Management, Settings, Account, etc.) already include `@page "/{culture}/..."` routes out of the box โ€” you do not need to add them manually. + +## Blazor WebAssembly (WebApp) + +Blazor WebAssembly (WASM) runs in the browser. On the **first page load**, the server renders the page via SSR, and the culture is detected from the URL. After WASM downloads, subsequent renders run in the browser. The WASM app fetches `/api/abp/application-configuration` from the server to get the current culture, so the culture stays consistent. + +Culture detection, cookie persistence, menu URLs, and language switching all work automatically. The WASM client reads the `UseRouteBasedCulture` flag from the server via `/api/abp/application-configuration`, so no client-side configuration is needed. + +### What requires manual changes + +Same as Blazor Server โ€” you must manually add `@page "/{culture}/..."` routes to your Blazor pages. + +## Angular + +The [ABP Angular UI](../ui/angular/quick-start.md) runs in the browser. The server still applies `UseRouteBasedCulture`; the client reads **`localization.useRouteBasedCulture`** from `/api/abp/application-configuration` (same payload as other UI types). There is no separate Angular setting. + +### Routing + +Angular does not add a culture segment to your route config automatically. Use **`withOptionalRouteCulturePrefix`** from **`@abp/ng.core`** so one route tree matches both **`/identity/users`** and **`/en/identity/users`** (the first path segment is matched only when it looks like a culture code, e.g. `en`, `tr`, `zh-Hans`). + +````typescript +import { Routes } from '@angular/router'; +import { withOptionalRouteCulturePrefix } from '@abp/ng.core'; + +const appRoutesCore: Routes = [ + // ... your routes (path: '', 'account', 'identity', lazy children, etc.) +]; + +export const appRoutes = withOptionalRouteCulturePrefix(appRoutesCore); +```` + +![Angular: routes wrapped with optional culture prefix](../../images/url-based-localization-angular-routes.png) + +### URL โ†’ session language + +When **`useRouteBasedCulture`** is **true**, **`RouteBasedCultureService`** (from `@abp/ng.core`) keeps the session language aligned with the first URL segment after navigation. This runs during application bootstrap and on each **`NavigationEnd`**. + +### Menu links, breadcrumbs, and `routerLink` + +Menu paths from **`RoutesService`** are usually **without** a culture prefix (`/identity/users`). Use the **`abpRouteCultureUrl`** pipe on **`routerLink`** (or **`RouteBasedCultureUrlService.prefixPathWithCulture`**) so links navigate to **`/en/identity/users`** when route-based culture is enabled. The **Basic** theme navigation and **Theme Shared** breadcrumb links follow this pattern. + +![Angular: culture-prefixed menu or URL bar](../../images/url-based-localization-angular-menu-url.png) + +### Language switcher (toolbar) + +If the user selects a language in the UI, call **`RouteBasedCultureUrlService.applyLanguageSelection(cultureName)`** (or **`navigateToUrlWithCulture`**) instead of only updating the session language. That rewrites the current URLโ€™s culture segment (or prepends it) so the address bar and session stay consistent; **`RouteBasedCultureService`** then picks up the culture from the URL after navigation. + +### Active menu, breadcrumbs, and route matching + +The browser URL may be **`/en/identity/users`** while menu items and **`RoutesService`** paths stay **`/identity/users`**. For comparisons (active state, **`findRoute`**, permission guard, dynamic layout), normalize the current URL with **`RouteBasedCultureUrlService.normalizeForMenuMatch`** (or **`stripCulturePrefixIfEnabled`**) or use **`getRoutePathForMatching`** where **`getRoutePath`** was used. + +### Configuration refresh + +**`RouteBasedCultureUrlService`** refreshes its cached **`useRouteBasedCulture`** and **languages** when application configuration is updated (for example after **`refreshAppState`**), so hot paths do not query configuration on every change detection cycle. + +## Multi-Tenancy Compatibility + +URL-based localization is fully compatible with [multi-tenancy URL routing](../architecture/multi-tenancy/index.md). The culture route is registered as a conventional route `{culture}/{controller}/{action}`. If your application uses tenant routing (e.g., `/{tenant}/...`), the tenant middleware strips the tenant segment before routing, and the culture segment is handled separately. + +Language switching also supports tenant-prefixed URLs. For example, `/tenant-a/zh-Hans/About` correctly switches to `/tenant-a/en/About`. + +## API Routes + +Routes like `/api/products` have no `{culture}` segment, so `RouteDataRequestCultureProvider` returns `null` and falls through to the next provider (Cookie โ†’ `Accept-Language` โ†’ default). API routes are completely unaffected. + +## Culture Detection Priority + +ASP.NET Core has a built-in [`RouteDataRequestCultureProvider`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.localization.routing.routedatarequestcultureprovider) (in `Microsoft.AspNetCore.Localization.Routing`) that reads culture from route data, but it is not included in the default provider list. When `UseRouteBasedCulture` is enabled, ABP inserts it after `QueryStringRequestCultureProvider` and before `CookieRequestCultureProvider`. The resulting provider order is: + +1. `QueryStringRequestCultureProvider` (ASP.NET Core default โ€” useful for debugging and testing) +2. `RouteDataRequestCultureProvider` (URL path โ€” inserted by ABP when enabled) +3. `CookieRequestCultureProvider` (ASP.NET Core default) +4. `AcceptLanguageHeaderRequestCultureProvider` (ASP.NET Core default) + +If a URL contains an invalid culture code (e.g. `/xyz1234/page`), `RequestLocalizationMiddleware` ignores it and falls through to the next provider. No error is thrown. diff --git a/docs/en/framework/infrastructure/event-bus/distributed/index.md b/docs/en/framework/infrastructure/event-bus/distributed/index.md index 5f2c7b11ec..54baeefcac 100644 --- a/docs/en/framework/infrastructure/event-bus/distributed/index.md +++ b/docs/en/framework/infrastructure/event-bus/distributed/index.md @@ -757,7 +757,44 @@ await distributedEventBus.PublishAsync( ### Subscribing to Dynamic Events -Use the `Subscribe` overload that accepts a string event name: +The recommended way to subscribe is to implement `IDistributedEventHandler` and use `IocEventHandlerFactory`. This mirrors how ABP manages typed handlers โ€” it creates a new DI scope per event, resolves a fresh handler instance, calls `HandleEventAsync`, then disposes the scope: + +````csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + context.Services.AddTransient(); +} + +public override void OnApplicationInitialization(ApplicationInitializationContext context) +{ + var eventBus = context.ServiceProvider.GetRequiredService(); + var scopeFactory = context.ServiceProvider.GetRequiredService(); + eventBus.Subscribe("MyDynamicEvent", new IocEventHandlerFactory(scopeFactory, typeof(MyDynamicEventHandler))); +} +```` + +The handler uses normal constructor injection โ€” no manual scope management needed: + +````csharp +public class MyDynamicEventHandler : IDistributedEventHandler +{ + private readonly IMyService _myService; + + public MyDynamicEventHandler(IMyService myService) + { + _myService = myService; + } + + public async Task HandleEventAsync(DynamicEventData eventData) + { + await _myService.ProcessAsync(eventData.EventName, eventData.Data); + } +} +```` + +`Subscribe` returns an `IDisposable`. Call `Dispose()` to unsubscribe at runtime. + +For simple stateless handlers that do not need DI services, you can also use `SingleInstanceHandlerFactory` with an inline handler: ````csharp var subscription = distributedEventBus.Subscribe( @@ -765,10 +802,8 @@ var subscription = distributedEventBus.Subscribe( new SingleInstanceHandlerFactory( new ActionEventHandler(eventData => { - // Access the event name and raw data var name = eventData.EventName; var data = eventData.Data; - return Task.CompletedTask; }))); @@ -776,13 +811,7 @@ var subscription = distributedEventBus.Subscribe( subscription.Dispose(); ```` -You can also subscribe using a typed distributed event handler: - -````csharp -distributedEventBus.Subscribe("MyDynamicEvent", myDistributedEventHandler); -```` - -Where `myDistributedEventHandler` implements `IDistributedEventHandler`. +> Do not inject `IServiceProvider` directly into a `SingleInstanceHandlerFactory`-based handler. Since the same instance is reused for every event, resolving scoped services directly from the root container causes a captive dependency and may throw a scope validation exception in development. Use `IocEventHandlerFactory` instead. ### Mixed Typed and Dynamic Handlers diff --git a/docs/en/images/url-based-localization-angular-menu-url.png b/docs/en/images/url-based-localization-angular-menu-url.png new file mode 100644 index 0000000000..f64ab92486 Binary files /dev/null and b/docs/en/images/url-based-localization-angular-menu-url.png differ diff --git a/docs/en/images/url-based-localization-angular-routes.png b/docs/en/images/url-based-localization-angular-routes.png new file mode 100644 index 0000000000..9ea19d386a Binary files /dev/null and b/docs/en/images/url-based-localization-angular-routes.png differ diff --git a/docs/en/package-version-changes.md b/docs/en/package-version-changes.md index 6b453dc1bd..dd380e78f0 100644 --- a/docs/en/package-version-changes.md +++ b/docs/en/package-version-changes.md @@ -9,6 +9,20 @@ ## 10.3.0-rc.1 +| Package | Old Version | New Version | PR | +|---------|-------------|-------------|-----| +| Autofac | 8.4.0 | 9.1.0 | #25190 | +| Autofac.Extensions.DependencyInjection | 10.0.0 | 11.0.0 | #25190 | +| Microsoft.Bcl.AsyncInterfaces | 10.0.2 | 10.0.4 | #25190 | + +## 10.2.0-rc.4 + +| Package | Old Version | New Version | PR | +|---------|-------------|-------------|-----| +| Scriban | 6.6.0 | 7.0.0 | #25170 | + +## 10.2.0-rc.3 + | Package | Old Version | New Version | PR | |---------|-------------|-------------|-----| | Microsoft.IdentityModel.JsonWebTokens | 8.14.0 | 8.16.0 | #25068 | @@ -52,3 +66,4 @@ |---------|-------------|-------------|-----| | Microsoft.SemanticKernel | 1.67.1 | 1.71.0 | [#24891](https://github.com/abpframework/abp/pull/24891) | | Microsoft.SemanticKernel.Abstractions | 1.67.1 | 1.71.0 | [#24891](https://github.com/abpframework/abp/pull/24891) | + diff --git a/docs/en/release-info/migration-guides/abp-10-3.md b/docs/en/release-info/migration-guides/abp-10-3.md new file mode 100644 index 0000000000..9b2ddc1ccf --- /dev/null +++ b/docs/en/release-info/migration-guides/abp-10-3.md @@ -0,0 +1,76 @@ +```json +//[doc-seo] +{ + "Description": "Upgrade your ABP solutions from v10.2 to v10.3 with this migration guide covering important behavior and integration changes." +} +``` + +# ABP Version 10.3 Migration Guide + +This document is a guide for upgrading ABP v10.2 solutions to ABP v10.3. There are no explicitly marked breaking changes in this release scope, but there are some important changes that may require action in specific application scenarios. + +> **Package Version Changes:** Before upgrading, review the [Package Version Changes](../../package-version-changes.md) document to see version changes on dependent NuGet packages and align your project with ABP's internal package versions. + +## Open-Source (Framework) + +This version contains the following changes on the open-source side: + +### `PermissionIntegrationController.IsGrantedAsync` switched to `HttpPost` + +**Who is affected** + +- Applications that call the permission integration endpoint directly (custom HTTP clients, custom JS, custom integrations). + +**What changed** + +- `PermissionIntegrationController.IsGrantedAsync` is now `HttpPost` instead of `HttpGet` to avoid URL-length limitations for large permission/user payloads. + +**What to do** + +- Update custom clients/integrations to send a POST request with payload in the request body. +- If you rely on generated ABP clients, regenerate/update client proxies after upgrading. + +> See [#25177](https://github.com/abpframework/abp/pull/25177) for details. + +### `IEntityCache` interface updates for batch dictionary APIs + +**Who is affected** + +- Applications with custom `IEntityCache` implementations/derivations or custom abstractions built on top of `IEntityCache`. + +**What changed** + +- New batch methods were added (`FindManyAsync` / `GetManyAsync`, and dictionary variants). +- `IEntityCache` no longer uses contravariant `in` on `TKey`. +- `TKey` now has a `notnull` constraint to support dictionary-based APIs. + +**What to do** + +- Update custom interfaces and implementations to match the latest `IEntityCache` signature and generic constraints. +- Rebuild solution and fix compile-time variance/constraint issues in custom cache abstractions. + +> See [#25088](https://github.com/abpframework/abp/pull/25088) and [#25090](https://github.com/abpframework/abp/pull/25090) for details. + +## Pro + +There are no explicitly marked breaking changes on the PRO side in this release scope. However, check the following if they apply to your application. + +### Account Pro and Identity Pro security behavior updates + +**Who is affected** + +- Applications using the **Account Pro** and **Identity Pro** modules for password reset/change and profile picture upload flows. + +**What changed** + +- Session revocation behavior was tightened after sensitive credential operations. +- Profile picture upload now enforces extension/size/magic-bytes validation by default. +- Forgot-password CAPTCHA and account-manage rate limiting capabilities were extended. + +**What to do** + +In most cases, no action is required on your part. However, please review the following considerations: + +- Re-test your sign-in, password reset, and password change flows, especially if you have session continuity expectations. +- If your application needs additional image types/sizes, configure `AbpProfilePictureOptions` explicitly. +- Review account security settings (`UseCaptchaOnForgotPassword` and related rate-limit options) and adjust them to your UX/security requirements. diff --git a/docs/en/release-info/migration-guides/index.md b/docs/en/release-info/migration-guides/index.md index abf3d87461..580640bdb7 100644 --- a/docs/en/release-info/migration-guides/index.md +++ b/docs/en/release-info/migration-guides/index.md @@ -9,6 +9,7 @@ The following documents explain how to migrate your existing ABP applications. We write migration documents only if you need to take an action while upgrading your solution. Otherwise, you can easily upgrade your solution using the [abp update command](../upgrading.md). +- [10.x to 10.3](abp-10-3.md) - [10.x to 10.2](abp-10-2.md) - [10.0 to 10.1](abp-10-1.md) - [9.x to 10.0](abp-10-0.md) diff --git a/docs/en/release-info/release-notes.md b/docs/en/release-info/release-notes.md index 77e5e54a2d..d98a17e2a8 100644 --- a/docs/en/release-info/release-notes.md +++ b/docs/en/release-info/release-notes.md @@ -14,9 +14,23 @@ Also see the following notes about ABP releases: * [ABP Studio release notes](../studio/release-notes.md) * [Change logs for ABP pro packages](https://abp.io/pro-releases) +## 10.3 (2026-04-01) + +> This is currently an RC (release-candidate) and you can see the detailed **[blog post / announcement](https://abp.io/community/announcements/announcing-abp-10-3-release-candidate-hgnpr9jq)** for the v10.3 release. + +* OpenIddict: `private_key_jwt` Client Authentication + `abp generate-jwks` +* Event Bus: String-Based Event Publishing with Dynamic Payload +* Background Jobs/Workers: String-Based Publishing with Dynamic Payload +* API Definition Endpoint: Descriptions and Documentation Support +* Entity Cache: New Batch APIs (`FindMany*` / `GetMany*`) +* Angular: User/Tenant Sharing and Tenant Switch Experience +* Angular: Upgrade to 21.2 + TypeScript 5.9 +* Introducing the `Volo.Abp.LuckyPenny.AutoMapper` Provider +* Security Improvements (Account Pro Module) + ## 10.2 (2026-02-24) -> This is currently an RC (release-candidate) and you can see the detailed **[blog post / announcement](https://abp.io/community/articles/announcing-abp-10-2-release-candidate-05zatjfq)** for the v10.2 release. +See the detailed **[blog post / announcement](https://abp.io/community/announcements/announcing-abp-10-2-stable-release-x47ytfww)** for the v10.2 release. * Multi-Tenant Account Usage: Shared User Accounts * Prevent Privilege Escalation: Assignment Restrictions for Roles and Permissions diff --git a/docs/en/release-info/road-map.md b/docs/en/release-info/road-map.md index 59a249c4f2..c83a7efff2 100644 --- a/docs/en/release-info/road-map.md +++ b/docs/en/release-info/road-map.md @@ -1,7 +1,7 @@ ```json //[doc-seo] { - "Description": "Explore the ABP Platform Road Map for insights on upcoming features, release schedules, and improvements in version 10.3, planned for April 2026." + "Description": "Explore the ABP Platform Road Map for insights on upcoming features, release schedules, and improvements in version 10.4, planned for May 2026." } ``` @@ -11,38 +11,36 @@ This document provides a road map, release schedule, and planned features for th ## Next Versions -### v10.3 +### v10.4 -The next version will be 10.3 and is planned to be released as a stable version in April 2026. We will be mostly working on the following topics: +After v10.3 reaches stable, the next planned version will be 10.4, which is scheduled to be released as a stable version in May 2026. We will be mostly working on the following topics: * Framework - * Resource-Based Authorization Improvements - * Handle datetime/timezone in `AbpExtensibleDataGrid` Component + * Blazor UI: Moving from Blazorise to MudBlazor + * Token Verification Improvements (Refresh Token Support) * Upgrading 3rd-party Dependencies * Enhancements in the Core Points * ABP Suite * Improvements on the generated codes for nullability * Improvements on Master-Detail Page Design (making it more compact) - * Improvements One-To-Many Scenarios - * File Upload Modal Enhancements * ABP Studio * Allow to Directly Create New Solutions with ABP's RC (Release Candidate) Versions - * Integrate AI Management Module with all solution templates and UIs (for Blazor & Angular UIs) * Automate More Details on New Service Creation for a Microservice Solution * Allow to Download ABP Samples from ABP Studio * Support Multiple Concurrent Kubernetes Deployment/Integration Scenarios * Improve the Module Installation Experience / Installation Guides * Application Modules - * AI Management: Chat History & Visual Improvements on the playground - * CMS Kit: Enhancements for Some Features (Rating, Dynamic Widgets, FAQ and more...) + * AI Management: Chat History & Multi-Tenancy Features + * New Module: Chat with your data + * CMS Kit: CodeMirror v6 Compatibility Update + * Payment Module: Email Notification Improvements * UI/UX Improvements on Existing Application Modules * Updating Existing Tutorials & Documents (with Other UI & DB Options) - * Microservice Development - * Modular Monolith Development + * React Native template and implementation documents ## Backlog Items @@ -60,7 +58,6 @@ The ABP framework is [open source](https://github.com/abpframework/abp) and free * [#2296](https://github.com/abpframework/abp/issues/2296) / Feature toggling infrastructure * [#15932](https://github.com/abpframework/abp/issues/15932) / Introduce ABP Diagnostics Module * [#16744](https://github.com/abpframework/abp/issues/16744) / State Management API -* [#17815](https://github.com/abpframework/abp/issues/17815) / Operation Rate Limiting * [#119](https://github.com/abpframework/abp/issues/119) / REST API Versioning Improvements * [#2087](https://github.com/abpframework/abp/issues/2087) / RavenDB Database Support diff --git a/docs/en/studio/release-notes.md b/docs/en/studio/release-notes.md index 6f0f552224..3f4714f57f 100644 --- a/docs/en/studio/release-notes.md +++ b/docs/en/studio/release-notes.md @@ -9,7 +9,12 @@ This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version. -## 2.2.3 (2026-03-24) Latest +## 2.2.4 (2026-03-25) Latest + +- Add `Template Create and Build` workflow +- Disable NuGetAudit in template common.props to prevent CLI deadlock during initial migration + +## 2.2.3 (2026-03-24) - Fix PostHog environment detection diff --git a/docs/en/studio/version-mapping.md b/docs/en/studio/version-mapping.md index f81cde93f0..baa5b24ff1 100644 --- a/docs/en/studio/version-mapping.md +++ b/docs/en/studio/version-mapping.md @@ -11,7 +11,7 @@ This document provides a general overview of the relationship between various ve | **ABP Studio Version** | **ABP Version of Startup Template** | |------------------------|---------------------------| -| 2.2.2 - 2.2.3 | 10.1.1 | +| 2.2.2 - 2.2.4 | 10.1.1 | | 2.2.1 | 10.1.0 | | 2.1.5 - 2.1.9 | 10.0.2 | | 2.1.0 - 2.1.4 | 10.0.1 | diff --git a/docs/en/tutorials/modular-crm/index.md b/docs/en/tutorials/modular-crm/index.md index b56d059d39..af34a79660 100644 --- a/docs/en/tutorials/modular-crm/index.md +++ b/docs/en/tutorials/modular-crm/index.md @@ -7,17 +7,10 @@ # Modular Monolith Application Development Tutorial -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` diff --git a/docs/en/tutorials/modular-crm/part-01.md b/docs/en/tutorials/modular-crm/part-01.md index 00d42fad3c..c2af1cd07d 100644 --- a/docs/en/tutorials/modular-crm/part-01.md +++ b/docs/en/tutorials/modular-crm/part-01.md @@ -7,17 +7,10 @@ # Creating the Initial Solution -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` @@ -42,7 +35,7 @@ In this first part of this tutorial, we will create a new ABP solution with modu Follow the *[Get Started](../../get-started/single-layer-web-application.md)* guide to create a single layer web application with the following configuration: * **Solution name**: `ModularCrm` -* **UI Framework**: {{if UI == "MVC"}}ASP.NET Core MVC / Razor Pages{{else if UI == "BlazorWebApp"}}Blazor WebApp{{end}} +* **UI Framework**: {{if UI == "MVC"}}ASP.NET Core MVC / Razor Pages{{else if UI == "BlazorWebApp"}}Blazor WebApp{{else if UI == "NG"}}Angular{{end}} * **Database Provider**: Entity Framework Core {{if UI == "NG"}}> **Note:** Angular users can continue with the Angular UI steps in the upcoming parts while following the same modularity flow. diff --git a/docs/en/tutorials/modular-crm/part-02.md b/docs/en/tutorials/modular-crm/part-02.md index ef38a09227..aa1f124e22 100644 --- a/docs/en/tutorials/modular-crm/part-02.md +++ b/docs/en/tutorials/modular-crm/part-02.md @@ -7,17 +7,10 @@ # Setting Up the Catalog Module -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` diff --git a/docs/en/tutorials/modular-crm/part-03.md b/docs/en/tutorials/modular-crm/part-03.md index 52e5098e60..e0db36d617 100644 --- a/docs/en/tutorials/modular-crm/part-03.md +++ b/docs/en/tutorials/modular-crm/part-03.md @@ -7,17 +7,10 @@ # Building the Catalog Module -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` @@ -639,4 +632,4 @@ yarn start ## Summary -In this part of the tutorial, you've built the functionality inside the _Catalog_ module, which was created in the [previous part](part-02.md), and created a basic {{if UI == "MVC"}}MVC{{else if UI == "NG"}}Angular{{end}} UI to list products. In the next part, you will create a new _Ordering_ module and install it into the main application. +In this part of the tutorial, you've built the functionality inside the _Catalog_ module, which was created in the [previous part](part-02.md), and created a basic {{if UI == "MVC"}}MVC{{else if UI == "BlazorWebApp"}}Blazor WebApp{{else if UI == "NG"}}Angular{{end}} UI to list products. In the next part, you will create a new _Ordering_ module and install it into the main application. diff --git a/docs/en/tutorials/modular-crm/part-04.md b/docs/en/tutorials/modular-crm/part-04.md index db119eed31..3c609c2c36 100644 --- a/docs/en/tutorials/modular-crm/part-04.md +++ b/docs/en/tutorials/modular-crm/part-04.md @@ -7,17 +7,10 @@ # Creating the Initial Ordering Module -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` @@ -55,11 +48,13 @@ Set `ModularCrm.Ordering` as the *Module name*, leave the *Output folder* as is {{if UI == "MVC"}} ![abp-studio-add-new-standard-module-ui-dialog](images/abp-studio-add-new-standard-module-ui-dialog.png) + +You can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the *MVC* option and click *Next*. + {{else if UI == "BlazorWebApp"}} ![abp-studio-add-new-standard-module-ui-dialog](images/abp-studio-add-new-standard-module-ui-dialog-blazor-webapp.png) -{{end}} -You can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the {{if UI == "MVC"}}*MVC*{{else if UI == "BlazorWebApp"}}*Blazor WebApp*{{end}} option and click *Next*. +You can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the *Blazor WebApp* option and click *Next*. {{else if UI == "NG"}} diff --git a/docs/en/tutorials/modular-crm/part-05.md b/docs/en/tutorials/modular-crm/part-05.md index c5582ec530..4387ff6908 100644 --- a/docs/en/tutorials/modular-crm/part-05.md +++ b/docs/en/tutorials/modular-crm/part-05.md @@ -7,17 +7,10 @@ # Building the Ordering Module -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` @@ -703,4 +696,4 @@ Navigate to the *Ordering* page and verify that the orders are listed. At this s ## Summary -In this part of the *Modular CRM* tutorial, you've built the functionality inside the Ordering module you created in the [previous part](part-04.md) and created a basic {{if UI == "MVC"}}MVC{{else if UI == "NG"}}Angular{{end}} UI to list orders. In the [next part](part-06.md), you will work on establishing communication between the Orders module and the Catalog module. +In this part of the *Modular CRM* tutorial, you've built the functionality inside the Ordering module you created in the [previous part](part-04.md) and created a basic {{if UI == "MVC"}}MVC{{else if UI == "BlazorWebApp"}}Blazor WebApp{{else if UI == "NG"}}Angular{{end}} UI to list orders. In the [next part](part-06.md), you will work on establishing communication between the Orders module and the Catalog module. diff --git a/docs/en/tutorials/modular-crm/part-06.md b/docs/en/tutorials/modular-crm/part-06.md index 7eb7c5faba..31cc0cb48c 100644 --- a/docs/en/tutorials/modular-crm/part-06.md +++ b/docs/en/tutorials/modular-crm/part-06.md @@ -7,17 +7,10 @@ # Integrating the Modules: Implementing Integration Services -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` @@ -293,6 +286,12 @@ Open the `Index.cshtml` file, and change the `@order.ProductId` part to `@order. ```` +That's all. Now, you can graph build the main application and run it in ABP Studio to see the result: + +![abp-studio-browser-list-of-orders-with-product-name](images/abp-studio-browser-list-of-orders-with-product-name.png) + +As you can see, we can see the product names instead of product IDs. + {{else if UI == "BlazorWebApp"}} Open the `Index.razor` file, and change the `@order.ProductId` part to `@order.ProductName` to write the product name instead of the product ID. The final `Index.razor` content should be the following: @@ -331,8 +330,6 @@ Open the `Index.razor` file, and change the `@order.ProductId` part to `@order.P } ```` -{{end}} - That's all. Now, you can graph build the main application and run it in ABP Studio to see the result: ![abp-studio-browser-list-of-orders-with-product-name](images/abp-studio-browser-list-of-orders-with-product-name.png) @@ -361,4 +358,4 @@ Then run the Angular app (`yarn start` in the `angular` folder), navigate to the ## Conclusion -In this part of the tutorial, you created and consumed an integration service between modules, then reflected the product name on the {{if UI == "MVC"}}MVC{{else if UI == "NG"}}Angular{{end}} UI. In the [next part](part-07.md), we will explore event based messaging between the modules. +In this part of the tutorial, you created and consumed an integration service between modules, then reflected the product name on the {{if UI == "MVC"}}MVC{{else if UI == "BlazorWebApp"}}Blazor WebApp{{else if UI == "NG"}}Angular{{end}} UI. In the [next part](part-07.md), we will explore event based messaging between the modules. diff --git a/docs/en/tutorials/modular-crm/part-07.md b/docs/en/tutorials/modular-crm/part-07.md index 2967b94dfa..540cb51610 100644 --- a/docs/en/tutorials/modular-crm/part-07.md +++ b/docs/en/tutorials/modular-crm/part-07.md @@ -7,17 +7,10 @@ # Integrating the Modules: Communication via Messages (Events) -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` diff --git a/docs/en/tutorials/modular-crm/part-08.md b/docs/en/tutorials/modular-crm/part-08.md index b7254b0c1f..f2739a53bb 100644 --- a/docs/en/tutorials/modular-crm/part-08.md +++ b/docs/en/tutorials/modular-crm/part-08.md @@ -5,22 +5,15 @@ } ``` -```json -//[doc-params] -{ - "UI": ["MVC", "NG"] -} -``` - -# Integrating the Modules: Joining the Products and Orders Data - ````json //[doc-params] { - "UI": ["MVC","BlazorWebApp"] + "UI": ["MVC", "BlazorWebApp", "NG"] } ```` +# Integrating the Modules: Joining the Products and Orders Data + ````json //[doc-nav] { diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpWasmCultureMenuItemUrlProvider.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpWasmCultureMenuItemUrlProvider.cs new file mode 100644 index 0000000000..9a1077e1b0 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/AbpWasmCultureMenuItemUrlProvider.cs @@ -0,0 +1,63 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.Client; +using Volo.Abp.DependencyInjection; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming; + +/// +/// Prepends the culture route prefix to menu item URLs in Blazor WebAssembly when route-based culture is enabled. +/// +public class AbpWasmCultureMenuItemUrlProvider : IMenuItemUrlProvider, ITransientDependency +{ + protected ICachedApplicationConfigurationClient ConfigurationClient { get; } + protected IMenuItemCulturePrefixHelper MenuItemCulturePrefixHelper { get; } + + public AbpWasmCultureMenuItemUrlProvider( + ICachedApplicationConfigurationClient configurationClient, + IMenuItemCulturePrefixHelper menuItemCulturePrefixHelper) + { + ConfigurationClient = configurationClient; + MenuItemCulturePrefixHelper = menuItemCulturePrefixHelper; + } + + public virtual async Task HandleAsync(MenuItemUrlProviderContext context) + { + if (!OperatingSystem.IsBrowser()) + { + return; + } + + var config = await ConfigurationClient.GetAsync(); + if (!config.Localization.UseRouteBasedCulture) + { + return; + } + + var culture = GetCulture(config); + if (string.IsNullOrEmpty(culture)) + { + return; + } + + await MenuItemCulturePrefixHelper.PrependCulturePrefixAsync(context.Menu, "/" + culture); + } + + protected virtual string? GetCulture(Mvc.ApplicationConfigurations.ApplicationConfigurationDto config) + { + var currentCulture = CultureInfo.CurrentCulture.Name; + var languages = config.Localization.Languages; + if (languages.Count == 0) + { + return null; + } + + var isKnownCulture = languages + .Any(l => string.Equals(l.CultureName, currentCulture, StringComparison.OrdinalIgnoreCase)); + + return isKnownCulture ? currentCulture : null; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/CultureAwareAuthenticationBase.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/CultureAwareAuthenticationBase.cs new file mode 100644 index 0000000000..26a25b7f0e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/CultureAwareAuthenticationBase.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Components; +using Volo.Abp.AspNetCore.Components; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming; + +/// +/// Shared base for WASM theme Authentication pages. +/// Provides a helper so the culture-aware +/// home URL construction is not duplicated across theme packages. +/// +public abstract class CultureAwareAuthenticationBase : AbpComponentBase +{ + [Inject] + protected NavigationManager Navigation { get; set; } = default!; + + [Parameter] + public string? Culture { get; set; } + + protected virtual string GetCultureAwareHomeUrl() + { + return string.IsNullOrEmpty(Culture) + ? Navigation.BaseUri + : Navigation.BaseUri + Culture + "/"; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/CultureAwareRedirectToLoginHelper.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/CultureAwareRedirectToLoginHelper.cs new file mode 100644 index 0000000000..02c2b749bf --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/CultureAwareRedirectToLoginHelper.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Components.Web; +using Volo.Abp.AspNetCore.Components.WebAssembly; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming; + +/// +/// Provides the shared culture-aware login redirect logic for all WASM theme +/// WebAssemblyRedirectToLogin components. Each theme must keep +/// @inherits RedirectToLogin for ABP service-replacement assignability, +/// so a common component base class is not feasible; this static helper +/// centralises the logic instead. +/// +public static class CultureAwareRedirectToLoginHelper +{ + public static async Task RedirectAsync( + NavigationManager navigation, + string loginUrl, + IRouteBasedCultureUrlHelper cultureUrlHelper, + IOptions webOptions) + { + var cultureLoginUrl = await cultureUrlHelper.PrependCulturePrefixAsync(loginUrl); + if (webOptions.Value.IsBlazorWebApp) + { + navigation.NavigateTo(cultureLoginUrl, forceLoad: true); + } + else + { + navigation.NavigateToLogin(cultureLoginUrl); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj index b3fc2633a7..76b63c76c7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj @@ -9,6 +9,10 @@ Nullable + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IRouteBasedCultureNavigationHelper.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IRouteBasedCultureNavigationHelper.cs new file mode 100644 index 0000000000..b2b34e1a65 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IRouteBasedCultureNavigationHelper.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Volo.Abp.Localization; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly; + +public interface IRouteBasedCultureNavigationHelper +{ + Task NavigateToNewCultureAsync( + NavigationManager navigationManager, + LanguageInfo newLanguage, + IEnumerable allLanguages); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IRouteBasedCultureUrlHelper.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IRouteBasedCultureUrlHelper.cs new file mode 100644 index 0000000000..f56aeaf693 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/IRouteBasedCultureUrlHelper.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly; + +public interface IRouteBasedCultureUrlHelper +{ + /// + /// Prepends the current culture to when route-based culture is enabled + /// and the current culture is a known application language. + /// Returns the original unchanged when the feature is disabled or the + /// culture is not recognised. + /// + Task PrependCulturePrefixAsync(string url); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/RouteBasedCultureNavigationHelper.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/RouteBasedCultureNavigationHelper.cs new file mode 100644 index 0000000000..6a16f7430a --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/RouteBasedCultureNavigationHelper.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly; + +public class RouteBasedCultureNavigationHelper : IRouteBasedCultureNavigationHelper, ITransientDependency +{ + public virtual Task NavigateToNewCultureAsync( + NavigationManager navigationManager, + LanguageInfo newLanguage, + IEnumerable allLanguages) + { + var relativePath = navigationManager.ToBaseRelativePath(navigationManager.Uri); + + // Separate the path from any query string or fragment so the culture segment + // is correctly identified even for URLs like "tr?x=1" (no slash after culture). + var suffixIndex = relativePath.IndexOfAny(['?', '#']); + var pathPart = suffixIndex >= 0 ? relativePath.Substring(0, suffixIndex) : relativePath; + var suffix = suffixIndex >= 0 ? relativePath.Substring(suffixIndex) : string.Empty; + + var slashIndex = pathPart.IndexOf('/'); + var firstSegment = GetFirstPathSegment(relativePath); + var pathRemainder = slashIndex >= 0 ? pathPart.Substring(slashIndex) : string.Empty; + + // No-op: the current URL already shows the target culture โ€” no navigation needed. + if (string.Equals(firstSegment, newLanguage.CultureName, StringComparison.OrdinalIgnoreCase)) + { + return Task.CompletedTask; + } + + var newRelativePath = allLanguages.Any(l => string.Equals(l.CultureName, firstSegment, StringComparison.OrdinalIgnoreCase)) + ? newLanguage.CultureName + pathRemainder + suffix + : newLanguage.CultureName + "/" + pathPart + suffix; + + navigationManager.NavigateTo(navigationManager.ToAbsoluteUri(newRelativePath).ToString(), forceLoad: true); + return Task.CompletedTask; + } + + /// + /// Returns the first path segment of , + /// stripping any query string or fragment before splitting on '/'. + /// For example: "zh-Hans/account?x=1" โ†’ "zh-Hans", "tr/home#top" โ†’ "tr". + /// + protected virtual string GetFirstPathSegment(string baseRelativePath) + { + var suffixIndex = baseRelativePath.IndexOfAny(['?', '#']); + var pathPart = suffixIndex >= 0 ? baseRelativePath.Substring(0, suffixIndex) : baseRelativePath; + var slashIndex = pathPart.IndexOf('/'); + return slashIndex >= 0 ? pathPart.Substring(0, slashIndex) : pathPart; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/RouteBasedCultureUrlHelper.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/RouteBasedCultureUrlHelper.cs new file mode 100644 index 0000000000..0c03e56b5b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/RouteBasedCultureUrlHelper.cs @@ -0,0 +1,90 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.Client; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly; + +public class RouteBasedCultureUrlHelper : IRouteBasedCultureUrlHelper, ITransientDependency +{ + private readonly ICachedApplicationConfigurationClient _configurationClient; + + public RouteBasedCultureUrlHelper(ICachedApplicationConfigurationClient configurationClient) + { + _configurationClient = configurationClient; + } + + public virtual async Task PrependCulturePrefixAsync(string url) + { + if (string.IsNullOrEmpty(url)) + { + return url; + } + + // Skip absolute URLs with a web scheme and protocol-relative URLs. + // Intentionally avoids Uri.TryCreate here: on Unix, root-relative paths such as + // "/account/login" are parsed as absolute file:// URIs, which would incorrectly + // skip them before the culture prefix could be applied. + if (url.StartsWith("//", StringComparison.Ordinal) || + url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || + url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) + { + return url; + } + + var config = await _configurationClient.GetAsync(); + if (config?.Localization.UseRouteBasedCulture != true) + { + return url; + } + + var currentCulture = CultureInfo.CurrentCulture.Name; + var isKnownCulture = config.Localization.Languages + .Any(l => string.Equals(l.CultureName, currentCulture, StringComparison.OrdinalIgnoreCase)); + + if (!isKnownCulture) + { + return url; + } + + // Idempotency guard: if the URL already carries the culture prefix, return it unchanged. + // Strip the leading scheme prefix (~/ or /) before checking the first path segment. + var pathForSegmentCheck = url.StartsWith("~/", StringComparison.Ordinal) ? url.Substring(2) + : url.StartsWith("/", StringComparison.Ordinal) ? url.Substring(1) + : url; + + if (string.Equals(GetFirstPathSegment(pathForSegmentCheck), + currentCulture, StringComparison.OrdinalIgnoreCase)) + { + return url; + } + + if (url.StartsWith("~/", StringComparison.Ordinal)) + { + return "~/" + currentCulture + "/" + url.Substring(2); + } + + if (url.StartsWith("/", StringComparison.Ordinal)) + { + return "/" + currentCulture + url; + } + + // Bare relative path (e.g. "authentication/login") + return currentCulture + "/" + url; + } + + /// + /// Returns the first path segment of , + /// stripping any query string or fragment before splitting on '/'. + /// For example: "zh-Hans/account?x=1" โ†’ "zh-Hans", "tr/home#top" โ†’ "tr". + /// + protected virtual string GetFirstPathSegment(string baseRelativePath) + { + var suffixIndex = baseRelativePath.IndexOfAny(['?', '#']); + var pathPart = suffixIndex >= 0 ? baseRelativePath.Substring(0, suffixIndex) : baseRelativePath; + var slashIndex = pathPart.IndexOf('/'); + return slashIndex >= 0 ? pathPart.Substring(0, slashIndex) : pathPart; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs index 5ae2a8ed2d..1f3bbe96a3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs @@ -34,6 +34,8 @@ public class ApplicationLocalizationConfigurationDto public Dictionary> LanguageFilesMap { get; set; } + public bool UseRouteBasedCulture { get; set; } + public ApplicationLocalizationConfigurationDto() { Values = new Dictionary>(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index ad8d8c1c28..9da7e7454f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -16,6 +16,8 @@ using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.AspNetCore.Mvc.DataAnnotations; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; +using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.AspNetCore.RequestLocalization; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Localization; @@ -212,6 +214,45 @@ public class AbpAspNetCoreMvcModule : AbpModule { preConfigureActions.Configure(options); }); + + ConfigureRouteBasedCulture(context); + } + + protected virtual void ConfigureRouteBasedCulture(ServiceConfigurationContext context) + { + context.Services.Configure(options => + { + options.ConstraintMap["culture"] = typeof(AbpCultureRouteConstraint); + }); + + context.Services + .AddOptions() + .PostConfigure>((routerOptions, abpLocOptions) => + { + if (abpLocOptions.Value.UseRouteBasedCulture) + { + routerOptions.EndpointConfigureActions.Insert(0, endpointContext => + { + endpointContext.Endpoints.MapControllerRoute( + "AbpCultureRoute", + AbpCultureRoutePagesConvention.CultureRouteTemplate + "/{controller=Home}/{action=Index}/{id?}"); + }); + } + }); + + context.Services + .AddOptions() + .PostConfigure>((pagesOptions, abpLocOptions) => + { + if (abpLocOptions.Value.UseRouteBasedCulture && + !pagesOptions.Conventions.OfType().Any()) + { + pagesOptions.Conventions.Add(new AbpCultureRoutePagesConvention()); + } + }); + + context.Services.TryAddSingleton(); + context.Services.Replace(ServiceDescriptor.Singleton()); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs index b1ae63c39b..f22b7739a2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs @@ -1,4 +1,5 @@ ๏ปฟusing Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.RequestLocalization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; @@ -27,6 +28,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApplicationConfigurationAppService { private readonly AbpLocalizationOptions _localizationOptions; + private readonly AbpRequestLocalizationOptions _requestLocalizationOptions; private readonly AbpMultiTenancyOptions _multiTenancyOptions; private readonly IServiceProvider _serviceProvider; private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider; @@ -46,6 +48,7 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp public AbpApplicationConfigurationAppService( IOptions localizationOptions, + IOptions requestLocalizationOptions, IOptions multiTenancyOptions, IServiceProvider serviceProvider, IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider, @@ -79,6 +82,7 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp _cachedObjectExtensionsDtoService = cachedObjectExtensionsDtoService; _options = options.Value; _localizationOptions = localizationOptions.Value; + _requestLocalizationOptions = requestLocalizationOptions.Value; _multiTenancyOptions = multiTenancyOptions.Value; } @@ -253,6 +257,7 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp localizationConfig.LanguagesMap = _localizationOptions.LanguagesMap; localizationConfig.LanguageFilesMap = _localizationOptions.LanguageFilesMap; + localizationConfig.UseRouteBasedCulture = _requestLocalizationOptions.UseRouteBasedCulture; return localizationConfig; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs index 688392f3f1..14a9ba5c51 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs @@ -1,6 +1,10 @@ -๏ปฟusing System; +using System; +using System.Collections.Generic; +using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.WebUtilities; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.Localization; @@ -9,25 +13,71 @@ public class AbpAspNetCoreMvcQueryStringCultureReplacement : IQueryStringCulture { public virtual Task ReplaceAsync(QueryStringCultureReplacementContext context) { - if (!string.IsNullOrWhiteSpace(context.ReturnUrl)) + if (string.IsNullOrWhiteSpace(context.ReturnUrl)) { - if (context.ReturnUrl.Contains("culture=", StringComparison.OrdinalIgnoreCase) && - context.ReturnUrl.Contains("ui-Culture=", StringComparison.OrdinalIgnoreCase)) - { - context.ReturnUrl = Regex.Replace( - context.ReturnUrl, - "culture=[A-Za-z-]+", - $"culture={context.RequestCulture.Culture}", - RegexOptions.Compiled | RegexOptions.IgnoreCase); - - context.ReturnUrl = Regex.Replace( - context.ReturnUrl, - "ui-culture=[A-Za-z-]+", - $"ui-culture={context.RequestCulture.UICulture}", - RegexOptions.Compiled | RegexOptions.IgnoreCase); - } + return Task.CompletedTask; } + var currentCulture = context.CurrentCulture + ?? context.HttpContext.GetRouteValue("culture")?.ToString(); + + if (!string.IsNullOrEmpty(currentCulture)) + { + var escapedCulture = Regex.Escape(currentCulture); + // Replace only the first occurrence so that paths like /en/products/en/details + // only have the leading culture segment replaced, while tenant-prefixed paths + // like /tenant-a/en/... are also handled correctly. + var pattern = $"/{escapedCulture}(?=/|$|\\?|#)"; + context.ReturnUrl = new Regex(pattern, RegexOptions.IgnoreCase) + .Replace(context.ReturnUrl, "/" + context.RequestCulture.Culture.Name, 1); + } + + context.ReturnUrl = ReplaceQueryStringCulture(context.ReturnUrl, context); + return Task.CompletedTask; } + + /// + /// Replaces culture and ui-culture query parameters in + /// with the values from . Each parameter is handled independently โ€” + /// the presence of one does not require the other. Uses a proper query parser instead of + /// regex to avoid false-positive matches inside other parameter values. + /// + protected virtual string ReplaceQueryStringCulture(string url, QueryStringCultureReplacementContext context) + { + var fragmentIndex = url.IndexOf('#'); + var fragment = fragmentIndex >= 0 ? url.Substring(fragmentIndex) : string.Empty; + var urlWithoutFragment = fragmentIndex >= 0 ? url.Substring(0, fragmentIndex) : url; + + var queryIndex = urlWithoutFragment.IndexOf('?'); + if (queryIndex < 0) + { + return url; + } + + var path = urlWithoutFragment.Substring(0, queryIndex); + var queryString = urlWithoutFragment.Substring(queryIndex); + var query = QueryHelpers.ParseQuery(queryString); + + if (!query.ContainsKey("culture") && !query.ContainsKey("ui-culture")) + { + return url; + } + + if (query.ContainsKey("culture")) + { + query["culture"] = context.RequestCulture.Culture.Name; + } + + if (query.ContainsKey("ui-culture")) + { + query["ui-culture"] = context.RequestCulture.UICulture.Name; + } + + var rebuiltUrl = QueryHelpers.AddQueryString( + path, + query.SelectMany(kvp => kvp.Value.Select(v => KeyValuePair.Create(kvp.Key, v)))); + + return rebuiltUrl + fragment; + } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureAwareUrlHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureAwareUrlHelper.cs new file mode 100644 index 0000000000..35c8dedeef --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureAwareUrlHelper.cs @@ -0,0 +1,71 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.AspNetCore.Routing; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +/// +/// Wraps an to automatically inject the culture route value +/// into all URL generation calls. +/// +public class AbpCultureAwareUrlHelper : IUrlHelper +{ + protected IUrlHelper Inner { get; } + protected string Culture { get; } + + public AbpCultureAwareUrlHelper(IUrlHelper inner, string culture) + { + Inner = inner; + Culture = culture; + } + + public ActionContext ActionContext => Inner.ActionContext; + + public virtual string? Action(UrlActionContext actionContext) + { + var values = new RouteValueDictionary(actionContext.Values); + values.TryAdd("culture", Culture); + + return Inner.Action(new UrlActionContext + { + Action = actionContext.Action, + Controller = actionContext.Controller, + Values = values, + Protocol = actionContext.Protocol, + Host = actionContext.Host, + Fragment = actionContext.Fragment, + }); + } + + public virtual string? Content(string? contentPath) + { + return Inner.Content(contentPath); + } + + public virtual bool IsLocalUrl(string? url) + { + return Inner.IsLocalUrl(url); + } + + public virtual string? Link(string? routeName, object? values) + { + var rvd = new RouteValueDictionary(values); + rvd.TryAdd("culture", Culture); + return Inner.Link(routeName, rvd); + } + + public virtual string? RouteUrl(UrlRouteContext routeContext) + { + var values = new RouteValueDictionary(routeContext.Values); + values.TryAdd("culture", Culture); + + return Inner.RouteUrl(new UrlRouteContext + { + RouteName = routeContext.RouteName, + Values = values, + Protocol = routeContext.Protocol, + Host = routeContext.Host, + Fragment = routeContext.Fragment, + }); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureMenuItemUrlProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureMenuItemUrlProvider.cs new file mode 100644 index 0000000000..1b91ce72e3 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureMenuItemUrlProvider.cs @@ -0,0 +1,69 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.RequestLocalization; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +/// +/// Prepends the culture route prefix to menu item URLs when route-based culture is enabled. +/// +public class AbpCultureMenuItemUrlProvider : IMenuItemUrlProvider, ITransientDependency +{ + protected IHttpContextAccessor HttpContextAccessor { get; } + protected IOptions LocalizationOptions { get; } + protected IOptions AbpLocalizationOptions { get; } + protected IMenuItemCulturePrefixHelper MenuItemCulturePrefixHelper { get; } + + public AbpCultureMenuItemUrlProvider( + IHttpContextAccessor httpContextAccessor, + IOptions localizationOptions, + IOptions abpLocalizationOptions, + IMenuItemCulturePrefixHelper menuItemCulturePrefixHelper) + { + HttpContextAccessor = httpContextAccessor; + LocalizationOptions = localizationOptions; + AbpLocalizationOptions = abpLocalizationOptions; + MenuItemCulturePrefixHelper = menuItemCulturePrefixHelper; + } + + public virtual async Task HandleAsync(MenuItemUrlProviderContext context) + { + if (!LocalizationOptions.Value.UseRouteBasedCulture) + { + return; + } + + var culture = GetCulture(); + if (string.IsNullOrEmpty(culture)) + { + return; + } + + await MenuItemCulturePrefixHelper.PrependCulturePrefixAsync(context.Menu, "/" + culture); + } + + protected virtual string? GetCulture() + { + var httpContext = HttpContextAccessor.HttpContext; + if (httpContext != null) + { + return AbpRequestCultureCookieHelper.GetRouteCulture(httpContext); + } + + // No HttpContext: fallback to CurrentCulture. + var currentCulture = CultureInfo.CurrentCulture.Name; + var isKnownCulture = AbpLocalizationOptions.Value.Languages + .Any(l => string.Equals(l.CultureName, currentCulture, StringComparison.OrdinalIgnoreCase)); + + return isKnownCulture ? currentCulture : null; + } + +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRouteConstraint.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRouteConstraint.cs new file mode 100644 index 0000000000..fe12bac3ff --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRouteConstraint.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.Localization; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +/// +/// A route constraint that only matches culture values configured in +/// . +/// +public class AbpCultureRouteConstraint : IRouteConstraint +{ + public virtual bool Match(HttpContext? httpContext, IRouter? route, string routeKey, + RouteValueDictionary values, RouteDirection routeDirection) + { + if (!values.TryGetValue(routeKey, out var value) || value is not string cultureValue) + { + return false; + } + + var languages = httpContext?.RequestServices + .GetService>()?.Value.Languages; + + if (languages == null || languages.Count == 0) + { + // During URL generation, HttpContext or services may not be available. + return routeDirection == RouteDirection.UrlGeneration; + } + + return languages.Any(l => + string.Equals(l.CultureName, cultureValue, StringComparison.OrdinalIgnoreCase)); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRoutePagesConvention.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRoutePagesConvention.cs new file mode 100644 index 0000000000..9410562f33 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRoutePagesConvention.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Mvc.ApplicationModels; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +/// +/// Adds a {culture}-prefixed route selector to every Razor Page. +/// Automatically registered when UseRouteBasedCulture is true. +/// +public class AbpCultureRoutePagesConvention : IPageRouteModelConvention +{ + /// + /// Route parameter template using the custom "culture" route constraint registered in + /// . The constraint only matches culture values + /// configured in . + /// + internal const string CultureRouteTemplate = "{culture:culture}"; + + public virtual void Apply(PageRouteModel model) + { + var selectorsToAdd = new List(); + + foreach (var selector in model.Selectors.ToList()) + { + var originalTemplate = selector.AttributeRouteModel?.Template?.TrimStart('/'); + if (originalTemplate == null) + { + continue; + } + + selectorsToAdd.Add(new SelectorModel + { + AttributeRouteModel = new AttributeRouteModel + { + Template = AttributeRouteModel.CombineTemplates(CultureRouteTemplate, originalTemplate), + Order = -1 + } + }); + } + + foreach (var selector in selectorsToAdd) + { + model.Selectors.Add(selector); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRouteUrlHelperFactory.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRouteUrlHelperFactory.cs new file mode 100644 index 0000000000..7be4456677 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureRouteUrlHelperFactory.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.AspNetCore.RequestLocalization; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Options; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +/// +/// Wraps the default to automatically inject the culture +/// route value into all URL generation calls when the current request has a {culture} route value. +/// Only activates when is true. +/// +public class AbpCultureRouteUrlHelperFactory : IUrlHelperFactory +{ + protected UrlHelperFactory Inner { get; } + protected IOptions LocalizationOptions { get; } + + public AbpCultureRouteUrlHelperFactory( + UrlHelperFactory inner, + IOptions localizationOptions) + { + Inner = inner; + LocalizationOptions = localizationOptions; + } + + public virtual IUrlHelper GetUrlHelper(ActionContext context) + { + var urlHelper = Inner.GetUrlHelper(context); + + if (!LocalizationOptions.Value.UseRouteBasedCulture) + { + return urlHelper; + } + + if (context.RouteData.Values.TryGetValue("culture", out var culture) && + culture != null) + { + return CreateCultureAwareUrlHelper(urlHelper, culture.ToString()!); + } + + return urlHelper; + } + + protected virtual AbpCultureAwareUrlHelper CreateCultureAwareUrlHelper(IUrlHelper urlHelper, string culture) + { + return new AbpCultureAwareUrlHelper(urlHelper, culture); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs index 73c93851ff..dc5dd3ccf6 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController.cs @@ -1,7 +1,8 @@ -๏ปฟusing Microsoft.AspNetCore.Localization; -using Microsoft.AspNetCore.Mvc; using System; +using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.RequestLocalization; using Volo.Abp.Auditing; using Volo.Abp.Localization; @@ -42,7 +43,12 @@ public class AbpLanguagesController : AbpController HttpContext.Items[AbpRequestLocalizationMiddleware.HttpContextItemName] = true; - var context = new QueryStringCultureReplacementContext(HttpContext, new RequestCulture(culture, uiCulture), returnUrl); + var context = new QueryStringCultureReplacementContext( + HttpContext, + new RequestCulture(culture, uiCulture), + returnUrl, + GetCurrentCultureFromRequestCookie()); + await QueryStringCultureReplacement.ReplaceAsync(context); if (!string.IsNullOrWhiteSpace(context.ReturnUrl)) @@ -53,6 +59,18 @@ public class AbpLanguagesController : AbpController return Redirect("~/"); } + protected virtual string? GetCurrentCultureFromRequestCookie() + { + var cookieValue = HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName]; + if (cookieValue == null) + { + return null; + } + + var result = CookieRequestCultureProvider.ParseCookieValue(cookieValue); + return result?.Cultures.FirstOrDefault().Value; + } + protected virtual string GetRedirectUrl(string returnUrl) { if (returnUrl.IsNullOrEmpty()) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/QueryStringCultureReplacementContext.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/QueryStringCultureReplacementContext.cs index b70c24fb95..15866f54bc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/QueryStringCultureReplacementContext.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/QueryStringCultureReplacementContext.cs @@ -1,4 +1,4 @@ -๏ปฟusing Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; namespace Volo.Abp.AspNetCore.Mvc.Localization; @@ -11,10 +11,17 @@ public class QueryStringCultureReplacementContext public string ReturnUrl { get; set; } - public QueryStringCultureReplacementContext(HttpContext httpContext, RequestCulture requestCulture, string returnUrl) + public string? CurrentCulture { get; } + + public QueryStringCultureReplacementContext( + HttpContext httpContext, + RequestCulture requestCulture, + string returnUrl, + string? currentCulture = null) { HttpContext = httpContext; RequestCulture = requestCulture; ReturnUrl = returnUrl; + CurrentCulture = currentCulture; } } diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestCultureCookieHelper.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestCultureCookieHelper.cs index 9bb5b61d28..552c3bfc84 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestCultureCookieHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestCultureCookieHelper.cs @@ -1,11 +1,41 @@ ๏ปฟusing System; +using System.Globalization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Routing; namespace Microsoft.AspNetCore.RequestLocalization; public static class AbpRequestCultureCookieHelper { + public const string HasRouteCultureCookieName = "Abp.HasRouteCulture"; + + /// + /// Gets the current route culture from the request. First checks route values, + /// then falls back to the HasRouteCulture cookie (set during Blazor SSR) with CurrentCulture. + /// Returns null if the request has no route-based culture. + /// + public static string? GetRouteCulture(HttpContext? httpContext) + { + if (httpContext == null) + { + return null; + } + + var routeCulture = httpContext.GetRouteValue("culture")?.ToString(); + if (!string.IsNullOrEmpty(routeCulture)) + { + return routeCulture; + } + + if (httpContext.Request.Cookies.ContainsKey(HasRouteCultureCookieName)) + { + return CultureInfo.CurrentCulture.Name; + } + + return null; + } + public static void SetCultureCookie( HttpContext httpContext, RequestCulture requestCulture) @@ -20,4 +50,21 @@ public static class AbpRequestCultureCookieHelper } ); } + + public static void SetHasRouteCultureCookie(HttpContext httpContext, bool hasRouteCulture) + { + if (hasRouteCulture) + { + httpContext.Response.Cookies.Append( + HasRouteCultureCookieName, "1", + new CookieOptions + { + IsEssential = true + }); + } + else + { + httpContext.Response.Cookies.Delete(HasRouteCultureCookieName); + } + } } diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs index cb531762ba..4683c3151d 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs @@ -1,7 +1,9 @@ -๏ปฟusing System.Threading.Tasks; +๏ปฟusing System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Localization.Routing; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Middleware; @@ -39,13 +41,28 @@ public class AbpRequestLocalizationMiddleware : AbpMiddlewareBase, ITransientDep if (context.Items[HttpContextItemName] == null) { var requestCultureFeature = context.Features.Get(); - if (requestCultureFeature?.Provider is QueryStringRequestCultureProvider) + if (requestCultureFeature?.Provider is QueryStringRequestCultureProvider + or RouteDataRequestCultureProvider) { AbpRequestCultureCookieHelper.SetCultureCookie( context, requestCultureFeature.RequestCulture ); } + + // Only manage HasRouteCulture cookie for Blazor component page requests. + // This cookie is used by AbpCultureMenuItemUrlProvider to determine if the + // initial SSR page had a culture prefix, since the Blazor interactive circuit + // (/_blazor) does not carry the original route values. + // Note: ComponentTypeMetadata is an internal ASP.NET Core type + // (Microsoft.AspNetCore.Components.Endpoints.ComponentTypeMetadata). + // We match by full type name to avoid false positives from other assemblies. + var endpoint = context.GetEndpoint(); + if (endpoint?.Metadata.Any(m => m.GetType().FullName == "Microsoft.AspNetCore.Components.Endpoints.ComponentTypeMetadata") == true) + { + AbpRequestCultureCookieHelper.SetHasRouteCultureCookie( + context, requestCultureFeature?.Provider is RouteDataRequestCultureProvider); + } } return Task.CompletedTask; diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptions.cs index bb83ce9a53..55394b7d17 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptions.cs @@ -9,6 +9,12 @@ public class AbpRequestLocalizationOptions { public List> RequestLocalizationOptionConfigurators { get; } + /// + /// Enables culture detection from route data (e.g. /{culture}/page). + /// Default value: false. + /// + public bool UseRouteBasedCulture { get; set; } + public AbpRequestLocalizationOptions() { RequestLocalizationOptionConfigurators = new List>(); diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs index cf9f128852..3cd2e88993 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Localization.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -70,9 +71,18 @@ public class DefaultAbpRequestLocalizationOptionsProvider : .ToArray() }; - foreach (var configurator in serviceScope.ServiceProvider - .GetRequiredService>() - .Value.RequestLocalizationOptionConfigurators) + var abpRequestLocalizationOptions = serviceScope.ServiceProvider + .GetRequiredService>() + .Value; + + if (abpRequestLocalizationOptions.UseRouteBasedCulture) + { + options.RequestCultureProviders.InsertAfter( + p => p is QueryStringRequestCultureProvider, + new RouteDataRequestCultureProvider()); + } + + foreach (var configurator in abpRequestLocalizationOptions.RequestLocalizationOptionConfigurators) { await configurator(serviceScope.ServiceProvider, options); } diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs index 7d1c3dee39..b92182db92 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs @@ -119,7 +119,6 @@ public static class AutofacRegistration .SingleInstance(); // Shims for keyed service compatibility. - builder.RegisterSource(); builder.ComponentRegistryBuilder.Registered += AddFromKeyedServiceParameterMiddleware; Register(builder, services, lifetimeScopeTagForSingletons); @@ -212,11 +211,15 @@ public static class AutofacRegistration this IRegistrationBuilder registrationBuilder, ServiceDescriptor descriptor) { + // If it's keyed, the service key won't be null. A null key results in it _not_ being a keyed service. if (descriptor.IsKeyedService) { var key = descriptor.ServiceKey!; + if (key.Equals(Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey)) + { + key = Autofac.Core.KeyedService.AnyKey; + } - // If it's keyed, the service key won't be null. A null key results in it _not_ being a keyed service. registrationBuilder.Keyed(key, descriptor.ServiceType); } else @@ -334,9 +337,7 @@ public static class AutofacRegistration var serviceProvider = context.Resolve(); - var keyedService = (Autofac.Core.KeyedService)requestContext.Service; - - var key = keyedService.ServiceKey; + var key = requestContext.Parameters.KeyedServiceKey(); return descriptor.KeyedImplementationFactory(serviceProvider, key); }) @@ -349,8 +350,7 @@ public static class AutofacRegistration continue; } - - if (!descriptor.IsKeyedService && descriptor.ImplementationFactory != null) + else if (!descriptor.IsKeyedService && descriptor.ImplementationFactory != null) { var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) => { @@ -371,7 +371,8 @@ public static class AutofacRegistration builder .RegisterInstance(descriptor.NormalizedImplementationInstance()!) .ConfigureServiceType(descriptor) - .ConfigureLifecycle(descriptor.Lifetime, null); + .ConfigureLifecycle(descriptor.Lifetime, null) + .ExternallyOwned(); } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs index 5ccd9034cd..decf844131 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/CmdHelper.cs @@ -1,7 +1,8 @@ -๏ปฟusing System; +using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; +using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -137,14 +138,11 @@ public class CmdHelper : ICmdHelper, ITransientDependency process.Start(); - using (var standardOutput = process.StandardOutput) - { - using (var standardError = process.StandardError) - { - output = standardOutput.ReadToEnd(); - output += standardError.ReadToEnd(); - } - } + var outputTask = process.StandardOutput.ReadToEndAsync(); + var errorTask = process.StandardError.ReadToEndAsync(); + + var results = Task.WhenAll(outputTask, errorTask).GetAwaiter().GetResult(); + output = results[0] + results[1]; process.WaitForExit(); diff --git a/framework/src/Volo.Abp.TextTemplating.Scriban/Volo/Abp/TextTemplating/Scriban/ScribanTemplateLocalizer.cs b/framework/src/Volo.Abp.TextTemplating.Scriban/Volo/Abp/TextTemplating/Scriban/ScribanTemplateLocalizer.cs index 6bf32d1a58..904a131342 100644 --- a/framework/src/Volo.Abp.TextTemplating.Scriban/Volo/Abp/TextTemplating/Scriban/ScribanTemplateLocalizer.cs +++ b/framework/src/Volo.Abp.TextTemplating.Scriban/Volo/Abp/TextTemplating/Scriban/ScribanTemplateLocalizer.cs @@ -18,16 +18,16 @@ public class ScribanTemplateLocalizer : IScriptCustomFunction _localizer = localizer; } - public object Invoke(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, - ScriptBlockStatement blockStatement) + public object? Invoke(TemplateContext context, ScriptNode? callerContext, ScriptArray arguments, + ScriptBlockStatement? blockStatement) { return GetString(arguments); } - public ValueTask InvokeAsync(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, - ScriptBlockStatement blockStatement) + public ValueTask InvokeAsync(TemplateContext context, ScriptNode? callerContext, ScriptArray arguments, + ScriptBlockStatement? blockStatement) { - return new ValueTask(GetString(arguments)); + return new ValueTask(GetString(arguments)); } private string GetString(ScriptArray arguments) @@ -43,7 +43,7 @@ public class ScribanTemplateLocalizer : IScriptCustomFunction return string.Empty; } - var args = arguments.Skip(1).Where(x => x != null && !x.ToString().IsNullOrWhiteSpace()).ToArray(); + var args = arguments.Skip(1).Where(x => x != null && !x.ToString().IsNullOrWhiteSpace()).Cast().ToArray(); return args.Any() ? _localizer[name.ToString()!, args] : _localizer[name.ToString()!]; } diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IMenuItemCulturePrefixHelper.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IMenuItemCulturePrefixHelper.cs new file mode 100644 index 0000000000..93d9992b3f --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IMenuItemCulturePrefixHelper.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.UI.Navigation; + +public interface IMenuItemCulturePrefixHelper +{ + Task PrependCulturePrefixAsync(IHasMenuItems menuWithItems, string prefix); +} diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IMenuItemUrlProvider.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IMenuItemUrlProvider.cs new file mode 100644 index 0000000000..faae8c2367 --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/IMenuItemUrlProvider.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.UI.Navigation; + +/// +/// Provides a way to modify menu item URLs after the menu is fully configured. +/// Implementations can transform URLs based on the current request context +/// (e.g. adding a culture prefix for URL-based localization). +/// +public interface IMenuItemUrlProvider +{ + Task HandleAsync(MenuItemUrlProviderContext context); +} diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuItemCulturePrefixHelper.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuItemCulturePrefixHelper.cs new file mode 100644 index 0000000000..242cf9f679 --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuItemCulturePrefixHelper.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.UI.Navigation; + +public class MenuItemCulturePrefixHelper : IMenuItemCulturePrefixHelper, ITransientDependency +{ + public virtual Task PrependCulturePrefixAsync(IHasMenuItems menuWithItems, string prefix) + { + PrependCulturePrefix(menuWithItems, prefix); + return Task.CompletedTask; + } + + protected virtual void PrependCulturePrefix(IHasMenuItems menuWithItems, string prefix) + { + foreach (var item in menuWithItems.Items) + { + if (item.Url != null) + { + if (item.Url.StartsWith("~/")) + { + item.Url = "~" + prefix + item.Url.Substring(1); + } + else if (item.Url.StartsWith("/")) + { + item.Url = prefix + item.Url; + } + } + + PrependCulturePrefix(item, prefix); + } + } +} diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuItemUrlProviderContext.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuItemUrlProviderContext.cs new file mode 100644 index 0000000000..55f9d178da --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuItemUrlProviderContext.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.UI.Navigation; + +public class MenuItemUrlProviderContext +{ + public ApplicationMenu Menu { get; } + + public MenuItemUrlProviderContext(ApplicationMenu menu) + { + Menu = menu; + } +} diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs index 6334ea9918..f1d8ae22d7 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs @@ -92,6 +92,12 @@ public class MenuManager : IMenuManager, ITransientDependency await CheckPermissionsAsync(scope.ServiceProvider, menu); } + + var urlProviderContext = new MenuItemUrlProviderContext(menu); + foreach (var urlProvider in scope.ServiceProvider.GetServices()) + { + await urlProvider.HandleAsync(urlProviderContext); + } } NormalizeMenu(menu); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index 8a929dd38a..496dba12ed 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -24,6 +24,7 @@ + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 9154608680..4339104b30 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -11,6 +11,7 @@ using Volo.Abp.AspNetCore.Mvc.GlobalFeatures; using Volo.Abp.AspNetCore.Mvc.Libs; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.Localization.Resource; +using Microsoft.AspNetCore.RequestLocalization; using Volo.Abp.AspNetCore.Security.Claims; using Volo.Abp.AspNetCore.TestBase; using Volo.Abp.Authorization; @@ -121,6 +122,11 @@ public class AbpAspNetCoreMvcTestModule : AbpModule options.Languages.Add(new LanguageInfo("el", "el", "ฮ•ฮปฮปฮทฮฝฮนฮบฮฌ")); }); + Configure(options => + { + options.UseRouteBasedCulture = true; + }); + Configure(options => { options.RootDirectory = "/Volo/Abp/AspNetCore/Mvc"; diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureAwareUrlHelper_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureAwareUrlHelper_Tests.cs new file mode 100644 index 0000000000..d761d85bf8 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureAwareUrlHelper_Tests.cs @@ -0,0 +1,137 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Routing; +using Microsoft.AspNetCore.RequestLocalization; +using Microsoft.AspNetCore.Routing; +using NSubstitute; +using Shouldly; +using Volo.Abp.AspNetCore.Mvc.Localization; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +public class AbpCultureAwareUrlHelper_Tests +{ + [Fact] + public void Action_Should_Inject_Culture() + { + var inner = Substitute.For(); + inner.Action(Arg.Any()).Returns(callInfo => + { + var ctx = callInfo.Arg(); + var values = new RouteValueDictionary(ctx.Values); + return values.ContainsKey("culture") ? $"/{values["culture"]}/{ctx.Controller}/{ctx.Action}" : $"/{ctx.Controller}/{ctx.Action}"; + }); + + var helper = new AbpCultureAwareUrlHelper(inner, "zh-Hans"); + var result = helper.Action(new UrlActionContext { Controller = "Home", Action = "Index" }); + + result.ShouldContain("zh-Hans"); + } + + [Fact] + public void Action_Should_Not_Override_Explicit_Culture() + { + var inner = Substitute.For(); + inner.Action(Arg.Any()).Returns(callInfo => + { + var ctx = callInfo.Arg(); + var values = new RouteValueDictionary(ctx.Values); + return $"/{values["culture"]}/Home/Index"; + }); + + var helper = new AbpCultureAwareUrlHelper(inner, "zh-Hans"); + var result = helper.Action(new UrlActionContext + { + Controller = "Home", + Action = "Index", + Values = new { culture = "en" } + }); + + // Explicit "en" should not be overridden by "zh-Hans" + result.ShouldBe("/en/Home/Index"); + } + + [Fact] + public void RouteUrl_Should_Inject_Culture() + { + var inner = Substitute.For(); + inner.RouteUrl(Arg.Any()).Returns(callInfo => + { + var ctx = callInfo.Arg(); + var values = new RouteValueDictionary(ctx.Values); + return values.ContainsKey("culture") ? $"/{values["culture"]}/page" : "/page"; + }); + + var helper = new AbpCultureAwareUrlHelper(inner, "tr"); + var result = helper.RouteUrl(new UrlRouteContext()); + + result.ShouldBe("/tr/page"); + } + + [Fact] + public void Content_Should_Pass_Through() + { + var inner = Substitute.For(); + inner.Content("~/test").Returns("/test"); + + var helper = new AbpCultureAwareUrlHelper(inner, "en"); + helper.Content("~/test").ShouldBe("/test"); + } + + [Fact] + public void IsLocalUrl_Should_Pass_Through() + { + var inner = Substitute.For(); + inner.IsLocalUrl("/test").Returns(true); + + var helper = new AbpCultureAwareUrlHelper(inner, "en"); + helper.IsLocalUrl("/test").ShouldBeTrue(); + } + + [Fact] + public void Factory_Should_Return_CultureAwareHelper_When_Culture_In_Route() + { + var factory = CreateFactory(useRouteBasedCulture: true); + var httpContext = new DefaultHttpContext(); + httpContext.Request.RouteValues["culture"] = "tr"; + var actionContext = new ActionContext(httpContext, new RouteData(httpContext.Request.RouteValues), new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor()); + + var urlHelper = factory.GetUrlHelper(actionContext); + + urlHelper.ShouldBeOfType(); + } + + [Fact] + public void Factory_Should_Return_Default_Helper_When_No_Culture() + { + var factory = CreateFactory(useRouteBasedCulture: true); + var httpContext = new DefaultHttpContext(); + var actionContext = new ActionContext(httpContext, new RouteData(), new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor()); + + var urlHelper = factory.GetUrlHelper(actionContext); + + urlHelper.ShouldNotBeOfType(); + } + + [Fact] + public void Factory_Should_Return_Default_Helper_When_RouteBasedCulture_Disabled() + { + var factory = CreateFactory(useRouteBasedCulture: false); + var httpContext = new DefaultHttpContext(); + httpContext.Request.RouteValues["culture"] = "tr"; + var actionContext = new ActionContext(httpContext, new RouteData(httpContext.Request.RouteValues), new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor()); + + // Even with culture in route, should not wrap when the feature is disabled + var urlHelper = factory.GetUrlHelper(actionContext); + + urlHelper.ShouldNotBeOfType(); + } + + private static AbpCultureRouteUrlHelperFactory CreateFactory(bool useRouteBasedCulture) + { + return new AbpCultureRouteUrlHelperFactory( + new UrlHelperFactory(), + Microsoft.Extensions.Options.Options.Create(new AbpRequestLocalizationOptions { UseRouteBasedCulture = useRouteBasedCulture })); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureMenuItemUrlProvider_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureMenuItemUrlProvider_Tests.cs new file mode 100644 index 0000000000..bd77480bc4 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpCultureMenuItemUrlProvider_Tests.cs @@ -0,0 +1,280 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.RequestLocalization; +using Microsoft.AspNetCore.Routing; +using Shouldly; +using MsOptions = Microsoft.Extensions.Options.Options; +using Volo.Abp.Localization; +using Volo.Abp.UI.Navigation; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +public class AbpCultureMenuItemUrlProvider_Tests +{ + [Fact] + public async Task Should_Not_Modify_Urls_When_RouteBasedCulture_Is_Disabled() + { + var provider = CreateProvider(useRouteBasedCulture: false, cultureName: "zh-Hans"); + var menu = CreateMenuWithItems("/home", "/about"); + + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + + menu.Items[0].Url.ShouldBe("/home"); + menu.Items[1].Url.ShouldBe("/about"); + } + + [Fact] + public async Task Should_Prepend_Culture_Prefix_When_Route_Has_Culture() + { + var provider = CreateProvider(useRouteBasedCulture: true, cultureName: "zh-Hans"); + var menu = CreateMenuWithItems("/home", "/about"); + + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + + menu.Items[0].Url.ShouldBe("/zh-Hans/home"); + menu.Items[1].Url.ShouldBe("/zh-Hans/about"); + } + + [Fact] + public async Task Should_Not_Add_Prefix_For_Mvc_Request_Without_Culture() + { + // MVC request to /about (no culture, no HasRouteCulture cookie). + var httpContext = new DefaultHttpContext(); + httpContext.Request.RouteValues["controller"] = "Home"; + httpContext.Request.RouteValues["action"] = "About"; + var httpContextAccessor = new HttpContextAccessor { HttpContext = httpContext }; + var localizationOptions = MsOptions.Create( + new AbpRequestLocalizationOptions { UseRouteBasedCulture = true }); + var abpLocOptions = new AbpLocalizationOptions(); + abpLocOptions.Languages.Add(new LanguageInfo("en")); + abpLocOptions.Languages.Add(new LanguageInfo("zh-Hans")); + var provider = new AbpCultureMenuItemUrlProvider( + httpContextAccessor, localizationOptions, MsOptions.Create(abpLocOptions), new MenuItemCulturePrefixHelper()); + + var menu = CreateMenuWithItems("/home", "/about"); + + var previousCulture = CultureInfo.CurrentCulture; + try + { + CultureInfo.CurrentCulture = new CultureInfo("zh-Hans"); + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + } + finally + { + CultureInfo.CurrentCulture = previousCulture; + } + + menu.Items[0].Url.ShouldBe("/home"); + menu.Items[1].Url.ShouldBe("/about"); + } + + [Fact] + public async Task Should_Fallback_To_CurrentCulture_In_Blazor_Circuit() + { + // Blazor Server interactive circuit: HttpContext exists (SignalR) but has + // no route culture. Cookie was set during SSR indicating route culture was used. + var httpContext = new DefaultHttpContext(); + httpContext.Request.Headers["Cookie"] = $"{AbpRequestCultureCookieHelper.HasRouteCultureCookieName}=1"; + var httpContextAccessor = new HttpContextAccessor { HttpContext = httpContext }; + var localizationOptions = MsOptions.Create( + new AbpRequestLocalizationOptions { UseRouteBasedCulture = true }); + var abpLocOptions = new AbpLocalizationOptions(); + abpLocOptions.Languages.Add(new LanguageInfo("en")); + abpLocOptions.Languages.Add(new LanguageInfo("zh-Hans")); + var provider = new AbpCultureMenuItemUrlProvider( + httpContextAccessor, localizationOptions, MsOptions.Create(abpLocOptions), new MenuItemCulturePrefixHelper()); + + var menu = CreateMenuWithItems("/home", "/about"); + + var previousCulture = CultureInfo.CurrentCulture; + try + { + CultureInfo.CurrentCulture = new CultureInfo("zh-Hans"); + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + } + finally + { + CultureInfo.CurrentCulture = previousCulture; + } + + menu.Items[0].Url.ShouldBe("/zh-Hans/home"); + menu.Items[1].Url.ShouldBe("/zh-Hans/about"); + } + + [Fact] + public async Task Should_Use_CurrentCulture_Fallback_When_No_HttpContext() + { + // Simulates Blazor interactive circuit: no HttpContext, but CurrentCulture is set. + // CurrentCulture (not CurrentUICulture) is used because {culture} route segments + // represent the culture, not the UI culture. + var provider = CreateProviderWithoutHttpContext( + useRouteBasedCulture: true, + knownLanguages: new[] { "en", "zh-Hans", "tr" }); + + var menu = CreateMenuWithItems("/home", "/about"); + + var previousCulture = CultureInfo.CurrentCulture; + try + { + CultureInfo.CurrentCulture = new CultureInfo("zh-Hans"); + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + } + finally + { + CultureInfo.CurrentCulture = previousCulture; + } + + menu.Items[0].Url.ShouldBe("/zh-Hans/home"); + menu.Items[1].Url.ShouldBe("/zh-Hans/about"); + } + + [Fact] + public async Task Should_Not_Modify_Urls_When_No_HttpContext_And_Unknown_Culture() + { + // Blazor interactive circuit with a culture that is not in the known languages list + var provider = CreateProviderWithoutHttpContext( + useRouteBasedCulture: true, + knownLanguages: new[] { "en", "tr" }); + + var menu = CreateMenuWithItems("/home", "/about"); + + var previousCulture = CultureInfo.CurrentCulture; + try + { + CultureInfo.CurrentCulture = new CultureInfo("fr"); + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + } + finally + { + CultureInfo.CurrentCulture = previousCulture; + } + + menu.Items[0].Url.ShouldBe("/home"); + menu.Items[1].Url.ShouldBe("/about"); + } + + [Fact] + public async Task Should_Prepend_Prefix_Recursively_For_Nested_Items() + { + var provider = CreateProvider(useRouteBasedCulture: true, cultureName: "tr"); + + var menu = new ApplicationMenu("TestMenu"); + var parent = new ApplicationMenuItem("Parent", "Parent", url: "/parent"); + var child = new ApplicationMenuItem("Child", "Child", url: "/child"); + var grandChild = new ApplicationMenuItem("GrandChild", "GrandChild", url: "/grandchild"); + child.AddItem(grandChild); + parent.AddItem(child); + menu.AddItem(parent); + + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + + parent.Url.ShouldBe("/tr/parent"); + child.Url.ShouldBe("/tr/child"); + grandChild.Url.ShouldBe("/tr/grandchild"); + } + + [Fact] + public async Task Should_Handle_Tilde_Slash_Urls() + { + // ~/identity/users is the pattern used by ABP module menu contributors (e.g. Identity) + var provider = CreateProvider(useRouteBasedCulture: true, cultureName: "zh-Hans"); + + var menu = new ApplicationMenu("TestMenu"); + menu.AddItem(new ApplicationMenuItem("Users", "Users", url: "~/identity/users")); + menu.AddItem(new ApplicationMenuItem("Roles", "Roles", url: "~/identity/roles")); + + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + + // ~/identity/users โ†’ ~/zh-Hans/identity/users + // Blazor theme strips "~/" via TrimStart('/', '~') โ†’ "zh-Hans/identity/users" + // With resolves to /zh-Hans/identity/users + menu.Items[0].Url.ShouldBe("~/zh-Hans/identity/users"); + menu.Items[1].Url.ShouldBe("~/zh-Hans/identity/roles"); + } + + [Fact] + public async Task Should_Not_Modify_External_Urls() + { + var provider = CreateProvider(useRouteBasedCulture: true, cultureName: "zh-Hans"); + + var menu = new ApplicationMenu("TestMenu"); + menu.AddItem(new ApplicationMenuItem("External", "External", url: "https://example.com/page")); + menu.AddItem(new ApplicationMenuItem("Relative", "Relative", url: "page")); + menu.AddItem(new ApplicationMenuItem("Local", "Local", url: "/local")); + + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + + // External and relative URLs should not be modified + menu.Items[0].Url.ShouldBe("https://example.com/page"); + menu.Items[1].Url.ShouldBe("page"); + // Local URL should be prefixed + menu.Items[2].Url.ShouldBe("/zh-Hans/local"); + } + + [Fact] + public async Task Should_Not_Throw_When_Url_Is_Null() + { + var provider = CreateProvider(useRouteBasedCulture: true, cultureName: "tr"); + + var menu = new ApplicationMenu("TestMenu"); + menu.AddItem(new ApplicationMenuItem("NoUrl", "No URL", url: null)); + menu.AddItem(new ApplicationMenuItem("WithUrl", "With URL", url: "/page")); + + await provider.HandleAsync(new MenuItemUrlProviderContext(menu)); + + // Null URL should remain null + menu.Items[0].Url.ShouldBeNull(); + // Normal URL should be prefixed + menu.Items[1].Url.ShouldBe("/tr/page"); + } + + private static AbpCultureMenuItemUrlProvider CreateProvider( + bool useRouteBasedCulture, + string? cultureName) + { + var httpContext = new DefaultHttpContext(); + if (cultureName != null) + { + httpContext.Request.RouteValues["culture"] = cultureName; + } + + var httpContextAccessor = new HttpContextAccessor { HttpContext = httpContext }; + var localizationOptions = MsOptions.Create( + new AbpRequestLocalizationOptions { UseRouteBasedCulture = useRouteBasedCulture }); + var abpLocalizationOptions = MsOptions.Create(new AbpLocalizationOptions()); + + return new AbpCultureMenuItemUrlProvider( + httpContextAccessor, localizationOptions, abpLocalizationOptions, new MenuItemCulturePrefixHelper()); + } + + private static AbpCultureMenuItemUrlProvider CreateProviderWithoutHttpContext( + bool useRouteBasedCulture, + string[] knownLanguages) + { + var httpContextAccessor = new HttpContextAccessor { HttpContext = null }; + var localizationOptions = MsOptions.Create( + new AbpRequestLocalizationOptions { UseRouteBasedCulture = useRouteBasedCulture }); + var abpLocOptions = new AbpLocalizationOptions(); + foreach (var lang in knownLanguages) + { + abpLocOptions.Languages.Add(new LanguageInfo(lang)); + } + + return new AbpCultureMenuItemUrlProvider( + httpContextAccessor, localizationOptions, MsOptions.Create(abpLocOptions), new MenuItemCulturePrefixHelper()); + } + + private static ApplicationMenu CreateMenuWithItems(params string[] urls) + { + var menu = new ApplicationMenu("TestMenu"); + for (var i = 0; i < urls.Length; i++) + { + menu.AddItem(new ApplicationMenuItem($"Item{i}", $"Item {i}", url: urls[i])); + } + return menu; + } + +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController_Tests.cs new file mode 100644 index 0000000000..491577c43e --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/AbpLanguagesController_Tests.cs @@ -0,0 +1,123 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Localization; +using Shouldly; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +public class AbpLanguagesController_Tests : AspNetCoreMvcTestBase +{ + private const string SwitchUrl = "/Abp/Languages/Switch"; + + [Fact] + public async Task Should_Replace_Route_Culture_In_ReturnUrl_When_Cookie_Is_Set() + { + var response = await SendSwitchRequestAsync( + targetCulture: "zh-Hans", + returnUrl: "/en/Home/About", + currentCultureCookie: "en"); + + response.StatusCode.ShouldBe(HttpStatusCode.Found); + response.Headers.Location?.ToString().ShouldBe("/zh-Hans/Home/About"); + } + + [Fact] + public async Task Should_Replace_Route_Culture_When_Switching_Back() + { + var response = await SendSwitchRequestAsync( + targetCulture: "en", + returnUrl: "/zh-Hans/About", + currentCultureCookie: "zh-Hans"); + + response.StatusCode.ShouldBe(HttpStatusCode.Found); + response.Headers.Location?.ToString().ShouldBe("/en/About"); + } + + [Fact] + public async Task Should_Replace_Region_Culture_In_ReturnUrl() + { + var response = await SendSwitchRequestAsync( + targetCulture: "zh-Hans", + returnUrl: "/en-US/products", + currentCultureCookie: "en-US"); + + response.StatusCode.ShouldBe(HttpStatusCode.Found); + response.Headers.Location?.ToString().ShouldBe("/zh-Hans/products"); + } + + [Fact] + public async Task Should_Not_Replace_When_No_Cookie() + { + // No cookie โ€” GetCurrentCultureFromRequestCookie returns null, no route replacement + var response = await SendSwitchRequestAsync( + targetCulture: "zh-Hans", + returnUrl: "/en/Home/About", + currentCultureCookie: null); + + response.StatusCode.ShouldBe(HttpStatusCode.Found); + response.Headers.Location?.ToString().ShouldBe("/en/Home/About"); + } + + [Fact] + public async Task Should_Redirect_To_Root_When_ReturnUrl_Is_Empty() + { + var response = await SendSwitchRequestAsync( + targetCulture: "zh-Hans", + returnUrl: "", + currentCultureCookie: "en"); + + response.StatusCode.ShouldBe(HttpStatusCode.Found); + response.Headers.Location?.ToString().ShouldStartWith("/"); + } + + [Fact] + public async Task Should_Not_Replace_Culture_Inside_Longer_Segment_Via_Http() + { + // "en" must not corrupt "/enterprise/products" + var response = await SendSwitchRequestAsync( + targetCulture: "zh-Hans", + returnUrl: "/enterprise/products", + currentCultureCookie: "en"); + + response.StatusCode.ShouldBe(HttpStatusCode.Found); + response.Headers.Location?.ToString().ShouldBe("/enterprise/products"); + } + + [Fact] + public async Task Should_Replace_Culture_After_Tenant_Segment() + { + // Multi-tenant URL: /tenant-a/zh-Hans/About โ†’ /tenant-a/en/About + var response = await SendSwitchRequestAsync( + targetCulture: "en", + returnUrl: "/tenant-a/zh-Hans/About", + currentCultureCookie: "zh-Hans"); + + response.StatusCode.ShouldBe(HttpStatusCode.Found); + response.Headers.Location?.ToString().ShouldBe("/tenant-a/en/About"); + } + + private async Task SendSwitchRequestAsync( + string targetCulture, + string returnUrl, + string? currentCultureCookie) + { + var url = $"{SwitchUrl}?culture={Uri.EscapeDataString(targetCulture)}" + + $"&uiCulture={Uri.EscapeDataString(targetCulture)}" + + $"&returnUrl={Uri.EscapeDataString(returnUrl)}"; + + var request = new HttpRequestMessage(HttpMethod.Get, url); + + if (currentCultureCookie != null) + { + var cookieValue = CookieRequestCultureProvider.MakeCookieValue( + new RequestCulture(currentCultureCookie, currentCultureCookie)); + request.Headers.Add("Cookie", + $"{CookieRequestCultureProvider.DefaultCookieName}={Uri.EscapeDataString(cookieValue)}"); + } + + return await Client.SendAsync(request); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/LanguageSwitchRouteCultureReplacement_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/LanguageSwitchRouteCultureReplacement_Tests.cs new file mode 100644 index 0000000000..1c5fd4cb22 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/LanguageSwitchRouteCultureReplacement_Tests.cs @@ -0,0 +1,259 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Localization; +using Shouldly; +using Volo.Abp.AspNetCore.Mvc.Localization; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +public class LanguageSwitchRouteCultureReplacement_Tests +{ + private readonly AbpAspNetCoreMvcQueryStringCultureReplacement _replacement = new(); + + [Fact] + public async Task Should_Replace_Route_Prefix() + { + var context = CreateContext("tr", "en", "/tr/products"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/en/products"); + } + + [Fact] + public async Task Should_Replace_Region_Culture() + { + var context = CreateContext("en-US", "zh-Hans", "/en-US/about"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/zh-Hans/about"); + } + + [Fact] + public async Task Should_Replace_Culture_Only_Url() + { + var context = CreateContext("tr", "en", "/tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/en"); + } + + [Fact] + public async Task Should_Replace_Culture_With_Query_String() + { + var context = CreateContext("tr", "en", "/tr?returnUrl=/home"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/en?returnUrl=/home"); + } + + [Fact] + public async Task Should_Replace_Culture_After_Tenant() + { + var context = CreateContext("zh-Hans", "en", "/tenant-a/zh-Hans/About"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/tenant-a/en/About"); + } + + [Fact] + public async Task Should_Replace_Culture_Only_After_Tenant() + { + var context = CreateContext("tr", "en", "/tenant-a/tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/tenant-a/en"); + } + + [Fact] + public async Task Should_Replace_Via_RouteData_When_No_CurrentCulture() + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.RouteValues["culture"] = "tr"; + var context = new QueryStringCultureReplacementContext( + httpContext, new RequestCulture("en"), "/tr/products"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/en/products"); + } + + [Fact] + public async Task Should_Not_Replace_When_No_Culture_Source() + { + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en"), "/volosoft/products"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/volosoft/products"); + } + + [Fact] + public async Task Should_Not_Replace_Culture_Inside_Longer_Segment() + { + // "en" must not match inside "enterprise" + var context = CreateContext("en", "tr", "/enterprise/products"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/enterprise/products"); + } + + [Fact] + public async Task Should_Not_Replace_Culture_When_Culture_Is_Segment_Prefix() + { + // "fr" appears at the start of "fr-zone" but is not a complete segment + var context = CreateContext("fr", "en", "/fr-zone/about"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/fr-zone/about"); + } + + [Fact] + public async Task Should_Replace_Culture_Before_Fragment() + { + var context = CreateContext("en", "tr", "/en#section"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/tr#section"); + } + + [Fact] + public async Task Should_Replace_Culture_Before_Fragment_With_Path() + { + var context = CreateContext("en", "tr", "/en/about#top"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/tr/about#top"); + } + + [Fact] + public async Task Should_Replace_Query_String_Culture() + { + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en", "en"), "/home?culture=tr&ui-culture=tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/home?culture=en&ui-culture=en"); + } + + [Fact] + public async Task Should_Replace_Both_Route_And_Query_String() + { + var context = CreateContext("tr", "en", "/tr/home?culture=tr&ui-culture=tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/en/home?culture=en&ui-culture=en"); + } + + [Fact] + public async Task Should_Handle_Null_ReturnUrl() + { + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en"), null!); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBeNull(); + } + + [Fact] + public async Task Should_Handle_Empty_ReturnUrl() + { + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en"), ""); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe(""); + } + + [Fact] + public async Task Should_Not_Replace_When_CurrentCulture_Not_In_ReturnUrl() + { + // currentCulture is "fr" but returnUrl has no "/fr" segment + var context = CreateContext("fr", "en", "/about"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/about"); + } + + [Fact] + public async Task Should_Handle_Same_Culture_Switch() + { + // Switching to the same culture โ€” no change + var context = CreateContext("en", "en", "/en/about"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/en/about"); + } + + [Fact] + public async Task Should_Replace_Case_Insensitive() + { + var context = CreateContext("zh-hans", "en", "/zh-Hans/about"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/en/about"); + } + + [Fact] + public async Task Should_Handle_Whitespace_ReturnUrl() + { + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en"), " "); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe(" "); + } + + [Fact] + public async Task Should_Prefer_CurrentCulture_Over_RouteData() + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.RouteValues["culture"] = "fr"; + var context = new QueryStringCultureReplacementContext( + httpContext, new RequestCulture("en"), "/tr/about", currentCulture: "tr"); + await _replacement.ReplaceAsync(context); + // Should use "tr" from CurrentCulture, not "fr" from RouteData + context.ReturnUrl.ShouldBe("/en/about"); + } + + [Fact] + public async Task Should_Only_Replace_Query_String_When_No_Route_Culture() + { + // No currentCulture, no RouteData โ€” only query string replacement + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en", "en"), "/?culture=tr&ui-culture=tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/?culture=en&ui-culture=en"); + } + + [Fact] + public async Task Should_Replace_Culture_When_Only_Culture_Param_Present() + { + // culture= and ui-culture= are now handled independently + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en"), "/?culture=tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/?culture=en"); + } + + [Fact] + public async Task Should_Replace_UiCulture_When_Only_UiCulture_Param_Present() + { + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), new RequestCulture("en"), "/?ui-culture=tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/?ui-culture=en"); + } + + [Fact] + public async Task Should_Support_Numeric_Region_Culture_Tag() + { + // es-419 (Latin America Spanish) contains a digit โ€” previously the regex + // [A-Za-z-]+ would not match it, leaving the query string unreplaced. + var context = new QueryStringCultureReplacementContext( + new DefaultHttpContext(), + new RequestCulture("es-419", "es-419"), + "/home?culture=tr&ui-culture=tr"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/home?culture=es-419&ui-culture=es-419"); + } + + [Fact] + public async Task Should_Replace_Only_First_Culture_Occurrence_In_Path() + { + // /en/products/en/details โ€” the second "/en" is part of the path content, + // not a culture prefix, and must not be replaced. + var context = CreateContext("en", "tr", "/en/products/en/details"); + await _replacement.ReplaceAsync(context); + context.ReturnUrl.ShouldBe("/tr/products/en/details"); + } + + private static QueryStringCultureReplacementContext CreateContext( + string currentCulture, string targetCulture, string returnUrl) + { + return new QueryStringCultureReplacementContext( + new DefaultHttpContext(), + new RequestCulture(targetCulture), + returnUrl, + currentCulture); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureApiRouting_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureApiRouting_Tests.cs new file mode 100644 index 0000000000..84f16e487c --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureApiRouting_Tests.cs @@ -0,0 +1,48 @@ +using System.Net; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.AspNetCore.App; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +public class RouteBasedCultureApiRouting_Tests : AspNetCoreMvcTestBase +{ + [Fact] + public async Task Api_Route_Should_Not_Be_Intercepted_By_Culture_Route() + { + var response = await GetResponseAsync("api/json-result-test/json-result-action"); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + response.Content.Headers.ContentType!.MediaType.ShouldBe("application/json"); + } + + [Fact] + public async Task Controller_Should_Work_With_Culture_Prefix() + { + var result = await GetResponseAsStringAsync( + "/tr" + GetUrl(nameof(SimpleController.Index))); + result.ShouldBe("Index-Result"); + } + + [Fact] + public async Task Controller_Should_Work_Without_Culture_Prefix() + { + var result = await GetResponseAsStringAsync( + GetUrl(nameof(SimpleController.Index))); + result.ShouldBe("Index-Result"); + } + + [Fact] + public async Task RazorPage_Should_Work_With_Culture_Prefix() + { + var response = await GetResponseAsync("/tr/Auditing/AuditTestPage"); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + [Fact] + public async Task RazorPage_Should_Work_Without_Culture_Prefix() + { + var response = await GetResponseAsync("/Auditing/AuditTestPage"); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureNavigationHelper_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureNavigationHelper_Tests.cs new file mode 100644 index 0000000000..08706b3179 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureNavigationHelper_Tests.cs @@ -0,0 +1,103 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Shouldly; +using Volo.Abp.AspNetCore.Components.WebAssembly; +using Volo.Abp.Localization; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +public class RouteBasedCultureNavigationHelper_Tests +{ + private static readonly IEnumerable AllLanguages = new[] + { + new LanguageInfo("en"), + new LanguageInfo("tr"), + new LanguageInfo("zh-Hans"), + }; + + private readonly RouteBasedCultureNavigationHelper _helper = new(); + + [Fact] + public async Task Should_Replace_Culture_In_Simple_Path() + { + var nav = new TestNavigationManager("https://example.com/", "https://example.com/tr/home"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("en"), AllLanguages); + nav.LastNavigatedUri.ShouldBe("https://example.com/en/home"); + } + + [Fact] + public async Task Should_Replace_Culture_When_No_Path_After_Culture() + { + var nav = new TestNavigationManager("https://example.com/", "https://example.com/tr"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("en"), AllLanguages); + nav.LastNavigatedUri.ShouldBe("https://example.com/en"); + } + + [Fact] + public async Task Should_Replace_Culture_When_Query_String_Follows_Culture_Directly() + { + // Regression: "tr?x=1" was being treated as a single segment "tr?x=1" + // instead of culture="tr" + suffix="?x=1". + var nav = new TestNavigationManager("https://example.com/", "https://example.com/tr?x=1"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("en"), AllLanguages); + nav.LastNavigatedUri.ShouldBe("https://example.com/en?x=1"); + } + + [Fact] + public async Task Should_Replace_Culture_When_Fragment_Follows_Culture_Directly() + { + var nav = new TestNavigationManager("https://example.com/", "https://example.com/tr#section"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("en"), AllLanguages); + nav.LastNavigatedUri.ShouldBe("https://example.com/en#section"); + } + + [Fact] + public async Task Should_Replace_Culture_Preserving_Path_Query_And_Fragment() + { + var nav = new TestNavigationManager("https://example.com/", "https://example.com/tr/about?ref=main#top"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("zh-Hans"), AllLanguages); + nav.LastNavigatedUri.ShouldBe("https://example.com/zh-Hans/about?ref=main#top"); + } + + [Fact] + public async Task Should_Prepend_Culture_When_No_Existing_Culture_Prefix() + { + var nav = new TestNavigationManager("https://example.com/", "https://example.com/identity/users"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("zh-Hans"), AllLanguages); + nav.LastNavigatedUri.ShouldBe("https://example.com/zh-Hans/identity/users"); + } + + [Fact] + public async Task Should_Prepend_Culture_When_At_Root() + { + var nav = new TestNavigationManager("https://example.com/", "https://example.com/"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("tr"), AllLanguages); + nav.LastNavigatedUri.ShouldBe("https://example.com/tr/"); + } + + [Fact] + public async Task Should_Not_Navigate_When_Target_Culture_Matches_Current() + { + var nav = new TestNavigationManager("https://example.com/", "https://example.com/tr/home"); + await _helper.NavigateToNewCultureAsync(nav, new LanguageInfo("tr"), AllLanguages); + // Already on /tr/home โ€” no navigation should occur + nav.LastNavigatedUri.ShouldBeNull(); + } + + private sealed class TestNavigationManager : NavigationManager + { + public string? LastNavigatedUri { get; private set; } + + public TestNavigationManager(string baseUri, string uri) + { + Initialize(baseUri, uri); + } + + protected override void NavigateToCore(string uri, bool forceLoad) + { + LastNavigatedUri = uri; + } + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureUrlHelper_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureUrlHelper_Tests.cs new file mode 100644 index 0000000000..b2e8ca129a --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/RouteBasedCultureUrlHelper_Tests.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using NSubstitute; +using Shouldly; +using Volo.Abp.AspNetCore.Components.WebAssembly; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using Volo.Abp.AspNetCore.Mvc.Client; +using Volo.Abp.Localization; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Localization; + +public class RouteBasedCultureUrlHelper_Tests +{ + private readonly ICachedApplicationConfigurationClient _configClient; + private readonly RouteBasedCultureUrlHelper _helper; + private readonly ApplicationConfigurationDto _config; + + public RouteBasedCultureUrlHelper_Tests() + { + _config = new ApplicationConfigurationDto + { + Localization = new ApplicationLocalizationConfigurationDto + { + UseRouteBasedCulture = true, + Languages = new List + { + new LanguageInfo("en"), + new LanguageInfo("zh-Hans"), + new LanguageInfo("tr"), + new LanguageInfo("es-419"), + } + } + }; + + _configClient = Substitute.For(); + _configClient.GetAsync().Returns(_config); + + _helper = new RouteBasedCultureUrlHelper(_configClient); + } + + [Theory] + [InlineData("https://auth-server.example.com/connect/authorize")] + [InlineData("http://example.com/login")] + public async Task Should_Not_Modify_Absolute_Urls(string url) + { + using var _ = CultureScope("zh-Hans"); + var result = await _helper.PrependCulturePrefixAsync(url); + result.ShouldBe(url); + } + + [Fact] + public async Task Should_Not_Modify_Protocol_Relative_Url() + { + using var _ = CultureScope("zh-Hans"); + var result = await _helper.PrependCulturePrefixAsync("//cdn.example.com/asset.js"); + result.ShouldBe("//cdn.example.com/asset.js"); + } + + [Fact] + public async Task Should_Prepend_Culture_To_Root_Relative_Url() + { + using var _ = CultureScope("zh-Hans"); + var result = await _helper.PrependCulturePrefixAsync("/account/manage-profile"); + result.ShouldBe("/zh-Hans/account/manage-profile"); + } + + [Fact] + public async Task Should_Prepend_Culture_To_Tilde_Slash_Url() + { + using var _ = CultureScope("tr"); + var result = await _helper.PrependCulturePrefixAsync("~/account/manage-profile"); + result.ShouldBe("~/tr/account/manage-profile"); + } + + [Fact] + public async Task Should_Prepend_Culture_To_Bare_Relative_Url() + { + // Default auth URLs like "authentication/login" have no leading slash. + using var _ = CultureScope("zh-Hans"); + var result = await _helper.PrependCulturePrefixAsync("authentication/login"); + result.ShouldBe("zh-Hans/authentication/login"); + } + + [Fact] + public async Task Should_Not_Modify_Url_When_Feature_Disabled() + { + _config.Localization.UseRouteBasedCulture = false; + using var _ = CultureScope("zh-Hans"); + var result = await _helper.PrependCulturePrefixAsync("/home"); + result.ShouldBe("/home"); + } + + [Fact] + public async Task Should_Not_Modify_Url_When_Culture_Not_In_Language_List() + { + using var _ = CultureScope("fr"); + var result = await _helper.PrependCulturePrefixAsync("/home"); + result.ShouldBe("/home"); + } + + [Fact] + public async Task Should_Return_Empty_String_Unchanged() + { + var result = await _helper.PrependCulturePrefixAsync(string.Empty); + result.ShouldBe(string.Empty); + } + + [Fact] + public async Task Should_Support_Numeric_Region_Culture_Tag() + { + using var _ = CultureScope("es-419"); + var result = await _helper.PrependCulturePrefixAsync("/home"); + result.ShouldBe("/es-419/home"); + } + + [Fact] + public async Task Should_Be_Idempotent_On_Root_Relative_Url() + { + using var _ = CultureScope("zh-Hans"); + var result = await _helper.PrependCulturePrefixAsync("/zh-Hans/account/manage-profile"); + result.ShouldBe("/zh-Hans/account/manage-profile"); + } + + [Fact] + public async Task Should_Be_Idempotent_On_Tilde_Slash_Url() + { + using var _ = CultureScope("tr"); + var result = await _helper.PrependCulturePrefixAsync("~/tr/account/manage-profile"); + result.ShouldBe("~/tr/account/manage-profile"); + } + + [Fact] + public async Task Should_Be_Idempotent_On_Bare_Relative_Url() + { + using var _ = CultureScope("zh-Hans"); + var result = await _helper.PrependCulturePrefixAsync("zh-Hans/authentication/login"); + result.ShouldBe("zh-Hans/authentication/login"); + } + + private static IDisposable CultureScope(string cultureName) + { + var previous = CultureInfo.CurrentCulture; + CultureInfo.CurrentCulture = new CultureInfo(cultureName); + return new DelegateDisposable(() => CultureInfo.CurrentCulture = previous); + } + + private sealed class DelegateDisposable : IDisposable + { + private readonly System.Action _onDispose; + public DelegateDisposable(System.Action onDispose) => _onDispose = onDispose; + public void Dispose() => _onDispose(); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/Localization/RouteBasedCultureTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/Localization/RouteBasedCultureTestModule.cs new file mode 100644 index 0000000000..31d6dc2bb6 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/Localization/RouteBasedCultureTestModule.cs @@ -0,0 +1,53 @@ +using System.Globalization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.RequestLocalization; +using Microsoft.AspNetCore.Routing; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Localization; + +[DependsOn(typeof(AbpAspNetCoreTestModule))] +public class RouteBasedCultureTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.UseRouteBasedCulture = true; + }); + + Configure(options => + { + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("tr", "tr", "Tรผrkรงe")); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + + app.UseRouting(); + app.UseAbpRequestLocalization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGet("{culture}/culture", async ctx => + { + await ctx.Response.WriteAsync(CultureInfo.CurrentCulture.Name); + }); + + endpoints.MapGet("culture", async ctx => + { + await ctx.Response.WriteAsync(CultureInfo.CurrentCulture.Name); + }); + + endpoints.MapGet("api/data", async ctx => + { + await ctx.Response.WriteAsync(CultureInfo.CurrentCulture.Name); + }); + }); + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/Localization/RouteBasedCulture_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/Localization/RouteBasedCulture_Tests.cs new file mode 100644 index 0000000000..ac3be73275 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/Localization/RouteBasedCulture_Tests.cs @@ -0,0 +1,75 @@ +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Shouldly; +using Xunit; + +namespace Volo.Abp.AspNetCore.Localization; + +public class RouteBasedCulture_Tests : IAsyncLifetime +{ + private WebApplication _app; + private HttpClient _client; + + public async Task InitializeAsync() + { + var builder = WebApplication.CreateBuilder(); + builder.WebHost.UseTestServer(); + builder.Host.UseAutofac(); + await builder.AddApplicationAsync(); + _app = builder.Build(); + await _app.InitializeApplicationAsync(); + await _app.StartAsync(); + _client = ((IHost)_app).GetTestClient(); + } + + public async Task DisposeAsync() + { + _client?.Dispose(); + if (_app != null) + { + await _app.StopAsync(); + await _app.DisposeAsync(); + } + } + + [Fact] + public async Task RouteBasedCulture_SetsCultureCorrectly() + { + var response = await _client!.GetStringAsync("/tr/culture"); + response.ShouldBe("tr"); + } + + [Fact] + public async Task RouteBasedCulture_SetsCookieOnResponse() + { + var response = await _client!.GetAsync("/tr/culture"); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + + response.Headers.Contains("Set-Cookie").ShouldBeTrue(); + var cookieValue = string.Join(";", response.Headers.GetValues("Set-Cookie")); + cookieValue.ShouldContain(CookieRequestCultureProvider.DefaultCookieName); + cookieValue.ShouldContain("tr"); + } + + [Fact] + public async Task RouteBasedCulture_InvalidCultureCodeFallsThrough() + { + // "xyz1234" is not a valid culture - should fall through to the default culture "en" + var response = await _client!.GetStringAsync("/xyz1234/culture"); + response.ShouldBe("en"); + } + + [Fact] + public async Task RouteBasedCulture_ApiRoutesNotAffected() + { + // /api/data has no {culture} prefix route - falls through to the default culture "en" + var response = await _client!.GetStringAsync("/api/data"); + response.ShouldBe("en"); + } +} diff --git a/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/AutofacRegistration_Tests.cs b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/AutofacRegistration_Tests.cs new file mode 100644 index 0000000000..cc6b1f1668 --- /dev/null +++ b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/AutofacRegistration_Tests.cs @@ -0,0 +1,157 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Modularity; +using Volo.Abp.Testing; +using Xunit; + +namespace Volo.Abp.Autofac; + +public class AutofacRegistration_Tests : AbpIntegratedTest +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + [Fact] + public void Should_Resolve_AnyKey_Keyed_Service_With_Any_Key() + { + // AnyKey registration should be resolvable with any key value. + var serviceWithKeyA = GetRequiredKeyedService("keyA"); + var serviceWithKeyB = GetRequiredKeyedService("keyB"); + var serviceWithKeyC = GetRequiredKeyedService(42); + + serviceWithKeyA.ShouldNotBeNull(); + serviceWithKeyB.ShouldNotBeNull(); + serviceWithKeyC.ShouldNotBeNull(); + + serviceWithKeyA.ShouldBeOfType(); + serviceWithKeyB.ShouldBeOfType(); + serviceWithKeyC.ShouldBeOfType(); + } + + [Fact] + public void Should_Pass_Correct_Key_To_Keyed_Factory() + { + var serviceA = GetRequiredKeyedService("alpha"); + var serviceB = GetRequiredKeyedService("beta"); + + serviceA.Key.ShouldBe("alpha"); + serviceB.Key.ShouldBe("beta"); + } + + [Fact] + public void Should_Not_Dispose_Instance_Registration_When_Scope_Disposed() + { + // Resolve the pre-registered singleton instance. + var instance = GetRequiredKeyedService("instance"); + instance.ShouldNotBeNull(); + instance.IsDisposed.ShouldBeFalse(); + + // The same instance should be returned from a child scope. + using (var scope = ServiceProvider.CreateScope()) + { + var scopedInstance = scope.ServiceProvider.GetRequiredKeyedService("instance"); + scopedInstance.ShouldBeSameAs(instance); + } + + // After the scope is disposed, the singleton instance should still be alive. + instance.IsDisposed.ShouldBeFalse(); + + // It should also be the same static instance registered in the module. + instance.ShouldBeSameAs(TestModule.DisposableInstanceForTest); + } + + [Fact] + public void Should_Resolve_Standard_Keyed_Services() + { + var big = GetRequiredKeyedService("big"); + var small = GetRequiredKeyedService("small"); + + big.ShouldBeOfType(); + small.ShouldBeOfType(); + + big.Get("test").ShouldBe("big:test"); + small.Get("test").ShouldBe("small:test"); + } + + [DependsOn(typeof(AbpAutofacModule))] + public class TestModule : AbpModule + { + public static DisposableInstance DisposableInstanceForTest { get; } = new(); + + public override void ConfigureServices(ServiceConfigurationContext context) + { + // AnyKey registration: this service can be resolved with any key. + context.Services.AddKeyedTransient( + Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey); + + // Keyed factory registration: the factory receives the actual key used for resolution. + context.Services.Add(ServiceDescriptor.KeyedTransient( + Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey, + (sp, key) => new KeyedFactoryServiceImpl(key))); + + // Instance registration with keyed service (ExternallyOwned should prevent Autofac from disposing it). + context.Services.AddKeyedSingleton("instance", DisposableInstanceForTest); + + // Standard keyed type registrations. + context.Services.AddKeyedTransient("big"); + context.Services.AddKeyedTransient("small"); + } + } + + public interface IAnyKeyService + { + } + + public class AnyKeyServiceImpl : IAnyKeyService + { + } + + public interface IKeyedFactoryService + { + object Key { get; } + } + + public class KeyedFactoryServiceImpl : IKeyedFactoryService + { + public object Key { get; } + + public KeyedFactoryServiceImpl(object key) + { + Key = key; + } + } + + public interface IDisposableInstance + { + bool IsDisposed { get; } + } + + public class DisposableInstance : IDisposableInstance, IDisposable + { + public bool IsDisposed { get; private set; } + + public void Dispose() + { + IsDisposed = true; + } + } + + public interface ITypedCache + { + string Get(string key); + } + + public class BigTypedCache : ITypedCache + { + public string Get(string key) => $"big:{key}"; + } + + public class SmallTypedCache : ITypedCache + { + public string Get(string key) => $"small:{key}"; + } +} diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/Utils/CmdHelper_Tests.cs b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/Utils/CmdHelper_Tests.cs new file mode 100644 index 0000000000..1526a18d42 --- /dev/null +++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/Utils/CmdHelper_Tests.cs @@ -0,0 +1,47 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Cli.Utils; +using Xunit; + +namespace Volo.Abp.Cli.Utils; + +public class CmdHelper_Tests : AbpCliTestBase +{ + private readonly ICmdHelper _cmdHelper; + + public CmdHelper_Tests() + { + _cmdHelper = GetRequiredService(); + } + + [Fact] + public async Task RunCmdAndGetOutput_Should_Not_Deadlock_With_Large_Stdout_And_Stderr() + { + // Reproduces the deadlock bug where sequential ReadToEnd() on stdout then stderr + // would block indefinitely when both pipe buffers (~64 KB on Linux/macOS, ~4 KB on + // Windows) filled up simultaneously. The process was blocked writing to stderr while + // the caller was blocked waiting for stdout to close โ€” a classic pipe deadlock. + // + // The fix reads both streams concurrently via ReadToEndAsync + Task.WhenAll, which + // drains both pipes at the same time and avoids the deadlock. + var command = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? @"for /L %i in (1,1,3000) do @(echo stdout-line-%i & echo stderr-line-%i 1>&2)" + : "for i in $(seq 1 5000); do echo stdout-line-$i; echo stderr-line-$i >&2; done"; + + string output = null; + var cmdTask = Task.Run(() => output = _cmdHelper.RunCmdAndGetOutput(command)); + var completed = await Task.WhenAny(cmdTask, Task.Delay(TimeSpan.FromSeconds(10))); + + // The original sequential code deadlocked here; 10 s is a generous upper bound. + (completed == cmdTask).ShouldBeTrue( + "RunCmdAndGetOutput should not deadlock when both stdout and stderr produce large output"); + + await cmdTask; + + output.ShouldNotBeNullOrWhiteSpace(); + output.ShouldContain("stdout-line-"); + output.ShouldContain("stderr-line-"); + } +} diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs index b77f282a85..efecb25b2b 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus.Local; @@ -372,6 +373,57 @@ public class LocalDistributedEventBus_Test : LocalDistributedEventBusTestBase } } + [Fact] + public async Task IocEventHandlerFactory_Should_Create_New_Scope_And_Dispose_Handler_Per_Event() + { + var handleCount = 0; + var disposeCount = 0; + var eventName = "IocEvent-" + Guid.NewGuid().ToString("N"); + + var services = new ServiceCollection(); + services.AddSingleton( + new TestCounterService(() => handleCount++, () => disposeCount++)); + services.AddTransient(); + using var provider = services.BuildServiceProvider(); + var scopeFactory = provider.GetRequiredService(); + + using var subscription = DistributedEventBus.Subscribe( + eventName, + new IocEventHandlerFactory(scopeFactory, typeof(DynamicIocEventHandlerWithCounter))); + + await DistributedEventBus.PublishAsync(eventName, new { Value = 1 }); + await DistributedEventBus.PublishAsync(eventName, new { Value = 2 }); + await DistributedEventBus.PublishAsync(eventName, new { Value = 3 }); + + // Handler is invoked exactly once per event. + Assert.Equal(3, handleCount); + // Handler is disposed at least once per event (the scope is always cleaned up). + Assert.True(disposeCount >= handleCount); + } + + [Fact] + public async Task IocEventHandlerFactory_Should_Resolve_DI_Services_In_Handler_Constructor() + { + var callCount = 0; + var eventName = "IocEvent-" + Guid.NewGuid().ToString("N"); + + var services = new ServiceCollection(); + services.AddSingleton(new TestCounterService(() => callCount++)); + services.AddTransient(); + using var provider = services.BuildServiceProvider(); + var scopeFactory = provider.GetRequiredService(); + + using var subscription = DistributedEventBus.Subscribe( + eventName, + new IocEventHandlerFactory(scopeFactory, typeof(DynamicIocEventHandlerWithService))); + + await DistributedEventBus.PublishAsync(eventName, new { Value = 1 }); + await DistributedEventBus.PublishAsync(eventName, new { Value = 2 }); + + // The handler resolved ITestCounterService via constructor injection + Assert.Equal(2, callCount); + } + class TestDynamicDistributedEventHandler : IDistributedEventHandler { private readonly Action _onHandle; @@ -387,4 +439,62 @@ public class LocalDistributedEventBus_Test : LocalDistributedEventBusTestBase return Task.CompletedTask; } } + + interface ITestCounterService + { + void OnHandle(); + void OnDispose(); + } + + class TestCounterService : ITestCounterService + { + private readonly Action _onHandle; + private readonly Action? _onDispose; + + public TestCounterService(Action onHandle, Action? onDispose = null) + { + _onHandle = onHandle; + _onDispose = onDispose; + } + + public void OnHandle() => _onHandle(); + public void OnDispose() => _onDispose?.Invoke(); + } + + class DynamicIocEventHandlerWithCounter : IDistributedEventHandler, IDisposable + { + private readonly ITestCounterService _counterService; + + public DynamicIocEventHandlerWithCounter(ITestCounterService counterService) + { + _counterService = counterService; + } + + public Task HandleEventAsync(DynamicEventData eventData) + { + _counterService.OnHandle(); + return Task.CompletedTask; + } + + public void Dispose() + { + _counterService.OnDispose(); + } + } + + class DynamicIocEventHandlerWithService : IDistributedEventHandler + { + private readonly ITestCounterService _counterService; + + public DynamicIocEventHandlerWithService(ITestCounterService counterService) + { + _counterService = counterService; + } + + public Task HandleEventAsync(DynamicEventData eventData) + { + _counterService.OnHandle(); + return Task.CompletedTask; + } + } } diff --git a/latest-versions.json b/latest-versions.json index 0646ca8ece..8873bc5e88 100644 --- a/latest-versions.json +++ b/latest-versions.json @@ -1,4 +1,13 @@ [ + { + "version": "10.2.0", + "releaseDate": "", + "type": "stable", + "message": "", + "leptonx": { + "version": "5.2.0" + } + }, { "version": "10.1.1", "releaseDate": "", diff --git a/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs index 3fae85c5b5..d40170ffec 100644 --- a/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs +++ b/modules/account/src/Volo.Abp.Account.Blazor/AbpAccountBlazorUserMenuContributor.cs @@ -15,7 +15,7 @@ public class AbpAccountBlazorUserMenuContributor : IMenuContributor var accountResource = context.GetLocalizer(); - context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountResource["MyAccount"], url: "account/manage-profile", icon: "fa fa-cog")); + context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountResource["MyAccount"], url: "~/account/manage-profile", icon: "fa fa-cog")); return Task.CompletedTask; } diff --git a/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor index 2341b9dc5b..c5ed90e5aa 100644 --- a/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor +++ b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor @@ -1,4 +1,5 @@ ๏ปฟ@page "/account/manage-profile" +@page "/{culture}/account/manage-profile" @using Microsoft.AspNetCore.Components.Forms @using Volo.Abp.Account.Localization @using Volo.Abp.AspNetCore.Components.Web diff --git a/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor.cs b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor.cs index 1aef6551c2..7cc4e6e357 100644 --- a/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor.cs +++ b/modules/account/src/Volo.Abp.Account.Blazor/Pages/Account/AccountManage.razor.cs @@ -8,6 +8,9 @@ namespace Volo.Abp.Account.Blazor.Pages.Account; public partial class AccountManage { + [Parameter] + public string? Culture { get; set; } + [Inject] protected IProfileAppService ProfileAppService { get; set; } [Inject] protected IUiMessageService UiMessageService { get; set; } diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor index 973912af30..fe01c0d5bb 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor @@ -33,6 +33,6 @@ - @L["Login"] + @L["Login"] diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor.cs index 84696d7f29..0ce5132a25 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor.cs +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.BasicTheme/Themes/Basic/LoginDisplay.razor.cs @@ -2,6 +2,8 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Routing; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.RequestLocalization; using Volo.Abp.UI.Navigation; namespace Volo.Abp.AspNetCore.Components.Server.BasicTheme.Themes.Basic; @@ -11,6 +13,9 @@ public partial class LoginDisplay : IDisposable [Inject] protected IMenuManager MenuManager { get; set; } + [Inject] + protected IHttpContextAccessor HttpContextAccessor { get; set; } + protected ApplicationMenu Menu { get; set; } protected override async Task OnInitializedAsync() @@ -20,6 +25,12 @@ public partial class LoginDisplay : IDisposable Navigation.LocationChanged += OnLocationChanged; } + protected string GetLoginUrl() + { + var culture = AbpRequestCultureCookieHelper.GetRouteCulture(HttpContextAccessor.HttpContext); + return string.IsNullOrEmpty(culture) ? "Account/Login" : $"{culture}/Account/Login"; + } + protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e) { InvokeAsync(StateHasChanged); diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs index 39cc08ddd1..8888d36fb1 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs @@ -14,8 +14,6 @@ public class BasicThemeToolbarContributor : IToolbarContributor { if (context.Toolbar.Name == StandardToolbars.Main) { - context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitch))); - //TODO: Can we find a different way to understand if authentication was configured or not? var authenticationStateProvider = context.ServiceProvider .GetService(); @@ -24,6 +22,8 @@ public class BasicThemeToolbarContributor : IToolbarContributor { context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay))); } + + context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitch))); } return Task.CompletedTask; diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor index 7814000136..86a74a5929 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LanguageSwitch.razor @@ -1,10 +1,15 @@ -๏ปฟ@using Volo.Abp.Localization +@using Volo.Abp.Localization @using System.Globalization @using System.Collections.Immutable @using Volo.Abp.AspNetCore.Components.Web +@using Volo.Abp.AspNetCore.Components.WebAssembly +@using Volo.Abp.AspNetCore.Mvc.Client @inject ILanguageProvider LanguageProvider @inject IJSRuntime JsRuntime @inject ICookieService CookieService +@inject NavigationManager NavigationManager +@inject ICachedApplicationConfigurationClient ConfigurationClient +@inject IRouteBasedCultureNavigationHelper CultureNavigationHelper @if (_otherLanguages != null && _otherLanguages.Any()) { @@ -22,9 +27,13 @@ @code { private IReadOnlyList _otherLanguages; private LanguageInfo _currentLanguage; + private bool _useRouteBasedCulture; protected override async Task OnInitializedAsync() { + var config = await ConfigurationClient.GetAsync(); + _useRouteBasedCulture = config.Localization.UseRouteBasedCulture; + var selectedLanguageName = await JsRuntime.InvokeAsync( "localStorage.getItem", "Abp.SelectedLanguage" @@ -57,6 +66,13 @@ private async Task ChangeLanguageAsync(LanguageInfo language) { + if (_useRouteBasedCulture) + { + await CultureNavigationHelper.NavigateToNewCultureAsync( + NavigationManager, language, _otherLanguages.Append(_currentLanguage)); + return; + } + await JsRuntime.InvokeVoidAsync( "localStorage.setItem", "Abp.SelectedLanguage", diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor index 6c02e4ffc0..b961dc6e6b 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor @@ -35,6 +35,6 @@ - @UiLocalizer["Login"] + @UiLocalizer["Login"] diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs index 08d40e4bfe..7fe86a6ecc 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs @@ -1,10 +1,11 @@ -๏ปฟusing System; +using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Routing; using Microsoft.AspNetCore.Components.WebAssembly.Authentication; using Microsoft.JSInterop; using Volo.Abp.AspNetCore.Components.Web.Security; +using Volo.Abp.AspNetCore.Components.WebAssembly; using Volo.Abp.UI.Navigation; namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic; @@ -17,10 +18,20 @@ public partial class LoginDisplay : IDisposable [Inject] protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; set; } + [Inject] + protected IRouteBasedCultureUrlHelper CultureUrlHelper { get; set; } + protected ApplicationMenu Menu { get; set; } + protected string LoginUrl { get; set; } = string.Empty; + + protected string LogoutUrl { get; set; } = string.Empty; + protected async override Task OnInitializedAsync() { + LoginUrl = await CultureUrlHelper.PrependCulturePrefixAsync(AuthenticationOptions.Value.LoginUrl); + LogoutUrl = await CultureUrlHelper.PrependCulturePrefixAsync(AuthenticationOptions.Value.LogoutUrl); + Menu = await MenuManager.GetAsync(StandardMenus.User); Navigation.LocationChanged += OnLocationChanged; @@ -35,6 +46,8 @@ public partial class LoginDisplay : IDisposable private async void ApplicationConfigurationChanged() { + LoginUrl = await CultureUrlHelper.PrependCulturePrefixAsync(AuthenticationOptions.Value.LoginUrl); + LogoutUrl = await CultureUrlHelper.PrependCulturePrefixAsync(AuthenticationOptions.Value.LogoutUrl); Menu = await MenuManager.GetAsync(StandardMenus.User); await InvokeAsync(StateHasChanged); } @@ -47,9 +60,11 @@ public partial class LoginDisplay : IDisposable private async Task NavigateToAsync(string uri, string target = null) { + uri = uri?.TrimStart('~', '/') ?? uri; + if (target == "_blank") { - await JsRuntime.InvokeVoidAsync("open", uri, target); + await JsRuntime.InvokeVoidAsync("open", Navigation.ToAbsoluteUri(uri).ToString(), target); } else { @@ -57,15 +72,15 @@ public partial class LoginDisplay : IDisposable } } - private void BeginSignOut() + private async Task BeginSignOut() { if (AbpAspNetCoreComponentsWebOptions.Value.IsBlazorWebApp) { - Navigation.NavigateTo(AuthenticationOptions.Value.LogoutUrl, forceLoad: true); + Navigation.NavigateTo(LogoutUrl, forceLoad: true); } else { - Navigation.NavigateToLogout(AuthenticationOptions.Value.LogoutUrl); + Navigation.NavigateToLogout(LogoutUrl); } } } diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/WebAssemblyRedirectToLogin.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/WebAssemblyRedirectToLogin.razor index f4f3e152ce..246682edf8 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/WebAssemblyRedirectToLogin.razor +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/WebAssemblyRedirectToLogin.razor @@ -1,25 +1,22 @@ -@inject NavigationManager Navigation @using Volo.Abp.DependencyInjection @using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic -@using Microsoft.AspNetCore.Components.WebAssembly.Authentication +@using Volo.Abp.AspNetCore.Components.WebAssembly.Theming @using Microsoft.Extensions.Options +@using Volo.Abp.AspNetCore.Components.WebAssembly @using Volo.Abp.AspNetCore.Components.Web @inherits RedirectToLogin @attribute [ExposeServices(typeof(RedirectToLogin))] @attribute [Dependency(ReplaceServices = true)] -@inject IOptions AuthenticationOptions +@inject NavigationManager Navigation +@inject IOptions AuthOptions +@inject IRouteBasedCultureUrlHelper CultureUrlHelper @inject IOptions AbpAspNetCoreComponentsWebOptions @code { - protected override void OnInitialized() + protected override void OnInitialized() { } + + protected override Task OnInitializedAsync() { - if (AbpAspNetCoreComponentsWebOptions.Value.IsBlazorWebApp) - { - Navigation.NavigateTo(AuthenticationOptions.Value.LoginUrl, forceLoad: true); - } - else - { - Navigation.NavigateToLogin(AuthenticationOptions.Value.LoginUrl); - } + return CultureAwareRedirectToLoginHelper.RedirectAsync(Navigation, AuthOptions.Value.LoginUrl, CultureUrlHelper, AbpAspNetCoreComponentsWebOptions); } } diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json index 5c37c1939d..2f6d5c7c8c 100644 --- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json +++ b/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": "~10.2.0-rc.3", - "@abp/prismjs": "~10.2.0-rc.3", - "@abp/highlight.js": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.shared": "~10.3.0-rc.1", + "@abp/prismjs": "~10.3.0-rc.1", + "@abp/highlight.js": "~10.3.0-rc.1" } } diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock index 9ab3575f58..cd2c7379d1 100644 --- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock +++ b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock @@ -2,204 +2,204 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== - dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== + dependencies: + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/clipboard@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.2.0-rc.3.tgz#8319a1ddb6e6811d1149f72224be8ebd0d1ceb75" - integrity sha512-0UdFRAbkyPV7I2fP80rg3iWLPNg7ejopf5vU34gEBSJKeNow9u6UK0tkNO1IReNbPbb7QypwX+voDy1voVAxZw== +"@abp/clipboard@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.3.0-rc.1.tgz#2350aba655b18510dea0ca50cb91e5e5960e9480" + integrity sha512-jKo5H0+FSA+1aDdIWDmyAwNP2nFf19x4nAHbclkwnsexHBRfQlvx6yB6sY85BP+Ft6zxIn9gRRLbJPvFwsKBWw== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" clipboard "^2.0.11" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/highlight.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-10.2.0-rc.3.tgz#1dcdd6b438664d4b214a4eb10af895cddc882b11" - integrity sha512-RgQ2wN/UUP9rTefPRJpgka2PDv6S5h1+lzHa8x+Z7aSBP3kuNbPOPvLPB9gKsc/r5tZRIcnRWXcKPnQL57q/0A== +"@abp/highlight.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-10.3.0-rc.1.tgz#76d699f549aa630afda1f822717a3d3e2d846e88" + integrity sha512-m43P+D3gOsbc6tr2qQ/OmpCU6IqfVkw1frq1J6DcwlpEf5rCFhSEuvSq7roe9OTqsFX0xa+a1X2BHRNc3CkS2Q== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@highlightjs/cdn-assets" "~11.11.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/prismjs@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.2.0-rc.3.tgz#3f82a7af908f147c0e52a50e47297696fdb9deaa" - integrity sha512-jjY7rBANt0WgLjKveB62035r67KgoQGXnRagiiRLu1olv/oUELT/MR2ii5mR831hq8ULlH7QN0ERyrcgCzcO5A== +"@abp/prismjs@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.3.0-rc.1.tgz#147852ca4e0f9ceebe5681b65ad440b48325021f" + integrity sha512-sAWkFAP8GPx4UBR2EXg9Uz0sivK9CTWccUGGecttK9mNf12YbtVftmS145Fgip2+ifklPTcVRjXWIghyJPYu5Q== dependencies: - "@abp/clipboard" "~10.2.0-rc.3" - "@abp/core" "~10.2.0-rc.3" + "@abp/clipboard" "~10.3.0-rc.1" + "@abp/core" "~10.3.0-rc.1" prismjs "^1.30.0" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json index 818fc1dc4d..77c5e48268 100644 --- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json +++ b/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": "~10.2.0-rc.3", - "@abp/prismjs": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1", + "@abp/prismjs": "~10.3.0-rc.1" }, "devDependencies": {} } diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock index 5ec3225cff..0fdc9022d1 100644 --- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock +++ b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock @@ -2,203 +2,203 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== - dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== + dependencies: + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/clipboard@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.2.0-rc.3.tgz#8319a1ddb6e6811d1149f72224be8ebd0d1ceb75" - integrity sha512-0UdFRAbkyPV7I2fP80rg3iWLPNg7ejopf5vU34gEBSJKeNow9u6UK0tkNO1IReNbPbb7QypwX+voDy1voVAxZw== +"@abp/clipboard@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.3.0-rc.1.tgz#2350aba655b18510dea0ca50cb91e5e5960e9480" + integrity sha512-jKo5H0+FSA+1aDdIWDmyAwNP2nFf19x4nAHbclkwnsexHBRfQlvx6yB6sY85BP+Ft6zxIn9gRRLbJPvFwsKBWw== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" clipboard "^2.0.11" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/prismjs@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.2.0-rc.3.tgz#3f82a7af908f147c0e52a50e47297696fdb9deaa" - integrity sha512-jjY7rBANt0WgLjKveB62035r67KgoQGXnRagiiRLu1olv/oUELT/MR2ii5mR831hq8ULlH7QN0ERyrcgCzcO5A== +"@abp/prismjs@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.3.0-rc.1.tgz#147852ca4e0f9ceebe5681b65ad440b48325021f" + integrity sha512-sAWkFAP8GPx4UBR2EXg9Uz0sivK9CTWccUGGecttK9mNf12YbtVftmS145Fgip2+ifklPTcVRjXWIghyJPYu5Q== dependencies: - "@abp/clipboard" "~10.2.0-rc.3" - "@abp/core" "~10.2.0-rc.3" + "@abp/clipboard" "~10.3.0-rc.1" + "@abp/core" "~10.3.0-rc.1" prismjs "^1.30.0" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/blogging/app/Volo.BloggingTestApp/package.json b/modules/blogging/app/Volo.BloggingTestApp/package.json index 9cfd74991f..48f658e59b 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/package.json +++ b/modules/blogging/app/Volo.BloggingTestApp/package.json @@ -3,7 +3,7 @@ "name": "volo.blogtestapp", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "~10.2.0-rc.3", - "@abp/blogging": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1", + "@abp/blogging": "~10.3.0-rc.1" } } diff --git a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock index 21b6f1c3c6..408f52ec6b 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock +++ b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock @@ -2,229 +2,229 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== - dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== + dependencies: + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/blogging@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-10.2.0-rc.3.tgz#530fa2cbf6e721947a633927f1ad191e72f3cb73" - integrity sha512-+FygNgff0TOxrD/OFps35DvZffWBwMCDpHosX98lfiW1eQwgbYmrkoapYxZlM4EkVDcGAVcZ38ZctGfipbMPvA== +"@abp/blogging@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-10.3.0-rc.1.tgz#12f6587632e431ead8e7dde57d6d6db343d709d6" + integrity sha512-sw/iIIWBHYCOxbkBv1LRtnuyweiAdldTE0oWxzFdQyChUYHR3DVXjKQxzi4YtcaxpNsmU/NAeOQAeyaRlNejRQ== dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" - "@abp/owl.carousel" "~10.2.0-rc.3" - "@abp/prismjs" "~10.2.0-rc.3" - "@abp/tui-editor" "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" + "@abp/owl.carousel" "~10.3.0-rc.1" + "@abp/prismjs" "~10.3.0-rc.1" + "@abp/tui-editor" "~10.3.0-rc.1" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/clipboard@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.2.0-rc.3.tgz#8319a1ddb6e6811d1149f72224be8ebd0d1ceb75" - integrity sha512-0UdFRAbkyPV7I2fP80rg3iWLPNg7ejopf5vU34gEBSJKeNow9u6UK0tkNO1IReNbPbb7QypwX+voDy1voVAxZw== +"@abp/clipboard@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.3.0-rc.1.tgz#2350aba655b18510dea0ca50cb91e5e5960e9480" + integrity sha512-jKo5H0+FSA+1aDdIWDmyAwNP2nFf19x4nAHbclkwnsexHBRfQlvx6yB6sY85BP+Ft6zxIn9gRRLbJPvFwsKBWw== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" clipboard "^2.0.11" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/owl.carousel@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-10.2.0-rc.3.tgz#88baa49d6f3f8427d2d62bd338b5c94f2819cad0" - integrity sha512-g4zPjqj7oadME1AprvwfUI7chIQoluLhmQKZsKhF9zHFlv3CmcxGCKZoUqCLubAMCBgrVHm9wIFJIxhfjJv/Gg== +"@abp/owl.carousel@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-10.3.0-rc.1.tgz#ef497d41765f6d15eb60d240b053406b80dd2b5e" + integrity sha512-6dNWJ7cTha3cdlNFreQGi6tzY4uYd5eSLAhdebEyPd72jKMpMxyfGQbi3x1hn3wP31/Wi1+QiELWIla1m5c9bg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" owl.carousel "^2.3.4" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/prismjs@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.2.0-rc.3.tgz#3f82a7af908f147c0e52a50e47297696fdb9deaa" - integrity sha512-jjY7rBANt0WgLjKveB62035r67KgoQGXnRagiiRLu1olv/oUELT/MR2ii5mR831hq8ULlH7QN0ERyrcgCzcO5A== +"@abp/prismjs@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.3.0-rc.1.tgz#147852ca4e0f9ceebe5681b65ad440b48325021f" + integrity sha512-sAWkFAP8GPx4UBR2EXg9Uz0sivK9CTWccUGGecttK9mNf12YbtVftmS145Fgip2+ifklPTcVRjXWIghyJPYu5Q== dependencies: - "@abp/clipboard" "~10.2.0-rc.3" - "@abp/core" "~10.2.0-rc.3" + "@abp/clipboard" "~10.3.0-rc.1" + "@abp/core" "~10.3.0-rc.1" prismjs "^1.30.0" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/tui-editor@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-10.2.0-rc.3.tgz#8d34e1c01ba1b23ef4de9176f77441ad79487b9d" - integrity sha512-0aUI5XmnkrrXi4mA7gS7Stwh+nJEBm/A9Swf6f6tylwTXrQczQp1wZVpJS6S7APUSO9P55xwVUePzmqf0hy/dw== +"@abp/tui-editor@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-10.3.0-rc.1.tgz#2c2353694efa6f61849f4ed8c769fea95e0304ee" + integrity sha512-Vxi9yKFJ5uBgmULppS67a4hBYC5/B+LIOdvG125x0FlCI5vO2+s+QMz09nQ6Fu4EaLmh4F0Qu0Q8FmRubpj7Jw== dependencies: - "@abp/jquery" "~10.2.0-rc.3" - "@abp/prismjs" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" + "@abp/prismjs" "~10.3.0-rc.1" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json index 6d3b8896e3..82362d6ebc 100644 --- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/package.json +++ b/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": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1" } } diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock index 34b0ad545a..6d0049cf6a 100644 --- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock +++ b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/yarn.lock @@ -2,186 +2,186 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/cms-kit/angular/package.json b/modules/cms-kit/angular/package.json index ba043380f5..95d7f2a23b 100644 --- a/modules/cms-kit/angular/package.json +++ b/modules/cms-kit/angular/package.json @@ -15,11 +15,11 @@ }, "private": true, "dependencies": { - "@abp/ng.account": "~10.2.0-rc.3", - "@abp/ng.identity": "~10.2.0-rc.3", - "@abp/ng.setting-management": "~10.2.0-rc.2", - "@abp/ng.tenant-management": "~10.2.0-rc.2", - "@abp/ng.theme.basic": "~10.2.0-rc.2", + "@abp/ng.account": "~10.3.0-rc.1", + "@abp/ng.identity": "~10.3.0-rc.1", + "@abp/ng.setting-management": "~10.3.0-rc.1", + "@abp/ng.tenant-management": "~10.3.0-rc.1", + "@abp/ng.theme.basic": "~10.3.0-rc.1", "@angular/animations": "~10.0.0", "@angular/common": "~10.0.0", "@angular/compiler": "~10.0.0", diff --git a/modules/cms-kit/angular/projects/cms-kit/package.json b/modules/cms-kit/angular/projects/cms-kit/package.json index 0bb9669741..4b5e9fbe48 100644 --- a/modules/cms-kit/angular/projects/cms-kit/package.json +++ b/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": ">=10.2.0-rc.3", - "@abp/ng.theme.shared": ">=10.2.0-rc.3" + "@abp/ng.core": ">=10.3.0-rc.1", + "@abp/ng.theme.shared": ">=10.3.0-rc.1" }, "dependencies": { "tslib": "^2.0.0" diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json index 6608451945..2c62a14d05 100644 --- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/package.json +++ b/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": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1" } } diff --git a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock index 34b0ad545a..6d0049cf6a 100644 --- a/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.IdentityServer/yarn.lock @@ -2,186 +2,186 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json index 33e9f7bc23..a442008f3f 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Host/package.json +++ b/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": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1" } } diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock index 34b0ad545a..6d0049cf6a 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Host/yarn.lock @@ -2,186 +2,186 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json index 2edf913c72..627b3ab9d7 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/package.json +++ b/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": "~10.2.0-rc.3", - "@abp/cms-kit": "10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1", + "@abp/cms-kit": "10.3.0-rc.1" } } diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock index 889362dc12..5a6925d6b7 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock @@ -2,294 +2,294 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== - dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== + dependencies: + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/clipboard@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.2.0-rc.3.tgz#8319a1ddb6e6811d1149f72224be8ebd0d1ceb75" - integrity sha512-0UdFRAbkyPV7I2fP80rg3iWLPNg7ejopf5vU34gEBSJKeNow9u6UK0tkNO1IReNbPbb7QypwX+voDy1voVAxZw== +"@abp/clipboard@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.3.0-rc.1.tgz#2350aba655b18510dea0ca50cb91e5e5960e9480" + integrity sha512-jKo5H0+FSA+1aDdIWDmyAwNP2nFf19x4nAHbclkwnsexHBRfQlvx6yB6sY85BP+Ft6zxIn9gRRLbJPvFwsKBWw== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" clipboard "^2.0.11" -"@abp/cms-kit.admin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/cms-kit.admin/-/cms-kit.admin-10.2.0-rc.3.tgz#7bcb00e91ed9c03a5b117a2571f7f85ce7b11335" - integrity sha512-HRf8MByB856/TkBvB2dd4hH7ljg3BL84fRT/OMACHeufUsyftTpE4CEwfbtINUGCy43pRAfF1d+L0c59W7W3hA== +"@abp/cms-kit.admin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/cms-kit.admin/-/cms-kit.admin-10.3.0-rc.1.tgz#ae092d1a75efbb257c725482a3139bdba3e804b7" + integrity sha512-enEcnM3MlDRpQ0YiBmy2km6mqiAUztOodhvuF8I63xONA1T4jlbJUi01sBq2lg3RyxKqv7xBStUxmdH2cw64Pg== dependencies: - "@abp/codemirror" "~10.2.0-rc.3" - "@abp/jstree" "~10.2.0-rc.3" - "@abp/markdown-it" "~10.2.0-rc.3" - "@abp/slugify" "~10.2.0-rc.3" - "@abp/tui-editor" "~10.2.0-rc.3" - "@abp/uppy" "~10.2.0-rc.3" + "@abp/codemirror" "~10.3.0-rc.1" + "@abp/jstree" "~10.3.0-rc.1" + "@abp/markdown-it" "~10.3.0-rc.1" + "@abp/slugify" "~10.3.0-rc.1" + "@abp/tui-editor" "~10.3.0-rc.1" + "@abp/uppy" "~10.3.0-rc.1" -"@abp/cms-kit.public@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/cms-kit.public/-/cms-kit.public-10.2.0-rc.3.tgz#63f2d4e7e9cbb5dc25d42dcfac86a975a6260bc0" - integrity sha512-OZMF0O6uCA1hq3MxZHIl1ktb1gHWlMmfTAvy+4K1S9rUzCEqbJQ0I78NK782LvWC5dI98xz7QmK6X6KjmbGmWA== +"@abp/cms-kit.public@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/cms-kit.public/-/cms-kit.public-10.3.0-rc.1.tgz#cda7ca27a95f5b3903ce12264d0cefc688b5a33a" + integrity sha512-b2utxPU9Q9pzJQjhqpOuB0IZCPJRMAwCSlkOnh6C1YIUwlEpiGU3XFYG92qcrbSjMuX4L4p/HhxNAw8PQkVO0Q== dependencies: - "@abp/highlight.js" "~10.2.0-rc.3" - "@abp/star-rating-svg" "~10.2.0-rc.3" + "@abp/highlight.js" "~10.3.0-rc.1" + "@abp/star-rating-svg" "~10.3.0-rc.1" -"@abp/cms-kit@10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-10.2.0-rc.3.tgz#32c681c0398b8103f844077190aa52f575e1907e" - integrity sha512-xluy79Mzaf2voYF50JukPFsPSIeCwqYOMxLYWGaizKd/jp2M70V4stsIXr5/+jRC4NfUWQsp8vfRW8aHWE4+og== +"@abp/cms-kit@10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-10.3.0-rc.1.tgz#89ae433f6f48a0b104300b8cdd2d83bdc619c8df" + integrity sha512-dZfWaxil5/51DYCc9GT4h7vuuZexkWGtyvEMs74/QKlPUyX4Ad6XklMVsCSDH0b0DqT+0RNRl9xBXkYkbC8/Lw== dependencies: - "@abp/cms-kit.admin" "~10.2.0-rc.3" - "@abp/cms-kit.public" "~10.2.0-rc.3" + "@abp/cms-kit.admin" "~10.3.0-rc.1" + "@abp/cms-kit.public" "~10.3.0-rc.1" -"@abp/codemirror@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-10.2.0-rc.3.tgz#3020488b6d1c85adc48abe50cc480bafa72d377d" - integrity sha512-AiQoNr31h2/Rvp9hVvQANh11qNujhpNUQo5f0pgQJp/cpkopVWEkp88U7DaXcYaeK7HCbnzpiFsso0j2XjZltg== +"@abp/codemirror@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-10.3.0-rc.1.tgz#f82db77ccb4995bf7929ab747dfb848f9e56f858" + integrity sha512-lylZ+3ThrRkZffWtni1rv7F3fiRol0ObIVRluRuhU49OXcrg7B7YD35/DWP8McEIF2VKT8gZSUHbBC/b1ycgJw== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" codemirror "^5.65.1" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/highlight.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-10.2.0-rc.3.tgz#1dcdd6b438664d4b214a4eb10af895cddc882b11" - integrity sha512-RgQ2wN/UUP9rTefPRJpgka2PDv6S5h1+lzHa8x+Z7aSBP3kuNbPOPvLPB9gKsc/r5tZRIcnRWXcKPnQL57q/0A== +"@abp/highlight.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-10.3.0-rc.1.tgz#76d699f549aa630afda1f822717a3d3e2d846e88" + integrity sha512-m43P+D3gOsbc6tr2qQ/OmpCU6IqfVkw1frq1J6DcwlpEf5rCFhSEuvSq7roe9OTqsFX0xa+a1X2BHRNc3CkS2Q== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@highlightjs/cdn-assets" "~11.11.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/jstree@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jstree/-/jstree-10.2.0-rc.3.tgz#bf60627ddb4146e9cb53e8b0eaefd1ad34078294" - integrity sha512-RMQSsJtHReKO37tHCVgedsODPjfFG5PKfUMbz8wWm9QY5bwPvMmJqGJdsik66oZ6EqDrFNpSVQ15SOt6q1Y+EQ== +"@abp/jstree@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jstree/-/jstree-10.3.0-rc.1.tgz#11a0b55c0fc5ceefead83caa93806cc856700181" + integrity sha512-1KrfLkTuJScpkiEOujjIYtoiSaRJ31FjYi3DanjbRznKmbFlmqE9VQDg90Dqb2z9r3Oqhj5opEbH7Q0OWwILLQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jstree "^3.3.17" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/markdown-it@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-10.2.0-rc.3.tgz#107350bcfa4ca76094f77c265a821a30b52bc5d4" - integrity sha512-fDjAmA8h9IBMKY+zW5zbHLeAQhEif5xP3mDSqWe5u/e49HRJpGe0cbBYTRT9gPQXSb4G4fuvGoOJZhy9EZUOtQ== +"@abp/markdown-it@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/markdown-it/-/markdown-it-10.3.0-rc.1.tgz#9acabf7b91ebbdcf4699924c046d2f9ae926374e" + integrity sha512-LE7lb47fgEH97RWFz/OXsvFuqkYSDjJUXWCG58HMsrwDqDqZhfLGPb13y5xueVTin+jdBFX5WadOV3fueRlMJQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" markdown-it "^14.1.0" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/prismjs@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.2.0-rc.3.tgz#3f82a7af908f147c0e52a50e47297696fdb9deaa" - integrity sha512-jjY7rBANt0WgLjKveB62035r67KgoQGXnRagiiRLu1olv/oUELT/MR2ii5mR831hq8ULlH7QN0ERyrcgCzcO5A== +"@abp/prismjs@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.3.0-rc.1.tgz#147852ca4e0f9ceebe5681b65ad440b48325021f" + integrity sha512-sAWkFAP8GPx4UBR2EXg9Uz0sivK9CTWccUGGecttK9mNf12YbtVftmS145Fgip2+ifklPTcVRjXWIghyJPYu5Q== dependencies: - "@abp/clipboard" "~10.2.0-rc.3" - "@abp/core" "~10.2.0-rc.3" + "@abp/clipboard" "~10.3.0-rc.1" + "@abp/core" "~10.3.0-rc.1" prismjs "^1.30.0" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/slugify@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/slugify/-/slugify-10.2.0-rc.3.tgz#cbd826c2806e62b37accdb7e80c0e3383c252146" - integrity sha512-un/xhJ9SV4md/Gia4tjIu34kSvkAVz4Hg1+vTpgG39ZvFYSn2NGqjX9J4jDffvjcsfPdyoZgDqtEiap5oppi6A== +"@abp/slugify@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/slugify/-/slugify-10.3.0-rc.1.tgz#c8157d107352d7146402206e24eccf6ab480aece" + integrity sha512-66Nd9c+u002OQf1IO2oQU7ZCThFEWUSVhxS56Un/sc6GOhuLe2TWDPuCbRe3qVuMU2sZdqf989w3WM4JBKCwtQ== dependencies: slugify "^1.6.6" -"@abp/star-rating-svg@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-10.2.0-rc.3.tgz#24b821cdb834dba2916bb9d379e6d71db355c5b7" - integrity sha512-lmPIcBCs8eyrNPS82KKtTEX1bPr7bQarjbxI0Q9oIHcmWqvd+RiOCrhIF8X0nJHR06+YApsrSmtnofz0XgWcXw== +"@abp/star-rating-svg@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-10.3.0-rc.1.tgz#bc247af6b2a5a7dcbb95acfa062cdb468aee7c63" + integrity sha512-ffaO88HeFmoOi5QvWBwlM9LKuK2zL5C99wZeM/o3kFdCk3+rbHf89582gqvbfXrn8g7slfzLflQUerRJhCP6QQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" star-rating-svg "^3.5.0" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/tui-editor@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-10.2.0-rc.3.tgz#8d34e1c01ba1b23ef4de9176f77441ad79487b9d" - integrity sha512-0aUI5XmnkrrXi4mA7gS7Stwh+nJEBm/A9Swf6f6tylwTXrQczQp1wZVpJS6S7APUSO9P55xwVUePzmqf0hy/dw== +"@abp/tui-editor@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-10.3.0-rc.1.tgz#2c2353694efa6f61849f4ed8c769fea95e0304ee" + integrity sha512-Vxi9yKFJ5uBgmULppS67a4hBYC5/B+LIOdvG125x0FlCI5vO2+s+QMz09nQ6Fu4EaLmh4F0Qu0Q8FmRubpj7Jw== dependencies: - "@abp/jquery" "~10.2.0-rc.3" - "@abp/prismjs" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" + "@abp/prismjs" "~10.3.0-rc.1" -"@abp/uppy@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/uppy/-/uppy-10.2.0-rc.3.tgz#3281f19bc4ef658b795d09f8b8e15fb96ce1eaf0" - integrity sha512-vldXB6xSnSVHnV8NIbNzZIFQceCZRVW/jNXZEfisIO+iE9Pp+oUBXUgK15EzxZ/qoo2oYZK4x24ZJfG1H9Mqpw== +"@abp/uppy@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/uppy/-/uppy-10.3.0-rc.1.tgz#c3be855b5060b3b58097b293f7ad6dbdc17a8c1d" + integrity sha512-tIR78C2drAIwy+PHegaftgMVLQ9oYeXtl7L4nrLm8P9XkJi5jfRnlV7PCQUosU0JiUf6zLd/+lPt/k3oAnChmA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" uppy "^5.1.2" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/docs/app/VoloDocs.Web/package.json b/modules/docs/app/VoloDocs.Web/package.json index f0144afb2f..9937a74b8b 100644 --- a/modules/docs/app/VoloDocs.Web/package.json +++ b/modules/docs/app/VoloDocs.Web/package.json @@ -3,7 +3,7 @@ "name": "volo.docstestapp", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "~10.2.0-rc.3", - "@abp/docs": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1", + "@abp/docs": "~10.3.0-rc.1" } } diff --git a/modules/docs/app/VoloDocs.Web/yarn.lock b/modules/docs/app/VoloDocs.Web/yarn.lock index 2d19298fbd..bfe3ce4b85 100644 --- a/modules/docs/app/VoloDocs.Web/yarn.lock +++ b/modules/docs/app/VoloDocs.Web/yarn.lock @@ -2,222 +2,222 @@ # yarn lockfile v1 -"@abp/anchor-js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/anchor-js/-/anchor-js-10.2.0-rc.3.tgz#4ebc0c9ae6e2d8e7f1292abe4d17547f717ebbfc" - integrity sha512-F0XKTjwVPHtGf0eOjZfLkOIeEj3PbRZkmVLRrP3poHO8/6P1NwXD/WPIkwDeCeMMNz9MlhC8Z9EDP2pRs1L/3g== +"@abp/anchor-js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/anchor-js/-/anchor-js-10.3.0-rc.1.tgz#20071132f70087c146c2fcc88320843e55216b46" + integrity sha512-W6CvSFvU5W19X53UTIBm5f8h3qJqm0Z398TeOtlbFdfPNBxpEU0Q5lVCo3/Qj85/AhEXA9S8iBl825XatNMf4w== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" anchor-js "^5.0.0" -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== - dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== - dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== + dependencies: + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== + dependencies: + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/clipboard@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.2.0-rc.3.tgz#8319a1ddb6e6811d1149f72224be8ebd0d1ceb75" - integrity sha512-0UdFRAbkyPV7I2fP80rg3iWLPNg7ejopf5vU34gEBSJKeNow9u6UK0tkNO1IReNbPbb7QypwX+voDy1voVAxZw== +"@abp/clipboard@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-10.3.0-rc.1.tgz#2350aba655b18510dea0ca50cb91e5e5960e9480" + integrity sha512-jKo5H0+FSA+1aDdIWDmyAwNP2nFf19x4nAHbclkwnsexHBRfQlvx6yB6sY85BP+Ft6zxIn9gRRLbJPvFwsKBWw== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" clipboard "^2.0.11" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/docs@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/docs/-/docs-10.2.0-rc.3.tgz#0bcc0ebd3218c9ee45375fdf9b2cd9692c1ac237" - integrity sha512-Lx7MZOWYjaT2Au8GKMNVhOau8nDyWIzjl82pH6ZTI8DK83GmDDCOPiPfiPr0tadGn8xnlFhmUPt/gZp4FWVJdA== +"@abp/docs@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/docs/-/docs-10.3.0-rc.1.tgz#eb565ee5dc89f6e34b4dd0fdf00024554fd5fe3e" + integrity sha512-BXgNLZ2E1TY8tXH4N23SxmoJ1u4R/6OBPS6O5kbhFyOPS5oLk8G5UPErkqbab00zdWt2owyFUWOTUxzay6yLuw== dependencies: - "@abp/anchor-js" "~10.2.0-rc.3" - "@abp/clipboard" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" - "@abp/prismjs" "~10.2.0-rc.3" + "@abp/anchor-js" "~10.3.0-rc.1" + "@abp/clipboard" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" + "@abp/prismjs" "~10.3.0-rc.1" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/prismjs@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.2.0-rc.3.tgz#3f82a7af908f147c0e52a50e47297696fdb9deaa" - integrity sha512-jjY7rBANt0WgLjKveB62035r67KgoQGXnRagiiRLu1olv/oUELT/MR2ii5mR831hq8ULlH7QN0ERyrcgCzcO5A== +"@abp/prismjs@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-10.3.0-rc.1.tgz#147852ca4e0f9ceebe5681b65ad440b48325021f" + integrity sha512-sAWkFAP8GPx4UBR2EXg9Uz0sivK9CTWccUGGecttK9mNf12YbtVftmS145Fgip2+ifklPTcVRjXWIghyJPYu5Q== dependencies: - "@abp/clipboard" "~10.2.0-rc.3" - "@abp/core" "~10.2.0-rc.3" + "@abp/clipboard" "~10.3.0-rc.1" + "@abp/core" "~10.3.0-rc.1" prismjs "^1.30.0" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor index 2dcaea5eac..2db9953cef 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor @@ -1,4 +1,5 @@ ๏ปฟ@page "/identity/roles" +@page "/{culture}/identity/roles" @attribute [Authorize(IdentityPermissions.Roles.Default)] @using Volo.Abp.Identity @using Microsoft.AspNetCore.Authorization diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs index 4e9a6576d1..485f2442d0 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Blazorise; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -16,6 +17,9 @@ namespace Volo.Abp.Identity.Blazor.Pages.Identity; public partial class RoleManagement { + [Parameter] + public string? Culture { get; set; } + protected const string PermissionProviderName = "R"; protected PermissionManagementModal PermissionManagementModal; diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor index 28cb7f0bed..c54970bd33 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor @@ -1,4 +1,5 @@ ๏ปฟ@page "/identity/users" +@page "/{culture}/identity/users" @attribute [Authorize(IdentityPermissions.Users.Default)] @using Microsoft.AspNetCore.Authorization @using Volo.Abp.PermissionManagement.Blazor.Components diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs index fc35245801..ccce1cc363 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs @@ -18,6 +18,9 @@ namespace Volo.Abp.Identity.Blazor.Pages.Identity; public partial class UserManagement { + [Parameter] + public string? Culture { get; set; } + protected const string PermissionProviderName = "U"; protected const string DefaultSelectedTab = "UserInformations"; diff --git a/modules/openiddict/app/OpenIddict.Demo.Server/package.json b/modules/openiddict/app/OpenIddict.Demo.Server/package.json index 33e9f7bc23..a442008f3f 100644 --- a/modules/openiddict/app/OpenIddict.Demo.Server/package.json +++ b/modules/openiddict/app/OpenIddict.Demo.Server/package.json @@ -3,6 +3,6 @@ "name": "my-app", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1" } } diff --git a/modules/openiddict/app/angular/package.json b/modules/openiddict/app/angular/package.json index ee690de622..814ee8a1ed 100644 --- a/modules/openiddict/app/angular/package.json +++ b/modules/openiddict/app/angular/package.json @@ -12,15 +12,15 @@ }, "private": true, "dependencies": { - "@abp/ng.account": "~10.2.0-rc.3", - "@abp/ng.components": "~10.2.0-rc.3", - "@abp/ng.core": "~10.2.0-rc.3", - "@abp/ng.oauth": "~10.2.0-rc.3", - "@abp/ng.identity": "~10.2.0-rc.3", - "@abp/ng.setting-management": "~10.2.0-rc.3", - "@abp/ng.tenant-management": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", - "@abp/ng.theme.lepton-x": "~5.2.0-rc.3", + "@abp/ng.account": "~10.3.0-rc.1", + "@abp/ng.components": "~10.3.0-rc.1", + "@abp/ng.core": "~10.3.0-rc.1", + "@abp/ng.oauth": "~10.3.0-rc.1", + "@abp/ng.identity": "~10.3.0-rc.1", + "@abp/ng.setting-management": "~10.3.0-rc.1", + "@abp/ng.tenant-management": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", + "@abp/ng.theme.lepton-x": "~5.3.0-rc.1", "@angular/animations": "^15.0.1", "@angular/common": "^15.0.1", "@angular/compiler": "^15.0.1", @@ -36,7 +36,7 @@ "zone.js": "~0.11.4" }, "devDependencies": { - "@abp/ng.schematics": "~10.2.0-rc.3", + "@abp/ng.schematics": "~10.3.0-rc.1", "@angular-devkit/build-angular": "^15.0.1", "@angular-eslint/builder": "~15.1.0", "@angular-eslint/eslint-plugin": "~15.1.0", diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json index 8b95d9be21..34ecf8e020 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi.Client/ClientProxies/permissionManagement-generate-proxy.json @@ -21,7 +21,7 @@ "parametersOnMethod": [ { "name": "input", - "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=10.1.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=10.3.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", "type": "System.Collections.Generic.List", "typeSimple": "[Volo.Abp.PermissionManagement.IsGrantedRequest]", "isOptional": false, @@ -40,13 +40,13 @@ "IsGrantedAsyncByInput": { "uniqueName": "IsGrantedAsyncByInput", "name": "IsGrantedAsync", - "httpMethod": "GET", + "httpMethod": "POST", "url": "integration-api/permission-management/permissions/is-granted", "supportedVersions": [], "parametersOnMethod": [ { "name": "input", - "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=10.1.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", + "typeAsString": "System.Collections.Generic.List`1[[Volo.Abp.PermissionManagement.IsGrantedRequest, Volo.Abp.PermissionManagement.Domain.Shared, Version=10.3.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib", "type": "System.Collections.Generic.List", "typeSimple": "[Volo.Abp.PermissionManagement.IsGrantedRequest]", "isOptional": false, @@ -63,7 +63,7 @@ "isOptional": false, "defaultValue": null, "constraintTypes": null, - "bindingSourceId": "ModelBinding", + "bindingSourceId": "Body", "descriptorName": "" } ], diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs index 8a25abfd4b..f42af51222 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.HttpApi/Volo/Abp/PermissionManagement/Integration/PermissionIntegrationController.cs @@ -20,7 +20,7 @@ public class PermissionIntegrationController: AbpControllerBase, IPermissionInte PermissionIntegrationService = permissionIntegrationService; } - [HttpGet] + [HttpPost] [Route("is-granted")] public virtual Task> IsGrantedAsync(List input) { diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/package.json b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/package.json index 5f35fde9e9..0f7bbd2759 100644 --- a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/package.json +++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/package.json @@ -3,6 +3,6 @@ "name": "demo-app", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1" } } diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/yarn.lock b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/yarn.lock index 34b0ad545a..6d0049cf6a 100644 --- a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/yarn.lock +++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/yarn.lock @@ -2,186 +2,186 @@ # yarn lockfile v1 -"@abp/aspnetcore.mvc.ui.theme.basic@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.2.0-rc.3.tgz#2558a534d330612e124ce0e9f42f2e65cd279a9c" - integrity sha512-cS0V3br2jJ+7zwV0yKjb62SObDMpWHkwZUWfryxzIi2x/5Xn25+CuHcRmcX6GOwO9l3q75vADk33DhP+d53XFA== +"@abp/aspnetcore.mvc.ui.theme.basic@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-10.3.0-rc.1.tgz#82f61b5d112c8cbc5c74077809d84525edc1200a" + integrity sha512-eo4ubQfc6zT2/uTKM7U7XS6vExSKsg2szfvybFuBWJjmgb1ybfU2dKDXK4OfLdt0/wUBqBlEKDNK6NWZTfiovQ== dependencies: - "@abp/aspnetcore.mvc.ui.theme.shared" "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.shared" "~10.3.0-rc.1" -"@abp/aspnetcore.mvc.ui.theme.shared@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.2.0-rc.3.tgz#df0ef67776ac194d535c62c27909a8e4b9eb7d06" - integrity sha512-6DlnJDnO2a+BvV3/laX8ZHpFvdRTJWDJWx+SWuqCo4BlDsgVCA91NTmdeH7t/LtgjOlS/C2uqRQtlcwqIi9GKw== +"@abp/aspnetcore.mvc.ui.theme.shared@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-10.3.0-rc.1.tgz#465bb75a8b974be7a7945099fd9055ee68e3c9fe" + integrity sha512-89ca3oXYFEkaKbC1+mNsn6U4x0bls5iffcp1ZqaY5LTfHUhO5tJXbNf5kiOiEwT9TCYwPUHyLbUd2+rT72MGFA== dependencies: - "@abp/aspnetcore.mvc.ui" "~10.2.0-rc.3" - "@abp/bootstrap" "~10.2.0-rc.3" - "@abp/bootstrap-datepicker" "~10.2.0-rc.3" - "@abp/bootstrap-daterangepicker" "~10.2.0-rc.3" - "@abp/datatables.net-bs5" "~10.2.0-rc.3" - "@abp/font-awesome" "~10.2.0-rc.3" - "@abp/jquery-validation-unobtrusive" "~10.2.0-rc.3" - "@abp/lodash" "~10.2.0-rc.3" - "@abp/luxon" "~10.2.0-rc.3" - "@abp/malihu-custom-scrollbar-plugin" "~10.2.0-rc.3" - "@abp/moment" "~10.2.0-rc.3" - "@abp/select2" "~10.2.0-rc.3" - "@abp/sweetalert2" "~10.2.0-rc.3" - "@abp/timeago" "~10.2.0-rc.3" - -"@abp/aspnetcore.mvc.ui@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.2.0-rc.3.tgz#4ddf1babf991772e38ecc11a5a61dcaa93b8521b" - integrity sha512-HKD0yw/xAMSSEfNv+xTSDfqGQVrrmenOdGe08EWa4N9wJywgbKsCVHuQva3zKlgMZ22EuF7MOFgEFwtKkizKoA== + "@abp/aspnetcore.mvc.ui" "~10.3.0-rc.1" + "@abp/bootstrap" "~10.3.0-rc.1" + "@abp/bootstrap-datepicker" "~10.3.0-rc.1" + "@abp/bootstrap-daterangepicker" "~10.3.0-rc.1" + "@abp/datatables.net-bs5" "~10.3.0-rc.1" + "@abp/font-awesome" "~10.3.0-rc.1" + "@abp/jquery-validation-unobtrusive" "~10.3.0-rc.1" + "@abp/lodash" "~10.3.0-rc.1" + "@abp/luxon" "~10.3.0-rc.1" + "@abp/malihu-custom-scrollbar-plugin" "~10.3.0-rc.1" + "@abp/moment" "~10.3.0-rc.1" + "@abp/select2" "~10.3.0-rc.1" + "@abp/sweetalert2" "~10.3.0-rc.1" + "@abp/timeago" "~10.3.0-rc.1" + +"@abp/aspnetcore.mvc.ui@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-10.3.0-rc.1.tgz#c5764ec2fcab13ee591863c54e59e33fe1da90b4" + integrity sha512-vmBsradTXcTEqHUXM5rTLYnsNNYJDeyyvz3kaLLqNwYhjo2FxL8D8IUZnp3Mk0qkBpYaYeGag5uxd06VDczDhg== dependencies: ansi-colors "^4.1.3" -"@abp/bootstrap-datepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.2.0-rc.3.tgz#9917c0081a34edae20d649a8b327bb3156929094" - integrity sha512-goU/TlVzCh6OEqmnu36R97fdgK3/4dByLoqwuy1ec/hoMKjaL1JC0wE+zZEQ9eRfaNpx3BhUv1Y1rsAZD09wLQ== +"@abp/bootstrap-datepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-10.3.0-rc.1.tgz#58586e2333116ef840c3abd44bb2b54f944c92b1" + integrity sha512-PEXWi22YfOBdbxCUfLkEAVL45DCxzDbNALFLfsCK3LPvXuL5Pw0YU0CrezAW54+1tzPpbWh1HLyEyaUAINz6Wg== dependencies: bootstrap-datepicker "^1.10.1" -"@abp/bootstrap-daterangepicker@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.2.0-rc.3.tgz#fa525bf38f11c42564069832f75f4cff6dd8994c" - integrity sha512-S+KHEgpUYdgcFWra6Ca4bBfHg1O0xswBCklSsHKmKJRRnZQMKJqlau+rvD4GR8KS99vLztinxJvYAotd+f5Eow== +"@abp/bootstrap-daterangepicker@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap-daterangepicker/-/bootstrap-daterangepicker-10.3.0-rc.1.tgz#088b96754014b3c7a8884689574c2332cd5c292e" + integrity sha512-uZRh/Eh/3nyFe4KfMLRMud5LmUs2JFKSeA4KeRliGe1PD68E6NizP/ZiNzkYFP2K2p0nNUQrqmSe7ZFHVELN4A== dependencies: - "@abp/moment" "~10.2.0-rc.3" + "@abp/moment" "~10.3.0-rc.1" bootstrap-daterangepicker "^3.1.0" -"@abp/bootstrap@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.2.0-rc.3.tgz#cfef1f95741f1a3566b26292b214ce671eff77c8" - integrity sha512-lcBqbs/kfqDQMzplZrM29Z4ZlT/qDMm47s0BwI/3dgdiN4D0fF6Nv+Q/W3zCCCWvWDFUtOXZQaz5+hbCp9o80g== +"@abp/bootstrap@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-10.3.0-rc.1.tgz#fc1ccf88e689af336fec9c76d367bcaf66253961" + integrity sha512-vdhaz3ccmIflmufhNiQE/8I2RZdSSv3V4sbA2NC24csx8xl4J/R2JFhTyTLixpxOR+/p1cWw1F2oMYVzjV0+eg== dependencies: - "@abp/core" "~10.2.0-rc.3" - "@abp/popper.js" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" + "@abp/popper.js" "~10.3.0-rc.1" bootstrap "^5.3.8" -"@abp/core@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.2.0-rc.3.tgz#63241199853f5d61bb24c83aacd49e9bbe77b9f5" - integrity sha512-cwis5nFMYWf5z1RH51GhiE9ZOj6hVOQ0QXk7qptgi0T3Uql5v3xlCzijhAJpiTgThamXS5J6vEaMjqRHKOfcIg== +"@abp/core@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/core/-/core-10.3.0-rc.1.tgz#68f85db8219e3a2618a60cf82933bc52a2d1ec49" + integrity sha512-tOl/yDSPqRaHbENFVYcjqkdKGM4Qhjd/QPushVaH57pxalmv6canhiWAa0x7W31qxdY9od48H7MYoJx61jURhw== dependencies: - "@abp/utils" "~10.2.0-rc.3" + "@abp/utils" "~10.3.0-rc.1" -"@abp/datatables.net-bs5@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.2.0-rc.3.tgz#4eccb40f5833df148dda5dc12052746fce1d754b" - integrity sha512-OHbJuFS3FloST1/aLg84pd9PAP2kAtlRv4An8zWmdlxwxaWPNzF83uar6kF4KyZZn02rhQtzSwGF0aZr2ipUdw== +"@abp/datatables.net-bs5@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-10.3.0-rc.1.tgz#55e8dde9024c51ccb70fe5b640bbb434fff2e00d" + integrity sha512-d6vFlrNgS6MIpXi2EcZjGFbFbCl5I5hzM49NxQeB3hyG7gUElFsEJkf66UcO8PN/56Uo+sFe/rCdrcvyLLDHmg== dependencies: - "@abp/datatables.net" "~10.2.0-rc.3" + "@abp/datatables.net" "~10.3.0-rc.1" datatables.net-bs5 "^2.3.4" -"@abp/datatables.net@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.2.0-rc.3.tgz#87745a9518c50fa96446e23276896c7e14d20800" - integrity sha512-SEUNIBhnvLrNhE3FrsynzoXTt/n5ewoE0A+duPNAPS7ckJb9t3qfTcHqGpomZ+mjcuF5IM/3S0F1uNET+QyOAw== +"@abp/datatables.net@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-10.3.0-rc.1.tgz#8e275f31d8b24b098c6acc3ec1de7ef2fe587e73" + integrity sha512-m57imr9KOkasgDCIFaIgoDqFDhS71wzClE2WCk+Uk7qHLRgRMa7CYRHh5xeck4hgPWq9DEmAZS0ogbHxLgkLKQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" datatables.net "^2.3.4" -"@abp/font-awesome@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.2.0-rc.3.tgz#44ed6883da8291a5e3f3281c116dabd593e8bf41" - integrity sha512-TzsLpl9aoRJOQrWyO/95hQvUpJ6vi6XAWUeAUOYJwMJpNN87Wvesbb5Umx4rJIe5+XGUPx33fMCJtQObhEnS8Q== +"@abp/font-awesome@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-10.3.0-rc.1.tgz#e9d4a1b36652773509259440b77b804af18c5364" + integrity sha512-8zvZh7lbPlvH0/SKYtUeQF+ezKSoohwFxzFhOJ88GOdtwp620mBCwYEHjZA64e/Xjk6Oda2VrdNJ318IvgjIvA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@fortawesome/fontawesome-free" "^7.0.1" -"@abp/jquery-validation-unobtrusive@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.2.0-rc.3.tgz#6b918a5a27057f4fe513001f8b66f8cc58a2c95b" - integrity sha512-U00D6Aau5X1lmKnTpRjflA/5zWkBy0K6OEuOs8jDp70FZr/Pj2tuSdz1Y7mxDeP3gLWxjCnRFK3X7sB8Z61zGw== +"@abp/jquery-validation-unobtrusive@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-10.3.0-rc.1.tgz#b547557e85838afcc783ef3d502c2da3a31f4a63" + integrity sha512-NU00gPTHDF2HTnsHaZKAp17DTgAHUCz1fwuXRq4f7Ke5Q9HwiJx2IpIFaeR49xe9XRg1d9iRbNKFkMycjX7rEg== dependencies: - "@abp/jquery-validation" "~10.2.0-rc.3" + "@abp/jquery-validation" "~10.3.0-rc.1" jquery-validation-unobtrusive "^4.0.0" -"@abp/jquery-validation@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.2.0-rc.3.tgz#d31fa3beeb8e81557015b59b9b27479966aa05f6" - integrity sha512-MAf3OnVaWbYcp9z6n1yzFsqmZaZdScTH7eCPQm+COO4+/M7Dl7Klbxc77Df7WBu2Cqih7B50WWAQZU6KUhb5iQ== +"@abp/jquery-validation@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-10.3.0-rc.1.tgz#c4ab1a0692c1d224c5f60ffc4cb25545a7024c31" + integrity sha512-JaUhEbhKFB1DPFe+xTeIqTvN3YgFm7gdlpqMxN9Q5k0mnecQHlNmXbmC0oDa+CyxZDvMjWOrSMrJw/8yL4moQQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" jquery-validation "^1.21.0" -"@abp/jquery@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.2.0-rc.3.tgz#2c1c5737941ecf206379d2de52b5ef4ebe291bcd" - integrity sha512-P9+zBDE5kSzQF2hzmjNumIDSVNFf+J8FvGXLeOteAcZqy3Cvc1z1okZGFA7nM28QYaAFAVIegabhKF+5IiafIg== +"@abp/jquery@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-10.3.0-rc.1.tgz#bc8d3a468483165f8d35cbfa5e91621c2fa53c8f" + integrity sha512-tCZsi5U3oWZOazxRuqrEPyE85jZ4D71IfSrT9/Brf1wAELyrttt5ke3P57yQqjBevbfSqW652Wxca/w2GidQcg== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" jquery "~3.7.1" -"@abp/lodash@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.2.0-rc.3.tgz#4f61145867f730da2aafd65c8c8dbe452c231142" - integrity sha512-bU55YMrq0pNLEzvUV1AujdCVP18rETrpCHjuFrqLi69weC73atLH1fAzQoWbVjKDXzZ8qOFM2s+naEtS5gEjAw== +"@abp/lodash@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-10.3.0-rc.1.tgz#7bdf8038f28a822dfc12f0bfa9b7d81f13e16d99" + integrity sha512-tlev/kkQ3Q+OC7BT1ZJ+TThIbVQ3CZ+mtEujLt6zHVIxx8tukbYmmDMpltrmOL2kGnQeDdMqFcQoNJAAYOju+A== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" lodash "^4.17.21" -"@abp/luxon@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.2.0-rc.3.tgz#3ff6f8b4226c67be051851587a7847737c258de1" - integrity sha512-m/gngYrFg2EBB1PIK0M8jD2LlsYnwzlJVS5MV2vmGZ4h4tmq8HOYGrVPPLnvljaaNioYX3z0N1EeQEA4vQcogw== +"@abp/luxon@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-10.3.0-rc.1.tgz#e13db7cade7761964e9820315e43bac182f80784" + integrity sha512-FB42gIKvfDJBu2vFZDBFVL6bn9jZpDpKdt5Kkp4OKQak9NHVyNuzH+R95Hr99vB+KELyTwW7hihc6Kl2oCrwWQ== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" luxon "^3.7.2" -"@abp/malihu-custom-scrollbar-plugin@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.2.0-rc.3.tgz#52eb0b0103b371be41fc89961335ed7a219cb10c" - integrity sha512-ZPcg1tehGz1dIOC7zqu/nsnV9mjPSoHb8TdhpAL6XERGAu2mwWvHBP2Zi7LE6PXYc7stF33i4u6Tr+OMMDrkrg== +"@abp/malihu-custom-scrollbar-plugin@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-10.3.0-rc.1.tgz#1af6ebce0553c368d884752efcaef6cceaeb806c" + integrity sha512-+BYN/3DhhtI7tS4nv4BpdsPiQLEVrLQ0KgawGRr1h3SV/nz1dtBTBgTbKvy/4bDHoMSKA1dPfudxi6XjgwUoBA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" malihu-custom-scrollbar-plugin "^3.1.5" -"@abp/moment@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.2.0-rc.3.tgz#991a8523b30d987930b6bf8b82647bbcae340f7c" - integrity sha512-s/r4BgDiqimPdNd1PBGMH/BbBtA77I1Mwmg/OaCUYYrUuWBGQHlsElO7sGEQwHGUfx0WjRG0wZ+jbV992qDhrA== +"@abp/moment@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/moment/-/moment-10.3.0-rc.1.tgz#82229c44e7b1417c872edec53ed3f51d06bf7e8b" + integrity sha512-hKQ8VE25Wqo1mj/ks8qw39ONLQK5sV33xc0bfYHTk0+NVAholAPZF7gjqiDzaAWXzVBVJjemH554AM3y14VNAA== dependencies: moment "^2.30.1" -"@abp/popper.js@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.2.0-rc.3.tgz#ad445921c951d297b6c8598062f06ee21c7a8bf0" - integrity sha512-tZd4+Q6xjKQJwe71jygVL9xIZqqTARyMOVJevCSEH9QU4OPPy2P0HW+hFatBNvHUKF7tuEl+i5PoQin5g/LANA== +"@abp/popper.js@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/popper.js/-/popper.js-10.3.0-rc.1.tgz#3d758e25e7b09210542e4da06558cd5a1b710b45" + integrity sha512-3PKJpwzTYAQ6UJFe3u9bn1qKRjXwmILlR9umyH998bfJLr0Zl04rBfcbIL9/l3S01qlCMt2bwjre0+wpRl+/OA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" "@popperjs/core" "^2.11.8" -"@abp/select2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.2.0-rc.3.tgz#d6ceac67fb4bb242cb231a870e9ee1bb2ca8ce02" - integrity sha512-aXuNqUg8+jK4nPVj6tsclOTqyXcRWC6a9rqEptSgpyoN4mE2Gsx8siIH8f8bdyZUMbww3ixTiTGKK5Hu7larrQ== +"@abp/select2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-10.3.0-rc.1.tgz#5292066ccf962ad92058d946b267d413c4876c40" + integrity sha512-gAJaAuLoHaOhkdDwS2F3ZH3CR//8EClkEWDde2AcYS+W2AY9/4g9kAMUOD5IrkrrYvJ+DDa9u426Ds8n8s/B9g== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" select2 "^4.0.13" -"@abp/sweetalert2@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.2.0-rc.3.tgz#69be81b56a6347d238cf07f6ae6a3c604740a910" - integrity sha512-gWodWf2YwMSULMkqOEzE7SNP7IFQt0EbV5fuuH71NkIaNIMHhnQgz76XiiFjN7CF4uZLoDmRSfIzx9RNzRpOqw== +"@abp/sweetalert2@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-10.3.0-rc.1.tgz#a344674f14b21f430a820805bc36768a6dde1f58" + integrity sha512-UV3nSA3LdgygFr1ruFZRU1PVan455NMFILisXKRYVu9QwweFInmnliR6FmcDlTmPFW7RCLBk+lC9UblEcDthUA== dependencies: - "@abp/core" "~10.2.0-rc.3" + "@abp/core" "~10.3.0-rc.1" sweetalert2 "^11.23.0" -"@abp/timeago@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.2.0-rc.3.tgz#b06dedf0f2363c697a7c6e1a0fb36d6b51537412" - integrity sha512-HDiUjIMV1cgDDC+w+P5irzq9C9lK1WAJcYxeyDg2UIbfhp8Na65syyeC34hRVOWFrUh3yvsJx1sw+2P2s5S9Og== +"@abp/timeago@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-10.3.0-rc.1.tgz#f0e476b65f19fd986c06231a331fdb4050d1a6c6" + integrity sha512-ydBvTJ73BrV7A69vtWRzw//JmrLu6r4ow8J3GZy8vEuH9vlBWe1JHcPK6lOD3DDM+K6Jag5/31RL45ZuSSxcvQ== dependencies: - "@abp/jquery" "~10.2.0-rc.3" + "@abp/jquery" "~10.3.0-rc.1" timeago "^1.6.7" -"@abp/utils@~10.2.0-rc.3": - version "10.2.0-rc.3" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.2.0-rc.3.tgz#3db132d3872c6f389a54c12bff343e756b5a39b2" - integrity sha512-MpI1G5hGs/YSL3g2sytSr5+cxhOsNDVe7k6lFWND+L8iECPROh1s8SAqDJ6eKxkQNwlwEtNc56Y+LdfJmKyeXA== +"@abp/utils@~10.3.0-rc.1": + version "10.3.0-rc.1" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-10.3.0-rc.1.tgz#b6e20d357b87a009ffef3e11a0e7cc3a887d461f" + integrity sha512-tBcywC3T2ZUKS6znm1lCd+jP0peZolYyxjs1F7wyyH/y+Y08NYtGgLG/A8EaIv7iDY2K4WExzvWjTHB4lE1mFA== dependencies: just-compare "^2.3.0" diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor index ad571fb448..74d1a50b7d 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor @@ -1,4 +1,5 @@ ๏ปฟ@page "/setting-management" +@page "/{culture}/setting-management" @using Microsoft.AspNetCore.Authorization @using Volo.Abp.AspNetCore.Components.Web.Theming.Layout @using Volo.Abp.Features diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs index 1b443fc827..3a1697ca86 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor/Pages/SettingManagement/SettingManagement.razor.cs @@ -12,6 +12,9 @@ namespace Volo.Abp.SettingManagement.Blazor.Pages.SettingManagement; public partial class SettingManagement { + [Parameter] + public string? Culture { get; set; } + [Inject] protected IServiceProvider ServiceProvider { get; set; } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor index c1bf81cc39..5efa90dd23 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor @@ -1,4 +1,5 @@ ๏ปฟ@page "/tenant-management/tenants" +@page "/{culture}/tenant-management/tenants" @attribute [Authorize(TenantManagementPermissions.Tenants.Default)] @using Microsoft.AspNetCore.Authorization @using Volo.Abp.FeatureManagement.Blazor.Components diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs index 272bd9cf7a..c1fdbce867 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Blazorise; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components; using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions; using Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns; using Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars; @@ -14,6 +15,9 @@ namespace Volo.Abp.TenantManagement.Blazor.Pages.TenantManagement; public partial class TenantManagement { + [Parameter] + public string? Culture { get; set; } + protected const string FeatureProviderName = "T"; protected bool HasManageFeaturesPermission; diff --git a/modules/virtual-file-explorer/app/package.json b/modules/virtual-file-explorer/app/package.json index 66e5edcb4a..fb9969f9b4 100644 --- a/modules/virtual-file-explorer/app/package.json +++ b/modules/virtual-file-explorer/app/package.json @@ -3,7 +3,7 @@ "name": "my-app", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "~10.2.0-rc.3", - "@abp/virtual-file-explorer": "~10.2.0-rc.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "~10.3.0-rc.1", + "@abp/virtual-file-explorer": "~10.3.0-rc.1" } } diff --git a/npm/lerna.json b/npm/lerna.json index 034a96e90b..7497b00594 100644 --- a/npm/lerna.json +++ b/npm/lerna.json @@ -1,5 +1,5 @@ { - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "packages": [ "packs/*" ], diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index 6726da34fb..25ab512788 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -48,8 +48,8 @@ }, "private": true, "devDependencies": { - "@abp/ng.theme.lepton-x": "~5.2.0-rc.3", - "@abp/utils": "~10.2.0-rc.3", + "@abp/ng.theme.lepton-x": "~5.3.0-rc.1", + "@abp/utils": "~10.3.0-rc.1", "@angular-devkit/build-angular": "~21.2.0", "@angular-devkit/core": "~21.2.0", "@angular-devkit/schematics": "~21.2.0", diff --git a/npm/ng-packs/packages/account-core/package.json b/npm/ng-packs/packages/account-core/package.json index b88d72931f..6c317fc541 100644 --- a/npm/ng-packs/packages/account-core/package.json +++ b/npm/ng-packs/packages/account-core/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.account.core", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.core": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.core": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/account/package.json b/npm/ng-packs/packages/account/package.json index b873e7a2d7..dda1cb637b 100644 --- a/npm/ng-packs/packages/account/package.json +++ b/npm/ng-packs/packages/account/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.account", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.account.core": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.account.core": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/cms-kit/package.json b/npm/ng-packs/packages/cms-kit/package.json index 3f9c491308..f1daf4e71a 100644 --- a/npm/ng-packs/packages/cms-kit/package.json +++ b/npm/ng-packs/packages/cms-kit/package.json @@ -1,15 +1,15 @@ { "name": "@abp/ng.cms-kit", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.components": "~10.2.0-rc.3", - "@abp/ng.setting-management": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.components": "~10.3.0-rc.1", + "@abp/ng.setting-management": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "@toast-ui/editor": "~3.0.0", "codemirror": "~6.0.0", "tslib": "^2.0.0" diff --git a/npm/ng-packs/packages/components/package.json b/npm/ng-packs/packages/components/package.json index 5da3f75860..2757c043e4 100644 --- a/npm/ng-packs/packages/components/package.json +++ b/npm/ng-packs/packages/components/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.components", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "peerDependencies": { - "@abp/ng.core": ">=10.2.0-rc.3", - "@abp/ng.theme.shared": ">=10.2.0-rc.3" + "@abp/ng.core": ">=10.3.0-rc.1", + "@abp/ng.theme.shared": ">=10.3.0-rc.1" }, "dependencies": { "chart.js": "^3.5.1", diff --git a/npm/ng-packs/packages/core/package.json b/npm/ng-packs/packages/core/package.json index f6f922517d..20de8332b5 100644 --- a/npm/ng-packs/packages/core/package.json +++ b/npm/ng-packs/packages/core/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.core", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/utils": "~10.2.0-rc.3", + "@abp/utils": "~10.3.0-rc.1", "just-clone": "^6.0.0", "just-compare": "^2.0.0", "ts-toolbelt": "^9.0.0", diff --git a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts index 81f9305f68..8d6b5f3992 100644 --- a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts +++ b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts @@ -14,7 +14,8 @@ import { ReplaceableComponentsService } from '../services/replaceable-components import { RouterEvents } from '../services/router-events.service'; import { RoutesService } from '../services/routes.service'; import { SubscriptionService } from '../services/subscription.service'; -import { findRoute, getRoutePath } from '../utils/route-utils'; +import { RouteBasedCultureUrlService } from '../services/route-based-culture-url.service'; +import { findRoute } from '../utils/route-utils'; import { TreeNode } from '../utils/tree-utils'; import { DYNAMIC_LAYOUTS_TOKEN } from '../tokens/dynamic-layout.token'; import { EnvironmentService } from '../services'; @@ -46,6 +47,7 @@ export class DynamicLayoutComponent { protected readonly subscription = inject(SubscriptionService); protected readonly routerEvents = inject(RouterEvents); protected readonly environment = inject(EnvironmentService); + protected readonly routeCultureUrl = inject(RouteBasedCultureUrlService); constructor() { const dynamicLayoutComponent = inject(DynamicLayoutComponent, { optional: true, skipSelf: true }); @@ -85,7 +87,7 @@ export class DynamicLayoutComponent { const routeData = this.route.snapshot.data || {}; let expectedLayout = routeData['layout'] as eLayoutType; - let node = findRoute(this.routes, getRoutePath(this.router)); + let node = findRoute(this.routes, this.routeCultureUrl.getRoutePathForMatching(this.router)); node = { parent: node } as TreeNode; while (node.parent) { diff --git a/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts b/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts index 41e07f8d1b..a6ae040597 100644 --- a/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts +++ b/npm/ng-packs/packages/core/src/lib/guards/permission.guard.ts @@ -10,8 +10,14 @@ import { HttpErrorResponse } from '@angular/common/http'; import { Observable, of } from 'rxjs'; import { filter, map, switchMap, take } from 'rxjs/operators'; import { AuthService, IAbpGuard } from '../abstracts'; -import { findRoute, getRoutePath } from '../utils/route-utils'; -import { RoutesService, PermissionService, HttpErrorReporterService, ConfigStateService } from '../services'; +import { findRoute } from '../utils/route-utils'; +import { + RoutesService, + PermissionService, + HttpErrorReporterService, + ConfigStateService, + RouteBasedCultureUrlService, +} from '../services'; import { isPlatformServer } from '@angular/common'; /** * @deprecated Use `permissionGuard` *function* instead. @@ -26,12 +32,16 @@ export class PermissionGuard implements IAbpGuard { protected readonly permissionService = inject(PermissionService); protected readonly httpErrorReporter = inject(HttpErrorReporterService); protected readonly configStateService = inject(ConfigStateService); + protected readonly routeCultureUrl = inject(RouteBasedCultureUrlService); canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { let { requiredPolicy } = route.data || {}; if (!requiredPolicy) { - const routeFound = findRoute(this.routesService, getRoutePath(this.router, state.url)); + const routeFound = findRoute( + this.routesService, + this.routeCultureUrl.getRoutePathForMatching(this.router, state.url), + ); requiredPolicy = routeFound?.requiredPolicy; } @@ -70,12 +80,13 @@ export const permissionGuard: CanActivateFn = ( const permissionService = inject(PermissionService); const httpErrorReporter = inject(HttpErrorReporterService); const configStateService = inject(ConfigStateService); + const routeCultureUrl = inject(RouteBasedCultureUrlService); const platformId = inject(PLATFORM_ID); let { requiredPolicy } = route.data || {}; if (!requiredPolicy) { - const routeFound = findRoute(routesService, getRoutePath(router, state.url)); + const routeFound = findRoute(routesService, routeCultureUrl.getRoutePathForMatching(router, state.url)); requiredPolicy = routeFound?.requiredPolicy; } diff --git a/npm/ng-packs/packages/core/src/lib/pipes/index.ts b/npm/ng-packs/packages/core/src/lib/pipes/index.ts index 0320350f55..0dfe63d39f 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/index.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/index.ts @@ -8,4 +8,5 @@ export * from './short-date-time.pipe'; export * from './utc-to-local.pipe'; export * from './async-localization.pipe'; export * from './lazy-localization.pipe'; +export * from './route-culture-url.pipe'; export * from './html-encode.pipe'; diff --git a/npm/ng-packs/packages/core/src/lib/pipes/route-culture-url.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/route-culture-url.pipe.ts new file mode 100644 index 0000000000..26e43153e1 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/pipes/route-culture-url.pipe.ts @@ -0,0 +1,18 @@ +import { Pipe, PipeTransform, inject } from '@angular/core'; +import { RouteBasedCultureUrlService } from '../services/route-based-culture-url.service'; + +/** + * Prefixes menu/navigation paths with the current culture when route-based culture is enabled. + * Impure so links update after language changes. + */ +@Pipe({ + name: 'abpRouteCultureUrl', + pure: false, +}) +export class AbpRouteCultureUrlPipe implements PipeTransform { + private readonly url = inject(RouteBasedCultureUrlService); + + transform(path: string | undefined | null): string | undefined | null { + return this.url.prefixPathWithCulture(path); + } +} diff --git a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.ts b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.ts index 524c9a8c78..b2d7b67bea 100644 --- a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.ts +++ b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.ts @@ -42,6 +42,7 @@ export interface ApplicationLocalizationConfigurationDto { defaultResourceName?: string; languagesMap: Record; languageFilesMap: Record; + useRouteBasedCulture: boolean; } export interface ApplicationLocalizationDto { diff --git a/npm/ng-packs/packages/core/src/lib/services/index.ts b/npm/ng-packs/packages/core/src/lib/services/index.ts index 205fd2f0dc..cccac2ffb6 100644 --- a/npm/ng-packs/packages/core/src/lib/services/index.ts +++ b/npm/ng-packs/packages/core/src/lib/services/index.ts @@ -16,6 +16,8 @@ export * from './resource-wait.service'; export * from './rest.service'; export * from './router-events.service'; export * from './router-wait.service'; +export * from './route-based-culture.service'; +export * from './route-based-culture-url.service'; export * from './routes.service'; export * from './session-state.service'; export * from './subscription.service'; diff --git a/npm/ng-packs/packages/core/src/lib/services/route-based-culture-url.service.ts b/npm/ng-packs/packages/core/src/lib/services/route-based-culture-url.service.ts new file mode 100644 index 0000000000..cbd94f3803 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/route-based-culture-url.service.ts @@ -0,0 +1,170 @@ +import { Location } from '@angular/common'; +import { isPlatformBrowser } from '@angular/common'; +import { Injectable, PLATFORM_ID, inject } from '@angular/core'; +import { Router } from '@angular/router'; +import { LanguageInfo } from '../proxy/volo/abp/localization/models'; +import { + findMatchingCultureName, + getFirstPathSegment, + stripCultureSegmentFromPath, +} from '../utils/route-based-culture.utils'; +import { getRoutePath } from '../utils/route-utils'; +import { ConfigStateService } from './config-state.service'; +import { SessionStateService } from './session-state.service'; + +/** + * URL helpers for route-based culture: prefix menu links, strip culture for route matching, + * and navigate when the user picks a language so the URL stays in sync with the session. + */ +@Injectable({ + providedIn: 'root', +}) +export class RouteBasedCultureUrlService { + private readonly router = inject(Router); + private readonly location = inject(Location); + private readonly configState = inject(ConfigStateService); + private readonly sessionState = inject(SessionStateService); + private readonly platformId = inject(PLATFORM_ID); + + /** Cached from localization config; refreshed when application configuration updates. */ + private useRouteBasedCulture = false; + private languages: LanguageInfo[] | undefined; + + constructor() { + this.refreshRouteCultureCache(); + this.configState.getAll$().subscribe(() => this.refreshRouteCultureCache()); + } + + private refreshRouteCultureCache(): void { + const loc = this.configState.getOne('localization'); + if (!loc) { + this.useRouteBasedCulture = false; + this.languages = undefined; + return; + } + this.useRouteBasedCulture = !!loc.useRouteBasedCulture; + this.languages = loc.languages as LanguageInfo[] | undefined; + } + + private isRouteBasedCultureEnabled(): boolean { + return this.useRouteBasedCulture; + } + + /** + * Same as {@link getRoutePath} but removes the leading culture segment when route-based culture is enabled, + * so paths match `RoutesService` entries (e.g. `/identity/users`). + */ + getRoutePathForMatching(router: Router, url = router.url): string { + const raw = getRoutePath(router, url); + return this.stripCulturePrefixIfEnabled(raw); + } + + /** + * Strips the leading culture segment when it matches a configured language and route-based culture is enabled. + * Use for menu active state, breadcrumbs, and any comparison between `router.url` and `RoutesService` paths. + */ + stripCulturePrefixIfEnabled(path: string): string { + if (!this.isRouteBasedCultureEnabled() || !path) { + return path; + } + return this.stripCulturePrefix(path); + } + + /** + * Alias for {@link stripCulturePrefixIfEnabled}: normalizes the current URL for **menu highlighting** + * when menu `link` values omit the culture segment (e.g. Lepton `NavbarRoutesComponent`, `NavbarService.getRouteItem`). + */ + normalizeForMenuMatch(path: string): string { + return this.stripCulturePrefixIfEnabled(path); + } + + /** + * Removes the first segment when it is a known UI culture (for matching and normalization). + */ + stripCulturePrefix(path: string): string { + return stripCultureSegmentFromPath(path, this.languages); + } + + /** + * Prefixes an app path with the current session culture when route-based culture is enabled + * (e.g. `/identity/users` โ†’ `/en/identity/users`). Use for `routerLink`, `navigateByUrl`, etc. + */ + prefixPathWithCulture(path: string | undefined | null): string | undefined | null { + if (path == null || path === '') { + return path; + } + + if (!this.isRouteBasedCultureEnabled()) { + return path; + } + + if (/^https?:\/\//i.test(path)) { + return path; + } + + const lang = this.sessionState.getLanguage(); + if (!lang) { + return path; + } + + const stripped = this.stripCulturePrefix(path); + const normalized = stripped.startsWith('/') ? stripped : '/' + stripped; + const suffix = normalized === '/' ? '' : normalized; + return `/${lang}${suffix}`; + } + + /** + * Rewrites the current URL so the first segment is {@link cultureName} (or prepends it). + * Call this when the user selects a language in the UI instead of only {@link SessionStateService.setLanguage} + * so the address bar stays aligned with the session. + */ + navigateToUrlWithCulture(cultureName: string): Promise | void { + if (!cultureName || !isPlatformBrowser(this.platformId)) { + return Promise.resolve(false); + } + + if (!this.isRouteBasedCultureEnabled()) { + this.sessionState.setLanguage(cultureName); + return Promise.resolve(true); + } + + const path = this.location.path(); + const newPath = this.rewritePathToCulture(path, cultureName); + return this.router.navigateByUrl(newPath); + } + + /** + * Preferred entry point for language pickers (e.g. Lepton toolbar): same as {@link navigateToUrlWithCulture}. + */ + applyLanguageSelection(cultureName: string): Promise | void { + return this.navigateToUrlWithCulture(cultureName); + } + + /** + * Builds a new path (including query/hash) with the given culture as the first segment, + * replacing the culture segment when one is already present. + */ + rewritePathToCulture(urlPath: string, newCulture: string): string { + const languages = this.languages; + const pathEnd = urlPath.search(/[?#]/); + const pathOnly = pathEnd >= 0 ? urlPath.slice(0, pathEnd) : urlPath; + const suffix = pathEnd >= 0 ? urlPath.slice(pathEnd) : ''; + + const first = getFirstPathSegment(pathOnly); + const firstIsCulture = !!findMatchingCultureName(first, languages); + + if (firstIsCulture) { + const segments = pathOnly.split('/').filter(s => s.length > 0); + if (segments.length === 0) { + return `/${newCulture}${suffix}`; + } + segments[0] = newCulture; + const joined = '/' + segments.join('/'); + return joined + suffix; + } + + const normalized = pathOnly.startsWith('/') ? pathOnly : '/' + pathOnly; + const rest = normalized === '/' ? '' : normalized; + return `/${newCulture}${rest}${suffix}`; + } +} diff --git a/npm/ng-packs/packages/core/src/lib/services/route-based-culture.service.ts b/npm/ng-packs/packages/core/src/lib/services/route-based-culture.service.ts new file mode 100644 index 0000000000..f78b6130a9 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/route-based-culture.service.ts @@ -0,0 +1,59 @@ +import { isPlatformBrowser } from '@angular/common'; +import { Injectable, PLATFORM_ID, inject } from '@angular/core'; +import { NavigationEnd, Router } from '@angular/router'; +import { filter } from 'rxjs/operators'; +import { LanguageInfo } from '../proxy/volo/abp/localization/models'; +import { findMatchingCultureName, getFirstPathSegment } from '../utils/route-based-culture.utils'; +import { ConfigStateService } from './config-state.service'; +import { SessionStateService } from './session-state.service'; + +/** + * When the backend enables URL-based localization (`localization.useRouteBasedCulture` from application configuration), + * keeps session language in sync with the first URL path segment (e.g. /en/..., /tr-TR/...). + * Works with nested routes because only the leading segment is interpreted as culture. + */ +@Injectable({ + providedIn: 'root', +}) +export class RouteBasedCultureService { + private readonly router = inject(Router); + private readonly configState = inject(ConfigStateService); + private readonly sessionState = inject(SessionStateService); + private readonly platformId = inject(PLATFORM_ID); + protected readonly localization = this.configState.getOne('localization'); + + constructor() { + if (!isPlatformBrowser(this.platformId)) { + return; + } + + if (!this.localization?.useRouteBasedCulture) { + return; + } + + this.router.events + .pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd)) + .subscribe(() => this.syncLanguageFromUrl()); + } + + /** + * Reads the culture from the current URL and updates session language when it matches a configured language. + * @param pathOverride Optional path (e.g. from `Location.path()` during app bootstrap before navigation settles). + */ + syncLanguageFromUrl(pathOverride?: string): void { + if (!isPlatformBrowser(this.platformId)) { + return; + } + + const languages = this.localization?.languages as LanguageInfo[] | undefined; + const path = pathOverride ?? this.router.url; + const firstSegment = getFirstPathSegment(path); + const cultureName = findMatchingCultureName(firstSegment, languages); + + if (!cultureName) { + return; + } + + this.sessionState.setLanguage(cultureName); + } +} diff --git a/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts b/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts index af961794f8..18d83290b1 100644 --- a/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts @@ -27,6 +27,10 @@ export class AbpTitleStrategy extends TitleStrategy { override updateTitle(routerState: RouterStateSnapshot) { this.routerState = routerState; + if (!routerState?.root) { + return; + } + const title = this.buildTitle(routerState); const projectName = this.localizationService.instant({ diff --git a/npm/ng-packs/packages/core/src/lib/tests/route-based-culture-url.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/route-based-culture-url.service.spec.ts new file mode 100644 index 0000000000..eaaf94df1b --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/route-based-culture-url.service.spec.ts @@ -0,0 +1,81 @@ +import { Location } from '@angular/common'; +import { TestBed } from '@angular/core/testing'; +import { Router } from '@angular/router'; +import { of } from 'rxjs'; +import { ConfigStateService } from '../services/config-state.service'; +import { RouteBasedCultureUrlService } from '../services/route-based-culture-url.service'; +import { SessionStateService } from '../services/session-state.service'; + +const languages = [ + { cultureName: 'en', displayName: 'English' }, + { cultureName: 'tr', displayName: 'Turkish' }, +]; + +describe('RouteBasedCultureUrlService', () => { + let service: RouteBasedCultureUrlService; + let configState: { getOne: ReturnType }; + let sessionState: { + getLanguage: ReturnType; + setLanguage: ReturnType; + }; + + function setup(useRouteBasedCulture: boolean) { + configState = { + getOne: vi.fn((key: string) => { + if (key === 'localization') { + return { useRouteBasedCulture, languages }; + } + return undefined; + }), + getAll$: () => of({}), + }; + sessionState = { + getLanguage: vi.fn(() => 'tr'), + setLanguage: vi.fn(), + }; + + TestBed.configureTestingModule({ + providers: [ + RouteBasedCultureUrlService, + { provide: ConfigStateService, useValue: configState }, + { provide: SessionStateService, useValue: sessionState }, + { + provide: Router, + useValue: { navigateByUrl: vi.fn(() => Promise.resolve(true)), url: '/tr' }, + }, + { provide: Location, useValue: { path: () => '/tr/home' } }, + ], + }); + + service = TestBed.inject(RouteBasedCultureUrlService); + } + + afterEach(() => { + TestBed.resetTestingModule(); + }); + + test('prefixPathWithCulture leaves path unchanged when useRouteBasedCulture is false', () => { + setup(false); + expect(service.prefixPathWithCulture('/identity/users')).toBe('/identity/users'); + }); + + test('prefixPathWithCulture prepends session culture when enabled', () => { + setup(true); + expect(service.prefixPathWithCulture('/identity/users')).toBe('/tr/identity/users'); + }); + + test('stripCulturePrefixIfEnabled removes leading culture segment', () => { + setup(true); + expect(service.stripCulturePrefixIfEnabled('/en/identity/users')).toBe('/identity/users'); + }); + + test('rewritePathToCulture replaces existing culture segment', () => { + setup(true); + expect(service.rewritePathToCulture('/en/home?x=1', 'tr')).toBe('/tr/home?x=1'); + }); + + test('rewritePathToCulture prepends culture when missing', () => { + setup(true); + expect(service.rewritePathToCulture('/identity/users', 'tr')).toBe('/tr/identity/users'); + }); +}); diff --git a/npm/ng-packs/packages/core/src/lib/tests/route-based-culture.utils.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/route-based-culture.utils.spec.ts new file mode 100644 index 0000000000..e9e2ea9b96 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/route-based-culture.utils.spec.ts @@ -0,0 +1,81 @@ +import { + findMatchingCultureName, + getFirstPathSegment, + normalizeUrlForRouteCultureMatch, + stripCultureSegmentFromPath, +} from '../utils/route-based-culture.utils'; +import type { LanguageInfo } from '../proxy/volo/abp/localization/models'; + +describe('route-based-culture.utils', () => { + describe('#getFirstPathSegment', () => { + test.each` + urlPath | expected + ${''} | ${''} + ${'/'} | ${''} + ${'/en'} | ${'en'} + ${'/en/account'} | ${'en'} + ${'en/account'} | ${'en'} + ${'/tr-TR/foo/bar'} | ${'tr-TR'} + ${'/zh-Hans/account?x=1'} | ${'zh-Hans'} + ${'tr/home#frag'} | ${'tr'} + `('should return $expected when urlPath is $urlPath', ({ urlPath, expected }) => { + expect(getFirstPathSegment(urlPath)).toBe(expected); + }); + }); + + describe('#findMatchingCultureName', () => { + const languages: LanguageInfo[] = [ + { cultureName: 'en' }, + { cultureName: 'tr-TR' }, + { cultureName: 'zh-Hans' }, + ]; + + test.each` + segment | expected + ${'en'} | ${'en'} + ${'EN'} | ${'en'} + ${'tr-tr'} | ${'tr-TR'} + ${'zh-hans'} | ${'zh-Hans'} + ${'account'} | ${undefined} + ${''} | ${undefined} + `('should return $expected when segment is $segment', ({ segment, expected }) => { + expect(findMatchingCultureName(segment, languages)).toBe(expected); + }); + + test('should return undefined when languages is empty', () => { + expect(findMatchingCultureName('en', [])).toBeUndefined(); + }); + }); + + describe('#stripCultureSegmentFromPath', () => { + const languages: LanguageInfo[] = [{ cultureName: 'en' }, { cultureName: 'tr' }]; + + test('should strip leading culture segment for menu matching', () => { + expect(stripCultureSegmentFromPath('/en/identity/users', languages)).toBe('/identity/users'); + }); + + test('should leave path unchanged when first segment is not a culture', () => { + expect(stripCultureSegmentFromPath('/identity/users', languages)).toBe('/identity/users'); + }); + + test('should preserve query string', () => { + expect(stripCultureSegmentFromPath('/en/home?x=1', languages)).toBe('/home?x=1'); + }); + }); + + describe('#normalizeUrlForRouteCultureMatch', () => { + const languages: LanguageInfo[] = [{ cultureName: 'en' }]; + + test('should no-op when useRouteBasedCulture is false', () => { + expect(normalizeUrlForRouteCultureMatch('/en/identity/users', false, languages)).toBe( + '/en/identity/users', + ); + }); + + test('should strip when enabled', () => { + expect(normalizeUrlForRouteCultureMatch('/en/identity/users', true, languages)).toBe( + '/identity/users', + ); + }); + }); +}); diff --git a/npm/ng-packs/packages/core/src/lib/tests/route-culture-url-matcher.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/route-culture-url-matcher.spec.ts new file mode 100644 index 0000000000..bad77e0aac --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tests/route-culture-url-matcher.spec.ts @@ -0,0 +1,44 @@ +import { UrlSegment } from '@angular/router'; +import { + createRouteCultureUrlMatcher, + isLikelyCultureSegment, +} from '../utils/route-culture-url-matcher'; + +describe('route-culture-url-matcher', () => { + describe('#isLikelyCultureSegment', () => { + test.each` + segment | expected + ${''} | ${false} + ${'en'} | ${true} + ${'tr'} | ${true} + ${'zh-Hans'} | ${true} + ${'pt-BR'} | ${true} + ${'home'} | ${false} + ${'identity'} | ${false} + ${'cms-kit'} | ${false} + ${'account'} | ${false} + `('should return $expected when segment is $segment', ({ segment, expected }) => { + expect(isLikelyCultureSegment(segment)).toBe(expected); + }); + }); + + describe('#createRouteCultureUrlMatcher', () => { + const matcher = createRouteCultureUrlMatcher(); + + test('should consume first segment when it is a culture code', () => { + const segments = [new UrlSegment('en', {}), new UrlSegment('home', {})]; + const result = matcher(segments, null as any, {} as any); + expect(result?.consumed).toEqual([segments[0]]); + expect(result?.posParams?.culture).toBe(segments[0]); + }); + + test('should return null when first segment is not a culture code', () => { + const segments = [new UrlSegment('identity', {})]; + expect(matcher(segments, null as any, {} as any)).toBeNull(); + }); + + test('should return null when there are no segments', () => { + expect(matcher([], null as any, {} as any)).toBeNull(); + }); + }); +}); diff --git a/npm/ng-packs/packages/core/src/lib/utils/index.ts b/npm/ng-packs/packages/core/src/lib/utils/index.ts index 9b542ec5b4..2a03a36c4e 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/index.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/index.ts @@ -15,6 +15,8 @@ export * from './multi-tenancy-utils'; export * from './number-utils'; export * from './object-utils'; export * from './queue'; +export * from './route-based-culture.utils'; +export * from './route-culture-url-matcher'; export * from './route-utils'; export * from './string-utils'; export * from './tree-utils'; diff --git a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts index 414f4d0a31..1534648a72 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts @@ -1,4 +1,4 @@ -import { registerLocaleData } from '@angular/common'; +import { Location, registerLocaleData } from '@angular/common'; import { inject, Injector } from '@angular/core'; import { tap, catchError } from 'rxjs/operators'; import { firstValueFrom, lastValueFrom, of, throwError, timeout } from 'rxjs'; @@ -7,6 +7,7 @@ import { Environment } from '../models/environment'; import { CurrentTenantDto } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models'; import { ConfigStateService } from '../services/config-state.service'; import { EnvironmentService } from '../services/environment.service'; +import { RouteBasedCultureService } from '../services/route-based-culture.service'; import { SessionStateService } from '../services/session-state.service'; import { CORE_OPTIONS } from '../tokens/options.token'; import { APP_INIT_ERROR_HANDLERS } from '../tokens/app-config.token'; @@ -63,6 +64,9 @@ export async function getInitialData() { await lastValueFrom(result$); } + const routeBasedCulture = injector.get(RouteBasedCultureService); + routeBasedCulture.syncLanguageFromUrl(injector.get(Location).path()); + await localeInitializer(injector); } diff --git a/npm/ng-packs/packages/core/src/lib/utils/route-based-culture.utils.ts b/npm/ng-packs/packages/core/src/lib/utils/route-based-culture.utils.ts new file mode 100644 index 0000000000..3c0f92b357 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/utils/route-based-culture.utils.ts @@ -0,0 +1,82 @@ +import type { LanguageInfo } from '../proxy/volo/abp/localization/models'; + +/** + * Returns the first path segment of a URL path (leading slashes are ignored). + * Strips query string and fragment first (e.g. "/zh-Hans/account?x=1" โ†’ "zh-Hans"). + */ +export function getFirstPathSegment(urlPath: string): string { + if (!urlPath) { + return ''; + } + + const suffixIndex = urlPath.search(/[?#]/); + const pathPart = suffixIndex >= 0 ? urlPath.slice(0, suffixIndex) : urlPath; + const segments = pathPart.split('/').filter(s => s.length > 0); + + return segments[0] ?? ''; +} + +/** + * If the first segment matches a configured language culture name (case-insensitive), + * returns the canonical culture name from configuration; otherwise undefined. + */ +export function findMatchingCultureName( + firstSegment: string, + languages: LanguageInfo[] | undefined, +): string | undefined { + if (!firstSegment || !languages?.length) { + return undefined; + } + + const normalized = firstSegment.toLowerCase(); + const match = languages.find( + lang => lang.cultureName && lang.cultureName.toLowerCase() === normalized, + ); + + return match?.cultureName; +} + +/** + * Removes the first path segment when it matches a configured UI culture (e.g. `/en/identity/users` โ†’ `/identity/users`). + * Use when comparing the **browser URL** to **menu links** that omit the culture segment. + */ +export function stripCultureSegmentFromPath( + path: string, + languages: LanguageInfo[] | undefined, +): string { + if (!path || !languages?.length) { + return path; + } + + const pathEnd = path.search(/[?#]/); + const pathOnly = pathEnd >= 0 ? path.slice(0, pathEnd) : path; + const suffix = pathEnd >= 0 ? path.slice(pathEnd) : ''; + + const first = getFirstPathSegment(pathOnly); + if (!first || !findMatchingCultureName(first, languages)) { + return path; + } + + const segments = pathOnly.split('/').filter(s => s.length > 0); + if (segments.length === 0) { + return path; + } + + const rest = segments.slice(1); + const normalized = rest.length ? '/' + rest.join('/') : '/'; + return normalized + suffix; +} + +/** + * When route-based culture is enabled, normalizes URLs for comparison with menu routes that do not include a culture prefix. + */ +export function normalizeUrlForRouteCultureMatch( + path: string, + useRouteBasedCulture: boolean, + languages: LanguageInfo[] | undefined, +): string { + if (!useRouteBasedCulture || !path) { + return path; + } + return stripCultureSegmentFromPath(path, languages); +} diff --git a/npm/ng-packs/packages/core/src/lib/utils/route-culture-url-matcher.ts b/npm/ng-packs/packages/core/src/lib/utils/route-culture-url-matcher.ts new file mode 100644 index 0000000000..0093c5cb67 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/utils/route-culture-url-matcher.ts @@ -0,0 +1,59 @@ +import { Route, Routes, UrlMatchResult, UrlSegment, UrlSegmentGroup } from '@angular/router'; + +/** + * Heuristic: first path segment looks like a BCP 47-style culture code (e.g. en, tr, zh-Hans, pt-BR). + * Used by the optional culture URL matcher so real routes like `identity` or `cms-kit` are not mistaken for cultures. + */ +export function isLikelyCultureSegment(segment: string): boolean { + if (!segment) { + return false; + } + + return /^[a-z]{2}(-[a-zA-Z0-9]{2,8})?$/.test(segment); +} + +/** + * Matcher that consumes the first segment when it looks like a culture code. + * Exposes it as the route param `culture` on matched routes. + */ +export function createRouteCultureUrlMatcher(): ( + segments: UrlSegment[], + group: UrlSegmentGroup, + route: Route, +) => UrlMatchResult | null { + return (segments: UrlSegment[]) => { + if (segments.length < 1) { + return null; + } + + const first = segments[0].path; + if (!isLikelyCultureSegment(first)) { + return null; + } + + return { + consumed: [segments[0]], + posParams: { culture: segments[0] }, + }; + }; +} + +/** + * Wraps your app routes so the same URLs work with or without a leading culture segment. + * + * Examples (same components for both shapes): + * - `/` and `/en` + * - `/home` and `/en/home` + * - `/identity/users` and `/en/identity/users` + * + * The culture segment is matched only when it passes {@link isLikelyCultureSegment} (e.g. `en`, `tr-TR`, `zh-Hans`). + * Session language from the URL is still applied only when `localization.useRouteBasedCulture` is true (`RouteBasedCultureService`). + */ +export function withOptionalRouteCulturePrefix(routes: Routes): Routes { + const matcher = createRouteCultureUrlMatcher(); + + return [ + { matcher, children: [...routes] }, + { path: '', children: [...routes] }, + ]; +} diff --git a/npm/ng-packs/packages/feature-management/package.json b/npm/ng-packs/packages/feature-management/package.json index 10c828d24a..0e8eeebbff 100644 --- a/npm/ng-packs/packages/feature-management/package.json +++ b/npm/ng-packs/packages/feature-management/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.feature-management", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "peerDependencies": { diff --git a/npm/ng-packs/packages/generators/package.json b/npm/ng-packs/packages/generators/package.json index 7c90010ca2..dbb4815044 100644 --- a/npm/ng-packs/packages/generators/package.json +++ b/npm/ng-packs/packages/generators/package.json @@ -1,6 +1,6 @@ { "name": "@abp/nx.generators", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "generators": "./generators.json", "type": "commonjs", diff --git a/npm/ng-packs/packages/identity/package.json b/npm/ng-packs/packages/identity/package.json index 390b4e8c9a..10f02845fb 100644 --- a/npm/ng-packs/packages/identity/package.json +++ b/npm/ng-packs/packages/identity/package.json @@ -1,15 +1,15 @@ { "name": "@abp/ng.identity", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.components": "~10.2.0-rc.3", - "@abp/ng.permission-management": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.components": "~10.3.0-rc.1", + "@abp/ng.permission-management": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/oauth/package.json b/npm/ng-packs/packages/oauth/package.json index b300586b42..7839f8ae15 100644 --- a/npm/ng-packs/packages/oauth/package.json +++ b/npm/ng-packs/packages/oauth/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.oauth", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.core": "~10.2.0-rc.3", - "@abp/utils": "~10.2.0-rc.3", + "@abp/ng.core": "~10.3.0-rc.1", + "@abp/utils": "~10.3.0-rc.1", "angular-oauth2-oidc": "^20.0.0", "just-clone": "^6.0.0", "just-compare": "^2.0.0", diff --git a/npm/ng-packs/packages/permission-management/package.json b/npm/ng-packs/packages/permission-management/package.json index cebef34556..a543261215 100644 --- a/npm/ng-packs/packages/permission-management/package.json +++ b/npm/ng-packs/packages/permission-management/package.json @@ -1,13 +1,13 @@ { "name": "@abp/ng.permission-management", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "peerDependencies": { diff --git a/npm/ng-packs/packages/schematics/package.json b/npm/ng-packs/packages/schematics/package.json index 8a1d8af6e4..57fa2ed133 100644 --- a/npm/ng-packs/packages/schematics/package.json +++ b/npm/ng-packs/packages/schematics/package.json @@ -1,6 +1,6 @@ { "name": "@abp/ng.schematics", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "author": "", "schematics": "./collection.json", "dependencies": { diff --git a/npm/ng-packs/packages/setting-management/package.json b/npm/ng-packs/packages/setting-management/package.json index e10ebccc0e..9a9255e9e8 100644 --- a/npm/ng-packs/packages/setting-management/package.json +++ b/npm/ng-packs/packages/setting-management/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.setting-management", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.components": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.components": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "peerDependencies": { diff --git a/npm/ng-packs/packages/tenant-management/package.json b/npm/ng-packs/packages/tenant-management/package.json index 5ff1d1445d..c0de3d0b5f 100644 --- a/npm/ng-packs/packages/tenant-management/package.json +++ b/npm/ng-packs/packages/tenant-management/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.tenant-management", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.feature-management": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.feature-management": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/theme-basic/package.json b/npm/ng-packs/packages/theme-basic/package.json index 58414b0a95..bfdbcac85e 100644 --- a/npm/ng-packs/packages/theme-basic/package.json +++ b/npm/ng-packs/packages/theme-basic/package.json @@ -1,14 +1,14 @@ { "name": "@abp/ng.theme.basic", - "version": "10.2.0-rc.3", + "version": "10.3.0-rc.1", "homepage": "https://abp.io", "repository": { "type": "git", "url": "https://github.com/abpframework/abp.git" }, "dependencies": { - "@abp/ng.account.core": "~10.2.0-rc.3", - "@abp/ng.theme.shared": "~10.2.0-rc.3", + "@abp/ng.account.core": "~10.3.0-rc.1", + "@abp/ng.theme.shared": "~10.3.0-rc.1", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html index afc498d5ac..e6475affa1 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.html @@ -6,7 +6,7 @@