Socket
Socket
Sign inDemoInstall

graphql-spotify

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphql-spotify - npm Package Compare versions

Comparing version 0.4.31 to 0.4.35

CODE_OF_CONDUCT.md

2

package.json
{
"name": "graphql-spotify",
"version": "0.4.31",
"version": "0.4.35",
"description": "GraphQL Schema And Resolvers For Spotify Web API",

@@ -5,0 +5,0 @@ "main": "dist/lib.js",

@@ -5,3 +5,3 @@ ## A [Spotify API](https://beta.developer.spotify.com/documentation/web-api/reference/) GraphQL Schema Implementation Built with [GraphQL.js](https://github.com/graphql/graphql-js)

Refer to `src/schema/RootQuery.js` for operations currently supported.
Refer to [src/schema/RootQuery.js](src/schema/RootQuery.js) for operations currently supported.
## Getting started

@@ -73,4 +73,4 @@ ```javascript

## Contribute
Anyone is welcome! Take a look at [Roadmap.md](./Roadmap.md) for PR ideas and file some issues!
Anyone is welcome! Take a look at [Roadmap.md](Roadmap.md) for PR ideas and file some issues!

@@ -5,2 +5,5 @@ import {

const MAX_PLAYLIST_TRACKS_FETCH_LIMIT = 100
const MAX_TOP_TYPE_FETCH_LIMIT = 50
export function makeResolvers(token) {

@@ -10,3 +13,3 @@ const {

AudioFeaturesLoader, SavedContainsLoader, TracksLoader, CategoriesLoader, RecommendationsLoader,
CategoryPlaylistLoader, CategoryLoader
CategoryPlaylistLoader, CategoryLoader, TopTypeLoader
} = makeLoaders(token);

@@ -46,2 +49,23 @@

return await RecommendationsLoader.load(args.parameters)
},
top: async (obj, args) => {
const { type, limit, offset, time_range } = args
const result = await TopTypeLoader.load({ type, limit, offset, time_range })
if (result.items.length >= limit) {
return result
}
let allItems = result.items
const totalFetchSize = Math.min(limit, result.total)
let currentOffset = allItems.length
let fetches = []
while (currentOffset < totalFetchSize) {
const fetchSize = Math.min(MAX_TOP_TYPE_FETCH_LIMIT, totalFetchSize - currentOffset);
fetches.push(TopTypeLoader.load({type, time_range, limit: fetchSize, offset: currentOffset }))
currentOffset = currentOffset + fetchSize;
}
const fetchResults = await Promise.all(fetches);
fetchResults.forEach((result) => {
allItems = allItems.concat(result.items)
})
return { total: result.total, items: allItems, limit: allItems.length, offset }
}

@@ -65,3 +89,3 @@ },

tracks: async (obj, args) => {
const { id: playlistId , owner: { id: userId }, tracks: { total, offset, items, limit }} = obj
const { id: playlistId , owner: { id: userId }, tracks: { total, offset, items }} = obj
// fetch with limit and offset when specified

@@ -72,3 +96,3 @@ if (args.limit && args.offset) {

// otherwise always fetch all of the tracks
// when resolving a full playlist there are already items
// when resolving a full playlist, tracks are set the first 100 tracks
let allItems = items || []

@@ -78,4 +102,5 @@ let currentOffset = allItems.length

while (currentOffset < total ) {
fetches.push(PlaylistTracksLoader.load({playlistId, userId, limit, offset: currentOffset }))
currentOffset = currentOffset + limit;
const fetchSize = Math.min(MAX_PLAYLIST_TRACKS_FETCH_LIMIT, total - currentOffset);
fetches.push(PlaylistTracksLoader.load({playlistId, userId, limit: fetchSize, offset: currentOffset }))
currentOffset = currentOffset + fetchSize;
}

@@ -91,3 +116,3 @@ const fetchResults = await Promise.all(fetches);

audio_features: async ({ id }) => {
return await AudioFeatureLoader.load(id)
return await AudioFeaturesLoader.load(id)
},

@@ -157,2 +182,8 @@ saved: async ({id}) => {

}
if (type === 'artist') {
return 'Artist'
}
if (type === 'track') {
return 'Track'
}
if (type === 'playlist') {

@@ -159,0 +190,0 @@ return 'Playlist'

@@ -12,2 +12,3 @@ const Artist = `

external_urls: ExternalUrls
type: String
}

@@ -14,0 +15,0 @@ `;

@@ -9,2 +9,4 @@ import Playlist from './Playlist'

import Paging from './Paging'
import TimeRange from './TimeRange'
import TopType from './TopType'
import AudioFeatures from './AudioFeatures'

@@ -28,4 +30,5 @@ import PlayHistory from './PlayHistory'

const typeDefs = [SchemaDefinition, RootQuery, Playlist, Image, User, PlaylistTrack, Track, Album, Artist, Paging,
AudioFeatures, PlayHistory, Category, RecommendationParameters, RecommendationsResponse, RecommendationsSeedObject, ExternalUrls];
AudioFeatures, PlayHistory, Category, RecommendationParameters, RecommendationsResponse, RecommendationsSeedObject,
ExternalUrls, TimeRange, TopType];
export default typeDefs
const Paging = `
union Item = Playlist | PlaylistTrack | Category
union Item = Playlist | PlaylistTrack | Category | Artist | Track
type Paging {

@@ -4,0 +4,0 @@ href: String

@@ -40,3 +40,8 @@ const RootQuery = `

recommendations(parameters: RecommendationParameters): RecommendationsResponse
"""
Get the current user’s top artists or tracks based on calculated affinity.
(https://beta.developer.spotify.com/documentation/web-api/reference/personalization/get-users-top-artists-and-tracks/)
Required Scope: **user-top-read**
"""
top(type: TopType!, limit: Int, offset: Int, time_range: TimeRange): Paging
}

@@ -43,0 +48,0 @@ type Mutation {

@@ -23,2 +23,3 @@ const Track = `

saved: Boolean
type: String
}

@@ -25,0 +26,0 @@ `

@@ -13,7 +13,7 @@ import 'isomorphic-fetch'

function cacheKeyFnForQueryKeys(key) {
return JSON.stringify(key)
return serializeToURLParameters(key)
}
function serializeToURLParameters(obj) {
return Object.entries(obj).map(([key, val]) => `${key}=${val}`).join('&')
return Object.entries(obj).map(([key, val]) => val && `${key}=${val}`).join('&')
}

@@ -100,2 +100,12 @@

export async function getTopType(token, params) {
const { type, limit, offset, time_range } = params
let res = await fetch(`https://api.spotify.com/v1/me/top/${type}?${serializeToURLParameters({ limit, offset, time_range })}`, {
method: 'GET',
headers: makeHeaders(token)
});
res = await res.json();
return res;
}
export async function getPlaylist(token, userId, playlistId)

@@ -257,2 +267,3 @@ {

}
export function makeRecommendationsLoader(token) {

@@ -265,2 +276,9 @@ const batchLoadFn = async ([key]) => {

export function makeGetTopTypeLoader(token) {
const batchLoadFn = async ([key]) => {
return [await getTopType(token, key)]
}
return new Dataloader(batchLoadFn, { batch: false, cacheKeyFn: cacheKeyFnForQueryKeys })
}
export function makeLoaders(token) {

@@ -279,4 +297,5 @@ return {

CategoryPlaylistLoader: makeCategoriesPlaylistsLoader(token),
CategoryLoader: makeCategoryLoader(token)
CategoryLoader: makeCategoryLoader(token),
TopTypeLoader: makeGetTopTypeLoader(token)
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc