Compare commits

..

41 Commits

Author SHA1 Message Date
XY Wang
1281ce8732
Add SupportsVolume in Device response (#971) 2024-05-10 08:51:14 +02:00
dependabot[bot]
72bf30aad5
Bump Microsoft.AspNetCore.Components.WebAssembly.DevServer (#964)
Bumps [Microsoft.AspNetCore.Components.WebAssembly.DevServer](https://github.com/dotnet/aspnetcore) from 8.0.3 to 8.0.4.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v8.0.3...v8.0.4)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly.DevServer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-07 23:39:51 +02:00
dependabot[bot]
d1f3d0088c
Bump Microsoft.AspNetCore.Components.WebAssembly from 7.0.17 to 7.0.18 (#963)
Bumps [Microsoft.AspNetCore.Components.WebAssembly](https://github.com/dotnet/aspnetcore) from 7.0.17 to 7.0.18.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v7.0.17...v7.0.18)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-07 23:18:48 +02:00
Sam
9cbd5f280e
Add note about not including "next" field when limiting fields and using pagination (#962) 2024-05-07 23:18:42 +02:00
Andrew Garvin
7bdaf060de
Minor documentation update (#969) 2024-05-07 23:18:04 +02:00
TheBoyLeastLikelyTo
f6cfedd7ef
Add SpotifyGPX to showcase (#966) 2024-05-07 23:17:44 +02:00
dependabot[bot]
6ceb598acf
Bump express in /SpotifyAPI.Web.Examples/Example.TokenSwap/Server (#960)
Bumps [express](https://github.com/expressjs/express) from 4.17.3 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.3...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-07 19:33:15 +02:00
dependabot[bot]
65e12e054d
Bump express from 4.18.2 to 4.19.2 in /SpotifyAPI.Docs (#961)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-07 19:33:06 +02:00
dependabot[bot]
59a07f6de3
Bump webpack-dev-middleware from 5.3.3 to 5.3.4 in /SpotifyAPI.Docs (#958)
Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4.
- [Release notes](https://github.com/webpack/webpack-dev-middleware/releases)
- [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4)

---
updated-dependencies:
- dependency-name: webpack-dev-middleware
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 11:19:42 +01:00
dependabot[bot]
ecb90f3c26
Bump follow-redirects from 1.15.5 to 1.15.6 in /SpotifyAPI.Docs (#955)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.5 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 11:19:33 +01:00
dependabot[bot]
35892dcad3
Bump Microsoft.AspNetCore.Components.WebAssembly.DevServer (#957)
Bumps [Microsoft.AspNetCore.Components.WebAssembly.DevServer](https://github.com/dotnet/aspnetcore) from 8.0.2 to 8.0.3.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v8.0.2...v8.0.3)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly.DevServer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-23 11:19:24 +01:00
dependabot[bot]
4a168e67c0
Bump Microsoft.AspNetCore.Components.WebAssembly from 7.0.16 to 7.0.17 (#956)
Bumps [Microsoft.AspNetCore.Components.WebAssembly](https://github.com/dotnet/aspnetcore) from 7.0.16 to 7.0.17.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v7.0.16...v7.0.17)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-22 17:31:14 +01:00
dependabot[bot]
6c6cc14ab1
Bump follow-redirects (#954)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-22 17:31:04 +01:00
dependabot[bot]
2e3469a8a2
Bump Microsoft.AspNetCore.Components.WebAssembly.DevServer (#948)
Bumps [Microsoft.AspNetCore.Components.WebAssembly.DevServer](https://github.com/dotnet/aspnetcore) from 8.0.1 to 8.0.2.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v8.0.1...v8.0.2)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly.DevServer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-27 21:37:45 +01:00
dependabot[bot]
630e1d2a37
Bump Microsoft.AspNetCore.Components.WebAssembly from 7.0.15 to 7.0.16 (#949)
Bumps [Microsoft.AspNetCore.Components.WebAssembly](https://github.com/dotnet/aspnetcore) from 7.0.15 to 7.0.16.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v7.0.15...v7.0.16)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-27 21:29:48 +01:00
dependabot[bot]
2583bf6ca3
Bump NUnit from 4.0.1 to 4.1.0 (#951)
Bumps [NUnit](https://github.com/nunit/nunit) from 4.0.1 to 4.1.0.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/v4.0.1...4.1.0)

---
updated-dependencies:
- dependency-name: NUnit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-27 21:29:39 +01:00
Farkas Olivér
b74f5c2148
Update RecommendationsResponse to match Spotify API (#950) 2024-02-27 21:29:20 +01:00
dependabot[bot]
0270373078
Bump Moq from 4.20.69 to 4.20.70 (#947)
Bumps [Moq](https://github.com/moq/moq) from 4.20.69 to 4.20.70.
- [Release notes](https://github.com/moq/moq/releases)
- [Changelog](https://github.com/devlooped/moq/blob/main/CHANGELOG.md)
- [Commits](https://github.com/moq/moq/compare/v4.20.69...v4.20.70)

---
updated-dependencies:
- dependency-name: Moq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-13 19:51:36 +01:00
dependabot[bot]
24e54a71ce
Bump NUnit from 4.0.0 to 4.0.1 (#946)
Bumps [NUnit](https://github.com/nunit/nunit) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/v4.0.0...v4.0.1)

---
updated-dependencies:
- dependency-name: NUnit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-13 19:47:05 +01:00
dependabot[bot]
2ab1b3b1d6
Bump Microsoft.NET.Test.Sdk from 17.8.0 to 17.9.0 (#945)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.8.0 to 17.9.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.8.0...v17.9.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-13 19:46:55 +01:00
Jonas Dellinger
038acf3061 update docs dependencies 2024-02-11 01:06:28 +01:00
Jonas Dellinger
dcec5467a8 fix null checks and duplicate EOL 2024-02-10 13:52:30 +01:00
XY Wang
d5059820b6
Add Locale param (#835)
* Add Locale

* Add ArtistRequest, ArtistsRelatedArtistsRequest

* Add ArtistRequest, ArtistsRelatedArtistsRequest

* Add Locale
2024-02-10 12:56:59 +01:00
Jonas Dellinger
2bfb7ba714 fix release workflow 2024-02-10 12:26:38 +01:00
Jonas Dellinger
0ba31b26db bump install version 2024-02-10 12:22:13 +01:00
Jonas Dellinger
78d2ff0b71 fix .net8 format with conditionals 2024-02-10 12:15:58 +01:00
Jonas Dellinger
70ef00a41e fix .net8 format 2024-02-10 12:02:50 +01:00
Jonas Dellinger
2bff224ef1 add .net8 support 2024-02-10 11:57:47 +01:00
Jonas Dellinger
78cc5a78da enable unused import warning and format code 2024-02-10 11:42:55 +01:00
Jonas Dellinger
4f94b564ea add HtmlDescription and TotalEpisodes fields 2024-02-10 11:42:37 +01:00
dependabot[bot]
0391371a8c
Bump NUnit from 3.13.3 to 4.0.0 (#922)
* Bump NUnit from 3.13.3 to 4.0.0

Bumps [NUnit](https://github.com/nunit/nunit) from 3.13.3 to 4.0.0.
- [Release notes](https://github.com/nunit/nunit/releases)
- [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md)
- [Commits](https://github.com/nunit/nunit/compare/v3.13.3...v4.0.0)

---
updated-dependencies:
- dependency-name: NUnit
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* update tests to nunit 4.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonas Dellinger <jonas@dellinger.dev>
2024-02-10 11:41:47 +01:00
Lewis-Fam
9dbd210a2f
Fixed issues #926, and #928. (#942)
* Fixed issues #926, and #928.
Added JsonConverter attributes to properties.

* Fixed complier warning CA1305
2024-02-10 11:03:22 +01:00
dependabot[bot]
0fe33df65a
Bump Microsoft.SourceLink.GitHub from 1.1.1 to 8.0.0 (#941)
Bumps [Microsoft.SourceLink.GitHub](https://github.com/dotnet/sourcelink) from 1.1.1 to 8.0.0.
- [Release notes](https://github.com/dotnet/sourcelink/releases)
- [Commits](https://github.com/dotnet/sourcelink/compare/1.1.1...8.0.0)

---
updated-dependencies:
- dependency-name: Microsoft.SourceLink.GitHub
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-10 10:58:00 +01:00
dependabot[bot]
c178d80c62
Bump NUnit.Console from 3.16.3 to 3.17.0 (#943)
Bumps [NUnit.Console](https://github.com/nunit/nunit-console) from 3.16.3 to 3.17.0.
- [Release notes](https://github.com/nunit/nunit-console/releases)
- [Changelog](https://github.com/nunit/nunit-console/blob/main/CHANGES.txt)
- [Commits](https://github.com/nunit/nunit-console/compare/3.16.3...3.17.0)

---
updated-dependencies:
- dependency-name: NUnit.Console
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-10 10:57:53 +01:00
Noel Griffin
a27c3729c8
Add Users Top Tracks / Users Top Artists to UserClient (#938)
* add top tracks & artists endpoints

* fix file extenstion

* added TODO

* Add Methods to interface

* Add Top items query class

* implement query into UserProfileClient.cs - Top Requests

* Tidy Up Naming

* Removed random json file change

* Added Tests.

* run formatter

* remove additional namespace

---------

Co-authored-by: Jonas Dellinger <jonas@dellinger.dev>
2024-01-19 19:56:07 +01:00
dependabot[bot]
01fcd1d7d1
Bump Microsoft.AspNetCore.Components.WebAssembly.DevServer (#935)
Bumps [Microsoft.AspNetCore.Components.WebAssembly.DevServer](https://github.com/dotnet/aspnetcore) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v8.0.0...v8.0.1)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly.DevServer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-15 11:06:45 +01:00
dependabot[bot]
f33dfd307a
Bump System.Net.Http.Json from 7.0.1 to 8.0.0 (#934)
Bumps [System.Net.Http.Json](https://github.com/dotnet/runtime) from 7.0.1 to 8.0.0.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v7.0.1...v8.0.0)

---
updated-dependencies:
- dependency-name: System.Net.Http.Json
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-15 11:02:12 +01:00
dependabot[bot]
48d1f6baa6
Bump Microsoft.SourceLink.GitHub from 1.1.1 to 8.0.0 (#936)
Bumps [Microsoft.SourceLink.GitHub](https://github.com/dotnet/sourcelink) from 1.1.1 to 8.0.0.
- [Release notes](https://github.com/dotnet/sourcelink/releases)
- [Commits](https://github.com/dotnet/sourcelink/compare/1.1.1...8.0.0)

---
updated-dependencies:
- dependency-name: Microsoft.SourceLink.GitHub
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-15 11:01:48 +01:00
dependabot[bot]
f737ba44e5
Bump Microsoft.AspNetCore.Components.WebAssembly from 7.0.13 to 7.0.15 (#937)
Bumps [Microsoft.AspNetCore.Components.WebAssembly](https://github.com/dotnet/aspnetcore) from 7.0.13 to 7.0.15.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md)
- [Commits](https://github.com/dotnet/aspnetcore/compare/v7.0.13...v7.0.15)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Components.WebAssembly
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-15 11:01:40 +01:00
SoNearSonar
f8d6b6ef69
Update Spotify content availability checker program links (#932)
* Update Spotify content checker links

* Clean up description

Somehow the old description got mixed in with the new one.

* Final update of new program

Small oversight.

---------

Co-authored-by: Jonas Dellinger <jonas@dellinger.dev>
2024-01-15 10:58:23 +01:00
Brad
023f004ed7
Update showcase.md (#933) 2024-01-15 10:54:27 +01:00
101 changed files with 2623 additions and 2040 deletions

View File

@ -20,6 +20,9 @@ dotnet_diagnostic.CA1003.severity = none
dotnet_diagnostic.IDE0130.severity = none
# Unused imports
dotnet_diagnostic.IDE0005.severity = warning
#
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true

View File

@ -18,7 +18,10 @@ jobs:
dotnet-version: "6.x"
- uses: actions/setup-dotnet@v3
with:
dotnet-version: "7.0.203"
dotnet-version: "7.x"
- uses: actions/setup-dotnet@v3
with:
dotnet-version: "8.x"
- name: Set RELEASE_VERSION
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Restore Packages
@ -54,12 +57,14 @@ jobs:
zip -j SpotifyAPI.Web-net5.0.zip SpotifyAPI.Web/bin/Release/net5.0/*
zip -j SpotifyAPI.Web-net6.0.zip SpotifyAPI.Web/bin/Release/net6.0/*
zip -j SpotifyAPI.Web-net7.0.zip SpotifyAPI.Web/bin/Release/net7.0/*
zip -j SpotifyAPI.Web-net8.0.zip SpotifyAPI.Web/bin/Release/net8.0/*
zip -j SpotifyAPI.Web.Auth-netstandard2.0.zip SpotifyAPI.Web.Auth/bin/Release/netstandard2.0/*
zip -j SpotifyAPI.Web.Auth-netstandard2.1.zip SpotifyAPI.Web.Auth/bin/Release/netstandard2.1/*
zip -j SpotifyAPI.Web.Auth-net5.0.zip SpotifyAPI.Web.Auth/bin/Release/net5.0/*
zip -j SpotifyAPI.Web.Auth-net6.0.zip SpotifyAPI.Web.Auth/bin/Release/net6.0/*
zip -j SpotifyAPI.Web.Auth-net7.0.zip SpotifyAPI.Web.Auth/bin/Release/net7.0/*
zip -j SpotifyAPI.Web.Auth-net8.0.zip SpotifyAPI.Web.Auth/bin/Release/net8.0/*
gh release upload "$RELEASE_VERSION" \
"SpotifyAPI.Web-netstandard2.0.zip" \
@ -67,10 +72,12 @@ jobs:
"SpotifyAPI.Web-net5.0.zip" \
"SpotifyAPI.Web-net6.0.zip" \
"SpotifyAPI.Web-net7.0.zip" \
"SpotifyAPI.Web-net8.0.zip" \
"SpotifyAPI.Web.Auth-netstandard2.0.zip" \
"SpotifyAPI.Web.Auth-netstandard2.1.zip" \
"SpotifyAPI.Web.Auth-net5.0.zip" \
"SpotifyAPI.Web.Auth-net6.0.zip" \
"SpotifyAPI.Web.Auth-net7.0.zip"
"SpotifyAPI.Web.Auth-net7.0.zip" \
"SpotifyAPI.Web.Auth-net8.0.zip"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -54,3 +54,8 @@ By requesting just the track name from the items, we don't have any kind of type
playlistGetItemsRequest.Fields.Add("items(track(name,type))");
```
If you're paginating a request with a subset of fields and you don't include the field `next`, we assume there is only one page and your results will be limited. To fix this, you must include `next` as one of the fields:
```csharp
playlistGetItemsRequest.Fields.Add("next, items(track(name,type))");
```

View File

@ -87,10 +87,9 @@ Send a PR via the "Edit this page" link at the end of the page!
> Sortify is a powerful tool that aims to help people organize their Spotify libraries. It allows you to sort existing playlists or create new ones. When creating, you have an option to merge or split the playlists. It also removes any track duplicates from them. All that, while being very simple and friendly to use.
### [Spotify Content Availability Checker](https://github.com/SoNearSonar/SpotifyContentAvailabilityChecker) by [@SoNearSonar](https://github.com/SoNearSonar/)
### [Spotify Song Availability Checker](https://github.com/CasualHonest/SpotifySongAvailabilityChecker) by [@CasualHonest](https://github.com/CasualHonest/)
> Spotify Song Availability Checker (SSAC) is a simple and lightweight tool that lets you check the availability of songs and albums on Spotify, giving you basic information about what you enter and displaying the available markets for said entry.
> Spotify Content Availability Checker is a program that lets you check the country availability of songs, albums, and podcasts on Spotify. The program also displays basic information about the content you enter in.
### [ConcertBuddy](https://github.com/skuill/ConcertBuddy) by [@skuill](https://github.com/skuill)
@ -98,3 +97,9 @@ Send a PR via the "Edit this page" link at the end of the page!
### [SpotifiCLI](https://github.com/kollibroman/SpotifyCLI) by [@kollibroman](https://github.com/kollibroman)
> Another cross-platform cli tool to interact with spotify api with focus on simplicity
### [BeatSpy](https://github.com/braddotwav/BeatSpy) by [@braddotwav](https://github.com/braddotwav)
> BeatSpy lets music producers and enthusiasts search for songs and instantly access valuable details like tempo, key, loudness, and more
### [SpotifyGPX](https://github.com/TheBoyLeastLikelyTo/SpotifyGPX) by [@TheBoyLeastLikelyTo](https://github.com/TheBoyLeastLikelyTo)
> SpotifyGPX lets you retrace the steps of a road trip by taking the songs you listened to and a tracked series of points, and pairing the two sets of data.

View File

@ -14,10 +14,10 @@
}
},
"dependencies": {
"@docusaurus/core": "^3.0.0",
"@docusaurus/preset-classic": "^3.0.0",
"@docusaurus/core": "^3.1.1",
"@docusaurus/preset-classic": "^3.1.1",
"@mdx-js/react": "^3.0.0",
"classnames": "^2.3.1",
"classnames": "^2.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-github-btn": "^1.2.0"
@ -36,7 +36,7 @@
},
"devDependencies": {
"import-sort-style-module": "^6.0.0",
"prettier": "^3.0.3",
"prettier": "^3.2.5",
"prettier-plugin-import-sort": "^0.0.7"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
import React from 'react';
const VERSION = '7.0.0';
const VERSION = '7.1.1';
const installCodeNuget = `Install-Package SpotifyAPI.Web
# Optional Auth module, which includes an embedded HTTP Server for OAuth2

View File

@ -1,7 +1,10 @@
using System;
using System.Runtime.Serialization;
namespace SpotifyAPI.Web.Auth
{
[System.Serializable]
public class AuthException : System.Exception
[Serializable]
public class AuthException : Exception
{
public AuthException(string? error, string? state)
{
@ -9,10 +12,12 @@ namespace SpotifyAPI.Web.Auth
State = state;
}
public AuthException(string message) : base(message) { }
public AuthException(string message, System.Exception inner) : base(message, inner) { }
protected AuthException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
public AuthException(string message, Exception inner) : base(message, inner) { }
#if NET8_0_OR_GREATER
[Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")]
#endif
protected AuthException(SerializationInfo info, StreamingContext context) : base(info, context) { }
public string? Error { get; set; }
public string? State { get; set; }

View File

@ -1,10 +1,8 @@
using System;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using EmbedIO;
using EmbedIO.Actions;

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0;net5.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net8.0;net7.0;net6.0;net5.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
<PackageId>SpotifyAPI.Web.Auth</PackageId>
@ -31,7 +31,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
<PackageReference Include="EmbedIO" Version="3.5.2">
<PrivateAssets>None</PrivateAssets>
</PackageReference>

View File

@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace Example.ASP.Pages
{

View File

@ -2,7 +2,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using SpotifyAPI.Web;
namespace Example.ASP.Pages

View File

@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Example.ASP
{

View File

@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

View File

@ -1,12 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Example.ASPBlazor.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

View File

@ -5,9 +5,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.18" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.4" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -9,6 +9,6 @@
"dependencies": {
"axios": "^1.6.0",
"body-parser": "^1.19.0",
"express": "^4.17.3"
"express": "^4.19.2"
}
}

View File

@ -29,27 +29,40 @@ axios@^1.6.0:
form-data "^4.0.0"
proxy-from-env "^1.1.0"
body-parser@1.19.2, body-parser@^1.19.0:
version "1.19.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e"
integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==
body-parser@1.20.2, body-parser@^1.19.0:
version "1.20.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
dependencies:
bytes "3.1.2"
content-type "~1.0.4"
content-type "~1.0.5"
debug "2.6.9"
depd "~1.1.2"
http-errors "1.8.1"
depd "2.0.0"
destroy "1.2.0"
http-errors "2.0.0"
iconv-lite "0.4.24"
on-finished "~2.3.0"
qs "6.9.7"
raw-body "2.4.3"
on-finished "2.4.1"
qs "6.11.0"
raw-body "2.5.2"
type-is "~1.6.18"
unpipe "1.0.0"
bytes@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
call-bind@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
set-function-length "^1.2.1"
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@ -64,20 +77,20 @@ content-disposition@0.5.4:
dependencies:
safe-buffer "5.2.1"
content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
content-type@~1.0.4, content-type@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
cookie@0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
debug@2.6.9:
version "2.6.9"
@ -86,20 +99,29 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
gopd "^1.0.1"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
depd@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
ee-first@1.1.1:
version "1.1.1"
@ -111,6 +133,18 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
es-define-property@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
dependencies:
get-intrinsic "^1.2.4"
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@ -121,59 +155,60 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
express@^4.17.3:
version "4.17.3"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1"
integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.19.2"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.4.2"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "~1.1.2"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "~1.1.2"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "~2.3.0"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.9.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.17.2"
serve-static "1.14.2"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "~1.5.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
finalhandler@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
finalhandler@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
dependencies:
debug "2.6.9"
encodeurl "~1.0.2"
escape-html "~1.0.3"
on-finished "~2.3.0"
on-finished "2.4.1"
parseurl "~1.3.3"
statuses "~1.5.0"
statuses "2.0.1"
unpipe "~1.0.0"
follow-redirects@^1.15.0:
version "1.15.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
form-data@^4.0.0:
version "4.0.0"
@ -194,15 +229,62 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
http-errors@1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
dependencies:
depd "~1.1.2"
es-errors "^1.3.0"
function-bind "^1.1.2"
has-proto "^1.0.1"
has-symbols "^1.0.3"
hasown "^2.0.0"
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
dependencies:
get-intrinsic "^1.1.3"
has-property-descriptors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
es-define-property "^1.0.0"
has-proto@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
hasown@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
http-errors@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
dependencies:
depd "2.0.0"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses ">= 1.5.0 < 2"
statuses "2.0.1"
toidentifier "1.0.1"
iconv-lite@0.4.24:
@ -281,10 +363,15 @@ negotiator@0.6.3:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
object-inspect@^1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
on-finished@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
dependencies:
ee-first "1.1.1"
@ -311,23 +398,25 @@ proxy-from-env@^1.1.0:
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
qs@6.9.7:
version "6.9.7"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe"
integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
qs@6.11.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
dependencies:
side-channel "^1.0.4"
range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c"
integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==
raw-body@2.5.2:
version "2.5.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
dependencies:
bytes "3.1.2"
http-errors "1.8.1"
http-errors "2.0.0"
iconv-lite "0.4.24"
unpipe "1.0.0"
@ -341,44 +430,66 @@ safe-buffer@5.2.1:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
send@0.17.2:
version "0.17.2"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820"
integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
dependencies:
debug "2.6.9"
depd "~1.1.2"
destroy "~1.0.4"
depd "2.0.0"
destroy "1.2.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
http-errors "1.8.1"
http-errors "2.0.0"
mime "1.6.0"
ms "2.1.3"
on-finished "~2.3.0"
on-finished "2.4.1"
range-parser "~1.2.1"
statuses "~1.5.0"
statuses "2.0.1"
serve-static@1.14.2:
version "1.14.2"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa"
integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==
serve-static@1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
dependencies:
encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.3"
send "0.17.2"
send "0.18.0"
set-function-length@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
gopd "^1.0.1"
has-property-descriptors "^1.0.2"
setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
side-channel@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
dependencies:
call-bind "^1.0.7"
es-errors "^1.3.0"
get-intrinsic "^1.2.4"
object-inspect "^1.13.1"
statuses@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
toidentifier@1.0.1:
version "1.0.1"

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Moq;

View File

@ -1,5 +1,3 @@
using System;
using Moq;
using NUnit.Framework;
using SpotifyAPI.Web.Http;
@ -13,13 +11,13 @@ namespace SpotifyAPI.Web
{
var defaultConfig = SpotifyClientConfig.CreateDefault();
Assert.IsInstanceOf(typeof(SimplePaginator), defaultConfig.DefaultPaginator);
Assert.IsInstanceOf(typeof(NetHttpClient), defaultConfig.HTTPClient);
Assert.IsInstanceOf(typeof(NewtonsoftJSONSerializer), defaultConfig.JSONSerializer);
Assert.AreEqual(SpotifyUrls.APIV1, defaultConfig.BaseAddress);
Assert.AreEqual(null, defaultConfig.Authenticator);
Assert.AreEqual(null, defaultConfig.HTTPLogger);
Assert.AreEqual(null, defaultConfig.RetryHandler);
Assert.That(defaultConfig.DefaultPaginator, Is.InstanceOf(typeof(SimplePaginator)));
Assert.That(defaultConfig.HTTPClient, Is.InstanceOf(typeof(NetHttpClient)));
Assert.That(defaultConfig.JSONSerializer, Is.InstanceOf(typeof(NewtonsoftJSONSerializer)));
Assert.That(SpotifyUrls.APIV1, Is.EqualTo(defaultConfig.BaseAddress));
Assert.That(null, Is.EqualTo(defaultConfig.Authenticator));
Assert.That(null, Is.EqualTo(defaultConfig.HTTPLogger));
Assert.That(null, Is.EqualTo(defaultConfig.RetryHandler));
}
[Test]
@ -30,18 +28,18 @@ namespace SpotifyAPI.Web
var defaultConfig = SpotifyClientConfig.CreateDefault(token, tokenType);
Assert.IsInstanceOf(typeof(SimplePaginator), defaultConfig.DefaultPaginator);
Assert.IsInstanceOf(typeof(NetHttpClient), defaultConfig.HTTPClient);
Assert.IsInstanceOf(typeof(NewtonsoftJSONSerializer), defaultConfig.JSONSerializer);
Assert.AreEqual(SpotifyUrls.APIV1, defaultConfig.BaseAddress);
Assert.AreEqual(null, defaultConfig.HTTPLogger);
Assert.AreEqual(null, defaultConfig.RetryHandler);
Assert.That(defaultConfig.DefaultPaginator, Is.InstanceOf(typeof(SimplePaginator)));
Assert.That(defaultConfig.HTTPClient, Is.InstanceOf(typeof(NetHttpClient)));
Assert.That(defaultConfig.JSONSerializer, Is.InstanceOf(typeof(NewtonsoftJSONSerializer)));
Assert.That(SpotifyUrls.APIV1, Is.EqualTo(defaultConfig.BaseAddress));
Assert.That(null, Is.EqualTo(defaultConfig.HTTPLogger));
Assert.That(null, Is.EqualTo(defaultConfig.RetryHandler));
Assert.IsInstanceOf(typeof(TokenAuthenticator), defaultConfig.Authenticator);
Assert.That(defaultConfig.Authenticator, Is.InstanceOf(typeof(TokenAuthenticator)));
var tokenHeaderAuth = defaultConfig.Authenticator as TokenAuthenticator;
Assert.AreEqual(token, tokenHeaderAuth.Token);
Assert.AreEqual(tokenType, tokenHeaderAuth.TokenType);
Assert.That(token, Is.EqualTo(tokenHeaderAuth.Token));
Assert.That(tokenType, Is.EqualTo(tokenHeaderAuth.TokenType));
}
[Test]
@ -51,9 +49,9 @@ namespace SpotifyAPI.Web
var defaultConfig = SpotifyClientConfig.CreateDefault();
var tokenConfig = defaultConfig.WithToken(token);
Assert.AreEqual(token, (tokenConfig.Authenticator as TokenAuthenticator).Token);
Assert.AreNotEqual(defaultConfig, tokenConfig);
Assert.AreEqual(null, defaultConfig.Authenticator);
Assert.That(token, Is.EqualTo((tokenConfig.Authenticator as TokenAuthenticator).Token));
Assert.That(defaultConfig, Is.Not.EqualTo(tokenConfig));
Assert.That(null, Is.EqualTo(defaultConfig.Authenticator));
}
}
}

View File

@ -1,5 +1,3 @@
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Moq;

View File

@ -31,5 +31,31 @@ namespace SpotifyAPI.Web
api.Verify(a => a.Get<PublicUser>(SpotifyUrls.User(userId), It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task GetTopTracks()
{
var request = new UsersTopItemsRequest(TimeRange.LongTerm);
var api = new Mock<IAPIConnector>();
var client = new UserProfileClient(api.Object);
var res = await client.GetTopTracks(request);
api.Verify(a => a.Get<UsersTopTracksResponse>(SpotifyUrls.TopTracks(), request.BuildQueryParams(), It.IsAny<CancellationToken>()), Times.Once);
}
[Test]
public async Task GetTopArtists()
{
var request = new UsersTopItemsRequest(TimeRange.LongTerm);
var api = new Mock<IAPIConnector>();
var client = new UserProfileClient(api.Object);
await client.GetTopArtists(request);
api.Verify(a => a.Get<UsersTopArtistsResponse>(SpotifyUrls.TopArtists(), request.BuildQueryParams(), It.IsAny<CancellationToken>()), Times.Once);
}
}
}

View File

@ -31,7 +31,7 @@ namespace SpotifyAPI.Web.Tests
serializer.SerializeRequest(request.Object);
Assert.AreEqual(input, request.Object.Body);
Assert.That(input, Is.EqualTo(request.Object.Body));
}
public static IEnumerable<object> SerializeTestSource
@ -65,8 +65,8 @@ namespace SpotifyAPI.Web.Tests
response.SetupGet(r => r.ContentType).Returns("media/mp4");
IAPIResponse<object> apiResonse = serializer.DeserializeResponse<object>(response.Object);
Assert.AreEqual(apiResonse.Body, null);
Assert.AreEqual(apiResonse.Response, response.Object);
Assert.That(apiResonse.Body, Is.Null);
Assert.That(apiResonse.Response, Is.EqualTo(response.Object));
}
[TestCase]
@ -78,8 +78,8 @@ namespace SpotifyAPI.Web.Tests
response.SetupGet(r => r.ContentType).Returns("application/json");
IAPIResponse<TestResponseObject> apiResonse = serializer.DeserializeResponse<TestResponseObject>(response.Object);
Assert.AreEqual(apiResonse.Body?.HelloWorld, false);
Assert.AreEqual(apiResonse.Response, response.Object);
Assert.That(apiResonse.Body?.HelloWorld, Is.False);
Assert.That(apiResonse.Response, Is.EqualTo(response.Object));
}
public class TestResponseObject

View File

@ -1,7 +0,0 @@
namespace SpotifyAPI.Web
{
public class ProxyConfigTest
{
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
@ -18,7 +19,7 @@ namespace SpotifyAPI.Web.Tests
request.SetupGet(r => r.Headers).Returns(new Dictionary<string, string>());
authenticator.Apply(request.Object, apiConnector.Object);
Assert.AreEqual(request.Object.Headers["Authorization"], "Bearer MyToken");
Assert.That(request.Object.Headers["Authorization"], Is.EqualTo("Bearer MyToken"));
}
}
}

View File

@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;

View File

@ -17,11 +17,11 @@ namespace SpotifyAPI.Web.Tests
var second = new SecondRequestModel { Second = false };
var secondParams = second.BuildQueryParams();
Assert.AreEqual(1, firstParams.Keys.Count);
Assert.AreEqual("true", firstParams["first"]);
Assert.That(1, Is.EqualTo(firstParams.Keys.Count));
Assert.That("true", Is.EqualTo(firstParams["first"]));
Assert.AreEqual(1, secondParams.Keys.Count);
Assert.AreEqual("false", secondParams["second"]);
Assert.That(1, Is.EqualTo(secondParams.Keys.Count));
Assert.That("false", Is.EqualTo(secondParams["second"]));
}
[Test]
@ -33,17 +33,17 @@ namespace SpotifyAPI.Web.Tests
var second = new SecondRequestModel { Second = false };
var secondParams = second.BuildBodyParams();
Assert.AreEqual("{\"first\":true}", firstParams.ToString(Formatting.None));
Assert.AreEqual("{\"second\":false}", secondParams.ToString(Formatting.None));
Assert.That("{\"first\":true}", Is.EqualTo(firstParams.ToString(Formatting.None)));
Assert.That("{\"second\":false}", Is.EqualTo(secondParams.ToString(Formatting.None)));
}
[Test]
public void EmptyListIsSkippedInQueryParams()
{
var first = new EmptyListExampleRequestModel();
Assert.AreEqual(new Dictionary<string, string> { }, first.BuildQueryParams());
Assert.That(new Dictionary<string, string> { }, Is.EqualTo(first.BuildQueryParams()));
first.List.Add("hello_world");
Assert.AreEqual(new Dictionary<string, string> { { "list", "hello_world" } }, first.BuildQueryParams());
Assert.That(new Dictionary<string, string> { { "list", "hello_world" } }, Is.EqualTo(first.BuildQueryParams()));
}
[Test]
@ -55,8 +55,8 @@ namespace SpotifyAPI.Web.Tests
};
var result = enumModel.BuildQueryParams();
Assert.AreEqual(1, result.Keys.Count);
Assert.AreEqual("two", result["an_enum"]);
Assert.That(1, Is.EqualTo(result.Keys.Count));
Assert.That("two", Is.EqualTo(result["an_enum"]));
}
[Test]
@ -68,8 +68,8 @@ namespace SpotifyAPI.Web.Tests
};
var result = enumModel.BuildQueryParams();
Assert.AreEqual(1, result.Keys.Count);
Assert.AreEqual("one,two", result["an_enum"]);
Assert.That(1, Is.EqualTo(result.Keys.Count));
Assert.That("one,two", Is.EqualTo(result["an_enum"]));
}
}

View File

@ -38,7 +38,7 @@ namespace SpotifyAPI.Web
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
});
Assert.AreEqual(1, retryCalled);
Assert.That(1, Is.EqualTo(retryCalled));
}
[Test]
@ -64,8 +64,8 @@ namespace SpotifyAPI.Web
};
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
Assert.AreEqual(2, retryCalled);
Assert.AreEqual(setup.Response.Object, response);
Assert.That(2, Is.EqualTo(retryCalled));
Assert.That(setup.Response.Object, Is.EqualTo(response));
setup.Sleep.Verify(s => s(TimeSpan.FromSeconds(50)), Times.Exactly(2));
}
@ -95,8 +95,8 @@ namespace SpotifyAPI.Web
};
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
Assert.AreEqual(1, retryCalled);
Assert.AreEqual(successResponse.Object, response);
Assert.That(1, Is.EqualTo(retryCalled));
Assert.That(successResponse.Object, Is.EqualTo(response));
setup.Sleep.Verify(s => s(TimeSpan.FromSeconds(50)), Times.Once);
}
@ -125,8 +125,8 @@ namespace SpotifyAPI.Web
};
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
Assert.AreEqual(1, retryCalled);
Assert.AreEqual(successResponse.Object, response);
Assert.That(1, Is.EqualTo(retryCalled));
Assert.That(successResponse.Object, Is.EqualTo(response));
setup.Sleep.Verify(s => s(TimeSpan.FromSeconds(50)), Times.Once);
}
@ -151,8 +151,8 @@ namespace SpotifyAPI.Web
};
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
Assert.AreEqual(10, retryCalled);
Assert.AreEqual(setup.Response.Object, response);
Assert.That(10, Is.EqualTo(retryCalled));
Assert.That(setup.Response.Object, Is.EqualTo(response));
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Exactly(10));
}
@ -177,8 +177,8 @@ namespace SpotifyAPI.Web
};
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
Assert.AreEqual(0, retryCalled);
Assert.AreEqual(setup.Response.Object, response);
Assert.That(0, Is.EqualTo(retryCalled));
Assert.That(setup.Response.Object, Is.EqualTo(response));
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Exactly(0));
}

View File

@ -1,18 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0;net5.0</TargetFrameworks>
<TargetFrameworks>net8.0;net7.0;net6.0</TargetFrameworks>
<LangVersion>9.0</LangVersion>
<IsPackable>false</IsPackable>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.69" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Console" Version="3.16.3" />
<PackageReference Include="NUnit.Console" Version="3.17.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,6 +1,5 @@
using System.Text;
using NUnit.Framework;
using SpotifyAPI.Web;
namespace SpotifyAPI.Web.Tests
{
@ -12,7 +11,7 @@ namespace SpotifyAPI.Web.Tests
{
var encoded = "SGVsbG9Xb3JsZA";
Assert.AreEqual("HelloWorld", Encoding.UTF8.GetString(Base64Util.UrlDecode(encoded)));
Assert.That("HelloWorld", Is.EqualTo(Encoding.UTF8.GetString(Base64Util.UrlDecode(encoded))));
}
[Test]
@ -20,7 +19,7 @@ namespace SpotifyAPI.Web.Tests
{
var decoded = "HelloWorld";
Assert.AreEqual("SGVsbG9Xb3JsZA", Base64Util.UrlEncode(Encoding.UTF8.GetBytes(decoded)));
Assert.That("SGVsbG9Xb3JsZA", Is.EqualTo(Base64Util.UrlEncode(Encoding.UTF8.GetBytes(decoded))));
}
[Test]
@ -29,7 +28,7 @@ namespace SpotifyAPI.Web.Tests
var bytes = new byte[] { 0x04, 0x9f, 0x9c, 0xff, 0x3f, 0x0a };
// normal base64: BJ+c/z8K
Assert.AreEqual("BJ-c_z8K", Base64Util.UrlEncode(bytes));
Assert.That("BJ-c_z8K", Is.EqualTo(Base64Util.UrlEncode(bytes)));
}
[Test]
@ -38,7 +37,7 @@ namespace SpotifyAPI.Web.Tests
var bytes = new byte[] { 0x04, 0x9f, 0x9c, 0xff, 0x3f, 0x0a };
// normal base64: BJ+c/z8K
Assert.AreEqual(bytes, Base64Util.UrlDecode("BJ-c_z8K"));
Assert.That(bytes, Is.EqualTo(Base64Util.UrlDecode("BJ-c_z8K")));
}
}
}

View File

@ -18,7 +18,7 @@ namespace SpotifyAPI.Web.Tests
{ "hello", "world" },
{ "nice", "day" }
};
Assert.AreEqual(expected, uri.ApplyParameters(parameters).ToString());
Assert.That(expected, Is.EqualTo(uri.ApplyParameters(parameters).ToString()));
}
[Test]
@ -32,7 +32,7 @@ namespace SpotifyAPI.Web.Tests
{ "hello", "world" },
{ "nice", "day" }
};
Assert.AreEqual(expected, uri.ApplyParameters(parameters).ToString());
Assert.That(expected, Is.EqualTo(uri.ApplyParameters(parameters).ToString()));
}
[Test]
@ -45,7 +45,7 @@ namespace SpotifyAPI.Web.Tests
{
{ "hello", "&world " },
};
Assert.AreEqual(expected, uri.ApplyParameters(parameters).ToString());
Assert.That(expected, Is.EqualTo(uri.ApplyParameters(parameters).ToString()));
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace SpotifyAPI.Web.Tests
@ -16,7 +15,7 @@ namespace SpotifyAPI.Web.Tests
var formatter = new URIParameterFormatProvider();
string func(FormattableString str) => str.ToString(formatter);
Assert.AreEqual(expected, func($"/users/{user}"));
Assert.That(expected, Is.EqualTo(func($"/users/{user}")));
}
[Test]
@ -28,7 +27,7 @@ namespace SpotifyAPI.Web.Tests
var formatter = new URIParameterFormatProvider();
string func(FormattableString str) => str.ToString(formatter);
Assert.AreEqual(expected, func($"/users/{user}"));
Assert.That(expected, Is.EqualTo(func($"/users/{user}")));
}
}
}

View File

@ -50,7 +50,7 @@ namespace SpotifyAPI.Web
public string ClientId { get; }
/// <summary>
/// The ClientID, defined in a spotify application in your Spotify Developer Dashboard
/// The Client secret, defined in a spotify application in your Spotify Developer Dashboard
/// </summary>
public string ClientSecret { get; }

View File

@ -16,6 +16,14 @@ namespace SpotifyAPI.Web
return API.Get<FullArtist>(URLs.Artist(artistId), cancel);
}
public Task<FullArtist> Get(string artistId, ArtistRequest request, CancellationToken cancel = default)
{
Ensure.ArgumentNotNullOrEmptyString(artistId, nameof(artistId));
Ensure.ArgumentNotNull(request, nameof(request));
return API.Get<FullArtist>(URLs.Artist(artistId), request.BuildQueryParams(), cancel);
}
public Task<Paging<SimpleAlbum>> GetAlbums(string artistId, CancellationToken cancel = default)
{
Ensure.ArgumentNotNullOrEmptyString(artistId, nameof(artistId));
@ -38,6 +46,14 @@ namespace SpotifyAPI.Web
return API.Get<ArtistsRelatedArtistsResponse>(URLs.ArtistRelatedArtists(artistId), cancel);
}
public Task<ArtistsRelatedArtistsResponse> GetRelatedArtists(string artistId, ArtistsRelatedArtistsRequest request, CancellationToken cancel = default)
{
Ensure.ArgumentNotNullOrEmptyString(artistId, nameof(artistId));
Ensure.ArgumentNotNull(request, nameof(request));
return API.Get<ArtistsRelatedArtistsResponse>(URLs.ArtistRelatedArtists(artistId), request.BuildQueryParams(), cancel);
}
public Task<ArtistsResponse> GetSeveral(ArtistsRequest request, CancellationToken cancel = default)
{
Ensure.ArgumentNotNull(request, nameof(request));

View File

@ -1,4 +1,3 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using SpotifyAPI.Web.Http;

View File

@ -31,6 +31,18 @@ namespace SpotifyAPI.Web
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<FullArtist> Get(string artistId, CancellationToken cancel = default);
/// <summary>
/// Get Spotify catalog information for a single artist identified by their unique Spotify ID.
/// </summary>
/// <param name="artistId">The Spotify ID of the artist.</param>
/// <param name="cancel">The cancellation-token to allow to cancel the request.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-an-artist
/// </remarks>
/// <returns></returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<FullArtist> Get(string artistId, ArtistRequest request, CancellationToken cancel = default);
/// <summary>
/// Get Spotify catalog information about an artists albums.
/// Optional parameters can be specified in the query string to filter and sort the response.
@ -81,5 +93,17 @@ namespace SpotifyAPI.Web
/// </remarks>
/// <returns></returns>
Task<ArtistsRelatedArtistsResponse> GetRelatedArtists(string artistId, CancellationToken cancel = default);
/// <summary>
/// Get Spotify catalog information about artists similar to a given artist.
/// Similarity is based on analysis of the Spotify communitys listening history.
/// </summary>
/// <param name="artistId">The Spotify ID for the artist</param>
/// <param name="cancel">The cancellation-token to allow to cancel the request.</param>
/// <remarks>
/// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-an-artists-related-artists
/// </remarks>
/// <returns></returns>
Task<ArtistsRelatedArtistsResponse> GetRelatedArtists(string artistId, ArtistsRelatedArtistsRequest request, CancellationToken cancel = default);
}
}

View File

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using SpotifyAPI.Web;
using SpotifyAPI.Web.Http;
namespace SpotifyAPI.Web

View File

@ -28,5 +28,23 @@ namespace SpotifyAPI.Web
/// <exception cref="APIUnauthorizedException">Thrown if the client is not authenticated.</exception>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task<PublicUser> Get(string userId, CancellationToken cancel = default);
/// <summary>
/// Get Top tracks for the current user
/// </summary>
/// <param name="request">The query params to send to get Top Artists </param>
/// <param name="cancel">The cancellation-token to allow to cancel the request.</param>
/// <remarks>https://developer.spotify.com/documentation/web-api/reference/get-users-top-artists-and-tracks</remarks>
/// <exception cref="APIUnauthorizedException">Thrown if the client is not authenticated.</exception>
Task<UsersTopTracksResponse> GetTopTracks(UsersTopItemsRequest request, CancellationToken cancel = default);
/// <summary>
/// Get Top arsists for the current user
/// </summary>
/// <param name="request">The query params to send to get Top Artists</param>
/// <param name="cancel">The cancellation-token to allow to cancel the request.</param>
/// <remarks>https://developer.spotify.com/documentation/web-api/reference/get-users-top-artists-and-tracks</remarks>
/// <exception cref="APIUnauthorizedException">Thrown if the client is not authenticated.</exception>
Task<UsersTopArtistsResponse> GetTopArtists(UsersTopItemsRequest request, CancellationToken cancel = default);
}
}

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
#if !NETSTANDARD2_0
using System.Runtime.CompilerServices;
#endif
using System.Threading;
using System.Threading.Tasks;
using SpotifyAPI.Web.Http;

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
#if !NETSTANDARD2_0
using System.Runtime.CompilerServices;
#endif
using System.Threading;
using System.Threading.Tasks;
using SpotifyAPI.Web.Http;

View File

@ -1,5 +1,4 @@
using System;
using System.Net.Http;
using SpotifyAPI.Web.Http;
namespace SpotifyAPI.Web

View File

@ -1,4 +1,3 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using SpotifyAPI.Web.Http;
@ -20,5 +19,20 @@ namespace SpotifyAPI.Web
return API.Get<PublicUser>(SpotifyUrls.User(userId), cancel);
}
public Task<UsersTopTracksResponse> GetTopTracks(UsersTopItemsRequest request, CancellationToken cancel = default)
{
Ensure.ArgumentNotNull(request, nameof(request));
return API.Get<UsersTopTracksResponse>(SpotifyUrls.TopTracks(), request.BuildQueryParams(), cancel);
}
public Task<UsersTopArtistsResponse> GetTopArtists(UsersTopItemsRequest request, CancellationToken cancel = default)
{
Ensure.ArgumentNotNull(request, nameof(request));
return API.Get<UsersTopArtistsResponse>(SpotifyUrls.TopArtists(), request.BuildQueryParams(), cancel);
}
}
}

View File

@ -30,6 +30,9 @@ namespace SpotifyAPI.Web
{
}
#if NET8_0_OR_GREATER
[Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")]
#endif
protected APIException(SerializationInfo info, StreamingContext context) : base(info, context)
{
Response = info.GetValue("APIException.Response", typeof(IResponse)) as IResponse;
@ -67,6 +70,11 @@ namespace SpotifyAPI.Web
return null;
}
#if NET8_0_OR_GREATER
[Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")]
#endif
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);

View File

@ -26,6 +26,9 @@ namespace SpotifyAPI.Web
public APIPagingException(string message, Exception innerException) : base(message, innerException) { }
#if NET8_0_OR_GREATER
[Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")]
#endif
protected APIPagingException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@ -26,6 +26,9 @@ namespace SpotifyAPI.Web
public APITooManyRequestsException(string message, Exception innerException) : base(message, innerException) { }
#if NET8_0_OR_GREATER
[Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")]
#endif
protected APITooManyRequestsException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@ -15,6 +15,9 @@ namespace SpotifyAPI.Web
public APIUnauthorizedException(string message, Exception innerException) : base(message, innerException) { }
#if NET8_0_OR_GREATER
[Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")]
#endif
protected APIUnauthorizedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@ -166,7 +166,7 @@ namespace SpotifyAPI.Web.Http
_httpClient.SetRequestTimeout(timeout);
}
private IRequest CreateRequest(
private Request CreateRequest(
Uri uri,
HttpMethod method,
IDictionary<string, string>? parameters,

View File

@ -1,5 +1,3 @@
using System.Threading.Tasks;
namespace SpotifyAPI.Web.Http
{
public interface IJSONSerializer

View File

@ -112,7 +112,7 @@ namespace SpotifyAPI.Web.Http
_httpClient.Timeout = timeout;
}
private static HttpMessageHandler CreateMessageHandler(IProxyConfig proxyConfig)
private static HttpClientHandler CreateMessageHandler(IProxyConfig proxyConfig)
{
var proxy = new WebProxy
{

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

View File

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;

View File

@ -0,0 +1,21 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
namespace SpotifyAPI.Web
{
public class DoubleToIntConverter : JsonConverter<int>
{
public override void WriteJson(JsonWriter? writer, int value, JsonSerializer serializer)
{
writer?.WriteValue(value);
}
public override int ReadJson(JsonReader? reader, Type objectType, int existingValue, bool hasExistingValue,
JsonSerializer serializer)
{
return reader != null ? Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture) : 0;
}
}
}

View File

@ -8,5 +8,16 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -24,6 +24,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("offset")]
public int? Offset { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -29,6 +29,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -0,0 +1,17 @@
namespace SpotifyAPI.Web
{
public class ArtistRequest : RequestParams
{
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -23,6 +23,17 @@ namespace SpotifyAPI.Web
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// The number of album objects to return. Default: 20. Minimum: 1. Maximum: 50. For example: limit=2
/// </summary>

View File

@ -0,0 +1,17 @@
namespace SpotifyAPI.Web
{
public class ArtistsRelatedArtistsRequest : RequestParams
{
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -21,6 +21,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("ids")]
public IList<string> Ids { get; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -19,6 +19,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string Market { get; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -10,6 +10,17 @@ namespace SpotifyAPI.Web
[QueryParam("country")]
public string? Country { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.
/// </summary>

View File

@ -13,6 +13,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -33,6 +33,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -25,6 +25,17 @@ namespace SpotifyAPI.Web
[QueryParam("limit")]
public int? Limit { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// The last artist ID retrieved from the previous request.
/// </summary>

View File

@ -24,6 +24,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -24,5 +24,16 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -24,6 +24,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -11,6 +11,17 @@ namespace SpotifyAPI.Web
[QueryParam("country")]
public string? Country { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.
/// </summary>

View File

@ -1,5 +1,3 @@
using System;
namespace SpotifyAPI.Web
{
public class PKCETokenRefreshRequest

View File

@ -9,6 +9,17 @@ namespace SpotifyAPI.Web
[QueryParam("limit")]
public int? Limit { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// The index of the first entity to return. Default: 0 (i.e., the first track). Use with limit to get the next set of entities.
/// </summary>

View File

@ -25,6 +25,17 @@ namespace SpotifyAPI.Web
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// This is set to `"track", "episode"` by default.
/// </summary>

View File

@ -29,6 +29,17 @@ namespace SpotifyAPI.Web
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// A comma-separated list of item types that your client supports besides the default track type.
/// Valid types are: track and episode. An unsupported type in the response is expected to be represented

View File

@ -9,6 +9,17 @@ namespace SpotifyAPI.Web
[QueryParam("limit")]
public int? Limit { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// A Unix timestamp in milliseconds. Returns all items after (but not including) this cursor position.
/// If after is specified, before must not be specified.

View File

@ -9,6 +9,17 @@ namespace SpotifyAPI.Web
[QueryParam("limit")]
public int? Limit { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// The index of the first playlist to return.
/// Default: 0 (the first object). Maximum offset: 100.000. Use with limit to get the next set of playlists.

View File

@ -65,6 +65,17 @@ namespace SpotifyAPI.Web
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// This is set to `"track", "episode"` by default.
/// </summary>

View File

@ -39,6 +39,17 @@ namespace SpotifyAPI.Web
[QueryParam("market")]
public string? Market { get; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// This is set to `"track", "episode"` by default.
/// </summary>

View File

@ -16,6 +16,16 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("offset")]
public int? Offset { get; set; }
}
}
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -60,6 +60,17 @@ namespace SpotifyAPI.Web
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// Multiple values. For each tunable track attribute, a hard floor on the selected track attributes value can be provided.
/// See tunable track attributes below for the list of available options.

View File

@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

View File

@ -59,6 +59,17 @@ namespace SpotifyAPI.Web
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
/// <summary>
/// Maximum number of results to return.
/// Default: 20

View File

@ -9,6 +9,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -29,6 +29,17 @@ namespace SpotifyAPI.Web
/// <value></value>
[QueryParam("market")]
public string? Market { get; set; }
/// <summary>
/// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code,
/// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)".
/// Provide this parameter if you want the category strings returned in a particular language.
/// Note that, if locale is not supplied, or if the specified language is not available,
/// the category strings returned will be in the Spotify default language (American English).
/// </summary>
/// <value></value>
[QueryParam("locale")]
public string? Locale { get; set; }
}
}

View File

@ -0,0 +1,47 @@
using System;
namespace SpotifyAPI.Web
{
public class UsersTopItemsRequest : RequestParams
{
public UsersTopItemsRequest(TimeRange timeRange)
{
Ensure.ArgumentNotNull(timeRange, nameof(TimeRange));
TimeRangeParam = timeRange;
}
/// <summary>
/// The TimeRange Param : How far to look back for the top items.
/// </summary>
/// <value></value>
[QueryParam("time_range")]
public TimeRange TimeRangeParam { get; } = TimeRange.MediumTerm;
/// <summary>
/// The maximum number of objects to return. Default: 20. Minimum: 1. Maximum: 50.
/// </summary>
/// <value></value>
[QueryParam("limit")]
public int? Limit { get; set; }
/// <summary>
/// The index of the first object to return. Default: 0 (i.e., the first object).
/// Use with limit to get the next set of objects.
/// </summary>
/// <value></value>
[QueryParam("offset")]
public int? Offset { get; set; }
}
public enum TimeRange
{
[String("short_term")]
ShortTerm,
[String("medium_term")]
MediumTerm,
[String("long_term")]
LongTerm
}
}

View File

@ -7,6 +7,7 @@ namespace SpotifyAPI.Web
public bool IsPrivateSession { get; set; }
public bool IsRestricted { get; set; }
public string Name { get; set; } = default!;
public bool SupportsVolume { get; set; }
public string Type { get; set; } = default!;
public int? VolumePercent { get; set; }
}

View File

@ -1,10 +1,12 @@
using Newtonsoft.Json;
namespace SpotifyAPI.Web
{
public class Followers
{
public string Href { get; set; } = default!;
[JsonConverter(typeof(DoubleToIntConverter))]
public int Total { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace SpotifyAPI.Web
{
@ -11,6 +12,7 @@ namespace SpotifyAPI.Web
public string Id { get; set; } = default!;
public List<Image> Images { get; set; } = default!;
public string Name { get; set; } = default!;
[JsonConverter(typeof(DoubleToIntConverter))]
public int Popularity { get; set; }
public string Type { get; set; } = default!;
public string Uri { get; set; } = default!;

View File

@ -8,6 +8,7 @@ namespace SpotifyAPI.Web
{
public string AudioPreviewUrl { get; set; } = default!;
public string Description { get; set; } = default!;
public string HtmlDescription { get; set; } = default!;
public int DurationMs { get; set; }
public bool Explicit { get; set; }
public Dictionary<string, string> ExternalUrls { get; set; } = default!;

View File

@ -7,6 +7,7 @@ namespace SpotifyAPI.Web
public List<string> AvailableMarkets { get; set; } = default!;
public List<Copyright> Copyrights { get; set; } = default!;
public string Description { get; set; } = default!;
public string HtmlDescription { get; set; } = default!;
public Paging<SimpleEpisode> Episodes { get; set; } = default!;
public bool Explicit { get; set; }
public Dictionary<string, string> ExternalUrls { get; set; } = default!;
@ -20,6 +21,7 @@ namespace SpotifyAPI.Web
public string Publisher { get; set; } = default!;
public string Type { get; set; } = default!;
public string Uri { get; set; } = default!;
public int TotalEpisodes { get; set; } = default!;
}
}

View File

@ -10,6 +10,7 @@ namespace SpotifyAPI.Web
public List<SimpleArtist> Artists { get; set; } = default!;
public List<string> AvailableMarkets { get; set; } = default!;
public int DiscNumber { get; set; }
[JsonConverter(typeof(DoubleToIntConverter))]
public int DurationMs { get; set; }
public bool Explicit { get; set; }
public Dictionary<string, string> ExternalIds { get; set; } = default!;

View File

@ -1,8 +1,12 @@
using Newtonsoft.Json;
namespace SpotifyAPI.Web
{
public class Image
{
[JsonConverter(typeof(DoubleToIntConverter))]
public int Height { get; set; }
[JsonConverter(typeof(DoubleToIntConverter))]
public int Width { get; set; }
public string Url { get; set; } = default!;
}

View File

@ -5,7 +5,7 @@ namespace SpotifyAPI.Web
public class RecommendationsResponse
{
public List<RecommendationSeed> Seeds { get; set; } = default!;
public List<SimpleTrack> Tracks { get; set; } = default!;
public List<FullTrack> Tracks { get; set; } = default!;
}
}

View File

@ -9,6 +9,7 @@ namespace SpotifyAPI.Web
{
public string AudioPreviewUrl { get; set; } = default!;
public string Description { get; set; } = default!;
public string HtmlDescription { get; set; } = default!;
public int DurationMs { get; set; }
public bool Explicit { get; set; }
public Dictionary<string, string> ExternalUrls { get; set; } = default!;

View File

@ -7,6 +7,7 @@ namespace SpotifyAPI.Web
public List<string> AvailableMarkets { get; set; } = default!;
public List<Copyright> Copyrights { get; set; } = default!;
public string Description { get; set; } = default!;
public string HtmlDescription { get; set; } = default!;
public bool Explicit { get; set; }
public Dictionary<string, string> ExternalUrls { get; set; } = default!;
public string Href { get; set; } = default!;
@ -19,6 +20,7 @@ namespace SpotifyAPI.Web
public string Publisher { get; set; } = default!;
public string Type { get; set; } = default!;
public string Uri { get; set; } = default!;
public int TotalEpisodes { get; set; } = default!;
}
}

View File

@ -1,5 +1,3 @@
using System;
namespace SpotifyAPI.Web
{
public class TrackMeta

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace SpotifyAPI.Web
{
public class UsersTopArtistsResponse
{
public string Href { get; set; } = default!;
public int Limit { get; set; }
public string Next { get; set; } = default!;
public int Offset { get; set; }
public string Previous { get; set; } = default!;
public int Total { get; set; } = default!;
public List<FullArtist> Items { get; set; } = default!;
}
}

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace SpotifyAPI.Web
{
public class UsersTopTracksResponse
{
public string Href { get; set; } = default!;
public int Limit { get; set; }
public string Next { get; set; } = default!;
public int Offset { get; set; }
public string Previous { get; set; } = default!;
public int Total { get; set; } = default!;
public List<FullTrack> Items { get; set; } = default!;
}
}

View File

@ -1,4 +1,3 @@
using System;
using System.Threading;
using System.Threading.Tasks;

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0;net5.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net8.0;net7.0;net6.0;net5.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
<PackageId>SpotifyAPI.Web</PackageId>
@ -32,7 +32,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3">
<PrivateAssets>None</PrivateAssets>
</PackageReference>

View File

@ -13,6 +13,10 @@ namespace SpotifyAPI.Web
public static Uri Me() => EUri($"me");
public static Uri TopTracks() => EUri($"me/top/tracks");
public static Uri TopArtists() => EUri($"me/top/artists");
public static Uri User(string userId) => EUri($"users/{userId}");
public static Uri Categories() => EUri($"browse/categories");

View File

@ -1,20 +1,32 @@
using System;
using System.Globalization;
#if NET8_0_OR_GREATER
using System.Text;
#endif
namespace SpotifyAPI.Web
{
internal class Base64Util
{
internal const string WebEncoders_InvalidCountOffsetOrLength = "Invalid {0}, {1} or {2} length.";
#if NET8_0_OR_GREATER
internal static CompositeFormat WebEncoders_MalformedInput = CompositeFormat.Parse("Malformed input: {0} is an invalid input length.");
#else
internal const string WebEncoders_MalformedInput = "Malformed input: {0} is an invalid input length.";
#endif
public static string UrlEncode(byte[] input)
{
#if NET8_0_OR_GREATER
ArgumentNullException.ThrowIfNull(input);
#else
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
#endif
// Special-case empty input
if (input.Length == 0)
@ -48,11 +60,15 @@ namespace SpotifyAPI.Web
public static byte[] UrlDecode(string input)
{
var buffer = new char[GetArraySizeRequiredToDecode(input.Length)];
#if NET8_0_OR_GREATER
ArgumentNullException.ThrowIfNull(input);
#else
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
#endif
var buffer = new char[GetArraySizeRequiredToDecode(input.Length)];
// Assumption: input is base64url encoded without padding and contains no whitespace.
@ -97,10 +113,14 @@ namespace SpotifyAPI.Web
private static int GetArraySizeRequiredToDecode(int count)
{
#if NET8_0_OR_GREATER
ArgumentOutOfRangeException.ThrowIfNegative(count);
#else
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
#endif
if (count == 0)
{

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