From 43f640ed71fdbaf5582d72e94fd72addf3908bcf Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Thu, 4 Dec 2025 17:52:05 -0300 Subject: [PATCH 01/12] Syntax improvements to spotify components --- .../add-items-to-playlist.mjs | 11 +- .../create-playlist/create-playlist.mjs | 8 +- .../get-album-tracks/get-album-tracks.mjs | 8 +- .../get-all-tracks-by-artist.mjs | 5 +- .../get-artist-top-tracks.mjs | 16 +- .../get-audio-features-for-a-track.mjs | 12 +- .../get-categorys-playlist.mjs | 14 +- .../get-currently-playing-track.mjs | 24 +-- .../get-playlist-items/get-playlist-items.mjs | 14 +- .../get-recommendations.mjs | 5 +- .../spotify/actions/get-track/get-track.mjs | 10 +- .../remove-items-from-playlist.mjs | 15 +- .../remove-user-saved-tracks.mjs | 10 +- .../spotify/actions/save-track/save-track.mjs | 10 +- components/spotify/spotify.app.mjs | 171 ++++++++++-------- 15 files changed, 171 insertions(+), 162 deletions(-) diff --git a/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs b/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs index 4921527431094..78947d570e74d 100644 --- a/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs +++ b/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs @@ -1,5 +1,3 @@ -import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { @@ -46,14 +44,15 @@ export default { uris: this.spotify.sanitizedArray(uris), }; - const resp = await axios($, this.spotify._getAxiosParams({ + const resp = await this.spotify._makeRequest({ + $, method: "POST", - path: `/playlists/${get(playlistId, "value", playlistId)}/tracks`, + url: `/playlists/${playlistId.value ?? playlistId}/tracks`, data, - })); + }); // eslint-disable-next-line multiline-ternary - $.export("$summary", `Successfully added ${data.uris.length} ${data.uris.length == 1 ? "item" : "items"} to "${get(playlistId, "label", playlistId)}"`); + $.export("$summary", `Successfully added ${data.uris.length} ${data.uris.length == 1 ? "item" : "items"} to "${playlistId.label ?? playlistId}"`); return resp; }, diff --git a/components/spotify/actions/create-playlist/create-playlist.mjs b/components/spotify/actions/create-playlist/create-playlist.mjs index 1492f0851ab07..65bda36e33d44 100644 --- a/components/spotify/actions/create-playlist/create-playlist.mjs +++ b/components/spotify/actions/create-playlist/create-playlist.mjs @@ -1,4 +1,3 @@ -import { axios } from "@pipedream/platform"; import spotify from "../../spotify.app.mjs"; export default { @@ -53,11 +52,12 @@ export default { collaborative: isCollaborative, }; - const resp = await axios($, this.spotify._getAxiosParams({ + const resp = await this.spotify._makeRequest({ + $, method: "POST", - path: `/users/${this.spotify.$auth.oauth_uid}/playlists`, + url: `/users/${this.spotify.$auth.oauth_uid}/playlists`, data, - })); + }); $.export("$summary", `Successfully created a new playlist, "${data.name}"`); diff --git a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs index 449596d3c8669..6865dbd000d55 100644 --- a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs +++ b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs @@ -1,4 +1,3 @@ -import { axios } from "@pipedream/platform"; import spotify from "../../spotify.app.mjs"; import { ITEM_TYPES } from "../../consts.mjs"; const DEFAULT_LIMIT = 20; @@ -50,10 +49,11 @@ export default { let total = 0; do { - const { items } = await axios($, this.spotify._getAxiosParams({ - path: `/albums/${this.albumId}/tracks`, + const { items } = await this.spotify._makeRequest({ + $, + url: `/albums/${this.albumId}/tracks`, params, - })); + }); tracks.push(...items); total = items.length; params.offset += params.limit; diff --git a/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs b/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs index 93eedefe324dd..19868559ff41e 100644 --- a/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs +++ b/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs @@ -1,4 +1,3 @@ -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { @@ -34,16 +33,18 @@ export default { } = this; const chunksOfAlbumIds = await this.spotify.fetchChunksOfAlbumsIds({ + $, artistId, market, }); const tracks = await this.spotify.getAllTracksByChunksOfAlbumIds({ + $, chunksOfAlbumIds, market, }); - $.export("$summary", `Successfully fetched ${tracks.length} tracks for "${get(artistId, "label", artistId)}"`); + $.export("$summary", `Successfully fetched ${tracks.length} tracks for "${artistId.label ?? artistId}"`); return tracks; }, diff --git a/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs b/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs index 3bdd3d87f1a8c..891ae91f104ca 100644 --- a/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs +++ b/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs @@ -1,10 +1,8 @@ -import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { name: "Get an Artist's Top Tracks", - description: "Get Spotify catalog information about an artist’s top tracks by country. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-an-artists-top-tracks).", + description: "Get Spotify catalog information about an artist's top tracks by country. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-an-artists-top-tracks).", key: "spotify-get-artist-top-tracks", version: "0.1.3", annotations: { @@ -34,16 +32,16 @@ export default { market, } = this; - const res = await axios($, this.spotify._getAxiosParams({ - method: "GET", - path: `/artists/${get(artistId, "value", artistId)}/top-tracks`, + const res = await this.spotify._makeRequest({ + $, + url: `/artists/${artistId.value ?? artistId}/top-tracks`, params: { market, }, - })); + }); - $.export("$summary", `Successfully fetched top tracks for "${get(artistId, "label", artistId)}"`); + $.export("$summary", `Successfully fetched top tracks for "${artistId.label ?? artistId}"`); - return get(res, "tracks", []); + return res.tracks ?? []; }, }; diff --git a/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs b/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs index c61d05a68ab0a..1a6abbbdcdd79 100644 --- a/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs +++ b/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs @@ -1,5 +1,3 @@ -import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { @@ -24,12 +22,12 @@ export default { }, async run({ $ }) { const { trackId } = this; - const resp = await axios($, this.spotify._getAxiosParams({ - method: "GET", - path: `/audio-features/${get(trackId, "value", trackId)}`, - })); + const resp = await this.spotify._makeRequest({ + $, + url: `/audio-features/${trackId.value ?? trackId}`, + }); - $.export("$summary", `Successfully fetched audio info for the track, "${get(trackId, "label", trackId)}"`); + $.export("$summary", `Successfully fetched audio info for the track, "${trackId.label ?? trackId}"`); return resp; }, diff --git a/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs b/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs index d1009c0a7cadc..798be9580e978 100644 --- a/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs +++ b/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs @@ -1,5 +1,3 @@ -import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { @@ -51,18 +49,18 @@ export default { offset, } = this; - const res = await axios($, this.spotify._getAxiosParams({ - method: "GET", - path: `/browse/categories/${get(categoryId, "value", categoryId)}/playlists`, + const res = await this.spotify._makeRequest({ + $, + url: `/browse/categories/${categoryId.value ?? categoryId}/playlists`, params: { limit, offset, country: market, }, - })); + }); - $.export("$summary", `Successfully fetched playlists for the "${get(categoryId, "label", categoryId)}" category`); + $.export("$summary", `Successfully fetched playlists for the "${categoryId.label ?? categoryId}" category`); - return get(res, "playlists.items", []); + return res.playlists?.items ?? []; }, }; diff --git a/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs b/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs index d54b4f4599964..71c1ef8020f79 100644 --- a/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs +++ b/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs @@ -1,4 +1,3 @@ -import { axios } from "@pipedream/platform"; import spotify from "../../spotify.app.mjs"; import { ITEM_TYPES } from "../../consts.mjs"; @@ -28,20 +27,17 @@ export default { const { market } = this; try { - const res = await axios( + const res = await this.spotify._makeRequest({ $, - this.spotify._getAxiosParams({ - method: "GET", - path: "/me/player/currently-playing", - params: { - market, - additional_types: [ - ITEM_TYPES.TRACK, - ITEM_TYPES.EPISODE, - ].join(","), - }, - }), - ); + url: "/me/player/currently-playing", + params: { + market, + additional_types: [ + ITEM_TYPES.TRACK, + ITEM_TYPES.EPISODE, + ].join(","), + }, + }); const itemType = res?.currently_playing_type || "track"; const itemName = res?.item?.name || "Nothing"; diff --git a/components/spotify/actions/get-playlist-items/get-playlist-items.mjs b/components/spotify/actions/get-playlist-items/get-playlist-items.mjs index 3e24cb5b5f2d0..8cdda3ed69634 100644 --- a/components/spotify/actions/get-playlist-items/get-playlist-items.mjs +++ b/components/spotify/actions/get-playlist-items/get-playlist-items.mjs @@ -1,5 +1,3 @@ -import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { @@ -60,9 +58,9 @@ export default { additionalTypes, } = this; - const res = await axios($, this.spotify._getAxiosParams({ - method: "GET", - path: `/playlists/${get(playlistId, "value", playlistId)}/tracks`, + const res = await this.spotify._makeRequest({ + $, + url: `/playlists/${playlistId.value ?? playlistId}/tracks`, params: { fields, market, @@ -70,10 +68,10 @@ export default { offset, additional_types: additionalTypes && additionalTypes.join(",").toLowerCase(), }, - })); + }); - $.export("$summary", `Successfully fetched details for "${get(playlistId, "label", playlistId)}"`); + $.export("$summary", `Successfully fetched details for "${playlistId.label ?? playlistId}"`); - return get(res, "items", []); + return res.items ?? []; }, }; diff --git a/components/spotify/actions/get-recommendations/get-recommendations.mjs b/components/spotify/actions/get-recommendations/get-recommendations.mjs index 3cc71f2a8f89e..67580c3fa9f05 100644 --- a/components/spotify/actions/get-recommendations/get-recommendations.mjs +++ b/components/spotify/actions/get-recommendations/get-recommendations.mjs @@ -70,7 +70,10 @@ export default { limit, }; - const response = await this.spotify.getRecommendations(params, $); + const response = await this.spotify.getRecommendations({ + $, + ...params, + }); if (response.tracks.length === 0) { $.export("$summary", "No recommendations found"); diff --git a/components/spotify/actions/get-track/get-track.mjs b/components/spotify/actions/get-track/get-track.mjs index 465d42d2b9b2f..1414ee71d9305 100644 --- a/components/spotify/actions/get-track/get-track.mjs +++ b/components/spotify/actions/get-track/get-track.mjs @@ -1,5 +1,3 @@ -import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { @@ -35,13 +33,13 @@ export default { market, } = this; - const res = await axios($, this.spotify._getAxiosParams({ - method: "GET", - path: `/tracks/${get(trackId, "value", trackId)}`, + const res = await this.spotify._makeRequest({ + $, + url: `/tracks/${trackId.value ?? trackId}`, params: { market, }, - })); + }); $.export("$summary", `Successfully fetched info for the track, "${res.name}"`); diff --git a/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs b/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs index af11d9388f061..ee9f10025c350 100644 --- a/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs +++ b/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs @@ -1,10 +1,8 @@ -import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import spotify from "../../spotify.app.mjs"; export default { name: "Remove Items from a Playlist", - description: "Remove one or more items from a user’s playlist. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/remove-tracks-playlist)", + description: "Remove one or more items from a user's playlist. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/remove-tracks-playlist)", key: "spotify-remove-items-from-playlist", version: "0.1.3", annotations: { @@ -33,7 +31,7 @@ export default { snapshotId: { type: "string", label: "Snapshot ID", - description: "The playlist’s snapshot ID against which you want to make the changes. The API will validate that the specified items exist and in the specified positions and make the changes, even if more recent changes have been made to the playlist.", + description: "The playlist's snapshot ID against which you want to make the changes. The API will validate that the specified items exist and in the specified positions and make the changes, even if more recent changes have been made to the playlist.", optional: true, }, }, @@ -53,14 +51,15 @@ export default { snapshot_id: snapshotId, }; - const resp = await axios($, this.spotify._getAxiosParams({ + const resp = await this.spotify._makeRequest({ + $, method: "DELETE", - path: `/playlists/${get(playlistId, "value", playlistId)}/tracks`, + url: `/playlists/${playlistId.value ?? playlistId}/tracks`, data, - })); + }); // eslint-disable-next-line multiline-ternary - $.export("$summary", `Successfully removed ${tracks.length} ${tracks.length == 1 ? "item" : "items"} from the playlist, "${get(playlistId, "label", playlistId)}"`); + $.export("$summary", `Successfully removed ${tracks.length} ${tracks.length == 1 ? "item" : "items"} from the playlist, "${playlistId.label ?? playlistId}"`); return resp; }, diff --git a/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs b/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs index 059efa6f4b988..3a000deefbdda 100644 --- a/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs +++ b/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs @@ -1,9 +1,8 @@ -import { axios } from "@pipedream/platform"; import spotify from "../../spotify.app.mjs"; export default { name: "Remove User's Saved Tracks", - description: "Remove one or more tracks from the current user’s ‘Your Music’ library. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/remove-tracks-user)", + description: "Remove one or more tracks from the current user's 'Your Music' library. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/remove-tracks-user)", key: "spotify-remove-user-saved-tracks", version: "0.1.3", annotations: { @@ -26,13 +25,14 @@ export default { const ids = this.spotify.sanitizedArray(savedUserTracksId); - const resp = await axios($, this.spotify._getAxiosParams({ + const resp = await this.spotify._makeRequest({ + $, method: "DELETE", - path: "/me/tracks", + url: "/me/tracks", data: { ids, }, - })); + }); // eslint-disable-next-line multiline-ternary $.export("$summary", `Successfully removed ${ids.length} ${ids.length == 1 ? "item" : "items"} from "Liked Songs"`); diff --git a/components/spotify/actions/save-track/save-track.mjs b/components/spotify/actions/save-track/save-track.mjs index 3a8d608580981..5af41fde78243 100644 --- a/components/spotify/actions/save-track/save-track.mjs +++ b/components/spotify/actions/save-track/save-track.mjs @@ -1,10 +1,9 @@ -import { axios } from "@pipedream/platform"; import isEmpty from "lodash/isEmpty.js"; import spotify from "../../spotify.app.mjs"; export default { name: "Save Tracks for User", - description: "Save one or more tracks to the current user’s \"Your Music\" library. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/save-tracks-user).", + description: "Save one or more tracks to the current user's \"Your Music\" library. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/save-tracks-user).", key: "spotify-save-track", version: "0.1.3", annotations: { @@ -27,13 +26,14 @@ export default { }, async run({ $ }) { const ids = this.spotify.sanitizedArray(this.trackIds); - const res = await axios($, this.spotify._getAxiosParams({ + const res = await this.spotify._makeRequest({ + $, method: "PUT", - path: "/me/tracks", + url: "/me/tracks", data: { ids, }, - })); + }); // eslint-disable-next-line multiline-ternary $.export("$summary", `Successfully saved ${ids.length} ${ids.length == 1 ? "track" : "tracks"} to "Liked Songs"`); diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index 3636b3b1a4b06..4c3acf22ca134 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -1,8 +1,6 @@ import { axios } from "@pipedream/platform"; -import get from "lodash/get.js"; import isArray from "lodash/isArray.js"; import isEmpty from "lodash/isEmpty.js"; -import isNil from "lodash/isNil.js"; import isString from "lodash/isString.js"; import { promisify } from "util"; import { @@ -35,7 +33,7 @@ export default { const items = await this.getPlaylistItems({ limit, offset: limit * page, - playlistId: get(playlistId, "value", playlistId), + playlistId: playlistId.value ?? playlistId, }); return { @@ -208,7 +206,7 @@ export default { methods: { sanitizedArray(value) { if (isArray(value)) { - return value.map((item) => get(item, "value", item)); + return value.map((item) => item.value ?? item); } // If is string, try to convert it in an array @@ -223,38 +221,11 @@ export default { throw new Error(`${value} is not an array or an array-like`); }, - _getAxiosParams(opts) { - return { - ...opts, - url: this._getBaseUrl() + opts.path + this._getQuery(opts.params), - headers: this._getHeaders(), - }; - }, - _getBaseUrl() { - return "https://api.spotify.com/v1"; - }, _getHeaders() { return { Authorization: `Bearer ${this.$auth.oauth_access_token}`, }; }, - _getQuery(params) { - if (!params) { - return ""; - } - - let query = "?"; - const keys = Object.keys(params); - for (let i = 0; i < keys.length; i++) { - // Explicity looking for nil values to avoid false negative for Boolean(false) - if (!isNil(params[keys[i]])) { - query += `${keys[i]}=${params[keys[i]]}&`; - } - } - - // It removes the last string char, it can be ? or & - return query.substr(0, query.length - 1); - }, async _paginate(resourceFn, params = {}) { let data = []; params.limit = 20; @@ -288,20 +259,25 @@ export default { const artists = track.artists.map((artist) => artist.name).join(", "); return `${track.name} [${artists}]`; }, - async _makeRequest(method, endpoint, params) { + async _makeRequest({ + $ = this, + headers, + ...args + } = {}) { const config = { - method, - url: `${await this._getBaseUrl()}${endpoint}`, - headers: await this._getHeaders(), - params, + baseURL: this._getBaseUrl(), + headers: { + ...headers, + ...this._getHeaders(), + }, + ...args, }; - return await this.retry(config); + return await this.retry($, config); }, // Retry axios request if not successful - async retry(config, retries = 3) { - let response; + async retry($, config, retries = 3) { try { - return await axios(this, { + return await axios($, { ...config, returnFullResponse: true, }); @@ -311,11 +287,11 @@ export default { } // if rate limit is exceeded, Retry-After will contain the # of seconds // to wait before retrying - const delay = (response && response.status == 429) - ? (response.headers["Retry-After"] * 1000) + const delay = (err && err.status == 429) + ? (err.headers["Retry-After"] * 1000) : 500; await pause(delay); - return this.retry(config, retries - 1); + return this.retry($, config, retries - 1); } }, async getItems(types, q, limit, offset) { @@ -340,9 +316,13 @@ export default { offset, }; - const res = await this._makeRequest("GET", "/search", params); + const res = await this._makeRequest({ + method: "GET", + url: "/search", + params, + }); return types.reduce((accumulator, type) => ( - accumulator.concat(get(res, `data.${ITEM_TYPES_RESULT_NAME[type]}.items`, [])) + accumulator.concat(res.data?.[ITEM_TYPES_RESULT_NAME[type]]?.items ?? []) ), []); }, getItemOptionLabel(item) { @@ -356,37 +336,77 @@ export default { } }, async getPlaylist({ - playlistId, params, + $, playlistId, ...args }) { - const res = await this._makeRequest("GET", `/playlists/${playlistId}`, params); - return get(res, "data", {}); + const res = await this._makeRequest({ + $, + url: `/playlists/${playlistId}`, + ...args, + }); + return res.data ?? {}; }, - async getPlaylists(params) { - const res = await this._makeRequest("GET", "/me/playlists", params); - return get(res, "data.items", null); + async getPlaylists({ + $, ...args + }) { + const res = await this._makeRequest({ + $, + url: "/me/playlists", + ...args, + }); + return res.data?.items ?? null; }, - async getCategories(params) { - const res = await this._makeRequest("GET", "/browse/categories", params); - return get(res, "data.categories.items", []); + async getCategories({ + $, ...args + }) { + const res = await this._makeRequest({ + $, + url: "/browse/categories", + ...args, + }); + return res.data?.categories?.items ?? []; }, - async getUserTracks(params) { - const res = await this._makeRequest("GET", "/me/tracks", params); - return get(res, "data.items", []); + async getUserTracks({ + $, ...args + }) { + const res = await this._makeRequest({ + $, + url: "/me/tracks", + ...args, + }); + return res.data?.items ?? []; }, - async getPlaylistItems(params) { - const { playlistId } = params; - const res = await this._makeRequest("GET", `/playlists/${playlistId}/tracks`, params); - return get(res, "data.items", []); + async getPlaylistItems({ + $, playlistId, ...args + }) { + const res = await this._makeRequest({ + $, + url: `/playlists/${playlistId}/tracks`, + ...args, + }); + return res.data?.items ?? []; }, - async getGenres() { - const { data } = await this._makeRequest("GET", "/recommendations/available-genre-seeds"); + async getGenres({ + $, ...args + } = {}) { + const { data } = await this._makeRequest({ + $, + url: "/recommendations/available-genre-seeds", + ...args, + }); return data.genres; }, - async getRecommendations(params) { - const { data } = await this._makeRequest("GET", "/recommendations", params); + async getRecommendations({ + $, ...args + }) { + const { data } = await this._makeRequest({ + $, + url: "/recommendations", + ...args, + }); return data; }, async fetchChunksOfAlbumsIds({ + $, artistId, market, }) { @@ -395,16 +415,16 @@ export default { let page = 0; let next = undefined; do { - const { data } = await this._makeRequest( - "GET", - `/artists/${get(artistId, "value", artistId)}/albums`, - { + const { data } = await this._makeRequest({ + $, + url: `/artists/${artistId.value ?? artistId}/albums`, + params: { market, limit, offset: limit * page, include_groups: "album,single", }, - ); + }); albums.push([ ...data.items.map((album) => album.id), ]); @@ -414,19 +434,20 @@ export default { return albums; }, async getAllTracksByChunksOfAlbumIds({ + $, chunksOfAlbumIds, market, }) { const tracks = []; for (const albumIds of chunksOfAlbumIds) { - const { data } = await this._makeRequest( - "GET", - "/albums", - { + const { data } = await this._makeRequest({ + $, + url: "/albums", + params: { market, ids: albumIds.join(","), }, - ); + }); tracks.push([ ...data.albums.map((album) => album.tracks.items).flat(), ]); From 2654eb2eca9fe093d21097e183d72f5d5579dbd9 Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 17:03:46 -0300 Subject: [PATCH 02/12] Adjusting default page size to 50 --- .../get-album-tracks/get-album-tracks.mjs | 13 +++--- components/spotify/actions/search/search.mjs | 6 ++- components/spotify/common/constants.mjs | 2 + components/spotify/spotify.app.mjs | 43 ++++++++----------- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs index 7a1e2ea228080..8d3e5023075bf 100644 --- a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs +++ b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs @@ -1,6 +1,8 @@ import spotify from "../../spotify.app.mjs"; -import { ITEM_TYPES } from "../../common/constants.mjs"; -const DEFAULT_LIMIT = 20; +import { + ITEM_TYPES, + PAGE_SIZE, +} from "../../common/constants.mjs"; export default { name: "Get Album Tracks", @@ -24,12 +26,11 @@ export default { query, page, }) { - const limit = DEFAULT_LIMIT; const albums = await this.spotify.getItems( ITEM_TYPES.ALBUM, query, - limit, - limit * page, + PAGE_SIZE, + PAGE_SIZE * page, ); return { options: albums.map((album) => ({ @@ -42,7 +43,7 @@ export default { }, async run({ $ }) { const params = { - limit: DEFAULT_LIMIT, + limit: PAGE_SIZE, offset: 0, }; const tracks = []; diff --git a/components/spotify/actions/search/search.mjs b/components/spotify/actions/search/search.mjs index a9781352b65ab..4d7b365e06235 100644 --- a/components/spotify/actions/search/search.mjs +++ b/components/spotify/actions/search/search.mjs @@ -1,7 +1,9 @@ import { ConfigurationError } from "@pipedream/platform"; import spotify from "../../spotify.app.mjs"; import { - ITEM_TYPES_LIST, ITEM_TYPES, + ITEM_TYPES_LIST, + ITEM_TYPES, + PAGE_SIZE, } from "../../common/constants.mjs"; export default { @@ -44,7 +46,7 @@ export default { "limit", ], description: "The maximum number of results to return per type.", - default: 20, + default: PAGE_SIZE, max: 50, }, offset: { diff --git a/components/spotify/common/constants.mjs b/components/spotify/common/constants.mjs index ccd3994fd1cad..405317c04d4dd 100644 --- a/components/spotify/common/constants.mjs +++ b/components/spotify/common/constants.mjs @@ -42,3 +42,5 @@ export const ITEM_TYPES_RESULT_NAME = { [ITEM_TYPES.SHOW]: "shows", [ITEM_TYPES.EPISODE]: "episodes", }; + +export const PAGE_SIZE = 50; diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index b15c3f2fb84c4..76898edae677c 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -6,6 +6,7 @@ import { promisify } from "util"; import { ITEM_TYPES, ITEM_TYPES_RESULT_NAME, + PAGE_SIZE, } from "./common/constants.mjs"; import Countries from "./country-codes.mjs"; @@ -29,10 +30,9 @@ export default { async options({ page, playlistId, }) { - const limit = 20; const items = await this.getPlaylistItems({ - limit, - offset: limit * page, + limit: PAGE_SIZE, + offset: PAGE_SIZE * page, playlistId: playlistId.value ?? playlistId, }); @@ -50,10 +50,9 @@ export default { description: "Search saved user tracks in \"Liked Songs\" or enter a custom expression to reference specific [Spotify ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) for the track. For example: `4iV5W9uYEdYUVa79Axb7Rh`. Maximum: 50 IDs.", withLabel: true, async options({ page }) { - const limit = 20; const items = await this.getUserTracks({ - limit, - offset: limit * page, + limit: PAGE_SIZE, + offset: PAGE_SIZE * page, }); return { @@ -74,12 +73,11 @@ export default { query, page, }) { - const limit = 20; const artists = await this.getItems( ITEM_TYPES.ARTIST, query, - limit, - limit * page, + PAGE_SIZE, + PAGE_SIZE * page, ); return { options: artists.map((artist) => ({ @@ -94,10 +92,9 @@ export default { label: "Playlist ID", description: "Select an existing playlist or pass a custom expression to reference a specific [`playlist_id`](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) (for example, `3cEYpjA9oz9GiPac4AsH4n`).", async options({ page }) { - const limit = 20; const playlists = await this.getPlaylists({ - limit, - offset: limit * page, + limit: PAGE_SIZE, + offset: PAGE_SIZE * page, }); return { options: playlists.map((playlist) => ({ @@ -113,10 +110,9 @@ export default { description: "Type to search for a category or enter a custom expression to reference a specific [category ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) (for example, `party`).", withLabel: true, async options({ page }) { - const limit = 20; const categories = await this.getCategories({ - limit, - offset: limit * page, + limit: PAGE_SIZE, + offset: PAGE_SIZE * page, }); return { options: categories.map((category) => ({ @@ -136,12 +132,11 @@ export default { query, page, }) { - const limit = 20; const tracks = await this.getItems( ITEM_TYPES.TRACK, query, - limit, - limit * page, + PAGE_SIZE, + PAGE_SIZE * page, ); return { options: tracks.map((track) => ({ @@ -161,15 +156,14 @@ export default { query, page, }) { - const limit = 20; const items = await this.getItems( [ ITEM_TYPES.TRACK, ITEM_TYPES.EPISODE, ], query, - limit, - limit * page, + PAGE_SIZE, + PAGE_SIZE * page, ); return { options: items.map((item) => ({ @@ -228,7 +222,7 @@ export default { }, async _paginate(resourceFn, params = {}) { let data = []; - params.limit = 20; + params.limit = PAGE_SIZE; params.offset = 0; do { @@ -415,7 +409,6 @@ export default { market, }) { const albums = []; - const limit = 20; let page = 0; let next = undefined; do { @@ -424,8 +417,8 @@ export default { url: `/artists/${artistId.value ?? artistId}/albums`, params: { market, - limit, - offset: limit * page, + limit: PAGE_SIZE, + offset: PAGE_SIZE * page, include_groups: "album,single", }, }); From 1877a7e9563e3dac30dd83e21a5484f50e162a95 Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 20:23:06 -0300 Subject: [PATCH 03/12] Fixing search method --- components/spotify/actions/search/search.mjs | 1 + components/spotify/spotify.app.mjs | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/components/spotify/actions/search/search.mjs b/components/spotify/actions/search/search.mjs index 4d7b365e06235..5bdabcc7567d7 100644 --- a/components/spotify/actions/search/search.mjs +++ b/components/spotify/actions/search/search.mjs @@ -75,6 +75,7 @@ export default { } const res = await this.spotify.search({ + $, q: this.query, type: this.type.join(","), market: this.market, diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index 76898edae677c..cfb5ae71879c5 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -399,8 +399,15 @@ export default { }); return data; }, - async search(params) { - const { data } = await this._makeRequest("GET", "/search", params); + async search({ + $, ...params + }) { + const { data } = await this._makeRequest({ + $, + method: "GET", + url: "/search", + params, + }); return data; }, async fetchChunksOfAlbumsIds({ From fefa808eb7c9e8897a9514e5affa2b202bfb08b2 Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 20:32:57 -0300 Subject: [PATCH 04/12] Removing remaining lodash calls --- components/spotify/actions/save-track/save-track.mjs | 3 +-- components/spotify/package.json | 3 +-- components/spotify/spotify.app.mjs | 9 +++------ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/components/spotify/actions/save-track/save-track.mjs b/components/spotify/actions/save-track/save-track.mjs index f2d6f69aa4143..02d45d110fef2 100644 --- a/components/spotify/actions/save-track/save-track.mjs +++ b/components/spotify/actions/save-track/save-track.mjs @@ -1,4 +1,3 @@ -import isEmpty from "lodash/isEmpty.js"; import spotify from "../../spotify.app.mjs"; export default { @@ -38,7 +37,7 @@ export default { // eslint-disable-next-line multiline-ternary $.export("$summary", `Successfully saved ${ids.length} ${ids.length == 1 ? "track" : "tracks"} to "Liked Songs"`); - return isEmpty(res) + return !res || Object.keys(res).length === 0 ? ids : res; }, diff --git a/components/spotify/package.json b/components/spotify/package.json index 602156221b1dd..309b5720aebe5 100644 --- a/components/spotify/package.json +++ b/components/spotify/package.json @@ -14,7 +14,6 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^3.1.1", - "lodash": "^4.17.21" + "@pipedream/platform": "^3.1.1" } } diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index cfb5ae71879c5..4507ed06165a8 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -1,7 +1,4 @@ import { axios } from "@pipedream/platform"; -import isArray from "lodash/isArray.js"; -import isEmpty from "lodash/isEmpty.js"; -import isString from "lodash/isString.js"; import { promisify } from "util"; import { ITEM_TYPES, @@ -199,14 +196,14 @@ export default { }, methods: { sanitizedArray(value) { - if (isArray(value)) { + if (Array.isArray(value)) { return value.map((item) => item.value ?? item); } // If is string, try to convert it in an array - if (isString(value)) { + if (typeof value === "string") { // Return an empty array if string is empty - if (isEmpty(value)) { + if (value === "" || value.length === 0) { return []; } From 1891e362541e6824868dd8232ae421734fb81d4a Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 20:36:48 -0300 Subject: [PATCH 05/12] Version bumps --- .../add-items-to-playlist.mjs | 2 +- .../create-playlist/create-playlist.mjs | 2 +- .../get-album-tracks/get-album-tracks.mjs | 2 +- .../get-all-tracks-by-artist.mjs | 2 +- .../get-artist-top-tracks.mjs | 2 +- .../get-audio-features-for-a-track.mjs | 2 +- .../get-categorys-playlist.mjs | 2 +- .../get-currently-playing-track.mjs | 2 +- .../get-playlist-items/get-playlist-items.mjs | 2 +- .../actions/get-playlist/get-playlist.mjs | 2 +- .../get-recommendations.mjs | 2 +- .../spotify/actions/get-track/get-track.mjs | 2 +- .../remove-items-from-playlist.mjs | 2 +- .../remove-user-saved-tracks.mjs | 2 +- .../spotify/actions/save-track/save-track.mjs | 2 +- components/spotify/actions/search/search.mjs | 2 +- components/spotify/package.json | 2 +- .../sources/new-playlist/new-playlist.mjs | 2 +- .../new-saved-track/new-saved-track.mjs | 2 +- .../new-track-by-artist.mjs | 2 +- .../new-track-in-playlist.mjs | 2 +- components/spotify/spotify.app.mjs | 3 + pnpm-lock.yaml | 135 ++++++++++++------ 23 files changed, 114 insertions(+), 66 deletions(-) diff --git a/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs b/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs index 2bf655588136f..7a1721e6f8999 100644 --- a/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs +++ b/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs @@ -4,7 +4,7 @@ export default { name: "Add Items to a Playlist", description: "Add one or more items to a user’s playlist. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/add-tracks-to-playlist).", key: "spotify-add-items-to-playlist", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/create-playlist/create-playlist.mjs b/components/spotify/actions/create-playlist/create-playlist.mjs index ec114a81ee55d..d936b05ad2307 100644 --- a/components/spotify/actions/create-playlist/create-playlist.mjs +++ b/components/spotify/actions/create-playlist/create-playlist.mjs @@ -4,7 +4,7 @@ export default { name: "Create a Playlist", description: "Create a playlist for a Spotify user. The playlist will be empty until you add tracks. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/create-playlist).", key: "spotify-create-playlist", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs index 8d3e5023075bf..97f01f5dbcc03 100644 --- a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs +++ b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs @@ -8,7 +8,7 @@ export default { name: "Get Album Tracks", description: "Get all tracks in an album. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/get-an-albums-tracks)", key: "spotify-get-album-tracks", - version: "0.0.5", + version: "0.0.6", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs b/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs index d84afda2318fd..8cf171d7ec192 100644 --- a/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs +++ b/components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs @@ -4,7 +4,7 @@ export default { name: "Get All Tracks by Artist", description: "Get Spotify tracks information related with an artist's. [see docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-multiple-albums).", key: "spotify-get-all-tracks-by-artist", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs b/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs index dbc16002cad9d..c4d77054cfd0e 100644 --- a/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs +++ b/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs @@ -4,7 +4,7 @@ export default { name: "Get an Artist's Top Tracks", description: "Get Spotify catalog information about an artist's top tracks by country. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-an-artists-top-tracks).", key: "spotify-get-artist-top-tracks", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs b/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs index 2acad308741d7..3e13b628485ca 100644 --- a/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs +++ b/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs @@ -4,7 +4,7 @@ export default { name: "Get Audio Features for a Track", description: "Get audio feature information for a single track identified by its unique Spotify ID. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-audio-features).", key: "spotify-get-audio-features-for-a-track", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs b/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs index ca7316ed6a57b..c65d98e331ee7 100644 --- a/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs +++ b/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs @@ -4,7 +4,7 @@ export default { name: "Get a Category's Playlists", description: "Get a list of Spotify playlists tagged with a particular category. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-a-categories-playlists).", key: "spotify-get-categorys-playlist", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs b/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs index 77a71abaab94b..5a93b723efa38 100644 --- a/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs +++ b/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs @@ -6,7 +6,7 @@ export default { description: "Get the object currently being played on the user's Spotify account. [See the documentation](https://developer.spotify.com/documentation/web-api/reference/get-the-users-currently-playing-track)", key: "spotify-get-currently-playing-track", - version: "0.0.5", + version: "0.0.6", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-playlist-items/get-playlist-items.mjs b/components/spotify/actions/get-playlist-items/get-playlist-items.mjs index daf2bc89c0c7e..f796c17e34904 100644 --- a/components/spotify/actions/get-playlist-items/get-playlist-items.mjs +++ b/components/spotify/actions/get-playlist-items/get-playlist-items.mjs @@ -4,7 +4,7 @@ export default { name: "Get a Playlist's Items", description: "Get full details of the items of a playlist owned by a Spotify user. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-playlists-tracks).", key: "spotify-get-playlist-items", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-playlist/get-playlist.mjs b/components/spotify/actions/get-playlist/get-playlist.mjs index 0339fe37f48c5..2fc1683207a4e 100644 --- a/components/spotify/actions/get-playlist/get-playlist.mjs +++ b/components/spotify/actions/get-playlist/get-playlist.mjs @@ -4,7 +4,7 @@ export default { name: "Get a Playlist", description: "Get a playlist owned by a Spotify user. [See the documentation](https://developer.spotify.com/documentation/web-api/reference/get-playlist).", key: "spotify-get-playlist", - version: "0.0.5", + version: "0.0.6", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-recommendations/get-recommendations.mjs b/components/spotify/actions/get-recommendations/get-recommendations.mjs index ee9374da72201..b25128e46f8b9 100644 --- a/components/spotify/actions/get-recommendations/get-recommendations.mjs +++ b/components/spotify/actions/get-recommendations/get-recommendations.mjs @@ -5,7 +5,7 @@ export default { name: "Get Recommendations", description: "Create a list of recommendations based on the available information for a given seed entity and matched against similar artists and tracks. If there is sufficient information about the provided seeds, a list of tracks will be returned together with pool size details. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-recommendations).", key: "spotify-get-recommendations", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/get-track/get-track.mjs b/components/spotify/actions/get-track/get-track.mjs index a56f434ce0ecf..e2a9f6cadc674 100644 --- a/components/spotify/actions/get-track/get-track.mjs +++ b/components/spotify/actions/get-track/get-track.mjs @@ -4,7 +4,7 @@ export default { name: "Get a Track", description: "Get a track by its name or ID. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/search)", key: "spotify-get-track", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs b/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs index 8b75ef9e829e1..284fed33267b9 100644 --- a/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs +++ b/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs @@ -4,7 +4,7 @@ export default { name: "Remove Items from a Playlist", description: "Remove one or more items from a user's playlist. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/remove-tracks-playlist)", key: "spotify-remove-items-from-playlist", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs b/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs index f23ebe866022f..a45cb3e1ae9ea 100644 --- a/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs +++ b/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs @@ -4,7 +4,7 @@ export default { name: "Remove User's Saved Tracks", description: "Remove one or more tracks from the current user's 'Your Music' library. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/remove-tracks-user)", key: "spotify-remove-user-saved-tracks", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/spotify/actions/save-track/save-track.mjs b/components/spotify/actions/save-track/save-track.mjs index 02d45d110fef2..0c5c7872ea139 100644 --- a/components/spotify/actions/save-track/save-track.mjs +++ b/components/spotify/actions/save-track/save-track.mjs @@ -4,7 +4,7 @@ export default { name: "Save Tracks for User", description: "Save one or more tracks to the current user's \"Your Music\" library. [See the docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/save-tracks-user).", key: "spotify-save-track", - version: "0.1.4", + version: "0.1.5", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/spotify/actions/search/search.mjs b/components/spotify/actions/search/search.mjs index 5bdabcc7567d7..dc6e9a69bca9a 100644 --- a/components/spotify/actions/search/search.mjs +++ b/components/spotify/actions/search/search.mjs @@ -10,7 +10,7 @@ export default { key: "spotify-search", name: "Search", description: "Search for items on Spotify (tracks, albums, artists, playlists, shows, or episodes). [See the docs here](https://developer.spotify.com/documentation/web-api/reference/search)", - version: "0.0.2", + version: "0.0.3", type: "action", annotations: { destructiveHint: false, diff --git a/components/spotify/package.json b/components/spotify/package.json index 309b5720aebe5..a324804d29986 100644 --- a/components/spotify/package.json +++ b/components/spotify/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/spotify", - "version": "0.7.5", + "version": "0.7.6", "description": "Pipedream Spotify Components", "main": "spotify.app.mjs", "keywords": [ diff --git a/components/spotify/sources/new-playlist/new-playlist.mjs b/components/spotify/sources/new-playlist/new-playlist.mjs index 93aea65f57390..e12ecda97e9af 100644 --- a/components/spotify/sources/new-playlist/new-playlist.mjs +++ b/components/spotify/sources/new-playlist/new-playlist.mjs @@ -6,7 +6,7 @@ export default { key: "spotify-new-playlist", name: "New Playlist", description: "Emit new event when a new playlist is created or followed by the current Spotify user.", - version: "0.1.3", + version: "0.1.4", props: { ...common.props, }, diff --git a/components/spotify/sources/new-saved-track/new-saved-track.mjs b/components/spotify/sources/new-saved-track/new-saved-track.mjs index 4831c5ff14604..25fb26257bc31 100644 --- a/components/spotify/sources/new-saved-track/new-saved-track.mjs +++ b/components/spotify/sources/new-saved-track/new-saved-track.mjs @@ -6,7 +6,7 @@ export default { key: "spotify-new-saved-track", name: "New Saved Track", description: "Emit new event for each new track saved to the current Spotify user's Music Library.", - version: "0.1.3", + version: "0.1.4", props: { ...common.props, db: "$.service.db", diff --git a/components/spotify/sources/new-track-by-artist/new-track-by-artist.mjs b/components/spotify/sources/new-track-by-artist/new-track-by-artist.mjs index 7029529f3b701..eebc1ac217f20 100644 --- a/components/spotify/sources/new-track-by-artist/new-track-by-artist.mjs +++ b/components/spotify/sources/new-track-by-artist/new-track-by-artist.mjs @@ -7,7 +7,7 @@ export default { key: "spotify-new-track-by-artist", name: "New Track by Artist", description: "Emit new event for each new Spotify track related with an artist. [see docs here](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-multiple-albums)", - version: "0.1.3", + version: "0.1.4", props: { ...common.props, db: "$.service.db", diff --git a/components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs b/components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs index 7377eb086e230..b52f048ad7287 100644 --- a/components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs +++ b/components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs @@ -7,7 +7,7 @@ export default { key: "spotify-new-track-in-playlist", name: "New Track in Playlist", description: "Emit new event for each new Spotify track added to a playlist", - version: "0.1.3", + version: "0.1.4", props: { ...common.props, db: "$.service.db", diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index 4507ed06165a8..22a408de41bfe 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -250,6 +250,9 @@ export default { const artists = track.artists.map((artist) => artist.name).join(", "); return `${track.name} [${artists}]`; }, + _getBaseUrl() { + return "https://api.spotify.com/v1"; + }, async _makeRequest({ $ = this, headers, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92607c0c47e53..8653b3d7ad15d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5107,8 +5107,7 @@ importers: specifier: ^3.1.1 version: 3.1.1 - components/fashn: - specifiers: {} + components/fashn: {} components/fastfield_mobile_forms: {} @@ -7710,8 +7709,7 @@ importers: specifier: ^3.1.1 version: 3.1.1 - components/jobsoid_careers_portal: - specifiers: {} + components/jobsoid_careers_portal: {} components/joggai: dependencies: @@ -14295,9 +14293,6 @@ importers: '@pipedream/platform': specifier: ^3.1.1 version: 3.1.1 - lodash: - specifier: ^4.17.21 - version: 4.17.21 components/spotlightr: dependencies: @@ -16795,8 +16790,7 @@ importers: specifier: ^3.1.1 version: 3.1.1 - components/xero_payroll: - specifiers: {} + components/xero_payroll: {} components/xola: dependencies: @@ -17585,7 +17579,7 @@ importers: version: 3.1.11 ts-jest: specifier: ^29.2.5 - version: 29.4.5(@babel/core@8.0.0-beta.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-beta.3))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)))(typescript@5.6.3) + version: 29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)))(typescript@5.6.3) tsup: specifier: ^8.3.6 version: 8.5.1(@microsoft/api-extractor@7.55.0(@types/node@20.19.25))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.6.3)(yaml@2.8.1) @@ -17628,7 +17622,7 @@ importers: version: 3.1.0 jest: specifier: ^29.1.2 - version: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + version: 29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) type-fest: specifier: ^4.15.0 version: 4.41.0 @@ -31769,17 +31763,17 @@ packages: superagent@3.8.1: resolution: {integrity: sha512-VMBFLYgFuRdfeNQSMLbxGSLfmXL/xc+OO+BZp41Za/NRDBet/BNbkRJrYzCUu0u4GU0i/ml2dtT8b9qgkw9z6Q==} engines: {node: '>= 4.0'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net superagent@4.1.0: resolution: {integrity: sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==} engines: {node: '>= 6.0'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net superagent@5.3.1: resolution: {integrity: sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==} engines: {node: '>= 7.0.0'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net supports-color@10.2.2: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} @@ -37320,7 +37314,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -37334,7 +37328,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -37355,7 +37349,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -37369,7 +37363,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -43772,13 +43766,13 @@ snapshots: safe-buffer: 5.2.1 sha.js: 2.4.12 - create-jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): + create-jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -43787,13 +43781,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + create-jest@29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -47684,16 +47678,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): + jest-cli@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + create-jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -47703,16 +47697,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + jest-cli@29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + create-jest: 29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -47722,7 +47716,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): + jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: '@babel/core': 7.28.5 '@jest/test-sequencer': 29.7.0 @@ -47748,12 +47742,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.25 - ts-node: 10.9.2(@types/node@20.19.25)(typescript@3.9.10) + ts-node: 10.9.2(@types/node@20.19.25)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)): dependencies: '@babel/core': 7.28.5 '@jest/test-sequencer': 29.7.0 @@ -47779,7 +47773,38 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.25 - ts-node: 10.9.2(@types/node@20.19.25)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@24.10.1)(typescript@3.9.10) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)): + dependencies: + '@babel/core': 7.28.5 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0(babel-plugin-macros@3.1.0) + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 24.10.1 + ts-node: 10.9.2(@types/node@24.10.1)(typescript@3.9.10) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -48015,24 +48040,24 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): + jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) + jest-cli: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node - jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + jest@29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-cli: 29.7.0(@types/node@24.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -53566,6 +53591,26 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)))(typescript@5.6.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.3 + type-fest: 4.41.0 + typescript: 5.6.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.28.5 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + jest-util: 29.7.0 + ts-jest@29.4.5(@babel/core@8.0.0-beta.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-beta.3))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)))(typescript@5.6.3): dependencies: bs-logger: 0.2.6 @@ -53586,7 +53631,7 @@ snapshots: babel-jest: 29.7.0(@babel/core@8.0.0-beta.3) jest-util: 29.7.0 - ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10): + ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -53600,26 +53645,26 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 3.9.10 + typescript: 5.6.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optional: true - ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3): + ts-node@10.9.2(@types/node@24.10.1)(typescript@3.9.10): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.25 + '@types/node': 24.10.1 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.6.3 + typescript: 3.9.10 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optional: true From 2f11e44bf21b221dadf4881589d295c851afdbdf Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 21:04:30 -0300 Subject: [PATCH 06/12] Adjusting response formats --- .../get-artist-top-tracks.mjs | 4 +- .../get-categorys-playlist.mjs | 4 +- .../get-playlist-items/get-playlist-items.mjs | 6 +- .../get-recommendations.mjs | 10 +-- .../spotify/actions/get-track/get-track.mjs | 6 +- .../remove-user-saved-tracks.mjs | 4 +- components/spotify/spotify.app.mjs | 67 +++++++------------ 7 files changed, 41 insertions(+), 60 deletions(-) diff --git a/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs b/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs index c4d77054cfd0e..5e6b87bc4cce8 100644 --- a/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs +++ b/components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs @@ -32,7 +32,7 @@ export default { market, } = this; - const res = await this.spotify._makeRequest({ + const { data } = await this.spotify._makeRequest({ $, url: `/artists/${artistId.value ?? artistId}/top-tracks`, params: { @@ -42,6 +42,6 @@ export default { $.export("$summary", `Successfully fetched top tracks for "${artistId.label ?? artistId}"`); - return res.tracks ?? []; + return data?.tracks ?? []; }, }; diff --git a/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs b/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs index c65d98e331ee7..3ef8aebd498d7 100644 --- a/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs +++ b/components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs @@ -49,7 +49,7 @@ export default { offset, } = this; - const res = await this.spotify._makeRequest({ + const { data } = await this.spotify._makeRequest({ $, url: `/browse/categories/${categoryId.value ?? categoryId}/playlists`, params: { @@ -61,6 +61,6 @@ export default { $.export("$summary", `Successfully fetched playlists for the "${categoryId.label ?? categoryId}" category`); - return res.playlists?.items ?? []; + return data?.playlists?.items ?? []; }, }; diff --git a/components/spotify/actions/get-playlist-items/get-playlist-items.mjs b/components/spotify/actions/get-playlist-items/get-playlist-items.mjs index f796c17e34904..7d602ccca46d2 100644 --- a/components/spotify/actions/get-playlist-items/get-playlist-items.mjs +++ b/components/spotify/actions/get-playlist-items/get-playlist-items.mjs @@ -51,19 +51,17 @@ export default { async run({ $ }) { const { playlistId, - market, fields, limit, offset, additionalTypes, } = this; - const res = await this.spotify._makeRequest({ + const { data } = await this.spotify._makeRequest({ $, url: `/playlists/${playlistId.value ?? playlistId}/tracks`, params: { fields, - market, limit, offset, additional_types: additionalTypes && additionalTypes.join(",").toLowerCase(), @@ -72,6 +70,6 @@ export default { $.export("$summary", `Successfully fetched details for "${playlistId.label ?? playlistId}"`); - return res.items ?? []; + return data?.items ?? []; }, }; diff --git a/components/spotify/actions/get-recommendations/get-recommendations.mjs b/components/spotify/actions/get-recommendations/get-recommendations.mjs index b25128e46f8b9..00e095908c8de 100644 --- a/components/spotify/actions/get-recommendations/get-recommendations.mjs +++ b/components/spotify/actions/get-recommendations/get-recommendations.mjs @@ -60,7 +60,7 @@ export default { const numSeeds = seedArtists.length + seedGenres.length + seedTracks.length; if (numSeeds > 5 || numSeeds < 1) { - throw new ConfigurationError("Must provide between 1 and 5 seeds in in any combination of `seedArtists`, `seedTracks` and `seedGenres`."); + throw new ConfigurationError("Must provide between 1 and 5 seeds in any combination of `seedArtists`, `seedTracks` and `seedGenres`."); } const params = { @@ -70,16 +70,16 @@ export default { limit, }; - const response = await this.spotify.getRecommendations({ + const { data } = await this.spotify.getRecommendations({ $, ...params, }); - if (response.tracks.length === 0) { + if (data?.tracks?.length === 0) { $.export("$summary", "No recommendations found"); return; } - $.export("$summary", `Successfully retrieved ${response.tracks.length} recommendation(s).`); - return response; + $.export("$summary", `Successfully retrieved ${data?.tracks?.length} recommendation(s).`); + return data; }, }; diff --git a/components/spotify/actions/get-track/get-track.mjs b/components/spotify/actions/get-track/get-track.mjs index e2a9f6cadc674..fc8c5484a4f14 100644 --- a/components/spotify/actions/get-track/get-track.mjs +++ b/components/spotify/actions/get-track/get-track.mjs @@ -33,7 +33,7 @@ export default { market, } = this; - const res = await this.spotify._makeRequest({ + const { data } = await this.spotify._makeRequest({ $, url: `/tracks/${trackId.value ?? trackId}`, params: { @@ -41,8 +41,8 @@ export default { }, }); - $.export("$summary", `Successfully fetched info for the track, "${res.name}"`); + $.export("$summary", `Successfully fetched info for the track, "${data?.name}"`); - return res; + return data ?? {}; }, }; diff --git a/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs b/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs index a45cb3e1ae9ea..69cc86c92e917 100644 --- a/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs +++ b/components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs @@ -25,7 +25,7 @@ export default { const ids = this.spotify.sanitizedArray(savedUserTracksId); - const resp = await this.spotify._makeRequest({ + const { data } = await this.spotify._makeRequest({ $, method: "DELETE", url: "/me/tracks", @@ -37,6 +37,6 @@ export default { // eslint-disable-next-line multiline-ternary $.export("$summary", `Successfully removed ${ids.length} ${ids.length == 1 ? "item" : "items"} from "Liked Songs"`); - return resp; + return data; }, }; diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index 22a408de41bfe..814811bef27da 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -269,23 +269,24 @@ export default { return await this.retry($, config); }, // Retry axios request if not successful - async retry($, config, retries = 3) { + async retry($, config, retries = 0) { try { return await axios($, { ...config, returnFullResponse: true, }); } catch (err) { - if (retries <= 1) { - throw new Error(err); + if (err?.status !== 429 || retries <= 3) { + $?.export?.("response", err); + throw new Error("Error response"); } // if rate limit is exceeded, Retry-After will contain the # of seconds // to wait before retrying - const delay = (err && err.status == 429) - ? (err.headers["Retry-After"] * 1000) - : 500; + const delay = err?.headers?.["Retry-After"] + ? err.headers["Retry-After"] * 1000 + : (retries * 3000); await pause(delay); - return this.retry($, config, retries - 1); + return this.retry($, config, retries + 1); } }, async getItems(types, q, limit, offset) { @@ -329,71 +330,53 @@ export default { return item.name; } }, - async getPlaylist({ - $, playlistId, ...args - }) { - const res = await this._makeRequest({ - $, + async getPlaylist(playlistId, args) { + const { data } = await this._makeRequest({ url: `/playlists/${playlistId}`, ...args, }); - return res.data ?? {}; + return data; }, - async getPlaylists({ - $, ...args - }) { - const res = await this._makeRequest({ - $, + async getPlaylists(args) { + const { data } = await this._makeRequest({ url: "/me/playlists", ...args, }); - return res.data?.items ?? null; + return data?.items ?? []; }, - async getCategories({ - $, ...args - }) { - const res = await this._makeRequest({ - $, + async getCategories(args) { + const { data } = await this._makeRequest({ url: "/browse/categories", ...args, }); - return res.data?.categories?.items ?? []; + return data?.categories?.items ?? []; }, - async getUserTracks({ - $, ...args - }) { - const res = await this._makeRequest({ - $, + async getUserTracks(args) { + const { data } = await this._makeRequest({ url: "/me/tracks", ...args, }); - return res.data?.items ?? []; + return data?.items ?? []; }, async getPlaylistItems({ $, playlistId, ...args }) { - const res = await this._makeRequest({ + const { data } = await this._makeRequest({ $, url: `/playlists/${playlistId}/tracks`, ...args, }); - return res.data?.items ?? []; + return data?.items ?? []; }, - async getGenres({ - $, ...args - } = {}) { + async getGenres(args) { const { data } = await this._makeRequest({ - $, url: "/recommendations/available-genre-seeds", ...args, }); - return data.genres; + return data?.genres; }, - async getRecommendations({ - $, ...args - }) { + async getRecommendations(args) { const { data } = await this._makeRequest({ - $, url: "/recommendations", ...args, }); From 672b3fd843ac73c77ca49e7e3eb31662b9260aff Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 21:18:03 -0300 Subject: [PATCH 07/12] Fixing more response formats --- .../add-items-to-playlist/add-items-to-playlist.mjs | 2 +- .../spotify/actions/create-playlist/create-playlist.mjs | 2 +- .../spotify/actions/get-album-tracks/get-album-tracks.mjs | 6 +++--- .../get-audio-features-for-a-track.mjs | 4 ++-- .../get-currently-playing-track.mjs | 2 +- .../remove-items-from-playlist.mjs | 2 +- components/spotify/actions/save-track/save-track.mjs | 2 +- components/spotify/spotify.app.mjs | 7 +++++-- 8 files changed, 15 insertions(+), 12 deletions(-) diff --git a/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs b/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs index 7a1721e6f8999..cefab130af30d 100644 --- a/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs +++ b/components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs @@ -44,7 +44,7 @@ export default { uris: this.spotify.sanitizedArray(uris), }; - const resp = await this.spotify._makeRequest({ + const { data: resp } = await this.spotify._makeRequest({ $, method: "POST", url: `/playlists/${playlistId.value ?? playlistId}/tracks`, diff --git a/components/spotify/actions/create-playlist/create-playlist.mjs b/components/spotify/actions/create-playlist/create-playlist.mjs index d936b05ad2307..af739031b8f32 100644 --- a/components/spotify/actions/create-playlist/create-playlist.mjs +++ b/components/spotify/actions/create-playlist/create-playlist.mjs @@ -52,7 +52,7 @@ export default { collaborative: isCollaborative, }; - const resp = await this.spotify._makeRequest({ + const { data: resp } = await this.spotify._makeRequest({ $, method: "POST", url: `/users/${this.spotify.$auth.oauth_uid}/playlists`, diff --git a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs index 97f01f5dbcc03..9dcb3d2e31be6 100644 --- a/components/spotify/actions/get-album-tracks/get-album-tracks.mjs +++ b/components/spotify/actions/get-album-tracks/get-album-tracks.mjs @@ -50,13 +50,13 @@ export default { let total = 0; do { - const { items } = await this.spotify._makeRequest({ + const { data } = await this.spotify._makeRequest({ $, url: `/albums/${this.albumId}/tracks`, params, }); - tracks.push(...items); - total = items.length; + tracks.push(...data.items); + total = data.items.length; params.offset += params.limit; } while (total === params.limit); diff --git a/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs b/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs index 3e13b628485ca..38f5955689005 100644 --- a/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs +++ b/components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs @@ -22,13 +22,13 @@ export default { }, async run({ $ }) { const { trackId } = this; - const resp = await this.spotify._makeRequest({ + const { data } = await this.spotify._makeRequest({ $, url: `/audio-features/${trackId.value ?? trackId}`, }); $.export("$summary", `Successfully fetched audio info for the track, "${trackId.label ?? trackId}"`); - return resp; + return data; }, }; diff --git a/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs b/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs index 5a93b723efa38..cb4fb8136156f 100644 --- a/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs +++ b/components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs @@ -27,7 +27,7 @@ export default { const { market } = this; try { - const res = await this.spotify._makeRequest({ + const { data: res } = await this.spotify._makeRequest({ $, url: "/me/player/currently-playing", params: { diff --git a/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs b/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs index 284fed33267b9..bc2406c665bdb 100644 --- a/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs +++ b/components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs @@ -51,7 +51,7 @@ export default { snapshot_id: snapshotId, }; - const resp = await this.spotify._makeRequest({ + const { data: resp } = await this.spotify._makeRequest({ $, method: "DELETE", url: `/playlists/${playlistId.value ?? playlistId}/tracks`, diff --git a/components/spotify/actions/save-track/save-track.mjs b/components/spotify/actions/save-track/save-track.mjs index 0c5c7872ea139..e5d1bc52d6d1b 100644 --- a/components/spotify/actions/save-track/save-track.mjs +++ b/components/spotify/actions/save-track/save-track.mjs @@ -25,7 +25,7 @@ export default { }, async run({ $ }) { const ids = this.spotify.sanitizedArray(this.trackIds); - const res = await this.spotify._makeRequest({ + const { data: res } = await this.spotify._makeRequest({ $, method: "PUT", url: "/me/tracks", diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index 814811bef27da..606ea16db2228 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -278,8 +278,9 @@ export default { } catch (err) { if (err?.status !== 429 || retries <= 3) { $?.export?.("response", err); - throw new Error("Error response"); + throw new Error("Error response exported in the \"response\" object"); } + // if rate limit is exceeded, Retry-After will contain the # of seconds // to wait before retrying const delay = err?.headers?.["Retry-After"] @@ -330,7 +331,9 @@ export default { return item.name; } }, - async getPlaylist(playlistId, args) { + async getPlaylist({ + playlistId, ...args + }) { const { data } = await this._makeRequest({ url: `/playlists/${playlistId}`, ...args, From 14df7e7c004d1efc60106353995853696e18c1bb Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 21:19:22 -0300 Subject: [PATCH 08/12] Fix --- components/spotify/spotify.app.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index 606ea16db2228..fd66263e7cfc7 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -276,7 +276,7 @@ export default { returnFullResponse: true, }); } catch (err) { - if (err?.status !== 429 || retries <= 3) { + if (err?.status !== 429 || retries >= 3) { $?.export?.("response", err); throw new Error("Error response exported in the \"response\" object"); } From fd2b72742a3289b233fa295c4076b667f2334991 Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 21:20:52 -0300 Subject: [PATCH 09/12] fixing silly validation --- components/spotify/spotify.app.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index fd66263e7cfc7..f5e7b4069766b 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -203,7 +203,7 @@ export default { // If is string, try to convert it in an array if (typeof value === "string") { // Return an empty array if string is empty - if (value === "" || value.length === 0) { + if (value === "") { return []; } From 40bc2a98436f020cda178d059a358535889fcb10 Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Wed, 10 Dec 2025 22:01:19 -0300 Subject: [PATCH 10/12] Adjusting retry delay --- components/spotify/spotify.app.mjs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index f5e7b4069766b..580bd21f8f03b 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -281,11 +281,7 @@ export default { throw new Error("Error response exported in the \"response\" object"); } - // if rate limit is exceeded, Retry-After will contain the # of seconds - // to wait before retrying - const delay = err?.headers?.["Retry-After"] - ? err.headers["Retry-After"] * 1000 - : (retries * 3000); + const delay = retries * 5000; await pause(delay); return this.retry($, config, retries + 1); } From 8b9f105b8747516dbae2ffc97a133d82e4c632f3 Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Mon, 15 Dec 2025 22:06:07 -0300 Subject: [PATCH 11/12] Adjusting request for max 20 albums --- components/spotify/spotify.app.mjs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/components/spotify/spotify.app.mjs b/components/spotify/spotify.app.mjs index 580bd21f8f03b..c6e4574fbdd9c 100644 --- a/components/spotify/spotify.app.mjs +++ b/components/spotify/spotify.app.mjs @@ -426,17 +426,22 @@ export default { }) { const tracks = []; for (const albumIds of chunksOfAlbumIds) { - const { data } = await this._makeRequest({ - $, - url: "/albums", - params: { - market, - ids: albumIds.join(","), - }, - }); - tracks.push([ - ...data.albums.map((album) => album.tracks.items).flat(), - ]); + // Spotify /albums endpoint accepts max 20 IDs per request + const maxAlbumsPerRequest = 20; + for (let i = 0; i < albumIds.length; i += maxAlbumsPerRequest) { + const albumIdsChunk = albumIds.slice(i, i + maxAlbumsPerRequest); + const { data } = await this._makeRequest({ + $, + url: "/albums", + params: { + market, + ids: albumIdsChunk.join(","), + }, + }); + tracks.push([ + ...data.albums.map((album) => album.tracks.items).flat(), + ]); + } } return tracks.flat(); }, From a2ffb2a4f5722d86bcdba0fb9925259c2d136a7f Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Tue, 16 Dec 2025 18:49:22 -0300 Subject: [PATCH 12/12] Fixing 'get recommendations' --- .../actions/get-recommendations/get-recommendations.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/spotify/actions/get-recommendations/get-recommendations.mjs b/components/spotify/actions/get-recommendations/get-recommendations.mjs index 00e095908c8de..f4a68c82c3f95 100644 --- a/components/spotify/actions/get-recommendations/get-recommendations.mjs +++ b/components/spotify/actions/get-recommendations/get-recommendations.mjs @@ -70,9 +70,9 @@ export default { limit, }; - const { data } = await this.spotify.getRecommendations({ + const data = await this.spotify.getRecommendations({ $, - ...params, + params, }); if (data?.tracks?.length === 0) {