diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 575923d62c..435201037d 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2023.3.2", + "version": "2024.1.4", "commands": [ "jb" ] @@ -15,13 +15,13 @@ ] }, "dotnet-reportgenerator-globaltool": { - "version": "5.2.0", + "version": "5.3.6", "commands": [ "reportgenerator" ] }, "docfx": { - "version": "2.74.0", + "version": "2.76.0", "commands": [ "docfx" ] diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 4205b1ceec..e7d3ce2494 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -39,7 +39,7 @@ When you are creating an enhancement suggestion, please include as many details - **Use a clear and descriptive title** for the issue to identify the suggestion. - **Provide a step-by-step description of the suggested enhancement** in as many details as possible. -- **Provide specific examples to demonstrate the usage.** Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks). +- **Provide specific examples to demonstrate the usage.** Include copy/pasteable snippets which you use in those examples as [Markdown code blocks](https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks). - **Describe the current behavior and explain which behavior you expected to see instead** and why. - **Explain why this enhancement would be useful** to most users and isn't something that can or should be implemented in your API project directly. - **Verify that your enhancement does not conflict** with the [JSON:API specification](https://jsonapi.org/). @@ -56,7 +56,7 @@ Please follow these steps to have your contribution considered by the maintainer - Follow all instructions in the template. Don't forget to add tests and update documentation. - After you submit your pull request, verify that all status checks are passing. In release builds, all compiler warnings are treated as errors, so you should address them before push. -We use [CSharpGuidelines](https://csharpcodingguidelines.com/) as our coding standard (with a few minor exceptions). Coding style is validated during PR build, where we inject an extra settings layer that promotes various suggestions to warning level. This ensures a high-quality codebase without interfering too much when editing code. +We use [CSharpGuidelines](https://csharpcodingguidelines.com/) as our coding standard. Coding style is validated during PR build, where we inject an extra settings layer that promotes various IDE suggestions to warning level. This ensures a high-quality codebase without interfering too much while editing code. You can run the following [PowerShell scripts](https://github.com/PowerShell/PowerShell/releases) locally: - `pwsh ./inspectcode.ps1`: Scans the code for style violations and opens the result in your web browser. - `pwsh ./cleanupcode.ps1 [branch-name-or-commit-hash]`: Reformats the codebase to match with our configured style, optionally only changed files since the specified branch (usually master). @@ -86,13 +86,39 @@ public sealed class AppDbContext : DbContext } ``` +### Pull request workflow + +Please follow the steps and guidelines below for a smooth experience. + +Authors: +- When opening a new pull request, create it in **Draft** mode. +- After you've completed the work *and* all checks are green, click the **Ready for review** button. + - If you have permissions to do so, ask a team member for review. +- Once the review has started, don't force-push anymore. +- When you've addressed feedback from a conversation, mark it with a thumbs-up or add a some text. +- Don't close a conversation you didn't start. The creator closes it after verifying the concern has been addressed. +- Apply suggestions in a batch, instead of individual commits (to minimize email notifications). +- Re-request review when you're ready for another round. +- If you want to clean up your commits before merge, let the reviewer know in time. This is optional. + +Reviewers: +- If you're unable to review within a few days, let the author know what to expect. +- Use **Start a review** instead of **Add single comment** (to minimize email notifications). +- Consider to use suggestions (the ± button). +- Don't close a conversation you didn't start. Close the ones you opened after verifying the concern has been addressed. +- Once approved, use a merge commit only if all commits are clean. Otherwise, squash them into a single commit. + A commit is considered clean when: + - It is properly documented and covers all aspects of an isolated change (code, style, tests, docs). + - Checking out the commit results in a green build. + - Having this commit show up in the history is helpful (and can potentially be reverted). + ## Creating a release (for maintainers) - Verify documentation is up-to-date -- Bump the package version in Directory.Build.props +- Bump the package version in `Directory.Build.props` - Create a GitHub release -- Update https://github.com/json-api-dotnet/JsonApiDotNetCore.MongoDb to consume the new version and release -- Create a new branch in https://github.com/json-api-dotnet/MigrationGuide and update README.md in master +- Update [JsonApiDotNetCore.MongoDb](https://github.com/json-api-dotnet/JsonApiDotNetCore.MongoDb) to consume the new version and release +- Create a new branch in [MigrationGuide](https://github.com/json-api-dotnet/MigrationGuide) and update README.md in master, if major version change ## Backporting and hotfixes (for maintainers) @@ -101,7 +127,7 @@ public sealed class AppDbContext : DbContext git checkout tags/v2.5.1 -b release/2.5.2 ``` - Cherrypick the merge commit: `git cherry-pick {git commit SHA}` -- Bump the package version in Directory.Build.props +- Bump the package version in `Directory.Build.props` - Make any other compatibility, documentation, or tooling related changes - Push the branch to origin and verify the build - Once the build is verified, create a GitHub release, tagging the release branch diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eb3aab63b2..da0993c185 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Tune GitHub-hosted runner network uses: smorimoto/tune-github-hosted-runner-network@v1 - name: Setup PostgreSQL - uses: ikalnytskyi/action-setup-postgres@v5 + uses: ikalnytskyi/action-setup-postgres@v6 with: username: postgres password: postgres @@ -48,36 +48,6 @@ jobs: dotnet-version: | 6.0.x 8.0.x - - name: Setup PowerShell (Ubuntu) - if: matrix.os == 'ubuntu-latest' - run: | - dotnet tool install --global PowerShell - - name: Find latest PowerShell version (Windows) - if: matrix.os == 'windows-latest' - shell: pwsh - run: | - $packageName = "powershell" - $outputText = dotnet tool search $packageName --take 1 - $outputLine = ("" + $outputText) - $indexOfVersionLine = $outputLine.IndexOf($packageName) - $latestVersion = $outputLine.substring($indexOfVersionLine + $packageName.length).trim().split(" ")[0].trim() - - Write-Output "Found PowerShell version: $latestVersion" - Write-Output "POWERSHELL_LATEST_VERSION=$latestVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - name: Setup PowerShell (Windows) - if: matrix.os == 'windows-latest' - shell: cmd - run: | - set DOWNLOAD_LINK=https://github.com/PowerShell/PowerShell/releases/download/v%POWERSHELL_LATEST_VERSION%/PowerShell-%POWERSHELL_LATEST_VERSION%-win-x64.msi - set OUTPUT_PATH=%RUNNER_TEMP%\PowerShell-%POWERSHELL_LATEST_VERSION%-win-x64.msi - echo Downloading from: %DOWNLOAD_LINK% to: %OUTPUT_PATH% - curl --location --output %OUTPUT_PATH% %DOWNLOAD_LINK% - msiexec.exe /package %OUTPUT_PATH% /quiet USE_MU=1 ENABLE_MU=1 ADD_PATH=1 DISABLE_TELEMETRY=1 - - name: Setup PowerShell (macOS) - if: matrix.os == 'macos-latest' - run: | - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - brew install --cask powershell - name: Show installed versions shell: pwsh run: | @@ -138,7 +108,9 @@ jobs: dotnet test --no-build --configuration Release --collect:"XPlat Code Coverage" --logger "GitHubActions;summary.includeSkippedTests=true" - name: Upload coverage to codecov.io if: matrix.os == 'ubuntu-latest' - uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + uses: codecov/codecov-action@v4 with: fail_ci_if_error: true verbose: true @@ -204,7 +176,7 @@ jobs: run: | $inspectCodeOutputPath = Join-Path $env:RUNNER_TEMP 'jetbrains-inspectcode-results.xml' Write-Output "INSPECT_CODE_OUTPUT_PATH=$inspectCodeOutputPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - dotnet jb inspectcode JsonApiDotNetCore.sln --build --dotnetcoresdk=$(dotnet --version) --output="$inspectCodeOutputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:ContinuousIntegrationBuild=false --properties:RunAnalyzers=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal + dotnet jb inspectcode JsonApiDotNetCore.sln --build --dotnetcoresdk=$(dotnet --version) --output="$inspectCodeOutputPath" --format="xml" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:ContinuousIntegrationBuild=false --properties:RunAnalyzers=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal - name: Verify outcome shell: pwsh run: | @@ -300,7 +272,7 @@ jobs: dotnet nuget push "$env:GITHUB_WORKSPACE/packages/*.nupkg" --api-key "$env:GITHUB_TOKEN" --source 'github' - name: Publish documentation if: github.event_name == 'push' && github.ref == 'refs/heads/master' - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_branch: gh-pages diff --git a/.github/workflows/deps-review.yml b/.github/workflows/deps-review.yml index b9945082d5..b9d6d20fff 100644 --- a/.github/workflows/deps-review.yml +++ b/.github/workflows/deps-review.yml @@ -11,4 +11,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@v4 - name: 'Dependency Review' - uses: actions/dependency-review-action@v3 + uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/qodana.yml b/.github/workflows/qodana.yml index f1a64da824..8ce0acd5db 100644 --- a/.github/workflows/qodana.yml +++ b/.github/workflows/qodana.yml @@ -22,7 +22,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2023.3 + uses: JetBrains/qodana-action@v2024.1 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} - name: Upload results to artifacts on failure diff --git a/.gitignore b/.gitignore index 85bd0f1080..c1757fc159 100644 --- a/.gitignore +++ b/.gitignore @@ -423,3 +423,6 @@ FodyWeavers.xsd **/.idea/**/httpRequests/ **/.idea/**/dataSources/ !**/.idea/**/codeStyles/* + +# Workaround for https://github.com/microsoft/kiota/issues/4228 +kiota-lock.json diff --git a/Directory.Build.props b/Directory.Build.props index 0c2b51e13b..860217f52e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -27,6 +27,6 @@ false $(MSBuildThisFileDirectory)CodingGuidelines.ruleset $(MSBuildThisFileDirectory)tests.runsettings - 5.5.1 + 5.6.0 diff --git a/JsonApiDotNetCore.sln.DotSettings b/JsonApiDotNetCore.sln.DotSettings index 6e4e064588..399be60883 100644 --- a/JsonApiDotNetCore.sln.DotSettings +++ b/JsonApiDotNetCore.sln.DotSettings @@ -59,6 +59,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); SUGGESTION HINT WARNING + SUGGESTION DO_NOT_SHOW HINT SUGGESTION @@ -589,11 +590,14 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); False <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy> True True True True True + True True Replace argument null check using throw expression with Guard clause True diff --git a/README.md b/README.md index f34dfd1bee..5ae9184e0c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -

- -

+ # JsonApiDotNetCore A framework for building [JSON:API](http://jsonapi.org/) compliant REST APIs using .NET Core and Entity Framework Core. Includes support for [Atomic Operations](https://jsonapi.org/ext/atomic/). diff --git a/ROADMAP.md b/ROADMAP.md index 270ae294e6..7ba6a2a5a8 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,12 +2,14 @@ This document provides an overview of the direction this project is heading and lists what we intend to work on in the near future. -> Disclaimer: This is an open source project. The available time of our contributors varies and therefore we do not plan release dates. This document expresses our current intent, which may change over time. +> Disclaimer: This is an open-source project. The available time of our contributors varies and therefore we do not plan release dates. This document expresses our current intent, which may change over time. -We have interest in the following topics. It's too soon yet to decide whether they'll make it into v5.x or in a later major version. +We have an interest in the following topics. It's too soon yet to decide whether they'll make it into v5.x or in a later major version. +- OpenAPI (Swagger): Generate documentation and typed clients [#1046](https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/1046) +- Query strings on JSON-mapped columns [#1439](https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/1439) +- Improved SQL Server support [#1118](https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/1118) - Optimistic concurrency [#1119](https://github.com/json-api-dotnet/JsonApiDotNetCore/pull/1119) -- OpenAPI (Swagger) [#1046](https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/1046) - Fluent API [#776](https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/776) - Idempotency [#1132](https://github.com/json-api-dotnet/JsonApiDotNetCore/pull/1132) @@ -19,3 +21,5 @@ Please give us feedback that will give us insight on the following points: * Existing features that are missing some capability or otherwise don't work well enough. * Missing features that should be added to the product. * Design choices for a feature that is currently in-progress. + +Please consider to [sponsor the project](https://github.com/sponsors/json-api-dotnet). diff --git a/WarningSeverities.DotSettings b/WarningSeverities.DotSettings index a0fae5acd2..060df315df 100644 --- a/WarningSeverities.DotSettings +++ b/WarningSeverities.DotSettings @@ -166,7 +166,6 @@ WARNING WARNING WARNING - WARNING WARNING WARNING WARNING diff --git a/benchmarks/Serialization/SerializationBenchmarkBase.cs b/benchmarks/Serialization/SerializationBenchmarkBase.cs index 4b16afb393..eba222c9d1 100644 --- a/benchmarks/Serialization/SerializationBenchmarkBase.cs +++ b/benchmarks/Serialization/SerializationBenchmarkBase.cs @@ -41,7 +41,7 @@ protected SerializationBenchmarkBase() var linkBuilder = new FakeLinkBuilder(); var metaBuilder = new NoMetaBuilder(); - IQueryConstraintProvider[] constraintProviders = Array.Empty(); + IQueryConstraintProvider[] constraintProviders = []; var resourceDefinitionAccessor = new NeverResourceDefinitionAccessor(); var sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor); var requestQueryStringAccessor = new FakeRequestQueryStringAccessor(); diff --git a/docs/docfx.json b/docs/docfx.json index 1d0e192ac2..eb94da412e 100644 --- a/docs/docfx.json +++ b/docs/docfx.json @@ -24,6 +24,9 @@ "internals/**.md", "toc.yml", "*.md" + ], + "exclude": [ + "**/README.md" ] } ], diff --git a/docs/home/assets/dark-mode.css b/docs/home/assets/dark-mode.css new file mode 100644 index 0000000000..80e9bd516d --- /dev/null +++ b/docs/home/assets/dark-mode.css @@ -0,0 +1,16 @@ +html { + background-color: #171717 !important; + filter: invert(100%) hue-rotate(180deg) brightness(105%) contrast(85%); + -webkit-filter: invert(100%) hue-rotate(180deg) brightness(105%) contrast(85%); +} + +body { + background-color: #FFF !important; +} + +img, +video, +body * [style*="background-image"] { + filter: hue-rotate(180deg) contrast(100%) invert(100%); + -webkit-filter: hue-rotate(180deg) contrast(100%) invert(100%); +} diff --git a/docs/home/assets/home.css b/docs/home/assets/home.css index 273efe261b..5314474112 100644 --- a/docs/home/assets/home.css +++ b/docs/home/assets/home.css @@ -603,3 +603,11 @@ div[sponsor]:hover { padding: 3px 0; } } + +/*-------------------------------------------------------------- +# Theme selection +--------------------------------------------------------------*/ +.btn-theme:focus, +.btn-theme:active { + box-shadow: none !important; +} diff --git a/docs/home/assets/home.js b/docs/home/assets/home.js index ed6571bf23..40e31c15ad 100644 --- a/docs/home/assets/home.js +++ b/docs/home/assets/home.js @@ -1,3 +1,31 @@ +function setTheme(theme) { + const darkModeStyleSheet = document.getElementById('dark-mode-style-sheet'); + const activeTheme = document.getElementById('active-theme'); + + if (theme === "auto") { + darkModeStyleSheet.disabled = !window.matchMedia("(prefers-color-scheme: dark)").matches; + activeTheme.className = "bi-circle-half"; + } + else if (theme === "dark") { + darkModeStyleSheet.disabled = false; + activeTheme.className = "bi bi-moon"; + } else if (theme === "light") { + darkModeStyleSheet.disabled = true; + activeTheme.className = "bi bi-sun"; + } + + localStorage.setItem("theme", theme) +} + +$('.theme-choice').click(function () { + setTheme(this.dataset.theme); +}) + +function initTheme() { + const theme = localStorage.getItem("theme") || "auto"; + setTheme(theme); +} + !(function($) { "use strict"; @@ -89,6 +117,7 @@ } $(window).on('load', function() { aos_init(); + initTheme(); }); })(jQuery); diff --git a/docs/home/assets/img/apple-touch-icon.png b/docs/home/assets/img/apple-touch-icon.png index 447cec2c47..cc7166ba70 100644 Binary files a/docs/home/assets/img/apple-touch-icon.png and b/docs/home/assets/img/apple-touch-icon.png differ diff --git a/docs/home/assets/img/favicon.png b/docs/home/assets/img/favicon.png index d752fd5d71..de5ad58040 100644 Binary files a/docs/home/assets/img/favicon.png and b/docs/home/assets/img/favicon.png differ diff --git a/docs/home/assets/img/logo.png b/docs/home/assets/img/logo.png deleted file mode 100644 index 2f43cfa72a..0000000000 Binary files a/docs/home/assets/img/logo.png and /dev/null differ diff --git a/docs/home/assets/img/logo.svg b/docs/home/assets/img/logo.svg new file mode 100644 index 0000000000..c7339d2031 --- /dev/null +++ b/docs/home/assets/img/logo.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JsonApiDotNetCore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/home/index.html b/docs/home/index.html index 2c3e57849b..e21d52ee9b 100644 --- a/docs/home/index.html +++ b/docs/home/index.html @@ -9,26 +9,57 @@ - + + + + +
+ +

JsonApiDotNetCore

-

A framework for building JSON:API compliant REST APIs using .NET Core and Entity Framework Core. Includes support for Atomic Operations.

+

+ A framework for building JSON:API compliant REST APIs using .NET Core and Entity Framework Core. + Includes support for Atomic Operations. +

Read more Getting started Contribute on GitHub
- project logo + project logo
@@ -43,12 +74,13 @@

A framework for building JSON

Objectives

- The goal of this library is to simplify the development of APIs that leverage the full range of features provided by the JSON:API specification. + The goal of this library is to simplify the development of APIs that leverage the full range of features + provided by the JSON:API specification. You just need to focus on defining the resources and implementing your custom business logic.

- +

Eliminate boilerplate

We strive to eliminate as much boilerplate as possible by offering out-of-the-box features such as sorting, filtering and pagination.

@@ -69,28 +101,28 @@

Features

The following features are supported, from HTTP all the way down to the database

-
+

Filtering

Perform compound filtering using the filter query string parameter

-
+
-
+

Sorting

Order resources on one or multiple attributes using the sort query string parameter

-