diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 62e682eb08..0c8eb39335 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,18 +48,18 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Setup .NET SDKs - uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 + uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0 with: dotnet-version: | 6.0.x 8.0.x - name: Setup .NET SDK - uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 + uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0 id: setup-dotnet - name: Setup NuGet cache - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1 with: path: ~/.nuget/packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props') }} @@ -72,21 +72,21 @@ jobs: - name: Upload Coverage Reports if: always() - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: coverage-${{ runner.os }} path: ./artifacts/coverage if-no-files-found: ignore - name: Upload coverage to Codecov - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 + uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 with: files: ./artifacts/coverage/coverage.cobertura.xml flags: ${{ runner.os }} token: ${{ secrets.CODECOV_TOKEN }} - name: Attest artifacts - uses: actions/attest-build-provenance@7668571508540a607bdfd90a87a560489fe372eb # v2.1.0 + uses: actions/attest-build-provenance@520d128f165991a6c774bcb264f323e3d70747f4 # v2.2.0 if: | runner.os == 'Windows' && github.event.repository.fork == false && @@ -95,7 +95,7 @@ jobs: subject-path: ./artifacts/package/release/* - name: Publish NuGet packages - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: packages-${{ runner.os }} path: ./artifacts/package/release @@ -115,12 +115,12 @@ jobs: steps: - name: Download packages - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: name: packages-Windows - name: Setup .NET SDK - uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 + uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0 with: dotnet-version: ${{ needs.build.outputs.dotnet-sdk-version }} @@ -158,12 +158,12 @@ jobs: steps: - name: Download packages - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: name: packages-Windows - name: Setup .NET SDK - uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 + uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0 with: dotnet-version: ${{ needs.build.outputs.dotnet-sdk-version }} @@ -185,12 +185,12 @@ jobs: steps: - name: Download packages - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: name: packages-Windows - name: Setup .NET SDK - uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0 + uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0 with: dotnet-version: ${{ needs.build.outputs.dotnet-sdk-version }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6aa10a3023..9c700a9ed1 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,12 +26,12 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Initialize CodeQL - uses: github/codeql-action/init@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: languages: csharp build-mode: none - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: category: '/language:csharp' diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 40ad817a2e..200ccfd125 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -25,20 +25,20 @@ jobs: persist-credentials: false - name: Run analysis - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: publish_results: true results_file: results.sarif results_format: sarif - name: Upload artifact - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: SARIF path: results.sarif retention-days: 5 - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: sarif_file: results.sarif diff --git a/Directory.Build.props b/Directory.Build.props index 290308ceeb..97479242c0 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -35,7 +35,7 @@ package-readme.md See $(PackageProjectUrl)/releases for details. false - 7.2.0 + 7.3.1 true git $(PackageProjectUrl).git @@ -45,7 +45,7 @@ 8.0.0 false - + preview.$(GITHUB_RUN_NUMBER) pr.$(GITHUB_REF_NAME.Replace('/merge', '')).$(GITHUB_RUN_NUMBER) $(GITHUB_REF.Replace('refs/tags/v', '')) diff --git a/Directory.Packages.props b/Directory.Packages.props index cf36e381e9..d4cd8fa690 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -26,7 +26,7 @@ - + diff --git a/README.md b/README.md index 63c8ea93c9..f5a9cffc6d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Once you have an API that can describe itself in Swagger, you've opened the trea | Swashbuckle Version | ASP.NET Core | Swagger / OpenAPI Spec. | swagger-ui | Redoc UI | |----------|----------|----------|----------|----------| | [CI](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/commits/master/) | >= 2.0.0 | 2.0, 3.0 | [5.x.x](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/package.json#L6) | [2.x.x](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.ReDoc/package.json#L6) | -| [7.2.0](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v7.2.0) | >= 2.0.0 | 2.0, 3.0 | 5.18.2 | 2.2.0 | +| [7.3.1](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v7.2.0) | >= 2.0.0 | 2.0, 3.0 | 5.20.0 | 2.4.0 | | [6.9.0](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v6.9.0) | >= 2.0.0 | 2.0, 3.0 | 5.17.14 | 2.1.5 | | [5.6.3](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v5.6.3) | >= 2.0.0 | 2.0, 3.0 | 3.32.5 | 2.0.0-rc.40 | | [4.0.0](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v4.0.0) | >= 2.0.0, < 3.0.0 | 2.0 | 3.19.5 | 1.22.2 | @@ -565,8 +565,8 @@ To enhance the generated docs with human-friendly descriptions, you can annotate [ProducesResponseType(500)] public Product GetById(int id) ``` - -4. You can also annotate types with summary and example tags: + +4. Annotate your types with summary and example tags, other tags (remarks, para, etc.) are not supported: ```csharp public class Product @@ -582,12 +582,12 @@ To enhance the generated docs with human-friendly descriptions, you can annotate /// /// 10 public int AvailableStock { get; set; } - + /// /// The sizes the product is available in /// /// ["Small", "Medium", "Large"] - public List Sizes { get; set; } + public List Sizes { get; set; } } ``` diff --git a/global.json b/global.json index 5858d94a61..dd3fa91f87 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.102", + "version": "9.0.200", "allowPrerelease": false, "rollForward": "latestMajor" } diff --git a/src/Swashbuckle.AspNetCore.Cli/Program.cs b/src/Swashbuckle.AspNetCore.Cli/Program.cs index 62dfadffb4..5b22a4ff87 100644 --- a/src/Swashbuckle.AspNetCore.Cli/Program.cs +++ b/src/Swashbuckle.AspNetCore.Cli/Program.cs @@ -1,10 +1,12 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.Loader; +using System.Text; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; @@ -41,29 +43,7 @@ public static int Main(string[] args) c.OnRun((namedArgs) => { - if (!File.Exists(namedArgs["startupassembly"])) - { - throw new FileNotFoundException(namedArgs["startupassembly"]); - } - - var depsFile = namedArgs["startupassembly"].Replace(".dll", ".deps.json"); - var runtimeConfig = namedArgs["startupassembly"].Replace(".dll", ".runtimeconfig.json"); - var commandName = args[0]; - - var subProcessArguments = new string[args.Length - 1]; - if (subProcessArguments.Length > 0) - { - Array.Copy(args, 1, subProcessArguments, 0, subProcessArguments.Length); - } - - var subProcessCommandLine = string.Format( - "exec --depsfile {0} --runtimeconfig {1} {2} _{3} {4}", // note the underscore prepended to the command name - EscapePath(depsFile), - EscapePath(runtimeConfig), - EscapePath(typeof(Program).GetTypeInfo().Assembly.Location), - commandName, - string.Join(" ", subProcessArguments.Select(x => EscapePath(x))) - ); + string subProcessCommandLine = PrepareCommandLine(args, namedArgs); var subProcess = Process.Start("dotnet", subProcessCommandLine); @@ -84,16 +64,7 @@ public static int Main(string[] args) c.Option("--yaml", "", true); c.OnRun((namedArgs) => { - // 1) Configure host with provided startupassembly - var startupAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath( - Path.Combine(Directory.GetCurrentDirectory(), namedArgs["startupassembly"])); - - // 2) Build a service container that's based on the startup assembly - var serviceProvider = GetServiceProvider(startupAssembly); - - // 3) Retrieve Swagger via configured provider - var swaggerProvider = serviceProvider.GetRequiredService(); - var swaggerOptions = serviceProvider.GetService>(); + SetupAndRetrieveSwaggerProviderAndOptions(namedArgs, out var swaggerProvider, out var swaggerOptions); var swaggerDocumentSerializer = swaggerOptions?.Value?.CustomDocumentSerializer; var swagger = swaggerProvider.GetSwagger( namedArgs["swaggerdoc"], @@ -156,9 +127,110 @@ public static int Main(string[] args) }); }); + // > dotnet swagger list + runner.SubCommand("list", "retrieves the list of Swagger document names from a startup assembly", c => + { + c.Argument("startupassembly", "relative path to the application's startup assembly"); + c.Option("--output", "relative path where the document names will be output, defaults to stdout"); + c.OnRun((namedArgs) => + { + string subProcessCommandLine = PrepareCommandLine(args, namedArgs); + + var subProcess = Process.Start("dotnet", subProcessCommandLine); + + subProcess.WaitForExit(); + return subProcess.ExitCode; + }); + }); + + // > dotnet swagger _list ... (* should only be invoked via "dotnet exec") + runner.SubCommand("_list", "", c => + { + c.Argument("startupassembly", ""); + c.Option("--output", ""); + c.OnRun((namedArgs) => + { + SetupAndRetrieveSwaggerProviderAndOptions(namedArgs, out var swaggerProvider, out var swaggerOptions); + IList docNames = new List(); + + string outputPath = namedArgs.TryGetValue("--output", out var arg1) + ? Path.Combine(Directory.GetCurrentDirectory(), arg1) + : null; + bool outputViaConsole = outputPath == null; + if (!string.IsNullOrEmpty(outputPath)) + { + string directoryPath = Path.GetDirectoryName(outputPath); + if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + } + + using Stream stream = outputViaConsole ? Console.OpenStandardOutput() : File.Create(outputPath); + using StreamWriter writer = new(stream, outputViaConsole ? Console.OutputEncoding : Encoding.UTF8); + + if (swaggerProvider is not ISwaggerDocumentMetadataProvider docMetaProvider) + { + writer.WriteLine($"The registered {nameof(ISwaggerProvider)} instance does not implement {nameof(ISwaggerDocumentMetadataProvider)}; unable to list the Swagger document names."); + return -1; + } + + docNames = docMetaProvider.GetDocumentNames(); + + foreach (var name in docNames) + { + writer.WriteLine($"\"{name}\""); + } + + return 0; + }); + }); + return runner.Run(args); } + private static void SetupAndRetrieveSwaggerProviderAndOptions(System.Collections.Generic.IDictionary namedArgs, out ISwaggerProvider swaggerProvider, out IOptions swaggerOptions) + { + // 1) Configure host with provided startupassembly + var startupAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath( + Path.Combine(Directory.GetCurrentDirectory(), namedArgs["startupassembly"])); + + // 2) Build a service container that's based on the startup assembly + var serviceProvider = GetServiceProvider(startupAssembly); + + // 3) Retrieve Swagger via configured provider + swaggerProvider = serviceProvider.GetRequiredService(); + swaggerOptions = serviceProvider.GetService>(); + } + + private static string PrepareCommandLine(string[] args, System.Collections.Generic.IDictionary namedArgs) + { + if (!File.Exists(namedArgs["startupassembly"])) + { + throw new FileNotFoundException(namedArgs["startupassembly"]); + } + + var depsFile = namedArgs["startupassembly"].Replace(".dll", ".deps.json"); + var runtimeConfig = namedArgs["startupassembly"].Replace(".dll", ".runtimeconfig.json"); + var commandName = args[0]; + + var subProcessArguments = new string[args.Length - 1]; + if (subProcessArguments.Length > 0) + { + Array.Copy(args, 1, subProcessArguments, 0, subProcessArguments.Length); + } + + var subProcessCommandLine = string.Format( + "exec --depsfile {0} --runtimeconfig {1} {2} _{3} {4}", // note the underscore prepended to the command name + EscapePath(depsFile), + EscapePath(runtimeConfig), + EscapePath(typeof(Program).GetTypeInfo().Assembly.Location), + commandName, + string.Join(" ", subProcessArguments.Select(x => EscapePath(x))) + ); + return subProcessCommandLine; + } + private static string EscapePath(string path) { return path.Contains(' ') diff --git a/src/Swashbuckle.AspNetCore.ReDoc/package-lock.json b/src/Swashbuckle.AspNetCore.ReDoc/package-lock.json index 9a5f9798ee..67ec1c6862 100644 --- a/src/Swashbuckle.AspNetCore.ReDoc/package-lock.json +++ b/src/Swashbuckle.AspNetCore.ReDoc/package-lock.json @@ -8,7 +8,7 @@ "name": "swashbuckle", "version": "1.0.0", "dependencies": { - "redoc": "2.2.0" + "redoc": "2.4.0" } }, "node_modules/@babel/runtime": { @@ -23,24 +23,6 @@ "node": ">=6.9.0" } }, - "node_modules/@cfaester/enzyme-adapter-react-18": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cfaester/enzyme-adapter-react-18/-/enzyme-adapter-react-18-0.8.0.tgz", - "integrity": "sha512-3Z3ThTUouHwz8oIyhTYQljEMNRFtlVyc3VOOHCbxs47U6cnXs8K9ygi/c1tv49s7MBlTXeIcuN+Ttd9aPtILFQ==", - "license": "MIT", - "dependencies": { - "enzyme-shallow-equal": "^1.0.0", - "function.prototype.name": "^1.1.6", - "has": "^1.0.4", - "react-is": "^18.2.0", - "react-shallow-renderer": "^16.15.0" - }, - "peerDependencies": { - "enzyme": "^3.11.0", - "react": ">=18", - "react-dom": ">=18" - } - }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", @@ -129,6 +111,13 @@ "license": "MIT", "peer": true }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/agent-base": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", @@ -171,112 +160,12 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.filter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.4.tgz", - "integrity": "sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-array-method-boxes-properly": "^1.0.0", - "es-object-atoms": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC", - "peer": true - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -286,25 +175,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/call-me-maybe": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", @@ -321,50 +191,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cheerio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", - "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", - "license": "MIT", - "peer": true, - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", - "whatwg-mimetype": "^4.0.0" - }, - "engines": { - "node": ">=18.17" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -387,1055 +213,190 @@ }, "node_modules/clsx": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "license": "MIT" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT", - "peer": true - }, - "node_modules/core-js": { - "version": "3.39.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", - "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "license": "ISC", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-to-react-native": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", - "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT", - "peer": true - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decko": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", - "integrity": "sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/discontinuous-range": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", - "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", - "license": "MIT", - "peer": true - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause", - "peer": true - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/dompurify": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.0.tgz", - "integrity": "sha512-AMdOzK44oFWqHEi0wpOqix/fUNY707OmoeFDnbi3Q5I8uOpy21ufUA5cDJPr0bosxrflOVD/H2DMSvuGKJGfmQ==", - "license": "(MPL-2.0 OR Apache-2.0)" - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/encoding-sniffer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", - "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", - "license": "MIT", - "peer": true, - "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/enzyme": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", - "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", - "license": "MIT", - "peer": true, - "dependencies": { - "array.prototype.flat": "^1.2.3", - "cheerio": "^1.0.0-rc.3", - "enzyme-shallow-equal": "^1.0.1", - "function.prototype.name": "^1.1.2", - "has": "^1.0.3", - "html-element-map": "^1.2.0", - "is-boolean-object": "^1.0.1", - "is-callable": "^1.1.5", - "is-number-object": "^1.0.4", - "is-regex": "^1.0.5", - "is-string": "^1.0.5", - "is-subset": "^0.1.1", - "lodash.escape": "^4.0.1", - "lodash.isequal": "^4.5.0", - "object-inspect": "^1.7.0", - "object-is": "^1.0.2", - "object.assign": "^4.1.0", - "object.entries": "^1.1.1", - "object.values": "^1.1.1", - "raf": "^3.4.1", - "rst-selector-parser": "^2.2.3", - "string.prototype.trim": "^1.2.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/enzyme-shallow-equal": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.7.tgz", - "integrity": "sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0", - "object-is": "^1.1.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-abstract": { - "version": "1.23.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.4.tgz", - "integrity": "sha512-HR1gxH5OaiN7XH7uiWH0RLw0RcFySiSoW1ctxmD1ahTw3uGBtkmm/ng0tDU1OtYx5OK6EOL5Y6O21cDflG3Jcg==", - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.3", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "license": "MIT", - "peer": true - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "license": "MIT", - "peer": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "license": "MIT" - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "license": "MIT" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreach": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", - "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", - "license": "MIT" - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-element-map": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.1.tgz", - "integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==", - "license": "MIT", - "peer": true, - "dependencies": { - "array.prototype.filter": "^1.0.0", - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "node_modules/http2-client": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", - "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", - "license": "MIT" - }, - "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "peer": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=7.0.0" } }, - "node_modules/is-regex": { + "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, + "peer": true, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "peer": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", "license": "MIT", + "peer": true, "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" } }, - "node_modules/is-subset": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", - "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==", + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT", "peer": true }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "ms": "^2.1.3" }, "engines": { - "node": ">= 0.4" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decko": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", + "integrity": "sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==" + }, + "node_modules/dompurify": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz", + "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/foreach": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", + "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", + "license": "MIT" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/http2-client": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", + "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "agent-base": "^7.0.2", + "debug": "4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 14" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "license": "MIT" + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } }, "node_modules/js-levenshtein": { "version": "1.1.6", @@ -1479,20 +440,6 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, - "node_modules/lodash.escape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", - "integrity": "sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "license": "MIT", - "peer": true - }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -1608,13 +555,6 @@ } } }, - "node_modules/moo": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", - "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", - "license": "BSD-3-Clause", - "peer": true - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -1640,29 +580,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nearley": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", - "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "commander": "^2.19.0", - "moo": "^0.5.0", - "railroad-diagrams": "^1.0.0", - "randexp": "0.4.6" - }, - "bin": { - "nearley-railroad": "bin/nearley-railroad.js", - "nearley-test": "bin/nearley-test.js", - "nearley-unparse": "bin/nearley-unparse.js", - "nearleyc": "bin/nearleyc.js" - }, - "funding": { - "type": "individual", - "url": "https://nearley.js.org/#give-to-nearley" - } - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -1704,19 +621,6 @@ "es6-promise": "^3.2.1" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "node_modules/oas-kit-common": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", @@ -1763,125 +667,37 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", - "license": "BSD-3-Clause", - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/oas-validator": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", - "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", - "license": "BSD-3-Clause", - "dependencies": { - "call-me-maybe": "^1.0.1", - "oas-kit-common": "^1.0.8", - "oas-linter": "^3.2.2", - "oas-resolver": "^2.5.6", - "oas-schema-walker": "^1.1.5", - "reftools": "^1.1.9", - "should": "^13.2.1", - "yaml": "^1.10.0" - }, - "funding": { - "url": "https://github.com/Mermade/oas-kit?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, + "license": "BSD-3-Clause", "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, - "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "license": "MIT", - "peer": true, + "node_modules/oas-validator": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", + "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", + "license": "BSD-3-Clause", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "call-me-maybe": "^1.0.1", + "oas-kit-common": "^1.0.8", + "oas-linter": "^3.2.2", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "reftools": "^1.1.9", + "should": "^13.2.1", + "yaml": "^1.10.0" }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, "node_modules/openapi-sampler": { @@ -1894,46 +710,6 @@ "json-pointer": "0.6.2" } }, - "node_modules/parse5": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", - "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "entities": "^4.5.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "peer": true, - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "license": "MIT", - "peer": true, - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -1946,13 +722,6 @@ "integrity": "sha512-rixgxw3SxyJbCaSpo1n35A/fwI1r2rdwMKOTCg/AcG+xOEyZcE8UHVjpZMFCVImzsFoCZeJTT+M/rdEIQYO2nw==", "license": "MIT" }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "license": "MIT", - "peer": true - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -1981,15 +750,6 @@ "node": ">=10" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/postcss": { "version": "8.4.38", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", @@ -2052,37 +812,6 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "license": "MIT", - "peer": true, - "dependencies": { - "performance-now": "^2.1.0" - } - }, - "node_modules/railroad-diagrams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", - "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", - "license": "CC0-1.0", - "peer": true - }, - "node_modules/randexp": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", - "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "discontinuous-range": "1.0.0", - "ret": "~0.1.10" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -2110,25 +839,6 @@ "react": "^18.3.1" } }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, - "node_modules/react-shallow-renderer": { - "version": "16.15.0", - "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", - "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", - "license": "MIT", - "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-tabs": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.0.2.tgz", @@ -2143,12 +853,11 @@ } }, "node_modules/redoc": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.2.0.tgz", - "integrity": "sha512-52rz/xJtpUBc3Y/GAkaX03czKhQXTxoU7WnkXNzRLuGwiGb/iEO4OgwcgQqtwHWrYNaZXTyqZ4MAVXpi/e1gAg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.4.0.tgz", + "integrity": "sha512-rFlfzFVWS9XJ6aYAs/bHnLhHP5FQEhwAHDBVgwb9L2FqDQ8Hu8rQ1G84iwaWXxZfPP9UWn7JdWkxI6MXr2ZDjw==", "license": "MIT", "dependencies": { - "@cfaester/enzyme-adapter-react-18": "^0.8.0", "@redocly/openapi-core": "^1.4.0", "classnames": "^2.3.2", "decko": "^1.2.0", @@ -2178,8 +887,8 @@ "peerDependencies": { "core-js": "^3.1.4", "mobx": "^6.0.4", - "react": "^16.8.4 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0", + "react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "styled-components": "^4.1.1 || ^5.1.1 || ^6.0.5" } }, @@ -2198,24 +907,6 @@ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "license": "MIT" }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2234,69 +925,6 @@ "node": ">=0.10.0" } }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/rst-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", - "integrity": "sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "lodash.flattendeep": "^4.4.0", - "nearley": "^2.7.10" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT", - "peer": true - }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -2307,38 +935,6 @@ "loose-envify": "^1.1.0" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -2400,24 +996,6 @@ "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", "license": "MIT" }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/slugify": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz", @@ -2456,55 +1034,6 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -2593,104 +1122,6 @@ "license": "0BSD", "peer": true }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", - "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18.17" - } - }, "node_modules/uri-js-replace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz", @@ -2718,29 +1149,6 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - } - }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -2751,41 +1159,6 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "license": "MIT", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/src/Swashbuckle.AspNetCore.ReDoc/package.json b/src/Swashbuckle.AspNetCore.ReDoc/package.json index dad4347995..81e0a67f7d 100644 --- a/src/Swashbuckle.AspNetCore.ReDoc/package.json +++ b/src/Swashbuckle.AspNetCore.ReDoc/package.json @@ -3,6 +3,6 @@ "version": "1.0.0", "private": true, "dependencies": { - "redoc": "2.2.0" + "redoc": "2.4.0" } } diff --git a/src/Swashbuckle.AspNetCore.Swagger/ISwaggerDocumentMetadataProvider.cs b/src/Swashbuckle.AspNetCore.Swagger/ISwaggerDocumentMetadataProvider.cs new file mode 100644 index 0000000000..60692cac42 --- /dev/null +++ b/src/Swashbuckle.AspNetCore.Swagger/ISwaggerDocumentMetadataProvider.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Swashbuckle.AspNetCore.Swagger +{ + public interface ISwaggerDocumentMetadataProvider + { + IList GetDocumentNames(); + } +} diff --git a/src/Swashbuckle.AspNetCore.Swagger/ISwaggerProvider.cs b/src/Swashbuckle.AspNetCore.Swagger/ISwaggerProvider.cs index eaba415b72..15fb8f9306 100644 --- a/src/Swashbuckle.AspNetCore.Swagger/ISwaggerProvider.cs +++ b/src/Swashbuckle.AspNetCore.Swagger/ISwaggerProvider.cs @@ -21,4 +21,4 @@ public UnknownSwaggerDocument(string documentName, IEnumerable knownDocu string.Join(",", knownDocuments?.Select(x => $"\"{x}\"")))) {} } -} \ No newline at end of file +} diff --git a/src/Swashbuckle.AspNetCore.Swagger/PublicAPI/PublicAPI.Unshipped.txt b/src/Swashbuckle.AspNetCore.Swagger/PublicAPI/PublicAPI.Unshipped.txt index e69de29bb2..97812dd87b 100644 --- a/src/Swashbuckle.AspNetCore.Swagger/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Swashbuckle.AspNetCore.Swagger/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Swashbuckle.AspNetCore.Swagger.ISwaggerDocumentMetadataProvider +Swashbuckle.AspNetCore.Swagger.ISwaggerDocumentMetadataProvider.GetDocumentNames() -> System.Collections.Generic.IList diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs index f30fc03ae8..3e405fd6d1 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/ConfigureSwaggerGeneratorOptions.cs @@ -117,6 +117,7 @@ public void DeepCopy(SwaggerGeneratorOptions source, SwaggerGeneratorOptions tar target.RequestBodyAsyncFilters = new List(source.RequestBodyAsyncFilters); target.SecuritySchemesSelector = source.SecuritySchemesSelector; target.PathGroupSelector = source.PathGroupSelector; + target.XmlCommentEndOfLine = source.XmlCommentEndOfLine; } private TFilter GetOrCreateFilter(FilterDescriptor filterDescriptor) diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs index 65ffc38307..c11436491d 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenOptionsExtensions.cs @@ -706,10 +706,10 @@ public static void IncludeXmlComments( var xmlDoc = xmlDocFactory(); var xmlDocMembers = XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc); - swaggerGenOptions.AddParameterFilterInstance(new XmlCommentsParameterFilter(xmlDocMembers)); - swaggerGenOptions.AddRequestBodyFilterInstance(new XmlCommentsRequestBodyFilter(xmlDocMembers)); - swaggerGenOptions.AddOperationFilterInstance(new XmlCommentsOperationFilter(xmlDocMembers)); - swaggerGenOptions.AddSchemaFilterInstance(new XmlCommentsSchemaFilter(xmlDocMembers)); + swaggerGenOptions.AddParameterFilterInstance(new XmlCommentsParameterFilter(xmlDocMembers, swaggerGenOptions.SwaggerGeneratorOptions)); + swaggerGenOptions.AddRequestBodyFilterInstance(new XmlCommentsRequestBodyFilter(xmlDocMembers, swaggerGenOptions.SwaggerGeneratorOptions)); + swaggerGenOptions.AddOperationFilterInstance(new XmlCommentsOperationFilter(xmlDocMembers, swaggerGenOptions.SwaggerGeneratorOptions)); + swaggerGenOptions.AddSchemaFilterInstance(new XmlCommentsSchemaFilter(xmlDocMembers, swaggerGenOptions.SwaggerGeneratorOptions)); if (includeControllerXmlComments) swaggerGenOptions.AddDocumentFilterInstance(new XmlCommentsDocumentFilter(xmlDocMembers, swaggerGenOptions.SwaggerGeneratorOptions)); diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/PublicAPI/PublicAPI.Unshipped.txt b/src/Swashbuckle.AspNetCore.SwaggerGen/PublicAPI/PublicAPI.Unshipped.txt index 57462c2db8..9103c715aa 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,5 @@ static Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory.CreateFromJson(string json, System.Text.Json.JsonSerializerOptions options) -> Microsoft.OpenApi.Any.IOpenApiAny +static Swashbuckle.AspNetCore.SwaggerGen.XmlCommentsTextHelper.Humanize(string text, string xmlCommentEndOfLine) -> string +Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetDocumentNames() -> System.Collections.Generic.IList +Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorOptions.XmlCommentEndOfLine.get -> string +Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorOptions.XmlCommentEndOfLine.set -> void diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs index 3e2a6404aa..1539afaea1 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/JsonSerializerDataContractResolver.cs @@ -142,6 +142,12 @@ public bool IsSupportedCollection(Type type, out Type itemType) } #endif + if (type.IsArray) + { + itemType = type.GetElementType(); + return true; + } + if (typeof(IEnumerable).IsAssignableFrom(type)) { itemType = typeof(object); diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs index 7d6c79ec1f..8e5a39ad42 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs @@ -10,9 +10,9 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.Extensions.Options; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; -using Microsoft.Extensions.Options; namespace Swashbuckle.AspNetCore.SwaggerGen { @@ -20,21 +20,22 @@ public class SchemaGenerator : ISchemaGenerator { private readonly SchemaGeneratorOptions _generatorOptions; private readonly ISerializerDataContractResolver _serializerDataContractResolver; - private readonly IOptions _mvcOptions; - public SchemaGenerator(SchemaGeneratorOptions generatorOptions, ISerializerDataContractResolver serializerDataContractResolver) - : this(generatorOptions, serializerDataContractResolver, null) + public SchemaGenerator( + SchemaGeneratorOptions generatorOptions, + ISerializerDataContractResolver serializerDataContractResolver) { + _generatorOptions = generatorOptions; + _serializerDataContractResolver = serializerDataContractResolver; } + [Obsolete($"{nameof(IOptions)} is no longer used. This constructor will be removed in a future major release.")] public SchemaGenerator( SchemaGeneratorOptions generatorOptions, ISerializerDataContractResolver serializerDataContractResolver, IOptions mvcOptions) + : this(generatorOptions, serializerDataContractResolver) { - _generatorOptions = generatorOptions; - _serializerDataContractResolver = serializerDataContractResolver; - _mvcOptions = mvcOptions; } public OpenApiSchema GenerateSchema( @@ -367,15 +368,13 @@ private OpenApiSchema CreateDictionarySchema(DataContract dataContract, SchemaRe AdditionalPropertiesAllowed = false }; } - else + + return new OpenApiSchema { - return new OpenApiSchema - { - Type = "object", - AdditionalPropertiesAllowed = true, - AdditionalProperties = GenerateSchema(dataContract.DictionaryValueType, schemaRepository) - }; - } + Type = "object", + AdditionalPropertiesAllowed = true, + AdditionalProperties = GenerateSchema(dataContract.DictionaryValueType, schemaRepository) + }; } private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaRepository schemaRepository) @@ -440,9 +439,6 @@ private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaReposi : GenerateSchemaForType(dataProperty.MemberType, schemaRepository); var markNonNullableTypeAsRequired = _generatorOptions.NonNullableReferenceTypesAsRequired -#if !NETSTANDARD2_0 - && (!_mvcOptions?.Value.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes ?? true) -#endif && (dataProperty.MemberInfo?.IsNonNullableReferenceType() ?? false); if (( diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs index e18b0139d5..2125075e23 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs @@ -20,7 +20,7 @@ namespace Swashbuckle.AspNetCore.SwaggerGen { - public class SwaggerGenerator : ISwaggerProvider, IAsyncSwaggerProvider + public class SwaggerGenerator : ISwaggerProvider, IAsyncSwaggerProvider, ISwaggerDocumentMetadataProvider { private readonly IApiDescriptionGroupCollectionProvider _apiDescriptionsProvider; private readonly ISchemaGenerator _schemaGenerator; @@ -112,6 +112,8 @@ public OpenApiDocument GetSwagger(string documentName, string host = null, strin } } + public IList GetDocumentNames() => _options.SwaggerDocs.Keys.ToList(); + private void SortSchemas(OpenApiDocument document) { document.Components.Schemas = new SortedDictionary(document.Components.Schemas, _options.SchemaComparer); @@ -602,10 +604,19 @@ private OpenApiParameter GenerateParameterWithoutFilter( In = location, Required = isRequired, Schema = schema, - Description = description + Description = description, + Style = GetParameterStyle(type, apiParameter.Source) }; } + private static ParameterStyle? GetParameterStyle(Type type, BindingSource source) + { + return source == BindingSource.Query && type?.IsGenericType == true && + typeof(IEnumerable>).IsAssignableFrom(type) + ? ParameterStyle.DeepObject + : null; + } + private (OpenApiParameter, ParameterFilterContext) GenerateParameterAndContext( ApiParameterDescription apiParameter, SchemaRepository schemaRepository) diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGeneratorOptions.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGeneratorOptions.cs index 0acde836f9..7d649c2c70 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGeneratorOptions.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGeneratorOptions.cs @@ -82,6 +82,8 @@ public SwaggerGeneratorOptions() public IList DocumentAsyncFilters { get; set; } + public string XmlCommentEndOfLine { get; set; } + private bool DefaultDocInclusionPredicate(string documentName, ApiDescription apiDescription) { return apiDescription.GroupName == null || apiDescription.GroupName == documentName; diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsDocumentFilter.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsDocumentFilter.cs index 0c2cbabcf6..8f06af7f92 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsDocumentFilter.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsDocumentFilter.cs @@ -55,7 +55,7 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) swaggerDoc.Tags.Add(new OpenApiTag { Name = nameAndType.Key, - Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml) + Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml, _options?.XmlCommentEndOfLine) }); } } diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsOperationFilter.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsOperationFilter.cs index cf18c61ea7..8bfcce7951 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsOperationFilter.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsOperationFilter.cs @@ -1,4 +1,5 @@ -using Microsoft.OpenApi.Models; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.Reflection; @@ -9,14 +10,17 @@ namespace Swashbuckle.AspNetCore.SwaggerGen public class XmlCommentsOperationFilter : IOperationFilter { private readonly IReadOnlyDictionary _xmlDocMembers; + private readonly SwaggerGeneratorOptions _options; - public XmlCommentsOperationFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc)) + public XmlCommentsOperationFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc), null) { } - internal XmlCommentsOperationFilter(IReadOnlyDictionary xmlDocMembers) + [ActivatorUtilitiesConstructor] + internal XmlCommentsOperationFilter(IReadOnlyDictionary xmlDocMembers, SwaggerGeneratorOptions options) { _xmlDocMembers = xmlDocMembers; + _options = options; } public void Apply(OpenApiOperation operation, OperationFilterContext context) @@ -52,11 +56,11 @@ private void ApplyMethodTags(OpenApiOperation operation, MethodInfo methodInfo) var summaryNode = methodNode.SelectFirstChild("summary"); if (summaryNode != null) - operation.Summary = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml); + operation.Summary = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml, _options?.XmlCommentEndOfLine); var remarksNode = methodNode.SelectFirstChild("remarks"); if (remarksNode != null) - operation.Description = XmlCommentsTextHelper.Humanize(remarksNode.InnerXml); + operation.Description = XmlCommentsTextHelper.Humanize(remarksNode.InnerXml, _options?.XmlCommentEndOfLine); var responseNodes = methodNode.SelectChildren("response"); ApplyResponseTags(operation, responseNodes); @@ -73,7 +77,7 @@ private void ApplyResponseTags(OpenApiOperation operation, XPathNodeIterator res operation.Responses[code] = response; } - response.Description = XmlCommentsTextHelper.Humanize(responseNodes.Current.InnerXml); + response.Description = XmlCommentsTextHelper.Humanize(responseNodes.Current.InnerXml, _options?.XmlCommentEndOfLine); } } } diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsParameterFilter.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsParameterFilter.cs index 07caf2044d..a3b81eb908 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsParameterFilter.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsParameterFilter.cs @@ -1,4 +1,5 @@ -using Microsoft.OpenApi.Models; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; using System.Collections.Generic; using System.Reflection; using System.Xml.XPath; @@ -8,14 +9,17 @@ namespace Swashbuckle.AspNetCore.SwaggerGen public class XmlCommentsParameterFilter : IParameterFilter { private readonly IReadOnlyDictionary _xmlDocMembers; + private readonly SwaggerGeneratorOptions _options; - public XmlCommentsParameterFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc)) + public XmlCommentsParameterFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc), null) { } - internal XmlCommentsParameterFilter(IReadOnlyDictionary xmlDocMembers) + [ActivatorUtilitiesConstructor] + internal XmlCommentsParameterFilter(IReadOnlyDictionary xmlDocMembers, SwaggerGeneratorOptions options) { _xmlDocMembers = xmlDocMembers; + _options = options; } public void Apply(OpenApiParameter parameter, ParameterFilterContext context) @@ -39,7 +43,7 @@ private void ApplyPropertyTags(OpenApiParameter parameter, ParameterFilterContex var summaryNode = propertyNode.SelectFirstChild("summary"); if (summaryNode != null) { - parameter.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml); + parameter.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml, _options?.XmlCommentEndOfLine); parameter.Schema.Description = null; // no need to duplicate } @@ -68,7 +72,7 @@ private void ApplyParamTags(OpenApiParameter parameter, ParameterFilterContext c if (paramNode != null) { - parameter.Description = XmlCommentsTextHelper.Humanize(paramNode.InnerXml); + parameter.Description = XmlCommentsTextHelper.Humanize(paramNode.InnerXml, _options?.XmlCommentEndOfLine); var example = paramNode.GetAttribute("example"); if (string.IsNullOrEmpty(example)) return; diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsRequestBodyFilter.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsRequestBodyFilter.cs index 4bbe79df43..fa76c98dc8 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsRequestBodyFilter.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsRequestBodyFilter.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Reflection; using System.Xml.XPath; +using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; namespace Swashbuckle.AspNetCore.SwaggerGen @@ -9,14 +10,17 @@ namespace Swashbuckle.AspNetCore.SwaggerGen public class XmlCommentsRequestBodyFilter : IRequestBodyFilter { private readonly IReadOnlyDictionary _xmlDocMembers; + private readonly SwaggerGeneratorOptions _options; - public XmlCommentsRequestBodyFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc)) + public XmlCommentsRequestBodyFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc), null) { } - internal XmlCommentsRequestBodyFilter(IReadOnlyDictionary xmlDocMembers) + [ActivatorUtilitiesConstructor] + internal XmlCommentsRequestBodyFilter(IReadOnlyDictionary xmlDocMembers, SwaggerGeneratorOptions options) { _xmlDocMembers = xmlDocMembers; + _options = options; } public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext context) @@ -89,7 +93,7 @@ public void Apply(OpenApiRequestBody requestBody, RequestBodyFilterContext conte var summaryNode = propertyNode.SelectFirstChild("summary"); if (summaryNode is not null) { - summary = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml); + summary = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml, _options?.XmlCommentEndOfLine); } var exampleNode = propertyNode.SelectFirstChild("example"); @@ -147,7 +151,7 @@ private void ApplyPropertyTagsForBody(OpenApiRequestBody requestBody, RequestBod return (null, null); } - var summary = XmlCommentsTextHelper.Humanize(paramNode.InnerXml); + var summary = XmlCommentsTextHelper.Humanize(paramNode.InnerXml, _options?.XmlCommentEndOfLine); var example = paramNode.GetAttribute("example"); return (summary, example); diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsSchemaFilter.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsSchemaFilter.cs index 67c7377c8b..812484b6c4 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsSchemaFilter.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsSchemaFilter.cs @@ -1,4 +1,5 @@ -using Microsoft.OpenApi.Models; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.Xml.XPath; @@ -8,14 +9,17 @@ namespace Swashbuckle.AspNetCore.SwaggerGen public class XmlCommentsSchemaFilter : ISchemaFilter { private readonly IReadOnlyDictionary _xmlDocMembers; + private readonly SwaggerGeneratorOptions _options; - public XmlCommentsSchemaFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc)) + public XmlCommentsSchemaFilter(XPathDocument xmlDoc) : this(XmlCommentsDocumentHelper.CreateMemberDictionary(xmlDoc), null) { } - internal XmlCommentsSchemaFilter(IReadOnlyDictionary xmlDocMembers) + [ActivatorUtilitiesConstructor] + internal XmlCommentsSchemaFilter(IReadOnlyDictionary xmlDocMembers, SwaggerGeneratorOptions options) { _xmlDocMembers = xmlDocMembers; + _options = options; } public void Apply(OpenApiSchema schema, SchemaFilterContext context) @@ -38,7 +42,7 @@ private void ApplyTypeTags(OpenApiSchema schema, Type type) if (typeSummaryNode != null) { - schema.Description = XmlCommentsTextHelper.Humanize(typeSummaryNode.InnerXml); + schema.Description = XmlCommentsTextHelper.Humanize(typeSummaryNode.InnerXml, _options?.XmlCommentEndOfLine); } } @@ -56,7 +60,9 @@ private void ApplyMemberTags(OpenApiSchema schema, SchemaFilterContext context) { var summaryNode = recordDefaultConstructorProperty.Value; if (summaryNode != null) - schema.Description = XmlCommentsTextHelper.Humanize(summaryNode); + { + schema.Description = XmlCommentsTextHelper.Humanize(summaryNode, _options?.XmlCommentEndOfLine); + } var example = recordDefaultConstructorProperty.GetAttribute("example"); if (!string.IsNullOrEmpty(example)) @@ -70,7 +76,9 @@ private void ApplyMemberTags(OpenApiSchema schema, SchemaFilterContext context) { var summaryNode = fieldOrPropertyNode.SelectFirstChild("summary"); if (summaryNode != null) - schema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml); + { + schema.Description = XmlCommentsTextHelper.Humanize(summaryNode.InnerXml, _options?.XmlCommentEndOfLine); + } var exampleNode = fieldOrPropertyNode.SelectFirstChild("example"); TrySetExample(schema, context, exampleNode?.Value); diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsTextHelper.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsTextHelper.cs index 6383b3a36f..7903a3e2ed 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsTextHelper.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsTextHelper.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net; +using System.Text; using System.Text.RegularExpressions; namespace Swashbuckle.AspNetCore.SwaggerGen @@ -8,24 +9,29 @@ namespace Swashbuckle.AspNetCore.SwaggerGen public static partial class XmlCommentsTextHelper { public static string Humanize(string text) + { + return Humanize(text, null); + } + + public static string Humanize(string text, string xmlCommentEndOfLine) { if (text == null) - throw new ArgumentNullException("text"); + throw new ArgumentNullException(nameof(text)); //Call DecodeXml at last to avoid entities like < and > to break valid xml return text - .NormalizeIndentation() + .NormalizeIndentation(xmlCommentEndOfLine) .HumanizeRefTags() .HumanizeHrefTags() .HumanizeCodeTags() .HumanizeMultilineCodeTags() .HumanizeParaTags() - .HumanizeBrTags() // must be called after HumanizeParaTags() so that it replaces any additional
tags + .HumanizeBrTags(xmlCommentEndOfLine) // must be called after HumanizeParaTags() so that it replaces any additional
tags .DecodeXml(); } - private static string NormalizeIndentation(this string text) + private static string NormalizeIndentation(this string text, string xmlCommentEndOfLine) { string[] lines = text.Split('\n'); string padding = GetCommonLeadingWhitespace(lines); @@ -45,7 +51,7 @@ private static string NormalizeIndentation(this string text) // remove leading empty lines, but not all leading padding // remove all trailing whitespace, regardless - return string.Join("\r\n", lines.SkipWhile(x => string.IsNullOrWhiteSpace(x))).TrimEnd(); + return string.Join(xmlCommentEndOfLine ?? "\r\n", lines.SkipWhile(x => string.IsNullOrWhiteSpace(x))).TrimEnd(); } private static string GetCommonLeadingWhitespace(string[] lines) @@ -101,17 +107,38 @@ private static string HumanizeCodeTags(this string text) private static string HumanizeMultilineCodeTags(this string text) { - return MultilineCodeTag().Replace(text, (match) => "```" + match.Groups["display"].Value + "```"); + return MultilineCodeTag().Replace(text, match => + { + var codeText = match.Groups["display"].Value; + if (LineBreaks().IsMatch(codeText)) + { + var builder = new StringBuilder().Append("```"); + if (!codeText.StartsWith("\r") && !codeText.StartsWith("\n")) + { + builder.AppendLine(); + } + + return builder.AppendLine(codeText.TrimEnd()) + .Append("```") + .ToString(); + } + + return $"```{codeText}```"; + }); } private static string HumanizeParaTags(this string text) { - return ParaTag().Replace(text, (match) => "
" + match.Groups["display"].Value); + return ParaTag().Replace(text, match => + { + var paraText = "
" + match.Groups["display"].Value.Trim(); + return LineBreaks().Replace(paraText, _ => string.Empty); + }); } - private static string HumanizeBrTags(this string text) + private static string HumanizeBrTags(this string text, string xmlCommentEndOfLine) { - return BrTag().Replace(text, m => Environment.NewLine); + return BrTag().Replace(text, _ => xmlCommentEndOfLine ?? Environment.NewLine); } private static string DecodeXml(this string text) @@ -125,6 +152,7 @@ private static string DecodeXml(this string text) private const string ParaTagPattern = @"(?.+?)"; private const string HrefPattern = @"(.*)<\/see>"; private const string BrPattern = @"(
)"; // handles
,
,
+ private const string LineBreaksPattern = @"\r?\n"; #if NET7_0_OR_GREATER [GeneratedRegex(RefTagPattern)] @@ -144,6 +172,9 @@ private static string DecodeXml(this string text) [GeneratedRegex(BrPattern)] private static partial Regex BrTag(); + + [GeneratedRegex(LineBreaksPattern)] + private static partial Regex LineBreaks(); #else private static readonly Regex _refTag = new(RefTagPattern); private static readonly Regex _codeTag = new(CodeTagPattern); @@ -151,6 +182,7 @@ private static string DecodeXml(this string text) private static readonly Regex _paraTag = new(ParaTagPattern, RegexOptions.Singleline); private static readonly Regex _hrefTag = new(HrefPattern); private static readonly Regex _brTag = new(BrPattern); + private static readonly Regex _lineBreaks = new(LineBreaksPattern); private static Regex RefTag() => _refTag; private static Regex CodeTag() => _codeTag; @@ -158,6 +190,7 @@ private static string DecodeXml(this string text) private static Regex ParaTag() => _paraTag; private static Regex HrefTag() => _hrefTag; private static Regex BrTag() => _brTag; + private static Regex LineBreaks() => _lineBreaks; #endif } } diff --git a/src/Swashbuckle.AspNetCore.SwaggerUI/PublicAPI/PublicAPI.Unshipped.txt b/src/Swashbuckle.AspNetCore.SwaggerUI/PublicAPI/PublicAPI.Unshipped.txt index e69de29bb2..974e583fc9 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerUI/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Swashbuckle.AspNetCore.SwaggerUI/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +static Microsoft.AspNetCore.Builder.SwaggerUIOptionsExtensions.EnableSwaggerDocumentUrlsEndpoint(this Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIOptions options) -> void +Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIOptions.ExposeSwaggerDocumentUrlsRoute.get -> bool +Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIOptions.ExposeSwaggerDocumentUrlsRoute.set -> void +Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIOptions.SwaggerDocumentUrlsPath.get -> string +Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIOptions.SwaggerDocumentUrlsPath.set -> void diff --git a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIJsonSerializerContext.cs b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIJsonSerializerContext.cs index 72e175fb6e..51e9fbe31d 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIJsonSerializerContext.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIJsonSerializerContext.cs @@ -1,5 +1,6 @@ #if NET6_0_OR_GREATER using System; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; @@ -8,6 +9,7 @@ namespace Swashbuckle.AspNetCore.SwaggerUI; [JsonSerializable(typeof(ConfigObject))] [JsonSerializable(typeof(InterceptorFunctions))] +[JsonSerializable(typeof(List))] [JsonSerializable(typeof(OAuthConfigObject))] // These primitive types are declared for common types that may be used with ConfigObject.AdditionalItems. See https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/2884. [JsonSerializable(typeof(bool))] diff --git a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs index 4a65cb7cf9..7def9d1d5b 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; @@ -88,6 +90,13 @@ public async Task Invoke(HttpContext httpContext) await RespondWithFile(httpContext.Response, match.Groups[1].Value); return; } + + var pattern = $"^/?{Regex.Escape(_options.RoutePrefix)}/{_options.SwaggerDocumentUrlsPath}/?$"; + if (Regex.IsMatch(path, pattern, RegexOptions.IgnoreCase)) + { + await RespondWithDocumentUrls(httpContext.Response); + return; + } } await _staticFileMiddleware.Invoke(httpContext); @@ -150,6 +159,36 @@ private async Task RespondWithFile(HttpResponse response, string fileName) } } +#if NET5_0_OR_GREATER + [UnconditionalSuppressMessage( + "AOT", + "IL2026:RequiresUnreferencedCode", + Justification = "Method is only called if the user provides their own custom JsonSerializerOptions.")] + [UnconditionalSuppressMessage( + "AOT", + "IL3050:RequiresDynamicCode", + Justification = "Method is only called if the user provides their own custom JsonSerializerOptions.")] +#endif + private async Task RespondWithDocumentUrls(HttpResponse response) + { + response.StatusCode = 200; + + response.ContentType = "application/javascript;charset=utf-8"; + string json = "[]"; + +#if NET6_0_OR_GREATER + if (_jsonSerializerOptions is null) + { + var l = new List(_options.ConfigObject.Urls); + json = JsonSerializer.Serialize(l, SwaggerUIOptionsJsonContext.Default.ListUrlDescriptor); + } +#endif + + json ??= JsonSerializer.Serialize(_options.ConfigObject, _jsonSerializerOptions); + + await response.WriteAsync(json, Encoding.UTF8); + } + #if NET5_0_OR_GREATER [UnconditionalSuppressMessage( "AOT", diff --git a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptions.cs b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptions.cs index 09fc304abe..28d337da37 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptions.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptions.cs @@ -63,6 +63,18 @@ public class SwaggerUIOptions /// Gets or sets the path or URL to the Swagger UI CSS file. /// public string StylesPath { get; set; } = "./swagger-ui.css"; + + /// + /// Gets or sets whether to expose the ConfigObject.Urls object via an + /// HTTP endpoint with the URL specified by + /// so that external code can auto-discover all Swagger documents. + /// + public bool ExposeSwaggerDocumentUrlsRoute { get; set; } = false; + + /// + /// Gets or sets the relative URL path to the route that exposes the values of the configured values. + /// + public string SwaggerDocumentUrlsPath { get; set; } = "documentUrls"; } public class ConfigObject diff --git a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptionsExtensions.cs b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptionsExtensions.cs index a5b05fa946..26a932b931 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptionsExtensions.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptionsExtensions.cs @@ -203,7 +203,7 @@ public static void ValidatorUrl(this SwaggerUIOptions options, string url) /// /// You can use this parameter to enable the swagger-ui's built-in validator (badge) functionality - /// Setting it to null will disable validation + /// Setting it to null will disable validation /// /// /// @@ -239,7 +239,7 @@ public static void OAuthUsername(this SwaggerUIOptions options, string value) /// /// Setting this exposes the client secrets in inline javascript in the swagger-ui generated html. public static void OAuthClientSecret(this SwaggerUIOptions options, string value) - { + { options.OAuthConfigObject.ClientSecret = value; } @@ -333,5 +333,15 @@ public static void UseResponseInterceptor(this SwaggerUIOptions options, string { options.Interceptors.ResponseInterceptorFunction = value; } + + /// + /// Function to enable the option to expose the available + /// Swagger document urls to external parties. + /// + /// + public static void EnableSwaggerDocumentUrlsEndpoint(this SwaggerUIOptions options) + { + options.ExposeSwaggerDocumentUrlsRoute = true; + } } } diff --git a/src/Swashbuckle.AspNetCore.SwaggerUI/package-lock.json b/src/Swashbuckle.AspNetCore.SwaggerUI/package-lock.json index cd96851db1..199246c5c8 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerUI/package-lock.json +++ b/src/Swashbuckle.AspNetCore.SwaggerUI/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "hasInstallScript": true, "dependencies": { - "swagger-ui-dist": "5.18.2" + "swagger-ui-dist": "5.20.0" } }, "node_modules/@scarf/scarf": { @@ -20,9 +20,9 @@ "license": "Apache-2.0" }, "node_modules/swagger-ui-dist": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.18.2.tgz", - "integrity": "sha512-J+y4mCw/zXh1FOj5wGJvnAajq6XgHOyywsa9yITmwxIlJbMqITq3gYRZHaeqLVH/eV/HOPphE6NjF+nbSNC5Zw==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.20.0.tgz", + "integrity": "sha512-V5pozVTZxivdoQq/SQWxj3A4cOu5opk9MEbcZANX3Pj8X8xCrD1QCtBT7744Pz9msOvt0nnmy9JvM/9PGonCdg==", "license": "Apache-2.0", "dependencies": { "@scarf/scarf": "=1.4.0" diff --git a/src/Swashbuckle.AspNetCore.SwaggerUI/package.json b/src/Swashbuckle.AspNetCore.SwaggerUI/package.json index 5f9fbb71bb..239eff8a56 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerUI/package.json +++ b/src/Swashbuckle.AspNetCore.SwaggerUI/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "private": true, "dependencies": { - "swagger-ui-dist": "5.18.2" + "swagger-ui-dist": "5.20.0" }, "scripts": { "postinstall": "node scripts/remove-source-map-links.js" diff --git a/test/Swashbuckle.AspNetCore.Annotations.Test/AnnotationsOperationFilterTests.cs b/test/Swashbuckle.AspNetCore.Annotations.Test/AnnotationsOperationFilterTests.cs index 2e71d29135..cee1575558 100644 --- a/test/Swashbuckle.AspNetCore.Annotations.Test/AnnotationsOperationFilterTests.cs +++ b/test/Swashbuckle.AspNetCore.Annotations.Test/AnnotationsOperationFilterTests.cs @@ -77,7 +77,7 @@ public void Apply_EnrichesResponseMetadata_IfActionDecoratedWithSwaggerResponseC .GetMethod(nameof(FakeControllerWithSwaggerAnnotations.ActionWithSwaggerResponseContentTypesAttributes)); var filterContext = new OperationFilterContext( apiDescription: null, - schemaRegistry: new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions()), Options.Create(new MvcOptions())), + schemaRegistry: new SchemaGenerator(new SchemaGeneratorOptions(), new JsonSerializerDataContractResolver(new JsonSerializerOptions())), schemaRepository: new SchemaRepository(), methodInfo: methodInfo); diff --git a/test/Swashbuckle.AspNetCore.Cli.Test/Swashbuckle.AspNetCore.Cli.Test.csproj b/test/Swashbuckle.AspNetCore.Cli.Test/Swashbuckle.AspNetCore.Cli.Test.csproj index d092c5648d..bd789f4a78 100644 --- a/test/Swashbuckle.AspNetCore.Cli.Test/Swashbuckle.AspNetCore.Cli.Test.csproj +++ b/test/Swashbuckle.AspNetCore.Cli.Test/Swashbuckle.AspNetCore.Cli.Test.csproj @@ -11,6 +11,7 @@ + diff --git a/test/Swashbuckle.AspNetCore.Cli.Test/ToolTests.cs b/test/Swashbuckle.AspNetCore.Cli.Test/ToolTests.cs index 0373863b69..343c0c5900 100644 --- a/test/Swashbuckle.AspNetCore.Cli.Test/ToolTests.cs +++ b/test/Swashbuckle.AspNetCore.Cli.Test/ToolTests.cs @@ -9,6 +9,20 @@ namespace Swashbuckle.AspNetCore.Cli.Test { public static class ToolTests { + [Fact] + public static void Can_Output_Swagger_Document_Names() + { + var result = RunToStringCommand((outputPath) => + [ + "list", + "--output", + outputPath, + Path.Combine(Directory.GetCurrentDirectory(), "MultipleVersions.dll") + ], nameof(Can_Output_Swagger_Document_Names)); + var expected = $"\"1.0\"{Environment.NewLine}\"2.0\"{Environment.NewLine}"; + Assert.Equal(expected, result); + } + [Fact] public static void Throws_When_Startup_Assembly_Does_Not_Exist() { @@ -19,7 +33,7 @@ public static void Throws_When_Startup_Assembly_Does_Not_Exist() [Fact] public static void Can_Generate_Swagger_Json() { - using var document = RunApplication((outputPath) => + using var document = RunToJsonCommand((outputPath) => [ "tofile", "--output", @@ -38,7 +52,7 @@ public static void Can_Generate_Swagger_Json() [Fact] public static void Overwrites_Existing_File() { - using var document = RunApplication((outputPath) => + using var document = RunToJsonCommand((outputPath) => { File.WriteAllText(outputPath, new string('x', 100_000)); @@ -62,7 +76,7 @@ public static void Overwrites_Existing_File() [Fact] public static void CustomDocumentSerializer_Writes_Custom_V2_Document() { - using var document = RunApplication((outputPath) => + using var document = RunToJsonCommand((outputPath) => [ "tofile", "--output", @@ -80,7 +94,7 @@ public static void CustomDocumentSerializer_Writes_Custom_V2_Document() [Fact] public static void CustomDocumentSerializer_Writes_Custom_V3_Document() { - using var document = RunApplication((outputPath) => + using var document = RunToJsonCommand((outputPath) => [ "tofile", "--output", @@ -98,7 +112,7 @@ public static void CustomDocumentSerializer_Writes_Custom_V3_Document() [Fact] public static void Can_Generate_Swagger_Json_ForTopLevelApp() { - using var document = RunApplication((outputPath) => + using var document = RunToJsonCommand((outputPath) => [ "tofile", "--output", @@ -117,7 +131,7 @@ public static void Can_Generate_Swagger_Json_ForTopLevelApp() [Fact] public static void Does_Not_Run_Crashing_HostedService() { - using var document = RunApplication((outputPath) => + using var document = RunToJsonCommand((outputPath) => [ "tofile", "--output", @@ -135,7 +149,7 @@ public static void Does_Not_Run_Crashing_HostedService() [Fact] public static void Creates_New_Folder_Path() { - using var document = RunApplication(outputPath => + using var document = RunToJsonCommand(outputPath => [ "tofile", "--output", @@ -151,7 +165,7 @@ public static void Creates_New_Folder_Path() Assert.True(productsPath.TryGetProperty("post", out _)); } - private static JsonDocument RunApplication(Func setup, string subOutputPath = default) + private static string RunToStringCommand(Func setup, string subOutputPath = default) { using var temporaryDirectory = new TemporaryDirectory(); @@ -163,7 +177,12 @@ private static JsonDocument RunApplication(Func setup, string Assert.Equal(0, Program.Main(args)); - string json = File.ReadAllText(outputPath); + return File.ReadAllText(outputPath); + } + + private static JsonDocument RunToJsonCommand(Func setup, string subOutputPath = default) + { + string json = RunToStringCommand(setup, subOutputPath); return JsonDocument.Parse(json); } diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_startupType=Basic.Startup_swaggerRequestUri=v1.verified.txt b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_startupType=Basic.Startup_swaggerRequestUri=v1.verified.txt index afe5520fc4..d569ed88c2 100644 --- a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_startupType=Basic.Startup_swaggerRequestUri=v1.verified.txt +++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_startupType=Basic.Startup_swaggerRequestUri=v1.verified.txt @@ -87,6 +87,31 @@ "x-purpose": "test" } }, + "/products/all": { + "get": { + "tags": [ + "CrudActions" + ], + "summary": "Get all products", + "description": "```\r\n {\r\n \"Id\":1,\r\n \"Description\":\"\",\r\n \"Status\": 0,\r\n \"Status2\": 1\r\n }\r\n```", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Product" + } + } + } + } + } + }, + "x-purpose": "test" + } + }, "/products/{id}": { "get": { "tags": [ @@ -174,6 +199,7 @@ "CrudActions" ], "summary": "Updates some properties of a specific product", + "description": "\r\nOnly provided properties will be updated, other remain unchanged.\r\n\r\nIdentifier must be non-default value\r\n\r\nBody must be specified", "operationId": "PatchProduct", "parameters": [ { @@ -811,6 +837,18 @@ "type": "string" } } + }, + { + "name": "search", + "in": "query", + "required": true, + "style": "deepObject", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } } ], "responses": { diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs index fcf9c11195..129487fd3d 100644 --- a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs +++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs @@ -36,7 +36,9 @@ public async Task SwaggerEndpoint_ReturnsValidSwaggerJson( using var swaggerResponse = await client.GetAsync(swaggerRequestUri); var swagger = await swaggerResponse.Content.ReadAsStringAsync(); - await Verifier.Verify(swagger).UseParameters(startupType, GetVersion(swaggerRequestUri)); + + await Verifier.Verify(NormalizeLineBreaks(swagger)) + .UseParameters(startupType, GetVersion(swaggerRequestUri)); } [Fact] @@ -94,6 +96,14 @@ private static async Task SwaggerResponse(HttpClient client, string swag return contentStream; } + /// + /// Normalize "\n" strings into "\r\n" which is expected linebreak in Verify verified.txt files. + /// + private static string NormalizeLineBreaks(string swagger) + { + return UnixNewLineRegex().Replace(swagger, "\\r\\n"); + } + private static string GetVersion(string swaggerUi) => #if NET6_0 Regex.Match(swaggerUi, "/\\w+/([\\w+\\d+.-]+)/").Groups[1].Value; @@ -103,5 +113,8 @@ private static string GetVersion(string swaggerUi) => [GeneratedRegex("/\\w+/([\\w+\\d+.-]+)/")] private static partial Regex VersionRegex(); #endif + + [GeneratedRegex(@"(?(new MvcOptions())); + return new SchemaGenerator(generatorOptions, new NewtonsoftDataContractResolver(serializerSettings)); } } } diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs index bb599457f9..6132214350 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/ConfigureSwaggerGeneratorOptionsTests.cs @@ -18,7 +18,7 @@ public static void DeepCopy_Copies_All_Properties() // If this assertion fails, it means that a new property has been added // to SwaggerGeneratorOptions and ConfigureSwaggerGeneratorOptions.DeepCopy() needs to be updated - Assert.Equal(23, publicProperties.Length); + Assert.Equal(24, publicProperties.Length); } [Fact] diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs index ebd1f0d895..fddcd8825d 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs @@ -984,6 +984,7 @@ public void GenerateSchema_SupportsOption_NonNullableReferenceTypesAsRequired_Re Assert.Equal(required, propertyIsRequired); } + [Obsolete($"{nameof(IOptions)} is not used.")] [Theory] [InlineData(typeof(TypeWithNullableContextAnnotated), nameof(TypeWithNullableContextAnnotated.SubTypeWithOneNonNullableContent), nameof(TypeWithNullableContextAnnotated.NonNullableString), false)] [InlineData(typeof(TypeWithNullableContextAnnotated), nameof(TypeWithNullableContextAnnotated.SubTypeWithOneNonNullableContent), nameof(TypeWithNullableContextAnnotated.NonNullableString), true)] @@ -1004,7 +1005,7 @@ public void GenerateSchema_SupportsOption_SuppressImplicitRequiredAttributeForNo subject.GenerateSchema(declaringType, schemaRepository); var propertyIsRequired = schemaRepository.Schemas[subType].Required.Contains(propertyName); - Assert.Equal(!suppress, propertyIsRequired); + Assert.True(propertyIsRequired); } [Theory] @@ -1064,6 +1065,18 @@ public void GenerateSchema_HandlesTypesWithNestedTypes() Assert.Equal("NestedType", schema.Properties["Property1"].Reference.Id); } + [Fact] + public void GenerateSchema_HandlesSquareArray() + { + var schemaRepository = new SchemaRepository(); + + var referenceSchema = Subject().GenerateSchema(typeof(string[,]), schemaRepository); + + Assert.NotNull(referenceSchema.Items); + Assert.NotNull(referenceSchema.Items.Type); + Assert.Equal("string", referenceSchema.Items.Type); + } + [Fact] public void GenerateSchema_HandlesRecursion_IfCalledAgainWithinAFilter() { @@ -1318,8 +1331,7 @@ public void GenerateSchema_GeneratesSchema_IfParameterHasTypeConstraints() private static SchemaGenerator Subject( Action configureGenerator = null, - Action configureSerializer = null, - Action configureMvcOptions = null) + Action configureSerializer = null) { var generatorOptions = new SchemaGeneratorOptions(); configureGenerator?.Invoke(generatorOptions); @@ -1327,10 +1339,23 @@ private static SchemaGenerator Subject( var serializerOptions = new JsonSerializerOptions(); configureSerializer?.Invoke(serializerOptions); + return new SchemaGenerator(generatorOptions, new JsonSerializerDataContractResolver(serializerOptions)); + } + + [Obsolete($"{nameof(IOptions)} is not used.")] + private static SchemaGenerator Subject( + Action configureGenerator, + Action configureMvcOptions) + { + var generatorOptions = new SchemaGeneratorOptions(); + configureGenerator?.Invoke(generatorOptions); + + var serializerOptions = new JsonSerializerOptions(); + var mvcOptions = new MvcOptions(); configureMvcOptions?.Invoke(mvcOptions); - return new SchemaGenerator(generatorOptions, new JsonSerializerDataContractResolver(serializerOptions), Options.Create(mvcOptions)); + return new SchemaGenerator(generatorOptions, new JsonSerializerDataContractResolver(serializerOptions), Options.Create(mvcOptions)); } } } diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs index 2aab436d56..b2cc53beea 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs @@ -38,7 +38,7 @@ public void GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGr c => nameof(c.ActionWithNoParameters), groupName: "v1", httpMethod: "GET", relativePath: "resource"), ApiDescriptionFactory.Create( - c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource"), + c => nameof(c.ActionWithNoParameters), groupName: "v2", httpMethod: "POST", relativePath: "resource") }, options: new SwaggerGeneratorOptions { @@ -50,6 +50,10 @@ public void GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGr } ); + var provider = Assert.IsAssignableFrom(subject); + var documentNames = provider.GetDocumentNames(); + Assert.Equal(["v1", "v2"], documentNames); + var document = subject.GetSwagger("v1"); Assert.Equal("V1", document.Info.Version); @@ -2519,6 +2523,51 @@ public void GetSwagger_OpenApiOperationWithRawContent_IsHandled() Assert.Single(document.Paths["/resource"].Operations); } + [Fact] + public void GetSwagger_BindingSourceQueryParameter_NotThrowsException() + { + var apiDescription = new ApiDescription + { + HttpMethod = "GET", + ActionDescriptor = new ActionDescriptor + { + RouteValues = new Dictionary + { + ["controller"] = "Catalog" + } + }, + RelativePath = "api/v1/Images/{image}", + GroupName = "v1", + ParameterDescriptions = + { + new ApiParameterDescription + { + Name = "width", + Source = BindingSource.Query, + DefaultValue = string.Empty, + Type = typeof(int) + } + } + }; + var subject = Subject( + apiDescriptions: + [ + apiDescription + ], + options: new SwaggerGeneratorOptions + { + SwaggerDocs = new Dictionary + { + ["v1"] = new() { Version = "V1", Title = "Test API" } + } + } + ); + + var document = subject.GetSwagger("v1"); + + Assert.NotNull(document); + } + private static SwaggerGenerator Subject( IEnumerable apiDescriptions, SwaggerGeneratorOptions options = null, @@ -2528,8 +2577,8 @@ private static SwaggerGenerator Subject( return new SwaggerGenerator( options ?? DefaultOptions, new FakeApiDescriptionGroupCollectionProvider(apiDescriptions), - new SchemaGenerator(new SchemaGeneratorOptions() { SchemaFilters = schemaFilters ?? [] }, new JsonSerializerDataContractResolver(new JsonSerializerOptions()), Options.Create(new MvcOptions())), - new FakeAuthenticationSchemeProvider(authenticationSchemes ?? Enumerable.Empty()) + new SchemaGenerator(new SchemaGeneratorOptions { SchemaFilters = schemaFilters ?? [] }, new JsonSerializerDataContractResolver(new JsonSerializerOptions())), + new FakeAuthenticationSchemeProvider(authenticationSchemes ?? []) ); } diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/XmlComments/XmlCommentsTextHelperTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/XmlComments/XmlCommentsTextHelperTests.cs index 9464de28ff..cf554a59d1 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/XmlComments/XmlCommentsTextHelperTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/XmlComments/XmlCommentsTextHelperTests.cs @@ -1,4 +1,5 @@ -using Xunit; +using System; +using Xunit; namespace Swashbuckle.AspNetCore.SwaggerGen.Test { @@ -129,10 +130,12 @@ Misplaced Tab Indentation [InlineData("DoWork is a method in TestClass.", "`DoWork` is a method in `TestClass`.")] [InlineData("DoWork is a method in \nTestClass\n.", "```DoWork``` is a method in ```\nTestClass\n```.")] [InlineData("This is a paragraph.", "\r\nThis is a paragraph.")] + [InlineData(" This is a paragraph .", "\r\nThis is a paragraph.")] [InlineData("GET /Todo?iscomplete=true&owner=mike", "GET /Todo?iscomplete=true&owner=mike")] [InlineData(@"Returns a item.", "Returns a null item.")] [InlineData(@"ISO currency code", "[ISO currency code](https://www.iso.org/iso-4217-currency-codes.html)")] [InlineData("First line.
Second line.
Third line.
Fourth line.", "First line.\r\nSecond line.\r\nThird line.\r\nFourth line.")] + [InlineData(" one two ","\r\none\r\ntwo")] public void Humanize_HumanizesInlineTags( string input, string expectedOutput) @@ -141,5 +144,111 @@ public void Humanize_HumanizesInlineTags( Assert.Equal(expectedOutput, output, false, true); } + + [Fact] + public void Humanize_MultilineBrTag_EolNotSpecified() + { + const string input = @" + This is a paragraph. +
+ A parameter after br tag."; + + var output = XmlCommentsTextHelper.Humanize(input); + + // Result view for Linux: This is a paragraph.\r\n\n\r\nA parameter after br tag. + var expected = string.Join("\r\n", + [ + "This is a paragraph.", + Environment.NewLine, + "A parameter after br tag." + ]); + Assert.Equal(expected, output, false, ignoreLineEndingDifferences: false); + } + + [Theory] + [InlineData("\r\n")] + [InlineData("\n")] + public void Humanize_MultilineBrTag_SpecificEol(string xmlCommentEndOfLine) + { + const string input = @" + This is a paragraph. +
+ A parameter after br tag."; + + var output = XmlCommentsTextHelper.Humanize(input, xmlCommentEndOfLine); + + var expected = string.Join(xmlCommentEndOfLine, + [ + "This is a paragraph.", + "", + "", + "A parameter after br tag." + ]); + Assert.Equal(expected, output, false, ignoreLineEndingDifferences: false); + } + + [Fact] + public void Humanize_ParaMultiLineTags() + { + const string input = @" + + This is a paragraph. + MultiLined. + + This is a paragraph ."; + + var output = XmlCommentsTextHelper.Humanize(input); + + Assert.Equal("\r\nThis is a paragraph. MultiLined.\r\n\r\nThis is a paragraph.", output, false, true); + } + + [Fact] + public void Humanize_CodeMultiLineTag() + { + const string input = @" + + { + ""Prop1"":1, + ""Prop2"":[] + } + "; + + var output = XmlCommentsTextHelper.Humanize(input); + + var expected = string.Join("\r\n", + [ + "```", + " {", + " \"Prop1\":1,", + " \"Prop2\":[]", + " }", + "```" + ]); + Assert.Equal(expected, output, false, true); + } + + [Fact] + public void Humanize_CodeMultiLineTag_OnSameLine() + { + const string input = @" + { + ""Prop1"":1, + ""Prop2"":[] + } + "; + + var output = XmlCommentsTextHelper.Humanize(input); + + var expected = string.Join("\r\n", + [ + "```", + "{", + " \"Prop1\":1,", + " \"Prop2\":[]", + " }", + "```" + ]); + Assert.Equal(expected, output, false, true); + } } } diff --git a/test/WebSites/Basic/Controllers/CrudActionsController.cs b/test/WebSites/Basic/Controllers/CrudActionsController.cs index 3e13b7ffdf..bb9368c63b 100644 --- a/test/WebSites/Basic/Controllers/CrudActionsController.cs +++ b/test/WebSites/Basic/Controllers/CrudActionsController.cs @@ -32,6 +32,23 @@ public Product Create([FromBody, Required]Product product) return product; } + /// Get all products + /// + /// + /// { + /// "Id":1, + /// "Description":"", + /// "Status": 0, + /// "Status2": 1 + /// } + /// + /// + [HttpGet("all")] + public List GetAll() + { + return []; + } + /// /// Searches the collection of products by description key words /// @@ -71,6 +88,14 @@ public void Update(int id, [FromBody, Required]Product product) /// /// Updates some properties of a specific product /// + /// + /// + /// Only provided properties will be updated, + /// other remain unchanged. + /// + /// Identifier must be non-default value + /// Body must be specified + /// /// /// [HttpPatch("{id}", Name = "PatchProduct")] @@ -114,4 +139,4 @@ public class Product public ProductStatus? Status2 { get; set; } } -} \ No newline at end of file +} diff --git a/test/WebSites/Basic/Controllers/FromQueryParamsController.cs b/test/WebSites/Basic/Controllers/FromQueryParamsController.cs index 9a16f877db..666dc02b7f 100644 --- a/test/WebSites/Basic/Controllers/FromQueryParamsController.cs +++ b/test/WebSites/Basic/Controllers/FromQueryParamsController.cs @@ -15,7 +15,7 @@ public IActionResult ValidateAddress([FromQuery]Address address) } [HttpGet("zip-codes/validate")] - public IActionResult ValidateZipCodes([FromQuery]IEnumerable zipCodes) + public IActionResult ValidateZipCodes([FromQuery]IEnumerable zipCodes, [FromQuery(Name = "search")] [Required] Dictionary parameters) { return new NoContentResult(); } diff --git a/test/WebSites/MultipleVersions/Startup.cs b/test/WebSites/MultipleVersions/Startup.cs index d7e47b398a..1f2552119c 100644 --- a/test/WebSites/MultipleVersions/Startup.cs +++ b/test/WebSites/MultipleVersions/Startup.cs @@ -59,6 +59,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVers { c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", $"Version {description.GroupName}"); } + c.EnableSwaggerDocumentUrlsEndpoint(); }); // Separate endpoints that contain only one version diff --git a/test/WebSites/NswagClientExample/NswagClientExample.csproj b/test/WebSites/NswagClientExample/NswagClientExample.csproj index 4a6258da9d..4d0328f6a6 100644 --- a/test/WebSites/NswagClientExample/NswagClientExample.csproj +++ b/test/WebSites/NswagClientExample/NswagClientExample.csproj @@ -3,8 +3,8 @@ net9.0;net8.0 $([System.IO.Path]::Combine('$(ArtifactsPath)', 'bin', 'Swashbuckle.AspNetCore.Cli', '$(Configuration.ToLower())_$(TargetFramework)')) - <_NSwagTool>$(NSwagExe_Net60) - <_NSwagTool Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">$(NSwagExe_Net80) + <_NSwagTool>$(NSwagExe_Net80) + <_NSwagTool Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net9.0'))">$(NSwagExe_Net90) diff --git a/test/WebSites/OAuth2Integration/AuthServer/Config.cs b/test/WebSites/OAuth2Integration/AuthServer/Config.cs index c51f6312d0..368cb8e820 100644 --- a/test/WebSites/OAuth2Integration/AuthServer/Config.cs +++ b/test/WebSites/OAuth2Integration/AuthServer/Config.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -using IdentityServer4.Models; -using IdentityServer4.Test; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Test; namespace OAuth2Integration.AuthServer { @@ -31,15 +31,12 @@ internal static IEnumerable Clients() internal static IEnumerable ApiResources() { - yield return new ApiResource + return new List { - Name = "api", - DisplayName = "API", - Scopes = - [ - new Scope("readAccess", "Access read operations"), - new Scope("writeAccess", "Access write operations") - ] + new ApiResource("api", "API") + { + Scopes = { "readAccess", "writeAccess" } + } }; } diff --git a/test/WebSites/OAuth2Integration/AuthServer/Controllers/AccountController.cs b/test/WebSites/OAuth2Integration/AuthServer/Controllers/AccountController.cs index f276bbb410..39a97b6f3b 100644 --- a/test/WebSites/OAuth2Integration/AuthServer/Controllers/AccountController.cs +++ b/test/WebSites/OAuth2Integration/AuthServer/Controllers/AccountController.cs @@ -1,9 +1,9 @@ using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; +using Duende.IdentityServer; +using Duende.IdentityServer.Test; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; -using IdentityServer4; -using IdentityServer4.Test; +using Microsoft.AspNetCore.Mvc; namespace OAuth2Integration.AuthServer.Controllers { @@ -22,12 +22,11 @@ public AccountController() public IActionResult Login(string returnUrl) { var viewModel = new LoginViewModel { Username = "joebloggs", Password = "pass123", ReturnUrl = returnUrl }; - return View("/AuthServer/Views/Login.cshtml", viewModel); } [HttpPost("login")] - public async Task Login([FromForm]LoginViewModel viewModel) + public async Task Login([FromForm] LoginViewModel viewModel) { if (!_userStore.ValidateCredentials(viewModel.Username, viewModel.Password)) { diff --git a/test/WebSites/OAuth2Integration/AuthServer/Controllers/ConsentController.cs b/test/WebSites/OAuth2Integration/AuthServer/Controllers/ConsentController.cs index 32e5652e3f..ae57220711 100644 --- a/test/WebSites/OAuth2Integration/AuthServer/Controllers/ConsentController.cs +++ b/test/WebSites/OAuth2Integration/AuthServer/Controllers/ConsentController.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using IdentityServer4.Models; -using IdentityServer4.Services; -using IdentityServer4.Stores; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Services; +using Duende.IdentityServer.Stores; using Microsoft.AspNetCore.Mvc; namespace OAuth2Integration.AuthServer.Controllers @@ -12,46 +12,50 @@ namespace OAuth2Integration.AuthServer.Controllers public class ConsentController : Controller { private readonly IIdentityServerInteractionService _interaction; - private readonly IClientStore _clientStore; - private readonly IResourceStore _resourceStore; public ConsentController( - IIdentityServerInteractionService interaction, - IClientStore clientStore, - IResourceStore resourceStore) + IIdentityServerInteractionService interaction) { _interaction = interaction; - _clientStore = clientStore; - _resourceStore = resourceStore; } [HttpGet("consent")] public async Task Consent(string returnUrl) { var request = await _interaction.GetAuthorizationContextAsync(returnUrl); - var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId); - var resource = await _resourceStore.FindApiResourceAsync("api"); var viewModel = new ConsentViewModel { ReturnUrl = returnUrl, - ClientName = client.ClientName, - ScopesRequested = resource.Scopes.Where(s => request.ScopesRequested.Contains(s.Name)) + ClientName = request.Client.ClientName, + ScopesRequested = request.ValidatedResources?.Resources?.ApiScopes ?? [] }; return View("/AuthServer/Views/Consent.cshtml", viewModel); } [HttpPost("consent")] - public async Task Consent([FromForm]ConsentViewModel viewModel) + public async Task Consent([FromForm] ConsentViewModel viewModel) { var request = await _interaction.GetAuthorizationContextAsync(viewModel.ReturnUrl); - // Communicate outcome of consent back to identityserver - var consentResponse = new ConsentResponse + ConsentResponse consentResponse; + if (viewModel.ScopesConsented != null && viewModel.ScopesConsented.Any()) { - ScopesConsented = viewModel.ScopesConsented - }; + consentResponse = new ConsentResponse + { + RememberConsent = true, + ScopesValuesConsented = viewModel.ScopesConsented.ToList() + }; + } + else + { + consentResponse = new ConsentResponse + { + Error = AuthorizationError.AccessDenied + }; + } + await _interaction.GrantConsentAsync(request, consentResponse); return Redirect(viewModel.ReturnUrl); @@ -62,7 +66,7 @@ public class ConsentViewModel { public string ReturnUrl { get; set; } public string ClientName { get; set; } - public IEnumerable ScopesRequested { get; set; } + public IEnumerable ScopesRequested { get; set; } public string[] ScopesConsented { get; set; } } } diff --git a/test/WebSites/OAuth2Integration/OAuth2Integration.csproj b/test/WebSites/OAuth2Integration/OAuth2Integration.csproj index 91b86c2dae..675259f21a 100644 --- a/test/WebSites/OAuth2Integration/OAuth2Integration.csproj +++ b/test/WebSites/OAuth2Integration/OAuth2Integration.csproj @@ -1,26 +1,29 @@ - + net9.0;net8.0 - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/test/WebSites/OAuth2Integration/ResourceServer/Controllers/ProductsController.cs b/test/WebSites/OAuth2Integration/ResourceServer/Controllers/ProductsController.cs index 15df0e1978..0c9f93ab1c 100644 --- a/test/WebSites/OAuth2Integration/ResourceServer/Controllers/ProductsController.cs +++ b/test/WebSites/OAuth2Integration/ResourceServer/Controllers/ProductsController.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; namespace OAuth2Integration.ResourceServer.Controllers { @@ -33,7 +33,7 @@ public Product GetProduct(int id) [HttpPost] [Authorize("writeAccess")] - public void CreateProduct([FromBody]Product product) + public void CreateProduct([FromBody] Product product) { } @@ -53,6 +53,6 @@ public class Product public enum ProductStatus { - InStock, ComingSoon + InStock, ComingSoon } -} \ No newline at end of file +} diff --git a/test/WebSites/OAuth2Integration/Startup.cs b/test/WebSites/OAuth2Integration/Startup.cs index 03d3cffd79..be39c5a612 100644 --- a/test/WebSites/OAuth2Integration/Startup.cs +++ b/test/WebSites/OAuth2Integration/Startup.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -24,7 +23,7 @@ public Startup(IConfiguration configuration) // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - // Register IdentityServer services to power OAuth2.0 flows + // Register Duende IdentityServer services to power OAuth2.0 flows services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryClients(AuthServer.Config.Clients()) @@ -36,11 +35,19 @@ public void ConfigureServices(IServiceCollection services) // See https://learn.microsoft.com/aspnet/core/security/authorization/limitingidentitybyscheme services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() - .AddIdentityServerAuthentication(c => + .AddJwtBearer("Bearer", options => { - c.Authority = "https://localhost:5001/auth-server/"; - c.RequireHttpsMetadata = false; - c.ApiName = "api"; + options.Authority = "https://localhost:5001/auth-server/"; + options.RequireHttpsMetadata = false; + options.Audience = "api"; + options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidAudience = "api", + ValidIssuer = options.Authority, + }; }); // Configure named auth policies that map directly to OAuth2.0 scopes