diff --git a/.changeset/README.md b/.changeset/README.md
new file mode 100644
index 0000000..654c6d4
--- /dev/null
+++ b/.changeset/README.md
@@ -0,0 +1,8 @@
+# Changesets
+
+Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
+with multi-package repos, or single-package repos to help you version and publish your code. You can
+find the full documentation for it [in our repository](https://github.com/changesets/changesets).
+
+We have a quick list of common questions to get you started engaging with this project in
+[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md).
diff --git a/.changeset/config.json b/.changeset/config.json
new file mode 100644
index 0000000..a5c99b8
--- /dev/null
+++ b/.changeset/config.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json",
+ "changelog": [
+ "@changesets/changelog-github",
+ { "repo": "neolution-ch/Neolution.Extensions.Caching" }
+ ],
+ "commit": false,
+ "fixed": [
+ [
+ "@neolution-ch/neolution.extensions.caching.abstractions",
+ "@neolution-ch/neolution.extensions.caching.distributed",
+ "@neolution-ch/neolution.extensions.caching.inmemory",
+ "@neolution-ch/neolution.extensions.caching.redishybrid"
+ ]
+ ],
+ "linked": [],
+ "access": "public",
+ "baseBranch": "main",
+ "updateInternalDependencies": "patch",
+ "ignore": []
+}
diff --git a/.changeset/strong-dragons-like.md b/.changeset/strong-dragons-like.md
new file mode 100644
index 0000000..a845151
--- /dev/null
+++ b/.changeset/strong-dragons-like.md
@@ -0,0 +1,2 @@
+---
+---
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..c5f84f8
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,29 @@
+name: Changeset Check
+
+on:
+ pull_request:
+ branches:
+ - main
+ - "release/**"
+
+jobs:
+ changeset-check:
+ name: Changeset Check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v6
+ with:
+ node-version: 24
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Check for changesets
+ if: github.head_ref != 'changeset-release/main' && !startsWith(github.head_ref, 'changeset-release/release/')
+ run: npx changeset status --since=origin/${{ github.base_ref }}
diff --git a/.github/workflows/dependabot-changeset.yml b/.github/workflows/dependabot-changeset.yml
new file mode 100644
index 0000000..d7b69c2
--- /dev/null
+++ b/.github/workflows/dependabot-changeset.yml
@@ -0,0 +1,82 @@
+name: Dependabot Changeset
+
+on:
+ pull_request:
+ types: [opened, synchronize]
+
+permissions:
+ contents: write
+
+jobs:
+ generate-changeset:
+ name: Generate Changeset
+ runs-on: ubuntu-latest
+ if: github.actor == 'dependabot[bot]'
+ steps:
+ - name: Generate App Token
+ id: app-token
+ uses: actions/create-github-app-token@v3
+ with:
+ app-id: ${{ secrets.CHANGSETS_BOT_APP_ID }}
+ private-key: ${{ secrets.CHANGSETS_BOT_PRIVATE_KEY }}
+
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+ ref: ${{ github.event.pull_request.head.ref }}
+ token: ${{ steps.app-token.outputs.token }}
+
+ - name: Check for existing changeset
+ id: check-changeset
+ shell: bash
+ run: |
+ CHANGESET_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- '.changeset/*.md' | grep -v README.md || true)
+ if [ -n "$CHANGESET_FILES" ]; then
+ echo "exists=true" >> "$GITHUB_OUTPUT"
+ echo "Changeset already exists, skipping generation"
+ else
+ echo "exists=false" >> "$GITHUB_OUTPUT"
+ fi
+
+ - name: Detect packable project changes
+ id: detect-changes
+ if: steps.check-changeset.outputs.exists == 'false'
+ shell: bash
+ run: |
+ # Any change to a packable .csproj propagates to consumers via NuGet
+ # dependencies. Changes confined to the (non-packable) UnitTests
+ # project under tests/ are excluded automatically and should produce
+ # an empty changeset.
+ CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- 'src/**/*.csproj')
+ if [ -n "$CHANGED" ]; then
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ echo "Packable .csproj changes detected:"
+ echo "$CHANGED"
+ else
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ echo "No packable .csproj changes detected (test-only or other internal update)"
+ fi
+
+ - name: Setup Node.js
+ if: steps.check-changeset.outputs.exists == 'false'
+ uses: actions/setup-node@v6
+ with:
+ node-version: 24
+
+ - name: Generate changeset
+ if: steps.check-changeset.outputs.exists == 'false'
+ run: node scripts/generate-dependabot-changeset.js
+ env:
+ PR_TITLE: ${{ github.event.pull_request.title }}
+ PR_BODY: ${{ github.event.pull_request.body }}
+ PACKABLE_PROJECTS_CHANGED: ${{ steps.detect-changes.outputs.changed }}
+
+ - name: Commit and push changeset
+ if: steps.check-changeset.outputs.exists == 'false'
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add .changeset/
+ git commit -m "chore: add changeset for dependency updates"
+ git push
diff --git a/.github/workflows/dotnet-publish.yml b/.github/workflows/dotnet-publish.yml
deleted file mode 100644
index a61f01a..0000000
--- a/.github/workflows/dotnet-publish.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-# https://docs.microsoft.com/en-us/azure/devops/artifacts/quickstarts/github-actions?view=azure-devops
-name: Publish NuGet package
-
-on:
- push:
- tags:
- - 'v*.*.*'
- workflow_dispatch:
-
-env:
- ARTIFACTS_FEED_URL: https://api.nuget.org/v3/index.json
- BUILD_CONFIGURATION: "Release"
- DOTNET_VERSION: "6.x"
-
-jobs:
- build-and-deploy:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v2
- with:
- fetch-depth: 0 # Needed for GitVersion to function correctly
-
- - name: Setup .NET
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: ${{ env.DOTNET_VERSION }}
- source-url: ${{ env.ARTIFACTS_FEED_URL }}
- env:
- NUGET_AUTH_TOKEN: ${{ secrets.NUGET_API_KEY_NEOLUTION }}
-
- - name: Install GitVersion
- uses: gittools/actions/gitversion/setup@v0.9.7
- with:
- versionSpec: '5.x'
-
- - name: Determine version number
- uses: gittools/actions/gitversion/execute@v0.9.7
-
- - name: Build and pack
- run: |
- dotnet restore
- dotnet build --configuration '${{ env.BUILD_CONFIGURATION }}' -p:Version=$GITVERSION_NUGETVERSION
- dotnet pack Neolution.Extensions.Caching.Abstractions/Neolution.Extensions.Caching.Abstractions.csproj --configuration '${{ env.BUILD_CONFIGURATION }}' --no-build -p:PackageVersion=$GITVERSION_NUGETVERSION
- dotnet pack Neolution.Extensions.Caching.InMemory/Neolution.Extensions.Caching.InMemory.csproj --configuration '${{ env.BUILD_CONFIGURATION }}' --no-build -p:PackageVersion=$GITVERSION_NUGETVERSION
- dotnet pack Neolution.Extensions.Caching.RedisHybrid/Neolution.Extensions.Caching.RedisHybrid.csproj --configuration '${{ env.BUILD_CONFIGURATION }}' --no-build -p:PackageVersion=$GITVERSION_NUGETVERSION
- dotnet pack Neolution.Extensions.Caching.Distributed/Neolution.Extensions.Caching.Distributed.csproj --configuration '${{ env.BUILD_CONFIGURATION }}' --no-build -p:PackageVersion=$GITVERSION_NUGETVERSION
-
-
- - name: Push NuGet package
- run: dotnet nuget push --skip-duplicate -k $NUGET_AUTH_TOKEN **/bin/Release/*.nupkg
- env:
- NUGET_AUTH_TOKEN: ${{ secrets.NUGET_API_KEY_NEOLUTION }}
diff --git a/.github/workflows/nuget-publish.yml b/.github/workflows/nuget-publish.yml
new file mode 100644
index 0000000..6cbfbd8
--- /dev/null
+++ b/.github/workflows/nuget-publish.yml
@@ -0,0 +1,80 @@
+name: NuGet Publish
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ publish:
+ name: Pack and push to nuget.org
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ ref: ${{ github.event.release.tag_name }}
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: "8.x"
+
+ - name: Map tag to project
+ id: map
+ shell: bash
+ run: |
+ TAG="${{ github.event.release.tag_name }}"
+ VERSION="${TAG##*@}"
+ NAME="${TAG%@*}"
+
+ PROJ_DIR=$(node -e "
+ const fs = require('fs');
+ const path = require('path');
+ for (const dir of fs.readdirSync('src')) {
+ const p = path.join('src', dir, 'package.json');
+ if (!fs.existsSync(p)) continue;
+ const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
+ if (pkg.name === process.argv[1]) {
+ console.log(path.join('src', dir));
+ break;
+ }
+ }
+ " "$NAME")
+
+ if [ -z "$PROJ_DIR" ]; then
+ echo "Tag '$TAG' does not match a known package under src/. Skipping."
+ echo "skip=true" >> "$GITHUB_OUTPUT"
+ exit 0
+ fi
+
+ PROJ_NAME=$(basename "$PROJ_DIR")
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
+ echo "project_dir=$PROJ_DIR" >> "$GITHUB_OUTPUT"
+ echo "project_name=$PROJ_NAME" >> "$GITHUB_OUTPUT"
+
+ - name: Remove package.json files from pack input
+ if: steps.map.outputs.skip != 'true'
+ shell: bash
+ run: find . -name package.json -not -path "./node_modules/*" -delete
+
+ - name: Restore
+ if: steps.map.outputs.skip != 'true'
+ run: dotnet restore ${{ steps.map.outputs.project_dir }}/${{ steps.map.outputs.project_name }}.csproj
+
+ - name: Pack
+ if: steps.map.outputs.skip != 'true'
+ run: |
+ dotnet pack ${{ steps.map.outputs.project_dir }}/${{ steps.map.outputs.project_name }}.csproj \
+ --configuration Release \
+ --no-restore \
+ -p:Version=${{ steps.map.outputs.version }} \
+ -p:PackageVersion=${{ steps.map.outputs.version }} \
+ -o ./nupkgs
+
+ - name: Push
+ if: steps.map.outputs.skip != 'true'
+ run: |
+ dotnet nuget push ./nupkgs/*.nupkg \
+ --source https://api.nuget.org/v3/index.json \
+ --api-key ${{ secrets.NUGET_API_KEY_NEOLUTION }} \
+ --skip-duplicate
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..7644bc2
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,104 @@
+name: Release
+
+on:
+ push:
+ branches:
+ - main
+ - "release/**"
+
+concurrency: ${{ github.workflow }}-${{ github.ref }}
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Generate App Token
+ id: app-token
+ uses: actions/create-github-app-token@v3
+ with:
+ app-id: ${{ secrets.CHANGSETS_BOT_APP_ID }}
+ private-key: ${{ secrets.CHANGSETS_BOT_PRIVATE_KEY }}
+
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+ token: ${{ steps.app-token.outputs.token }}
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v6
+ with:
+ node-version: 24
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Create Release Pull Request or Publish
+ id: changesets
+ uses: changesets/action@v1
+ with:
+ version: node scripts/sync-versions.js
+ publish: node scripts/publish.js
+ title: "chore: version packages"
+ commit: "chore: version packages"
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
+
+ - name: Create release branch on major version bump
+ if: steps.changesets.outputs.published == 'true' && github.ref == 'refs/heads/main'
+ uses: actions/github-script@v8
+ with:
+ script: |
+ const published = JSON.parse('${{ steps.changesets.outputs.publishedPackages }}');
+ if (!published.length) return;
+
+ const newVersion = published[0].version;
+ const newMajor = parseInt(newVersion.split('.')[0], 10);
+
+ // Only act on stable major bumps (not prereleases)
+ if (newVersion.includes('-') || newMajor < 1) return;
+
+ const prevMajor = newMajor - 1;
+ const branchName = `release/v${prevMajor}.x`;
+
+ try {
+ await github.rest.repos.getBranch({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ branch: branchName,
+ });
+ console.log(`Branch ${branchName} already exists, skipping.`);
+ return;
+ } catch (e) {
+ if (e.status !== 404) throw e;
+ }
+
+ const tags = await github.paginate(github.rest.repos.listTags, {
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ per_page: 100,
+ });
+
+ const prevTag = tags.find(t => {
+ const match = t.name.match(/(?:^v?|@)(\d+)\.\d+\.\d+$/);
+ return match && parseInt(match[1], 10) === prevMajor;
+ });
+
+ if (!prevTag) {
+ console.log(`No tag found for v${prevMajor}, skipping branch creation.`);
+ return;
+ }
+
+ await github.rest.git.createRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: `refs/heads/${branchName}`,
+ sha: prevTag.commit.sha,
+ });
+
+ console.log(`Created ${branchName} from tag ${prevTag.name} (${prevTag.commit.sha}).`);
diff --git a/.gitignore b/.gitignore
index b8656b3..55c1eb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -426,3 +426,9 @@ App_Data/
# Repository rules
# ================
+
+# Changesets internal cache
+.changeset/.cache/
+
+# Local NuGet pack output
+nupkgs/
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..cffe8cd
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+save-exact=true
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..5d08263
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,15 @@
+
+
+ 2.1.1
+ Neolution
+ Neolution AG
+ Copyright © Neolution AG
+ https://github.com/neolution-ch/Neolution.Extensions.Caching
+ https://github.com/neolution-ch/Neolution.Extensions.Caching
+ git
+ MIT
+ true
+ true
+ snupkg
+
+
diff --git a/GitVersion.yml b/GitVersion.yml
deleted file mode 100644
index edd2ff1..0000000
--- a/GitVersion.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-mode: ContinuousDelivery
-branches:
- feature:
- mode: ContinuousDeployment
-ignore:
- sha: []
-merge-message-formats: {}
diff --git a/Neolution.Extensions.Caching.sln b/Neolution.Extensions.Caching.sln
index f1eaef3..1748c56 100644
--- a/Neolution.Extensions.Caching.sln
+++ b/Neolution.Extensions.Caching.sln
@@ -6,19 +6,19 @@ MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E00BB836-121A-4858-8763-4A47C8855095}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
- azure-pipelines.yml = azure-pipelines.yml
+ Directory.Build.props = Directory.Build.props
README.md = README.md
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.UnitTests", "Neolution.Extensions.Caching.UnitTests\Neolution.Extensions.Caching.UnitTests.csproj", "{04A35DA9-EEC3-4937-8A14-39623DA66F35}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.UnitTests", "tests\Neolution.Extensions.Caching.UnitTests\Neolution.Extensions.Caching.UnitTests.csproj", "{04A35DA9-EEC3-4937-8A14-39623DA66F35}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.Abstractions", "Neolution.Extensions.Caching.Abstractions\Neolution.Extensions.Caching.Abstractions.csproj", "{68AB5C41-FF5D-4669-8648-0F330AF73DE9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.Abstractions", "src\Neolution.Extensions.Caching.Abstractions\Neolution.Extensions.Caching.Abstractions.csproj", "{68AB5C41-FF5D-4669-8648-0F330AF73DE9}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.InMemory", "Neolution.Extensions.Caching.InMemory\Neolution.Extensions.Caching.InMemory.csproj", "{682B05A7-F3F3-4918-A5BB-8E6482E2C705}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.InMemory", "src\Neolution.Extensions.Caching.InMemory\Neolution.Extensions.Caching.InMemory.csproj", "{682B05A7-F3F3-4918-A5BB-8E6482E2C705}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.RedisHybrid", "Neolution.Extensions.Caching.RedisHybrid\Neolution.Extensions.Caching.RedisHybrid.csproj", "{49874974-90FA-4683-84BF-7B217D072899}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neolution.Extensions.Caching.RedisHybrid", "src\Neolution.Extensions.Caching.RedisHybrid\Neolution.Extensions.Caching.RedisHybrid.csproj", "{49874974-90FA-4683-84BF-7B217D072899}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neolution.Extensions.Caching.Distributed", "Neolution.Extensions.Caching.Distributed\Neolution.Extensions.Caching.Distributed.csproj", "{AFEFABB1-E20A-4274-8E2A-AC50123AF295}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neolution.Extensions.Caching.Distributed", "src\Neolution.Extensions.Caching.Distributed\Neolution.Extensions.Caching.Distributed.csproj", "{AFEFABB1-E20A-4274-8E2A-AC50123AF295}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index 5b89c1b..0000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,74 +0,0 @@
-# ASP.NET Core
-# Build and test ASP.NET Core projects targeting .NET Core.
-# Add steps that run tests, create a NuGet package, deploy, and more:
-# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core
-
-name: $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)
-
-trigger:
-- master
-- release/*
-
-pool:
- vmImage: Ubuntu-latest
-
-resources:
- repositories:
- - repository: templates
- type: git
- name: neolution-pipelines/pipeline-templates
-
-variables:
- BuildConfiguration: 'Release'
-
-steps:
-
-- task: UseDotNet@2
- displayName: Install .NET Core SDK
- inputs:
- packageType: 'sdk'
- version: '6.x'
-
-- task: gitversion/setup@0
- displayName: Install GitVersion
- inputs:
- versionSpec: '5.x'
-
-- task: gitversion/execute@0
- displayName: Execute GitVersion
-
-- task: PowerShell@2
- displayName: Update Build Number
- inputs:
- targetType: 'inline'
- script: 'Write-Host "##vso[build.updatebuildnumber]$(NuGetVersion)"'
-
-- task: DotNetCoreCLI@2
- displayName: Restore
- inputs:
- command: restore
- projects: '**/*.csproj'
- vstsFeed: 'dc68f94e-847b-4595-86ba-405d5744b21d'
-
-- task: DotNetCoreCLI@2
- displayName: Build
- inputs:
- projects: '**/*.csproj'
- arguments: '--configuration $(BuildConfiguration)'
-
-- template: testing/unittests.yml@templates
-
-- task: DotNetCoreCLI@2
- displayName: Pack
- inputs:
- command: pack
- packagesToPack: '**/Neolution.Extensions.Caching.Abstractions.csproj;**/Neolution.Extensions.Caching.RedisHybrid.csproj;**/Neolution.Extensions.Caching.InMemory.csproj;**/Neolution.Extensions.Caching.Distributed.csproj'
- nobuild: true
- versioningScheme: byEnvVar
- versionEnvVar: NuGetVersion
-
-- task: DotNetCoreCLI@2
- displayName: Push
- inputs:
- command: push
- publishVstsFeed: 'dc68f94e-847b-4595-86ba-405d5744b21d'
diff --git a/docs/CHANGESETS.md b/docs/CHANGESETS.md
new file mode 100644
index 0000000..35249ae
--- /dev/null
+++ b/docs/CHANGESETS.md
@@ -0,0 +1,349 @@
+# Changesets in this repo (NuGet edition)
+
+This guide explains how versioning and releases work in `Neolution.Extensions.Caching`. It is the .NET-flavoured counterpart of the org's canonical [Changesets Guide](https://github.com/neolution-ch/changeset-test/blob/main/docs/CHANGESETS.md). Read the canonical doc for the underlying mental model and rare scenarios (prereleases, backports, recovery). Read this doc for the specifics of working with a NuGet-only project.
+
+## Table of contents
+
+- [Overview](#overview)
+- [Why `package.json` files exist in a .NET repo](#why-packagejson-files-exist-in-a-net-repo)
+- [For contributors](#for-contributors)
+ - [Adding a changeset](#adding-a-changeset)
+ - [Choosing the right semver bump](#choosing-the-right-semver-bump)
+ - [Empty changesets](#empty-changesets)
+ - [What if you forget a changeset](#what-if-you-forget-a-changeset)
+ - [Changeset file format](#changeset-file-format)
+ - [Locally testing a `.nupkg` before opening a PR](#locally-testing-a-nupkg-before-opening-a-pr)
+- [For maintainers](#for-maintainers)
+ - [Regular release flow](#regular-release-flow)
+ - [How the fixed group works](#how-the-fixed-group-works)
+ - [Prereleases / release candidates](#prereleases--release-candidates)
+ - [Backporting on `release/vX.x` branches](#backporting-on-releasevxx-branches)
+ - [Recovering from a failed publish](#recovering-from-a-failed-publish)
+ - [Manual publish fallback](#manual-publish-fallback)
+ - [Reverting a release](#reverting-a-release)
+ - [Dependabot automation](#dependabot-automation)
+- [Reference](#reference)
+ - [`.changeset/config.json`](#changesetconfigjson)
+ - [Workflows](#workflows)
+ - [Useful commands](#useful-commands)
+ - [Where to find what](#where-to-find-what)
+
+## Overview
+
+This repository publishes four libraries to **nuget.org**, always in lockstep at the same version:
+
+| Library | Path | Workspace package name |
+| --------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------ |
+| `Neolution.Extensions.Caching.Abstractions` | `src/Neolution.Extensions.Caching.Abstractions/` | `@neolution-ch/neolution.extensions.caching.abstractions` |
+| `Neolution.Extensions.Caching.Distributed` | `src/Neolution.Extensions.Caching.Distributed/` | `@neolution-ch/neolution.extensions.caching.distributed` |
+| `Neolution.Extensions.Caching.InMemory` | `src/Neolution.Extensions.Caching.InMemory/` | `@neolution-ch/neolution.extensions.caching.inmemory` |
+| `Neolution.Extensions.Caching.RedisHybrid` | `src/Neolution.Extensions.Caching.RedisHybrid/` | `@neolution-ch/neolution.extensions.caching.redishybrid` |
+
+The test project lives at `tests/Neolution.Extensions.Caching.UnitTests/`. It is **not** a workspace package (`tests/` is outside the `src/*` workspace glob), so changes confined to it never require a changeset.
+
+The release flow:
+
+```
+PR opens
+ ├─ build + test (dotnet.yml)
+ └─ Changeset Check (ci.yml) ← blocks PR if no changeset
+
+PR merges to main
+ └─ Release workflow opens/updates a "chore: version packages" PR
+
+Version Packages PR merges to main
+ └─ Release workflow runs scripts/publish.js
+ → pushes 4 git tags
+ → creates 4 GitHub Releases
+ ↓
+ release: published event (×4)
+ ↓
+ nuget-publish.yml fires four times in parallel
+ → dotnet pack + dotnet nuget push
+ ↓
+ Four new versions on nuget.org
+```
+
+## Why `package.json` files exist in a .NET repo
+
+Changesets is a JavaScript tool. To use it for version coordination on a .NET project, the repo grows a few npm-flavoured files. None of them are ever published to npm:
+
+- Every per-project `package.json` carries `"private": true`. `npm publish` refuses to run on private packages, so a fat-fingered local `npm publish` cannot leak anything.
+- The `@neolution-ch/...` names are local identifiers for the changesets config. They are not reserved on npmjs.com.
+- `nuget-publish.yml` deletes every `package.json` before `dotnet pack` runs, so they never end up inside the `.nupkg`.
+- The only artifact pushed anywhere outside this repo is the `.nupkg`, going to nuget.org via `dotnet nuget push` using `NUGET_API_KEY_NEOLUTION`.
+
+Mental model:
+
+| Concern | Owned by | Output |
+| ------------------------ | --------------------------------- | -------------------------------------------- |
+| What version is next | Changesets (JS, `package.json`) | Bumped `package.json` + `Directory.Build.props` |
+| What changed (notes) | Changesets | `CHANGELOG.md`, GitHub Release body |
+| Building the artifact | `dotnet pack` | `.nupkg` files |
+| Publishing the artifact | `dotnet nuget push` | nuget.org listing |
+
+Treat `package.json` like the old `GitVersion.yml`: configuration for the versioning tool, not something downstream consumers ever see.
+
+## For contributors
+
+### Adding a changeset
+
+After making your code changes, from the repo root:
+
+```bash
+npx changeset
+```
+
+Pick **any one** of the four libraries (the other three auto-bump to match, see [How the fixed group works](#how-the-fixed-group-works)), pick a bump type, write a one-paragraph summary. The result is a new file under `.changeset/`, e.g. `.changeset/brave-dogs-dance.md`. Commit it alongside your code change.
+
+### Choosing the right semver bump
+
+| Bump | When to use | Example |
+| ----- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
+| patch | Bug fix, internal refactor that doesn't change the public API, doc update on a public type | Fix `RedisHybridCache.Set` swallowing exceptions; rename a private field |
+| minor | Backwards-compatible addition | Add a new option on `MessagePackDistributedCacheOptions`; add a new public extension |
+| major | Breaking change | Rename or remove a public type/method; change a method signature; drop a TFM |
+
+When in doubt, pick the smallest bump that's accurate.
+
+### Empty changesets
+
+Some changes don't need to ship — CI tweaks, doc-only changes under `docs/`, build script edits. The CI **still requires** a changeset to be present, so add an empty one:
+
+```bash
+npx changeset --empty
+```
+
+The PR title will be reused as the changeset summary. Nothing gets bumped, no changelog entry is generated.
+
+### What if you forget a changeset
+
+The **Changeset Check** workflow fails. Fix:
+
+```bash
+npx changeset # or --empty for non-shipping changes
+git add .changeset/*.md
+git commit -m "Add changeset"
+git push
+```
+
+CI re-runs and goes green.
+
+### Changeset file format
+
+```markdown
+---
+"@neolution-ch/neolution.extensions.caching.distributed": minor
+---
+
+Add `IDistributedCache.GetOrSetAsync` overload that accepts a `CancellationToken`.
+```
+
+The YAML frontmatter declares the bump. The body is Markdown and becomes the changelog entry. Because the four packages are fixed, listing just one is enough.
+
+### Locally testing a `.nupkg` before opening a PR
+
+The canonical doc covers npm-only [pkg.pr.new](https://pkg.pr.new) previews. For NuGet, do it manually:
+
+1. Pack the library locally:
+ ```bash
+ dotnet pack src/Neolution.Extensions.Caching.Distributed/Neolution.Extensions.Caching.Distributed.csproj \
+ -c Release \
+ -p:Version=2.2.0-local.1 \
+ -o ./nupkgs
+ ```
+2. Add a `NuGet.config` to the consuming project that points at the local folder:
+ ```xml
+
+
+
+
+
+ ```
+3. `dotnet add package Neolution.Extensions.Caching.Distributed --version 2.2.0-local.1`
+
+Use any unique prerelease suffix you want; the package never leaves your disk.
+
+## For maintainers
+
+### Regular release flow
+
+1. Contributor PR with a changeset merges into `main`.
+2. **Release workflow** opens (or updates) a PR titled **chore: version packages**. The PR diff:
+ - Bumps every `package.json` from `X.Y.Z` to the new version (all four, because fixed).
+ - Bumps `Directory.Build.props` `` to the new version.
+ - Generates/updates per-project `CHANGELOG.md` files.
+ - Deletes the consumed `.changeset/*.md` files.
+3. Review the PR, then **merge it** when you want to ship.
+4. The Release workflow runs again, executes `scripts/publish.js`, the action pushes four tags and creates four GitHub Releases.
+5. The `release: published` event fires the **NuGet Publish** workflow four times (once per Release), each packing and pushing one library to nuget.org.
+
+You can batch multiple changeset-bearing PRs before merging the Version Packages PR. All accumulated changesets fold into a single release.
+
+### How the fixed group works
+
+`fixed: [[…]]` in `.changeset/config.json` lists all four library package names as one group. The rules:
+
+- All four always share the same version.
+- A changeset selecting any one of them bumps all four.
+- The **highest requested bump wins**: if changeset A says `patch` and changeset B says `minor`, the next release is a `minor`.
+- Every release ships all four packages, even if only one changed code-wise. This matches the existing pre-changesets convention on nuget.org (every version 2.0.0 through 2.1.1 is present for all four).
+
+Example, starting at `2.1.1`:
+
+| Pending changesets | Next version |
+| --------------------------------------------------------- | ------------ |
+| `…distributed: patch` | `2.1.2` |
+| `…inmemory: minor` | `2.2.0` |
+| `…redishybrid: patch` + `…abstractions: minor` | `2.2.0` |
+| `…abstractions: major` | `3.0.0` |
+
+### Prereleases / release candidates
+
+Use only for major releases. See the canonical doc's [Prereleases section](https://github.com/neolution-ch/changeset-test/blob/main/docs/CHANGESETS.md#prereleases--release-candidates) for the full walkthrough. nuget.org accepts SemVer 2.0 prerelease suffixes (`3.0.0-beta.0`, `3.0.0-rc.1`) natively, so the npm-flavoured commands in the canonical doc work as-is:
+
+```bash
+git checkout -b chore/enter-beta
+npx changeset pre enter beta
+git commit -am "Enter prerelease mode (beta)"
+# PR → main, merge
+```
+
+Once on `main`, every Version Packages PR bumps the beta counter. Exit with `npx changeset pre exit` on a new PR.
+
+Consumers on `dotnet add package Neolution.Extensions.Caching.Abstractions` keep getting the latest stable (e.g. `2.1.1`); they have to ask for the prerelease explicitly with `--prerelease` or `--version 3.0.0-beta.0`.
+
+### Backporting on `release/vX.x` branches
+
+When `main` has moved on to a new major (e.g. v3) but a fix is needed for the old major (v2), use a `release/v2.x` branch. The Release workflow auto-creates `release/v(N-1).x` whenever a new major is published from `main` — see `scripts:` block in `release.yml`. For all other cases (manually creating it retroactively, when to use it, what a backport PR looks like), follow the [Backporting section of the canonical doc](https://github.com/neolution-ch/changeset-test/blob/main/docs/CHANGESETS.md#backporting--hotfixes-on-older-versions) — both `ci.yml` and `release.yml` already trigger on `release/**`.
+
+> **nuget.org has no dist-tags.** The canonical doc's `--tag release-v1` mechanism is npm-only. On nuget.org, "latest" is always the highest stable SemVer. A backport release like `2.2.4` will never be served to a `dotnet add package` that resolves to `3.x` because `3.x > 2.x`. No extra config needed.
+
+### Recovering from a failed publish
+
+`dotnet nuget push --skip-duplicate` is idempotent. If `nuget-publish.yml` fails partway:
+
+1. Open the failing run on the **Actions** tab.
+2. Click **Re-run failed jobs**.
+3. Already-pushed packages return "Conflict 409" which `--skip-duplicate` swallows; remaining packages get pushed.
+
+If the Release workflow created the tags + Releases but a Release fired the wrong publish:
+- Inspect the Release page — confirm which package it represents (`@neolution-ch/...@version` tag).
+- Re-run the corresponding NuGet Publish workflow run.
+
+### Manual publish fallback
+
+If CI is broken and a release is urgent:
+
+```bash
+# Pull latest main (or the release branch)
+git checkout main && git pull
+
+# If versions haven't been bumped yet, do it locally:
+node scripts/sync-versions.js
+git add . && git commit -m "Version packages"
+
+# Pack each library (any directory under src/ with a .csproj)
+for dir in src/*/; do
+ proj=$(basename "$dir")
+ dotnet pack "$dir$proj.csproj" -c Release -o ./nupkgs
+done
+
+# Push to nuget.org with a maintainer's personal API key
+dotnet nuget push ./nupkgs/*.nupkg \
+ --source https://api.nuget.org/v3/index.json \
+ --api-key \
+ --skip-duplicate
+
+# Push tags (one per package)
+git tag "@neolution-ch/neolution.extensions.caching.abstractions@2.2.0"
+git tag "@neolution-ch/neolution.extensions.caching.distributed@2.2.0"
+git tag "@neolution-ch/neolution.extensions.caching.inmemory@2.2.0"
+git tag "@neolution-ch/neolution.extensions.caching.redishybrid@2.2.0"
+git push --tags
+```
+
+Then create the GitHub Releases manually from the tags, copy-pasting the changelog body.
+
+### Reverting a release
+
+nuget.org does **not allow deletion** of published packages. It does allow **unlisting** (the version stays accessible by exact version, but isn't returned for "latest" or default queries).
+
+Preferred path:
+
+1. `git revert `
+2. `npx changeset` → patch → "Revert "
+3. Merge to `main`, let the regular flow ship the next patch.
+
+Only unlist on nuget.org if the bad version is genuinely dangerous (e.g. ships secrets). To unlist: nuget.org → package page → Manage Package → Listing → Unlist.
+
+### Dependabot automation
+
+Dependabot PRs do not include changesets, so CI would normally fail. The **Dependabot Changeset** workflow handles this automatically:
+
+1. Dependabot opens a PR.
+2. `dependabot-changeset.yml` runs because `github.actor == 'dependabot[bot]'`.
+3. The workflow checks whether any `.csproj` under `src/` changed (the test project under `tests/` is excluded automatically).
+ - If yes → emits a `patch` changeset for all four fixed-group packages.
+ - If no (test-only update) → emits an **empty** changeset.
+4. `scripts/generate-dependabot-changeset.js` parses the PR body for `Bumps [X] from Y to Z` / `Updated [X] from Y to Z` lines and includes a bump table in the changeset body.
+5. The bot commits the changeset to the PR branch. CI re-runs, passes.
+
+If parsing fails, the workflow still emits a changeset using just the PR title. It never blocks the PR.
+
+## Reference
+
+### `.changeset/config.json`
+
+| Option | Value | Meaning |
+| ---------------------------- | -------------------------------------------------------------- | ----------------------------------------------------- |
+| `changelog` | `["@changesets/changelog-github", { "repo": "neolution-ch/Neolution.Extensions.Caching" }]` | Changelogs include PR links and contributor credit |
+| `commit` | `false` | `npx changeset` does not auto-commit |
+| `fixed` | All four library names in one inner array | The four packages always share a version |
+| `access` | `public` | Marks intent (would only matter on an npm publish) |
+| `baseBranch` | `main` | Comparisons run against `origin/main` |
+| `updateInternalDependencies` | `patch` | Internal dependency ranges update on every release |
+| `ignore` | `[]` | No packages excluded |
+
+### Workflows
+
+| File | Trigger | Purpose |
+| --------------------------------------------- | -------------------------------------- | -------------------------------------------------------- |
+| `.github/workflows/dotnet.yml` | PR or push to `main` | Build + test |
+| `.github/workflows/ci.yml` | PR to `main` / `release/**` | **Changeset Check** — blocks PRs without a changeset |
+| `.github/workflows/release.yml` | Push to `main` / `release/**` | Open Version PR; on subsequent push, push tags + Releases |
+| `.github/workflows/nuget-publish.yml` | `release: published` | `dotnet pack` + `dotnet nuget push` |
+| `.github/workflows/dependabot-changeset.yml` | PR opened/synced (Dependabot only) | Auto-generate a changeset for the PR |
+
+The Release workflow uses the **CSAG-Changesets-Bot** GitHub App token, not `GITHUB_TOKEN`, so Version Packages PRs trigger CI checks (GITHUB_TOKEN-pushed PRs do not).
+
+### Useful commands
+
+```bash
+# Add a changeset (interactive)
+npx changeset
+
+# Add an empty changeset (no release)
+npx changeset --empty
+
+# Check if changesets exist (what CI runs)
+npx changeset status --since=origin/main
+
+# Preview what versions would be bumped
+npx changeset status --verbose
+
+# Apply changesets locally (bump version + write CHANGELOGs + update .csproj via Directory.Build.props)
+node scripts/sync-versions.js
+
+# Enter / exit prerelease mode (allowed tags: alpha, beta, rc)
+npx changeset pre enter
+npx changeset pre exit
+```
+
+### Where to find what
+
+- **Current version of the libraries** → `Directory.Build.props`'s `` (and any `package.json`).
+- **What's been released** → GitHub Releases page + each `src/Neolution.Extensions.Caching.*/CHANGELOG.md`.
+- **What's queued to ship next** → `.changeset/*.md` files. `npx changeset status --verbose` summarises.
+- **Why a tag has the form `@neolution-ch/...@version`** → changesets/action [tag-name code](https://github.com/changesets/action/blob/main/src/run.ts).
+- **Canonical org-wide release flow doc** → [neolution-ch/changeset-test/docs/CHANGESETS.md](https://github.com/neolution-ch/changeset-test/blob/main/docs/CHANGESETS.md).
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..894329a
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1414 @@
+{
+ "name": "neolution.extensions.caching",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "neolution.extensions.caching",
+ "workspaces": [
+ "src/*"
+ ],
+ "devDependencies": {
+ "@changesets/changelog-github": "^0.5.0",
+ "@changesets/cli": "^2.27.0"
+ }
+ },
+ "Neolution.Extensions.Caching.Abstractions": {
+ "name": "@neolution-ch/neolution.extensions.caching.abstractions",
+ "version": "2.1.1",
+ "extraneous": true
+ },
+ "Neolution.Extensions.Caching.Distributed": {
+ "name": "@neolution-ch/neolution.extensions.caching.distributed",
+ "version": "2.1.1",
+ "extraneous": true
+ },
+ "Neolution.Extensions.Caching.InMemory": {
+ "name": "@neolution-ch/neolution.extensions.caching.inmemory",
+ "version": "2.1.1",
+ "extraneous": true
+ },
+ "Neolution.Extensions.Caching.RedisHybrid": {
+ "name": "@neolution-ch/neolution.extensions.caching.redishybrid",
+ "version": "2.1.1",
+ "extraneous": true
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
+ "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@changesets/apply-release-plan": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.1.1.tgz",
+ "integrity": "sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/config": "^3.1.4",
+ "@changesets/get-version-range-type": "^0.4.0",
+ "@changesets/git": "^3.0.4",
+ "@changesets/should-skip-package": "^0.1.2",
+ "@changesets/types": "^6.1.0",
+ "@manypkg/get-packages": "^1.1.3",
+ "detect-indent": "^6.0.0",
+ "fs-extra": "^7.0.1",
+ "lodash.startcase": "^4.4.0",
+ "outdent": "^0.5.0",
+ "prettier": "^2.7.1",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.5.3"
+ }
+ },
+ "node_modules/@changesets/assemble-release-plan": {
+ "version": "6.0.10",
+ "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.10.tgz",
+ "integrity": "sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.4",
+ "@changesets/should-skip-package": "^0.1.2",
+ "@changesets/types": "^6.1.0",
+ "@manypkg/get-packages": "^1.1.3",
+ "semver": "^7.5.3"
+ }
+ },
+ "node_modules/@changesets/changelog-git": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz",
+ "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/types": "^6.1.0"
+ }
+ },
+ "node_modules/@changesets/changelog-github": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.2.tgz",
+ "integrity": "sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/get-github-info": "^0.7.0",
+ "@changesets/types": "^6.1.0",
+ "dotenv": "^8.1.0"
+ }
+ },
+ "node_modules/@changesets/cli": {
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.31.0.tgz",
+ "integrity": "sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/apply-release-plan": "^7.1.1",
+ "@changesets/assemble-release-plan": "^6.0.10",
+ "@changesets/changelog-git": "^0.2.1",
+ "@changesets/config": "^3.1.4",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.4",
+ "@changesets/get-release-plan": "^4.0.16",
+ "@changesets/git": "^3.0.4",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/pre": "^2.0.2",
+ "@changesets/read": "^0.6.7",
+ "@changesets/should-skip-package": "^0.1.2",
+ "@changesets/types": "^6.1.0",
+ "@changesets/write": "^0.4.0",
+ "@inquirer/external-editor": "^1.0.2",
+ "@manypkg/get-packages": "^1.1.3",
+ "ansi-colors": "^4.1.3",
+ "enquirer": "^2.4.1",
+ "fs-extra": "^7.0.1",
+ "mri": "^1.2.0",
+ "package-manager-detector": "^0.2.0",
+ "picocolors": "^1.1.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.5.3",
+ "spawndamnit": "^3.0.1",
+ "term-size": "^2.1.0"
+ },
+ "bin": {
+ "changeset": "bin.js"
+ }
+ },
+ "node_modules/@changesets/config": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.4.tgz",
+ "integrity": "sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.4",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/should-skip-package": "^0.1.2",
+ "@changesets/types": "^6.1.0",
+ "@manypkg/get-packages": "^1.1.3",
+ "fs-extra": "^7.0.1",
+ "micromatch": "^4.0.8"
+ }
+ },
+ "node_modules/@changesets/errors": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz",
+ "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extendable-error": "^0.1.5"
+ }
+ },
+ "node_modules/@changesets/get-dependents-graph": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.4.tgz",
+ "integrity": "sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/types": "^6.1.0",
+ "@manypkg/get-packages": "^1.1.3",
+ "picocolors": "^1.1.0",
+ "semver": "^7.5.3"
+ }
+ },
+ "node_modules/@changesets/get-github-info": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.7.0.tgz",
+ "integrity": "sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dataloader": "^1.4.0",
+ "node-fetch": "^2.5.0"
+ }
+ },
+ "node_modules/@changesets/get-release-plan": {
+ "version": "4.0.16",
+ "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.16.tgz",
+ "integrity": "sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/assemble-release-plan": "^6.0.10",
+ "@changesets/config": "^3.1.4",
+ "@changesets/pre": "^2.0.2",
+ "@changesets/read": "^0.6.7",
+ "@changesets/types": "^6.1.0",
+ "@manypkg/get-packages": "^1.1.3"
+ }
+ },
+ "node_modules/@changesets/get-version-range-type": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz",
+ "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@changesets/git": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz",
+ "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/errors": "^0.2.0",
+ "@manypkg/get-packages": "^1.1.3",
+ "is-subdir": "^1.1.1",
+ "micromatch": "^4.0.8",
+ "spawndamnit": "^3.0.1"
+ }
+ },
+ "node_modules/@changesets/logger": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz",
+ "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picocolors": "^1.1.0"
+ }
+ },
+ "node_modules/@changesets/parse": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.3.tgz",
+ "integrity": "sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/types": "^6.1.0",
+ "js-yaml": "^4.1.1"
+ }
+ },
+ "node_modules/@changesets/pre": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz",
+ "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/errors": "^0.2.0",
+ "@changesets/types": "^6.1.0",
+ "@manypkg/get-packages": "^1.1.3",
+ "fs-extra": "^7.0.1"
+ }
+ },
+ "node_modules/@changesets/read": {
+ "version": "0.6.7",
+ "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.7.tgz",
+ "integrity": "sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/git": "^3.0.4",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/parse": "^0.4.3",
+ "@changesets/types": "^6.1.0",
+ "fs-extra": "^7.0.1",
+ "p-filter": "^2.1.0",
+ "picocolors": "^1.1.0"
+ }
+ },
+ "node_modules/@changesets/should-skip-package": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz",
+ "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/types": "^6.1.0",
+ "@manypkg/get-packages": "^1.1.3"
+ }
+ },
+ "node_modules/@changesets/types": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz",
+ "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@changesets/write": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz",
+ "integrity": "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@changesets/types": "^6.1.0",
+ "fs-extra": "^7.0.1",
+ "human-id": "^4.1.1",
+ "prettier": "^2.7.1"
+ }
+ },
+ "node_modules/@inquirer/external-editor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz",
+ "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chardet": "^2.1.1",
+ "iconv-lite": "^0.7.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@manypkg/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "@types/node": "^12.7.1",
+ "find-up": "^4.1.0",
+ "fs-extra": "^8.1.0"
+ }
+ },
+ "node_modules/@manypkg/find-root/node_modules/@types/node": {
+ "version": "12.20.55",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
+ "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@manypkg/find-root/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/@manypkg/get-packages": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz",
+ "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "@changesets/types": "^4.0.1",
+ "@manypkg/find-root": "^1.1.0",
+ "fs-extra": "^8.1.0",
+ "globby": "^11.0.0",
+ "read-yaml-file": "^1.1.0"
+ }
+ },
+ "node_modules/@manypkg/get-packages/node_modules/@changesets/types": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz",
+ "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@manypkg/get-packages/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/@neolution-ch/neolution.extensions.caching.abstractions": {
+ "resolved": "src/Neolution.Extensions.Caching.Abstractions",
+ "link": true
+ },
+ "node_modules/@neolution-ch/neolution.extensions.caching.distributed": {
+ "resolved": "src/Neolution.Extensions.Caching.Distributed",
+ "link": true
+ },
+ "node_modules/@neolution-ch/neolution.extensions.caching.inmemory": {
+ "resolved": "src/Neolution.Extensions.Caching.InMemory",
+ "link": true
+ },
+ "node_modules/@neolution-ch/neolution.extensions.caching.redishybrid": {
+ "resolved": "src/Neolution.Extensions.Caching.RedisHybrid",
+ "link": true
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/better-path-resolve": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz",
+ "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-windows": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chardet": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
+ "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/dataloader": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz",
+ "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/detect-indent": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
+ "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
+ "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/enquirer": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
+ "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.1",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/extendable-error": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz",
+ "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/human-id": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.1.3.tgz",
+ "integrity": "sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "human-id": "dist/cli.js"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-subdir": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz",
+ "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "better-path-resolve": "1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lodash.startcase": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
+ "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/outdent": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz",
+ "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/p-filter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz",
+ "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/package-manager-detector": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz",
+ "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quansync": "^0.2.7"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/quansync": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
+ "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/read-yaml-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz",
+ "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.5",
+ "js-yaml": "^3.6.1",
+ "pify": "^4.0.1",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/read-yaml-file/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/read-yaml-file/node_modules/js-yaml": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
+ "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/spawndamnit": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz",
+ "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==",
+ "dev": true,
+ "license": "SEE LICENSE IN LICENSE",
+ "dependencies": {
+ "cross-spawn": "^7.0.5",
+ "signal-exit": "^4.0.1"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/term-size": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
+ "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
+ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "src/Neolution.Extensions.Caching.Abstractions": {
+ "name": "@neolution-ch/neolution.extensions.caching.abstractions",
+ "version": "2.1.1"
+ },
+ "src/Neolution.Extensions.Caching.Distributed": {
+ "name": "@neolution-ch/neolution.extensions.caching.distributed",
+ "version": "2.1.1"
+ },
+ "src/Neolution.Extensions.Caching.InMemory": {
+ "name": "@neolution-ch/neolution.extensions.caching.inmemory",
+ "version": "2.1.1"
+ },
+ "src/Neolution.Extensions.Caching.RedisHybrid": {
+ "name": "@neolution-ch/neolution.extensions.caching.redishybrid",
+ "version": "2.1.1"
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..160c037
--- /dev/null
+++ b/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "neolution.extensions.caching",
+ "private": true,
+ "workspaces": ["src/*"],
+ "scripts": {
+ "changeset": "changeset",
+ "version-packages": "node scripts/sync-versions.js",
+ "release": "changeset publish"
+ },
+ "devDependencies": {
+ "@changesets/cli": "^2.27.0",
+ "@changesets/changelog-github": "^0.5.0"
+ }
+}
diff --git a/scripts/generate-dependabot-changeset.js b/scripts/generate-dependabot-changeset.js
new file mode 100644
index 0000000..5576d0c
--- /dev/null
+++ b/scripts/generate-dependabot-changeset.js
@@ -0,0 +1,113 @@
+const fs = require("fs");
+const path = require("path");
+const crypto = require("crypto");
+
+const prTitle = process.env.PR_TITLE || "";
+const prBody = process.env.PR_BODY || "";
+const packableProjectsChanged = process.env.PACKABLE_PROJECTS_CHANGED === "true";
+
+/**
+ * Read the fixed package groups from .changeset/config.json
+ */
+function getFixedPackages() {
+ const configPath = path.resolve(__dirname, "..", ".changeset", "config.json");
+ const raw = fs.readFileSync(configPath, "utf8").replace(/^/, "");
+ const config = JSON.parse(raw);
+ return (config.fixed || []).flat();
+}
+
+/**
+ * Parse dependency updates from the Dependabot PR body.
+ *
+ * Security PRs use: "Bumps [name](url) from X to Y"
+ * Grouped PRs use: "Updated [name](url) from X to Y"
+ */
+function parseDependencyUpdates(body) {
+ const regex = /(?:Bumps|Updated) \[([^\]]+)\]\([^)]+\) from (\S+) to (\S+)/g;
+ const updates = [];
+ let match;
+ while ((match = regex.exec(body)) !== null) {
+ updates.push({
+ name: match[1],
+ from: match[2].replace(/[.,;:]+$/, ""),
+ to: match[3].replace(/[.,;:]+$/, ""),
+ });
+ }
+ return updates;
+}
+
+/**
+ * Compare two version strings and return the bump type.
+ * Handles versions with or without 'v' prefix.
+ * Falls back to "patch" if versions can't be parsed.
+ */
+function getBumpType(from, to) {
+ const parse = (v) =>
+ v
+ .replace(/^v/, "")
+ .split(".")
+ .map((n) => parseInt(n, 10));
+ const fromParts = parse(from);
+ const toParts = parse(to);
+
+ if (fromParts.some(isNaN) || toParts.some(isNaN)) {
+ return "patch";
+ }
+
+ if ((toParts[0] || 0) !== (fromParts[0] || 0)) return "major";
+ if ((toParts[1] || 0) !== (fromParts[1] || 0)) return "minor";
+ return "patch";
+}
+
+function bumpEmoji(bumpType) {
+ switch (bumpType) {
+ case "major":
+ return "🔴 major";
+ case "minor":
+ return "🟡 minor";
+ default:
+ return "🟢 patch";
+ }
+}
+
+function buildChangeset(fixedPackages, updates) {
+ const lines = [];
+
+ lines.push("---");
+ if (packableProjectsChanged) {
+ for (const pkg of fixedPackages) {
+ lines.push(`"${pkg}": patch`);
+ }
+ }
+ lines.push("---");
+ lines.push("");
+
+ lines.push(prTitle);
+
+ if (updates.length > 0) {
+ lines.push("");
+ lines.push("| Package | From | To | Bump |");
+ lines.push("|---------|------|----|------|");
+ for (const dep of updates) {
+ const bump = getBumpType(dep.from, dep.to);
+ lines.push(
+ `| ${dep.name} | ${dep.from} | ${dep.to} | ${bumpEmoji(bump)} |`,
+ );
+ }
+ }
+
+ lines.push("");
+ return lines.join("\n");
+}
+
+const fixedPackages = getFixedPackages();
+const updates = parseDependencyUpdates(prBody);
+const content = buildChangeset(fixedPackages, updates);
+
+const id = crypto.randomBytes(8).toString("hex");
+const filename = `dependabot-${id}.md`;
+const changesetDir = path.resolve(__dirname, "..", ".changeset");
+const filepath = path.join(changesetDir, filename);
+
+fs.writeFileSync(filepath, content, "utf8");
+console.log(`Created changeset: .changeset/${filename}`);
diff --git a/scripts/publish.js b/scripts/publish.js
new file mode 100644
index 0000000..cfccdd7
--- /dev/null
+++ b/scripts/publish.js
@@ -0,0 +1,54 @@
+/**
+ * Custom publish script for changesets/action.
+ *
+ * This repo publishes NuGet packages, not npm packages. We still use
+ * @changesets to manage versions and changelogs, and we still use
+ * changesets/action to push git tags and create GitHub Releases. The actual
+ * artifact build/push is handled by .github/workflows/nuget-publish.yml,
+ * which triggers on the Releases that this step creates.
+ *
+ * changesets/action detects "what was published" by scanning this script's
+ * stdout for lines matching: New tag: @
+ * For each match it pushes the tag and creates the GitHub Release. See:
+ * https://github.com/changesets/action/blob/main/src/run.ts
+ *
+ * Workspace packages live under src/. We emit a "New tag:" line per package
+ * if (and only if) the tag for the current version does not already exist,
+ * making this script idempotent across workflow re-runs.
+ */
+
+const fs = require("fs");
+const path = require("path");
+const { execSync } = require("child_process");
+
+const repoRoot = path.join(__dirname, "..");
+const srcDir = path.join(repoRoot, "src");
+
+const packages = fs
+ .readdirSync(srcDir)
+ .map((dir) => path.join(srcDir, dir, "package.json"))
+ .filter((p) => fs.existsSync(p))
+ .map((p) => JSON.parse(fs.readFileSync(p, "utf8")))
+ .map((pkg) => ({ name: pkg.name, version: pkg.version }));
+
+if (packages.length === 0) {
+ console.error("ERROR: No workspace packages found under src/");
+ process.exit(1);
+}
+
+const firstTag = `${packages[0].name}@${packages[0].version}`;
+const existing = execSync(`git tag -l "${firstTag}"`, {
+ cwd: repoRoot,
+ encoding: "utf8",
+}).trim();
+
+if (existing) {
+ console.log(
+ `Tag ${firstTag} already exists. Nothing to release. Exiting cleanly.`,
+ );
+ process.exit(0);
+}
+
+for (const pkg of packages) {
+ console.log(`New tag: ${pkg.name}@${pkg.version}`);
+}
diff --git a/scripts/sync-versions.js b/scripts/sync-versions.js
new file mode 100644
index 0000000..ae7231e
--- /dev/null
+++ b/scripts/sync-versions.js
@@ -0,0 +1,36 @@
+const fs = require("fs");
+const path = require("path");
+const { execSync } = require("child_process");
+
+execSync("npx changeset version", { stdio: "inherit" });
+
+const repoRoot = path.join(__dirname, "..");
+const srcDir = path.join(repoRoot, "src");
+const libs = fs
+ .readdirSync(srcDir)
+ .filter((d) => fs.existsSync(path.join(srcDir, d, "package.json")));
+
+if (libs.length === 0) {
+ console.error("ERROR: No workspace packages found under src/");
+ process.exit(1);
+}
+
+const referencePkgJson = path.join(srcDir, libs[0], "package.json");
+const version = JSON.parse(fs.readFileSync(referencePkgJson, "utf8")).version;
+
+const propsPath = path.join(repoRoot, "Directory.Build.props");
+let props = fs.readFileSync(propsPath, "utf8");
+const updated = props.replace(
+ /[^<]*<\/Version>/,
+ `${version}`,
+);
+
+if (props === updated) {
+ console.error(
+ "ERROR: Could not find ... in Directory.Build.props",
+ );
+ process.exit(1);
+}
+
+fs.writeFileSync(propsPath, updated);
+console.log(`Updated Directory.Build.props to ${version}`);
diff --git a/Neolution.Extensions.Caching.Abstractions/CacheEntryOptions.cs b/src/Neolution.Extensions.Caching.Abstractions/CacheEntryOptions.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Abstractions/CacheEntryOptions.cs
rename to src/Neolution.Extensions.Caching.Abstractions/CacheEntryOptions.cs
diff --git a/Neolution.Extensions.Caching.Abstractions/DistributedCache.cs b/src/Neolution.Extensions.Caching.Abstractions/DistributedCache.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Abstractions/DistributedCache.cs
rename to src/Neolution.Extensions.Caching.Abstractions/DistributedCache.cs
diff --git a/Neolution.Extensions.Caching.Abstractions/IDistributedCache.cs b/src/Neolution.Extensions.Caching.Abstractions/IDistributedCache.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Abstractions/IDistributedCache.cs
rename to src/Neolution.Extensions.Caching.Abstractions/IDistributedCache.cs
diff --git a/Neolution.Extensions.Caching.Abstractions/IMemoryCache.cs b/src/Neolution.Extensions.Caching.Abstractions/IMemoryCache.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Abstractions/IMemoryCache.cs
rename to src/Neolution.Extensions.Caching.Abstractions/IMemoryCache.cs
diff --git a/Neolution.Extensions.Caching.Abstractions/MemoryCache.cs b/src/Neolution.Extensions.Caching.Abstractions/MemoryCache.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Abstractions/MemoryCache.cs
rename to src/Neolution.Extensions.Caching.Abstractions/MemoryCache.cs
diff --git a/Neolution.Extensions.Caching.Abstractions/Neolution.Extensions.Caching.Abstractions.csproj b/src/Neolution.Extensions.Caching.Abstractions/Neolution.Extensions.Caching.Abstractions.csproj
similarity index 100%
rename from Neolution.Extensions.Caching.Abstractions/Neolution.Extensions.Caching.Abstractions.csproj
rename to src/Neolution.Extensions.Caching.Abstractions/Neolution.Extensions.Caching.Abstractions.csproj
diff --git a/src/Neolution.Extensions.Caching.Abstractions/package.json b/src/Neolution.Extensions.Caching.Abstractions/package.json
new file mode 100644
index 0000000..95e9895
--- /dev/null
+++ b/src/Neolution.Extensions.Caching.Abstractions/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "@neolution-ch/neolution.extensions.caching.abstractions",
+ "version": "2.1.1",
+ "private": true
+}
diff --git a/Neolution.Extensions.Caching.Distributed/MessagePackDistributedCache.cs b/src/Neolution.Extensions.Caching.Distributed/MessagePackDistributedCache.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Distributed/MessagePackDistributedCache.cs
rename to src/Neolution.Extensions.Caching.Distributed/MessagePackDistributedCache.cs
diff --git a/Neolution.Extensions.Caching.Distributed/MessagePackDistributedCacheOptions.cs b/src/Neolution.Extensions.Caching.Distributed/MessagePackDistributedCacheOptions.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Distributed/MessagePackDistributedCacheOptions.cs
rename to src/Neolution.Extensions.Caching.Distributed/MessagePackDistributedCacheOptions.cs
diff --git a/Neolution.Extensions.Caching.Distributed/Neolution.Extensions.Caching.Distributed.csproj b/src/Neolution.Extensions.Caching.Distributed/Neolution.Extensions.Caching.Distributed.csproj
similarity index 100%
rename from Neolution.Extensions.Caching.Distributed/Neolution.Extensions.Caching.Distributed.csproj
rename to src/Neolution.Extensions.Caching.Distributed/Neolution.Extensions.Caching.Distributed.csproj
diff --git a/Neolution.Extensions.Caching.Distributed/ServiceCollectionExtensions.cs b/src/Neolution.Extensions.Caching.Distributed/ServiceCollectionExtensions.cs
similarity index 100%
rename from Neolution.Extensions.Caching.Distributed/ServiceCollectionExtensions.cs
rename to src/Neolution.Extensions.Caching.Distributed/ServiceCollectionExtensions.cs
diff --git a/src/Neolution.Extensions.Caching.Distributed/package.json b/src/Neolution.Extensions.Caching.Distributed/package.json
new file mode 100644
index 0000000..dc64365
--- /dev/null
+++ b/src/Neolution.Extensions.Caching.Distributed/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "@neolution-ch/neolution.extensions.caching.distributed",
+ "version": "2.1.1",
+ "private": true
+}
diff --git a/Neolution.Extensions.Caching.InMemory/InMemoryCache.cs b/src/Neolution.Extensions.Caching.InMemory/InMemoryCache.cs
similarity index 100%
rename from Neolution.Extensions.Caching.InMemory/InMemoryCache.cs
rename to src/Neolution.Extensions.Caching.InMemory/InMemoryCache.cs
diff --git a/Neolution.Extensions.Caching.InMemory/Neolution.Extensions.Caching.InMemory.csproj b/src/Neolution.Extensions.Caching.InMemory/Neolution.Extensions.Caching.InMemory.csproj
similarity index 100%
rename from Neolution.Extensions.Caching.InMemory/Neolution.Extensions.Caching.InMemory.csproj
rename to src/Neolution.Extensions.Caching.InMemory/Neolution.Extensions.Caching.InMemory.csproj
diff --git a/Neolution.Extensions.Caching.InMemory/ServiceCollectionExtensions.cs b/src/Neolution.Extensions.Caching.InMemory/ServiceCollectionExtensions.cs
similarity index 100%
rename from Neolution.Extensions.Caching.InMemory/ServiceCollectionExtensions.cs
rename to src/Neolution.Extensions.Caching.InMemory/ServiceCollectionExtensions.cs
diff --git a/src/Neolution.Extensions.Caching.InMemory/package.json b/src/Neolution.Extensions.Caching.InMemory/package.json
new file mode 100644
index 0000000..055ea81
--- /dev/null
+++ b/src/Neolution.Extensions.Caching.InMemory/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "@neolution-ch/neolution.extensions.caching.inmemory",
+ "version": "2.1.1",
+ "private": true
+}
diff --git a/Neolution.Extensions.Caching.RedisHybrid/MsgPackSerializer.cs b/src/Neolution.Extensions.Caching.RedisHybrid/MsgPackSerializer.cs
similarity index 100%
rename from Neolution.Extensions.Caching.RedisHybrid/MsgPackSerializer.cs
rename to src/Neolution.Extensions.Caching.RedisHybrid/MsgPackSerializer.cs
diff --git a/Neolution.Extensions.Caching.RedisHybrid/Neolution.Extensions.Caching.RedisHybrid.csproj b/src/Neolution.Extensions.Caching.RedisHybrid/Neolution.Extensions.Caching.RedisHybrid.csproj
similarity index 100%
rename from Neolution.Extensions.Caching.RedisHybrid/Neolution.Extensions.Caching.RedisHybrid.csproj
rename to src/Neolution.Extensions.Caching.RedisHybrid/Neolution.Extensions.Caching.RedisHybrid.csproj
diff --git a/Neolution.Extensions.Caching.RedisHybrid/RedisHybridCache.cs b/src/Neolution.Extensions.Caching.RedisHybrid/RedisHybridCache.cs
similarity index 100%
rename from Neolution.Extensions.Caching.RedisHybrid/RedisHybridCache.cs
rename to src/Neolution.Extensions.Caching.RedisHybrid/RedisHybridCache.cs
diff --git a/Neolution.Extensions.Caching.RedisHybrid/ServiceCollectionExtensions.cs b/src/Neolution.Extensions.Caching.RedisHybrid/ServiceCollectionExtensions.cs
similarity index 100%
rename from Neolution.Extensions.Caching.RedisHybrid/ServiceCollectionExtensions.cs
rename to src/Neolution.Extensions.Caching.RedisHybrid/ServiceCollectionExtensions.cs
diff --git a/src/Neolution.Extensions.Caching.RedisHybrid/package.json b/src/Neolution.Extensions.Caching.RedisHybrid/package.json
new file mode 100644
index 0000000..64c4092
--- /dev/null
+++ b/src/Neolution.Extensions.Caching.RedisHybrid/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "@neolution-ch/neolution.extensions.caching.redishybrid",
+ "version": "2.1.1",
+ "private": true
+}
diff --git a/Neolution.Extensions.Caching.UnitTests/DistributedCacheAsyncTests.cs b/tests/Neolution.Extensions.Caching.UnitTests/DistributedCacheAsyncTests.cs
similarity index 100%
rename from Neolution.Extensions.Caching.UnitTests/DistributedCacheAsyncTests.cs
rename to tests/Neolution.Extensions.Caching.UnitTests/DistributedCacheAsyncTests.cs
diff --git a/Neolution.Extensions.Caching.UnitTests/DistributedCacheTests.cs b/tests/Neolution.Extensions.Caching.UnitTests/DistributedCacheTests.cs
similarity index 100%
rename from Neolution.Extensions.Caching.UnitTests/DistributedCacheTests.cs
rename to tests/Neolution.Extensions.Caching.UnitTests/DistributedCacheTests.cs
diff --git a/Neolution.Extensions.Caching.UnitTests/MemoryCacheTests.cs b/tests/Neolution.Extensions.Caching.UnitTests/MemoryCacheTests.cs
similarity index 100%
rename from Neolution.Extensions.Caching.UnitTests/MemoryCacheTests.cs
rename to tests/Neolution.Extensions.Caching.UnitTests/MemoryCacheTests.cs
diff --git a/Neolution.Extensions.Caching.UnitTests/Models/TestCacheId.cs b/tests/Neolution.Extensions.Caching.UnitTests/Models/TestCacheId.cs
similarity index 100%
rename from Neolution.Extensions.Caching.UnitTests/Models/TestCacheId.cs
rename to tests/Neolution.Extensions.Caching.UnitTests/Models/TestCacheId.cs
diff --git a/Neolution.Extensions.Caching.UnitTests/Neolution.Extensions.Caching.UnitTests.csproj b/tests/Neolution.Extensions.Caching.UnitTests/Neolution.Extensions.Caching.UnitTests.csproj
similarity index 81%
rename from Neolution.Extensions.Caching.UnitTests/Neolution.Extensions.Caching.UnitTests.csproj
rename to tests/Neolution.Extensions.Caching.UnitTests/Neolution.Extensions.Caching.UnitTests.csproj
index 858824e..f57e4ab 100644
--- a/Neolution.Extensions.Caching.UnitTests/Neolution.Extensions.Caching.UnitTests.csproj
+++ b/tests/Neolution.Extensions.Caching.UnitTests/Neolution.Extensions.Caching.UnitTests.csproj
@@ -34,9 +34,9 @@
-
-
-
+
+
+
diff --git a/Neolution.Extensions.Caching.UnitTests/RedisHybridCacheTests.cs b/tests/Neolution.Extensions.Caching.UnitTests/RedisHybridCacheTests.cs
similarity index 100%
rename from Neolution.Extensions.Caching.UnitTests/RedisHybridCacheTests.cs
rename to tests/Neolution.Extensions.Caching.UnitTests/RedisHybridCacheTests.cs
diff --git a/Neolution.Extensions.Caching.UnitTests/TestData/ServiceCollectionTestDataCollection.cs b/tests/Neolution.Extensions.Caching.UnitTests/TestData/ServiceCollectionTestDataCollection.cs
similarity index 100%
rename from Neolution.Extensions.Caching.UnitTests/TestData/ServiceCollectionTestDataCollection.cs
rename to tests/Neolution.Extensions.Caching.UnitTests/TestData/ServiceCollectionTestDataCollection.cs