Skip to content

Conversation

@GTFalcao
Copy link
Collaborator

@GTFalcao GTFalcao commented Dec 10, 2025

Closes #19314

Fixed rate limit error handling, increased default page size to the max of 50 to reduce amount of requests performed, and other adjustments

Summary by CodeRabbit

  • Refactor

    • Unified Spotify request handling and standardized response shapes across actions and sources.
  • Improvements

    • Default page size increased to 50 for broader results and consistent pagination.
    • Search, fetch and list flows standardized; several actions now return normalized data and clearer summaries.
    • Minor description/text normalization for consistency.
  • Chores

    • Version bumps across Spotify components and package; removed some legacy dependencies.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 10, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Dec 12, 2025 8:05pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Dec 12, 2025 8:05pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 10, 2025

Walkthrough

Centralizes Spotify HTTP requests into this.spotify._makeRequest, removes direct axios/lodash usages, introduces PAGE_SIZE = 50, passes $ context through public methods, standardizes request/response shapes, and adds retry/backoff handling for rate-limited responses.

Changes

Cohort / File(s) Summary
Action files migrated to _makeRequest
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs, components/spotify/actions/create-playlist/create-playlist.mjs, components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs, components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs, components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs, components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs, components/spotify/actions/get-playlist-items/get-playlist-items.mjs, components/spotify/actions/get-track/get-track.mjs, components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs, components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs, components/spotify/actions/save-track/save-track.mjs
Replaced axios/_getAxiosParams usage with this.spotify._makeRequest({ $, url, method, params, data }); removed axios and lodash/get imports; changed id resolution to value ?? id; updated response destructuring, summaries, and bumped versions.
Actions adopting PAGE_SIZE / $ propagation
components/spotify/actions/get-album-tracks/get-album-tracks.mjs, components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs, components/spotify/actions/search/search.mjs
Introduced PAGE_SIZE for limits/offsets, pass $ into spotify app methods, removed lodash/get usage, and set search default limit to PAGE_SIZE.
Call-site parameter change
components/spotify/actions/get-recommendations/get-recommendations.mjs
Call shape changed from getRecommendations(params, $) to getRecommendations({ $, ...params }); response handling updated to use wrapped data.
Core app refactor / request abstraction
components/spotify/spotify.app.mjs
Added _makeRequest({ $ = this, headers, ...args }), removed legacy helpers (_getAxiosParams, _getQuery, etc.), standardized request shape (url/params/data), propagated $ through public methods, replaced lodash with native checks, centralized pagination via PAGE_SIZE, and refactored retry to retry($, config, retries). Many public method signatures changed to accept $ and object args.
Constants
components/spotify/common/constants.mjs
Added exported PAGE_SIZE = 50.
Metadata-only bumps / minor edits
components/spotify/actions/get-playlist/get-playlist.mjs, components/spotify/sources/new-playlist/new-playlist.mjs, components/spotify/sources/new-saved-track/new-saved-track.mjs, components/spotify/sources/new-track-by-artist/new-track-by-artist.mjs, components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs, components/spotify/package.json
Version increments, minor punctuation/text normalizations, and removal of lodash from package.json dependencies.
Small formatting/EOF fixes
components/factorial_api_keys/factorial_api_keys.app.mjs, components/flowii/flowii.app.mjs, components/hailey_hr/hailey_hr.app.mjs, components/nuvemshop/nuvemshop.app.mjs, components/simpleem/simpleem.app.mjs, components/suitecrm/suitecrm.app.mjs
Added trailing newlines; no functional changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Action as Action (component)
  participant App as Spotify App (this.spotify)
  participant API as Spotify Web API

  Note over Action,App: Actions call centralized _makeRequest with $ and object-style args
  Action->>App: _makeRequest({ $, method, url, params, data })
  App->>API: HTTP request (baseURL + url, headers, params, data)
  alt Success (2xx)
    API-->>App: 200 + payload
    App-->>Action: normalized response (data / data?.items)
  else Retryable (429)
    API-->>App: 429 + Retry-After
    App->>App: retry($, config, retries-1) with exponential backoff or Retry-After
    App->>API: HTTP retry request
    API-->>App: payload or final error
    App-->>Action: final response or error object
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • components/spotify/spotify.app.mjs: verify _makeRequest semantics, header/baseURL composition, and 429 retry/backoff behavior (respecting Retry-After).
    • Pagination changes: ensure PAGE_SIZE propagation and offset calculations across callers.
    • Call-site updates: confirm all callers pass { $ } where required and match new method signatures.
    • Response-shape changes: verify consumers expecting previous shapes (e.g., full res) handle new data-focused responses.
    • Actions with changed return semantics (e.g., save-track) should be checked for downstream effects.

Suggested reviewers

  • jcortes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Changes are in-scope with one notable exception: multiple app component files (factorial_api_keys, flowii, hailey_hr, nuvemshop, simpleem, suitecrm) have only trailing newline additions unrelated to Spotify improvements or rate limiting. Remove out-of-scope formatting changes to non-Spotify components (trailing newline additions to factorial_api_keys, flowii, hailey_hr, nuvemshop, simpleem, and suitecrm app files).
Title check ❓ Inconclusive The title "Spotify improvements" is vague and generic, using non-descriptive phrasing that doesn't clearly convey the main changes. Use a more specific title that highlights the primary change, such as "Add Spotify 429 rate limit handling with exponential backoff" or "Implement rate limit handling and increase default page size for Spotify".
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The PR description provides context but does not follow the required template structure with a "WHY" section. The description is relatively brief and lacks detailed explanation.
Linked Issues check ✅ Passed The PR addresses the core requirements from #19314: implements 429 rate limit handling with exponential backoff retries, respects Retry-After header, and reduces request volume by increasing default page size to 50.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch spotify-improvements-fixes

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40bc2a9 and f392709.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • components/factorial_api_keys/factorial_api_keys.app.mjs (1 hunks)
  • components/flowii/flowii.app.mjs (1 hunks)
  • components/hailey_hr/hailey_hr.app.mjs (1 hunks)
  • components/nuvemshop/nuvemshop.app.mjs (1 hunks)
  • components/simpleem/simpleem.app.mjs (1 hunks)
  • components/suitecrm/suitecrm.app.mjs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Lint Code Base
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
🔇 Additional comments (2)
components/simpleem/simpleem.app.mjs (1)

11-11: No functional change (trailing newline only).

components/suitecrm/suitecrm.app.mjs (1)

1-11: File appears tangential to PR scope.

This SuiteCRM app module is unrelated to the Spotify improvements objectives (rate limiting, retry logic, pagination). The only change is a trailing newline. Please verify this file's inclusion in the PR is intentional.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/spotify/spotify.app.mjs (1)

433-452: getAllTracksByChunksOfAlbumIds – logic OK, but double flattening is a bit noisy

The new $‑aware implementation and use of _makeRequest look correct. You currently:

  • Map each chunk to data.albums.map(...).flat() and push that into tracks, then
  • Return tracks.flat().

This works, but you could simplify to a single flatten:

-      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(),
-        ]);
-      }
-      return tracks.flat();
+      for (const albumIds of chunksOfAlbumIds) {
+        const { data } = await this._makeRequest({
+          $,
+          url: "/albums",
+          params: {
+            market,
+            ids: albumIds.join(","),
+          },
+        });
+        tracks.push(...data.albums.flatMap((album) => album.tracks.items));
+      }
+      return tracks;

Not a correctness issue, just a small readability/efficiency improvement.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e61aaaa and 2654eb2.

📒 Files selected for processing (17)
  • components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1 hunks)
  • components/spotify/actions/create-playlist/create-playlist.mjs (1 hunks)
  • components/spotify/actions/get-album-tracks/get-album-tracks.mjs (3 hunks)
  • components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs (1 hunks)
  • components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (2 hunks)
  • components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1 hunks)
  • components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1 hunks)
  • components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1 hunks)
  • components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1 hunks)
  • components/spotify/actions/get-recommendations/get-recommendations.mjs (1 hunks)
  • components/spotify/actions/get-track/get-track.mjs (1 hunks)
  • components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (3 hunks)
  • components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (2 hunks)
  • components/spotify/actions/save-track/save-track.mjs (2 hunks)
  • components/spotify/actions/search/search.mjs (2 hunks)
  • components/spotify/common/constants.mjs (1 hunks)
  • components/spotify/spotify.app.mjs (15 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs
  • components/spotify/actions/get-track/get-track.mjs
  • components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs
  • components/spotify/actions/get-playlist-items/get-playlist-items.mjs
  • components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs
  • components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs
  • components/spotify/actions/create-playlist/create-playlist.mjs
  • components/spotify/spotify.app.mjs
  • components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs
  • components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs
  • components/spotify/actions/save-track/save-track.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.

Applied to files:

  • components/spotify/actions/get-playlist-items/get-playlist-items.mjs
📚 Learning: 2024-09-25T16:13:11.505Z
Learnt from: LucBerge
Repo: PipedreamHQ/pipedream PR: 14080
File: components/nocodb/nocodb.app.mjs:133-133
Timestamp: 2024-09-25T16:13:11.505Z
Learning: When implementing pagination with an offset, incrementing `args.params.offset` within the loop ensures correct tracking of the offset, particularly when a maximum count limit (`max`) is used.

Applied to files:

  • components/spotify/actions/search/search.mjs
🧬 Code graph analysis (11)
components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs (1)
components/spotify/spotify.app.mjs (3)
  • tracks (135-140)
  • tracks (438-438)
  • artistId (415-424)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (4)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/create-playlist/create-playlist.mjs (1)
  • resp (55-60)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • resp (54-59)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)
  • resp (28-35)
components/spotify/actions/get-track/get-track.mjs (7)
components/spotify/actions/search/search.mjs (1)
  • res (77-84)
components/spotify/spotify.app.mjs (6)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)
  • res (30-40)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)
  • res (35-41)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • res (61-71)
components/spotify/actions/save-track/save-track.mjs (1)
  • res (29-36)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (3)
components/spotify/actions/create-playlist/create-playlist.mjs (2)
  • resp (55-60)
  • data (48-53)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)
  • resp (25-28)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (2)
  • resp (54-59)
  • data (49-52)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (5)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)
  • res (30-40)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)
  • res (35-41)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/actions/save-track/save-track.mjs (1)
  • res (29-36)
components/spotify/actions/get-recommendations/get-recommendations.mjs (4)
components/spotify/actions/get-playlist/get-playlist.mjs (1)
  • response (29-32)
components/spotify/actions/get-album-tracks/get-album-tracks.mjs (1)
  • params (45-48)
components/spotify/spotify.app.mjs (2)
  • params (306-311)
  • params (403-403)
components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs (1)
  • params (53-55)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (4)
components/spotify/spotify.app.mjs (7)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
  • artistId (415-424)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • res (61-71)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (4)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/create-playlist/create-playlist.mjs (1)
  • resp (55-60)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)
  • resp (25-28)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • resp (54-59)
components/spotify/actions/create-playlist/create-playlist.mjs (4)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)
  • resp (25-28)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • resp (54-59)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)
  • resp (28-35)
components/spotify/spotify.app.mjs (4)
components/spotify/common/constants.mjs (4)
  • PAGE_SIZE (46-46)
  • PAGE_SIZE (46-46)
  • ITEM_TYPES_RESULT_NAME (37-44)
  • ITEM_TYPES_RESULT_NAME (37-44)
components/spotify/actions/get-album-tracks/get-album-tracks.mjs (3)
  • params (45-48)
  • albums (29-34)
  • tracks (49-49)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/sources/new-saved-track/new-saved-track.mjs (1)
  • tracks (41-41)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (5)
components/spotify/spotify.app.mjs (6)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • res (61-71)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/common/constants.mjs (2)
  • ITEM_TYPES (1-8)
  • ITEM_TYPES (1-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Lint Code Base
🔇 Additional comments (27)
components/spotify/actions/search/search.mjs (2)

4-6: LGTM! Centralized PAGE_SIZE constant improves maintainability.

The import of PAGE_SIZE from the constants file is a good refactoring that promotes consistency across the codebase.


49-49: LGTM! Increased default page size reduces API requests.

Changing the default limit from 20 to PAGE_SIZE (50) aligns with the PR objectives to reduce the number of requests performed. Since the max constraint is already set to 50, this change is valid and optimal.

components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs (2)

36-36: LGTM! Context parameter correctly added.

The addition of the $ parameter to both method calls aligns with the PR's refactoring to support centralized request handling with context propagation.

Also applies to: 42-42


47-47: LGTM! Optional chaining replaces lodash dependency.

Replacing lodash.get with native optional chaining (??) is more idiomatic and removes unnecessary dependencies.

components/spotify/common/constants.mjs (1)

46-46: LGTM! Centralized PAGE_SIZE constant optimizes pagination.

The PAGE_SIZE constant set to 50 (Spotify's maximum) centralizes pagination configuration and helps reduce the number of API requests, aligning with the PR objectives.

components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)

30-40: LGTM! Successful migration to centralized request helper.

The refactoring from direct axios usage to _makeRequest is well-executed. The additional_types array is correctly joined with commas, and the $ context parameter is properly passed.

components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (2)

25-28: LGTM! Clean migration to centralized request pattern.

The refactoring correctly uses _makeRequest with the trackId.value ?? trackId pattern to handle both object and string forms of trackId.


30-30: LGTM! Optional chaining improves code clarity.

Replacing lodash.get with native optional chaining is more idiomatic and removes external dependencies.

components/spotify/actions/create-playlist/create-playlist.mjs (1)

55-60: LGTM! Correct POST request migration.

The refactoring to _makeRequest properly specifies the POST method, constructs the URL with the authenticated user's ID, and passes the $ context parameter correctly.

components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (2)

47-52: LGTM! Consistent refactoring to centralized request helper.

The migration correctly uses _makeRequest with the POST method and handles both object and string forms of playlistId via the playlistId.value ?? playlistId pattern.


55-55: LGTM! Native optional chaining replaces lodash.

Using playlistId.label ?? playlistId instead of lodash.get is more idiomatic and reduces dependencies.

components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (2)

35-41: LGTM! Successful migration to centralized request pattern.

The refactoring correctly uses _makeRequest with the artistId.value ?? artistId pattern and properly passes the $ context parameter.


43-43: LGTM! Consistent use of optional chaining throughout.

Both the summary message and return statement now use native optional chaining (??) instead of lodash.get, making the code more idiomatic and removing external dependencies.

Also applies to: 45-45

components/spotify/actions/get-album-tracks/get-album-tracks.mjs (1)

2-57: PAGE_SIZE-based pagination and _makeRequest usage look correct

The album options query and the run loop both use PAGE_SIZE and offset stepping in a consistent way, and the _makeRequest call/response destructuring ({ items }) matches the Spotify API shape. No issues from my side here.

components/spotify/actions/get-track/get-track.mjs (1)

36-42: Track fetch refactor to _makeRequest is consistent

The new _makeRequest call (URL construction, market param, and use of trackId.value ?? trackId) aligns with the other Spotify actions in this PR and should be functionally equivalent to the previous axios-based implementation.

components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)

5-63: DELETE request refactor and messaging look correct

Switching to this.spotify._makeRequest for the DELETE /playlists/${playlistId}/tracks call while keeping the { tracks, snapshot_id } payload, and updating the summary to use playlistId.label ?? playlistId, all look consistent with the rest of the Spotify actions.

components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)

5-35: _makeRequest usage for removing saved tracks is consistent

The new _makeRequest call to DELETE /me/tracks with data: { ids } and the updated summary message are both in line with other actions in this PR. Returning resp from run also improves debuggability without changing input behavior.

components/spotify/actions/save-track/save-track.mjs (1)

6-36: Save-track refactor and return behavior look good

Using _makeRequest for PUT /me/tracks and returning ids when the response is empty (while preserving any non-empty response) is a clean improvement and consistent with how other actions in this PR expose API results.

components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)

52-65: Functional refactor looks good; check limit default in description

The _makeRequest refactor (URL based on categoryId.value ?? categoryId, and returning res.playlists?.items ?? []) is solid and defensively handles missing playlists.

However, the limit prop description still says Default: 20.. If the shared Spotify limit propDefinition now defaults to the new PAGE_SIZE (50) as part of this PR, consider updating this text to avoid confusion, for example:

-      description: "The maximum number of items to return. Default: 20.",
+      description: "The maximum number of items to return. Default: 50.",

Likely an incorrect or invalid review comment.

components/spotify/spotify.app.mjs (8)

31-37: PAGE_SIZE / offset usage in dynamic options – confirm page indexing

Using a centralized PAGE_SIZE and offset: PAGE_SIZE * page across option loaders is good for consistency and reducing requests, but it assumes page is 0‑based. If page is 1‑based in this environment, you’ll skip the first page of results. Please confirm the paging contract for dynamic options and adjust the offset formula if needed.

Also applies to: 53-56, 76-81, 95-98, 113-116, 135-140, 159-167


201-204: sanitizedArray mapping correctly handles option objects and primitives

Updating the array branch to item.value ?? item makes this helper work for both { label, value } objects and raw values, without breaking existing primitive arrays. No issues here.


313-320: getItems refactor to _makeRequest looks correct

Using _makeRequest({ method: "GET", url: "/search", params }) and reducing over res.data?.[ITEM_TYPES_RESULT_NAME[type]]?.items ?? [] for each type is a clean, defensive approach. Optional chaining + nullish coalescing covers sparse responses without throwing.


332-371: $-aware helpers (getPlaylist*, getCategories, getUserTracks) – align caller usage with new signature

The new signatures like:

async getPlaylists({ $, ...args }) { ... }
async getUserTracks({ $, ...args }) { ... }

are consistent with the $‑first pattern used in actions (e.g. this.spotify._makeRequest({ $, ... })). However, internal callers in this same file (propDefinitions) still call these helpers without $, which leads to the $: undefined forwarding issue described in the _makeRequest comment.

Once _makeRequest is fixed to normalize $, these helpers will work both from:

  • Actions/sources: getUserTracks({ $, limit, offset })
  • Internal app code: getUserTracks({ limit, offset })

Please also confirm that external callers (e.g. sources like new-saved-track) have been updated to call these new object‑destructuring signatures.


406-432: fetchChunksOfAlbumsIds – good PAGE_SIZE usage; verify $ and this binding with _paginate

The refactor to use _makeRequest({ $, url, params }) with limit: PAGE_SIZE / offset: PAGE_SIZE * page is consistent and should reduce the number of API calls.

However, note the interaction with _paginate and the external snippet:

// components/spotify/sources/new-saved-track/new-saved-track.mjs
const tracks = await this.spotify._paginate(this.spotify.getUserTracks.bind(this));

Since getUserTracks now calls this._makeRequest, this pattern of bind(this) (where this is the action context, not the app) may mean this._makeRequest is undefined inside getUserTracks, depending on how the runtime binds app methods.

Please double‑check the this binding strategy for _paginate + getUserTracks and adjust either:

  • The call site (e.g. this.spotify.getUserTracks.bind(this.spotify) or a wrapper that passes { $, ...params }), or
  • The helper signatures to not rely on this at all and instead accept $ explicitly.

402-405: No action required – search method is correct

The search method at lines 402-405 correctly uses the current _makeRequest signature. The _makeRequest method accepts positional parameters (method, url, data), and search properly calls it with this._makeRequest("GET", "/search", params). All other methods in the file follow the same pattern, indicating this is the expected calling convention.


284-286: Unable to verify: File not found in repository

The file components/spotify/spotify.app.mjs could not be located in the current repository. Without access to the actual code and its context, I cannot verify whether the concern about err.headers being potentially undefined when err.status === 429 is valid.

To verify this review comment, please confirm:

  • The correct file path in your repository
  • Whether this code still exists in the current state of the codebase

If the file exists in a different location or has been modified, provide the current location so verification can proceed.


256-270: The identified issues do not match the current codebase. _getBaseUrl() is defined at line 253 and returns the Spotify API base URL. _getHeaders() is defined at line 242 and properly returns authorization headers. The _makeRequest method's $ = this default parameter is appropriate for the existing code patterns. The concern about undefined $ being forwarded through non-existent helper methods is not applicable to the current implementation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/spotify/spotify.app.mjs (1)

272-289: Preserve original axios error details when retries are exhausted

Wrapping the caught value in new Error(err) will usually produce a message like [object Object] for axios-style errors, obscuring status and response data; it’s better to rethrow err directly or use err.message (and, if needed, attach response info). Also, since retry now inspects err.status and err.headers["Retry-After"], please confirm that @pipedream/platform’s axios (with returnFullResponse: true) exposes errors in that shape so the 429 backoff logic actually triggers.

♻️ Duplicate comments (1)
components/spotify/spotify.app.mjs (1)

223-240: _paginate unconditionally forces limit = PAGE_SIZE, ignoring caller-provided limits

Overwriting params.limit with PAGE_SIZE means any explicit limit a caller passes to _paginate is ignored, which can change behavior for existing callers that relied on a different page size. Consider only defaulting when params.limit is null / undefined, or explicitly documenting _paginate as always enforcing PAGE_SIZE.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2654eb2 and 1877a7e.

📒 Files selected for processing (2)
  • components/spotify/actions/search/search.mjs (3 hunks)
  • components/spotify/spotify.app.mjs (15 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
📚 Learning: 2024-09-25T16:13:11.505Z
Learnt from: LucBerge
Repo: PipedreamHQ/pipedream PR: 14080
File: components/nocodb/nocodb.app.mjs:133-133
Timestamp: 2024-09-25T16:13:11.505Z
Learning: When implementing pagination with an offset, incrementing `args.params.offset` within the loop ensures correct tracking of the offset, particularly when a maximum count limit (`max`) is used.

Applied to files:

  • components/spotify/spotify.app.mjs
  • components/spotify/actions/search/search.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/spotify/spotify.app.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (5)
components/spotify/actions/search/search.mjs (1)

4-7: Search action PAGE_SIZE default and $ forwarding look correct

Using PAGE_SIZE as the default limit (with max: 50) aligns with the shared Spotify pagination config, and forwarding $ into this.spotify.search matches the new object-argument signature without changing validation behavior.

Also applies to: 49-49, 77-85

components/spotify/spotify.app.mjs (4)

9-10: Consistent PAGE_SIZE-based pagination across helpers looks good

Importing PAGE_SIZE and using it for limit plus offset = PAGE_SIZE * page in prop options() resolvers and album-chunk helpers keeps pagination uniform and respects Spotify’s documented limits; the calculations and use of playlistId.value ?? playlistId and similar patterns are sound.

Also applies to: 30-37, 52-56, 72-81, 94-98, 112-116, 131-140, 156-167, 422-429, 447-454


201-204: sanitizedArray now correctly extracts values from { label, value } option arrays

Mapping arrays via item.value ?? item cleanly supports both primitive arrays and arrays of option objects without breaking existing callers, and avoids extra branching.


313-320: New _makeRequest-based helpers (getItems/search/playlists/categories/tracks) are consistent and robust once baseURL is fixed

Delegating to _makeRequest and then accessing res.data / { data } with optional chaining (?. / ??) provides a uniform, safer pattern for reading Spotify responses, and returning plain data structures from these helpers makes the calling actions simpler. Once the _getBaseUrl issue is resolved, these methods look solid.

Also applies to: 332-412


413-459: Chunked albums / tracks helpers correctly compose pagination and flattening

fetchChunksOfAlbumsIds and getAllTracksByChunksOfAlbumIds correctly handle artistId.value ?? artistId, paginate with PAGE_SIZE, and return flattened track arrays from chunked album IDs; the array-of-arrays then .flat() pattern is coherent and easy to follow.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
components/spotify/spotify.app.mjs (1)

278-289: Use safer property access on error object

The error object structure from @pipedream/platform axios may vary. Consider using optional chaining for safer access to err.status and err.headers. Also, HTTP/2 normalizes header names to lowercase, so retry-after is more portable than Retry-After.

       // 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)
+      const delay = (err?.status === 429)
+        ? ((err.headers?.["retry-after"] ?? err.headers?.["Retry-After"]) * 1000)
         : 500;
components/spotify/actions/get-album-tracks/get-album-tracks.mjs (1)

2-61: PAGE_SIZE-based pagination and _makeRequest usage are correct

Importing ITEM_TYPES / PAGE_SIZE, using PAGE_SIZE in the options query, and paging album tracks via a do/while that advances params.offset until items.length < params.limit is logically sound and matches the shared pattern introduced elsewhere. If you revisit this later, you might consider renaming total (which holds the page’s item count) to something like pageItemCount for clarity, but it’s not functionally required.

components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)

5-35: DELETE refactor is correct; consider aligning user-facing terminology

The change to this.spotify._makeRequest for DELETE "/me/tracks" with data: { ids } and the version/description updates all look correct and consistent with the other Spotify actions. As a small UX polish, you may want to standardize the wording between the description (“Your Music” library) and the summary (“Liked Songs”) so users see a single, consistent term for this collection.

♻️ Duplicate comments (3)
components/spotify/actions/get-recommendations/get-recommendations.mjs (1)

61-64: Fix typo in seed validation error message

The error message still reads “Must provide between 1 and 5 seeds in in any combination…”. The duplicated “in” should be removed:

-      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`.");
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)

52-59: market is destructured but not defined as a prop

market is destructured from this on line 54 and forwarded in params, but there's no market prop defined in this action. This means market will always be undefined.

components/spotify/spotify.app.mjs (1)

220-240: _paginate always uses PAGE_SIZE – ensure this is documented

As noted in a previous review, params.limit is unconditionally set to PAGE_SIZE. This is fine for internal optimization, but any caller-supplied limit will be ignored. Consider adding a brief comment noting this behavior.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1877a7e and 1891e36.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (22)
  • components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (2 hunks)
  • components/spotify/actions/create-playlist/create-playlist.mjs (2 hunks)
  • components/spotify/actions/get-album-tracks/get-album-tracks.mjs (3 hunks)
  • components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs (2 hunks)
  • components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (2 hunks)
  • components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (2 hunks)
  • components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (2 hunks)
  • components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (2 hunks)
  • components/spotify/actions/get-playlist-items/get-playlist-items.mjs (2 hunks)
  • components/spotify/actions/get-playlist/get-playlist.mjs (1 hunks)
  • components/spotify/actions/get-recommendations/get-recommendations.mjs (2 hunks)
  • components/spotify/actions/get-track/get-track.mjs (2 hunks)
  • components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (3 hunks)
  • components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (2 hunks)
  • components/spotify/actions/save-track/save-track.mjs (2 hunks)
  • components/spotify/actions/search/search.mjs (3 hunks)
  • components/spotify/package.json (2 hunks)
  • components/spotify/sources/new-playlist/new-playlist.mjs (1 hunks)
  • components/spotify/sources/new-saved-track/new-saved-track.mjs (1 hunks)
  • components/spotify/sources/new-track-by-artist/new-track-by-artist.mjs (1 hunks)
  • components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs (1 hunks)
  • components/spotify/spotify.app.mjs (15 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/spotify/package.json
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs
  • components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs
  • components/spotify/actions/save-track/save-track.mjs
  • components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs
  • components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs
  • components/spotify/spotify.app.mjs
  • components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs
📚 Learning: 2024-09-25T16:13:11.505Z
Learnt from: LucBerge
Repo: PipedreamHQ/pipedream PR: 14080
File: components/nocodb/nocodb.app.mjs:133-133
Timestamp: 2024-09-25T16:13:11.505Z
Learning: When implementing pagination with an offset, incrementing `args.params.offset` within the loop ensures correct tracking of the offset, particularly when a maximum count limit (`max`) is used.

Applied to files:

  • components/spotify/actions/search/search.mjs
  • components/spotify/spotify.app.mjs
🧬 Code graph analysis (12)
components/spotify/actions/get-album-tracks/get-album-tracks.mjs (2)
components/spotify/common/constants.mjs (2)
  • PAGE_SIZE (46-46)
  • PAGE_SIZE (46-46)
components/spotify/spotify.app.mjs (3)
  • page (419-419)
  • tracks (132-137)
  • tracks (445-445)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (7)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)
  • res (35-41)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • res (61-71)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/actions/save-track/save-track.mjs (1)
  • res (28-35)
components/spotify/spotify.app.mjs (6)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
components/spotify/common/constants.mjs (2)
  • ITEM_TYPES (1-8)
  • ITEM_TYPES (1-8)
components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs (1)
components/spotify/spotify.app.mjs (3)
  • tracks (132-137)
  • tracks (445-445)
  • artistId (422-431)
components/spotify/actions/search/search.mjs (1)
components/spotify/common/constants.mjs (2)
  • PAGE_SIZE (46-46)
  • PAGE_SIZE (46-46)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (4)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)
  • res (35-41)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)
  • res (30-40)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • res (61-71)
components/spotify/spotify.app.mjs (6)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (7)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)
  • res (30-40)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • res (61-71)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/actions/save-track/save-track.mjs (1)
  • res (28-35)
components/spotify/actions/search/search.mjs (1)
  • res (77-85)
components/spotify/spotify.app.mjs (7)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
  • artistId (422-431)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (4)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/create-playlist/create-playlist.mjs (1)
  • resp (55-60)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • resp (54-59)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)
  • resp (28-35)
components/spotify/actions/save-track/save-track.mjs (7)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)
  • res (35-41)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)
  • res (30-40)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • res (61-71)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/actions/search/search.mjs (1)
  • res (77-85)
components/spotify/spotify.app.mjs (6)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (4)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/create-playlist/create-playlist.mjs (1)
  • resp (55-60)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)
  • resp (25-28)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • resp (54-59)
components/spotify/actions/create-playlist/create-playlist.mjs (4)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)
  • resp (25-28)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • resp (54-59)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)
  • resp (28-35)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (7)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)
  • res (35-41)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)
  • res (52-60)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)
  • res (30-40)
components/spotify/actions/get-track/get-track.mjs (1)
  • res (36-42)
components/spotify/actions/save-track/save-track.mjs (1)
  • res (28-35)
components/spotify/actions/search/search.mjs (1)
  • res (77-85)
components/spotify/spotify.app.mjs (6)
  • res (313-317)
  • res (335-339)
  • res (345-349)
  • res (355-359)
  • res (365-369)
  • res (375-379)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (4)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)
  • resp (25-28)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)
  • resp (28-35)
components/spotify/spotify.app.mjs (2)
  • tracks (132-137)
  • tracks (445-445)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Ensure component commits modify component versions
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (21)
components/spotify/actions/get-playlist/get-playlist.mjs (2)

7-7: Version bump aligns with PR refactoring objectives.

The version update from 0.0.5 to 0.0.6 is appropriate for this action migration to the new centralized API pattern.


23-36: The spotify.getPlaylist method has been properly updated.

The method correctly accepts the $ context parameter and uses the centralized _makeRequest API, which delegates to this.retry($, config) for rate limit error handling. All PR objectives are satisfied.

components/spotify/sources/new-track-by-artist/new-track-by-artist.mjs (1)

10-10: Version bump only, consistent with PR scope

Version update to 0.1.4 matches the rest of the Spotify sources and doesn’t change behavior. No issues here.

components/spotify/package.json (1)

3-3: Package metadata and dependency cleanup look good

Bumping @pipedream/spotify to 0.7.6 and dropping lodash (keeping only @pipedream/platform) is consistent with the codebase changes away from lodash and with the PR description. No problems from a packaging standpoint.

Also applies to: 17-18

components/spotify/sources/new-playlist/new-playlist.mjs (1)

9-9: New source version aligned with other Spotify sources

Version updated to 0.1.4 with no logic change. This keeps the source versioning in sync with the rest of the Spotify updates.

components/spotify/sources/new-saved-track/new-saved-track.mjs (1)

9-9: Version bump only; behavior unchanged

The source version moves to 0.1.4 without any functional differences. Existing DB / pagination behavior remains intact.

components/spotify/sources/new-track-in-playlist/new-track-in-playlist.mjs (1)

10-10: Version update consistent with other playlist-related sources

Updating to 0.1.4 is in line with the broader Spotify source version bumps. No functional change or concern here.

components/spotify/actions/get-all-tracks-by-artist/get-all-tracks-by-artist.mjs (1)

7-7: Correctly threads $ into helpers and improves summary label

Passing $ into fetchChunksOfAlbumsIds and getAllTracksByChunksOfAlbumIds matches the centralized request pattern and lets downstream code handle rate limits / logging. The updated summary (artistId.label ?? artistId) is also more robust for select-type props. Version bump to 0.1.5 is appropriate for this behavioral tweak.

Also applies to: 35-39, 41-45, 47-47

components/spotify/actions/get-recommendations/get-recommendations.mjs (1)

73-76: New getRecommendations call shape matches app helper convention

Wrapping the params with { $, ...params } is consistent with the updated Spotify app helpers that expect a single options object and need $ for context. This wiring looks correct alongside the version bump to 0.1.5.

components/spotify/actions/search/search.mjs (1)

4-7: Adopting PAGE_SIZE and passing $ into search is correct

Importing PAGE_SIZE and using it as the default limit (with max: 50) matches the PR goal of using Spotify’s max page size by default. Updating the spotify.search call to include $ follows the new helper pattern and supports centralized error / rate-limit handling. Version bump to 0.0.3 is appropriate.

Also applies to: 13-13, 49-49, 78-79

components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)

25-30: LGTM!

The refactoring to use the centralized _makeRequest helper is correctly implemented. The nullish coalescing pattern for trackId.value ?? trackId and trackId.label ?? trackId properly handles both object and string inputs, consistent with other actions in this PR.

components/spotify/spotify.app.mjs (5)

253-270: LGTM - _getBaseUrl is now defined

The previously reported issue about missing _getBaseUrl has been addressed. The implementation correctly returns the Spotify API base URL and is properly used in _makeRequest.


332-411: LGTM - Internal methods correctly handle response structure

All internal methods (getPlaylist, getPlaylists, getCategories, getUserTracks, getPlaylistItems, getGenres, getRecommendations, search) correctly access res.data or destructure { data }, properly handling the returnFullResponse: true behavior.


313-320: LGTM!

The getItems method correctly accesses res.data with optional chaining, properly handling the full response structure.


413-460: LGTM!

Both fetchChunksOfAlbumsIds and getAllTracksByChunksOfAlbumIds correctly destructure { data } from the _makeRequest response, properly handling the full response structure.


198-214: LGTM!

Clean refactoring from lodash utilities to native JavaScript. The use of Array.isArray and typeof is idiomatic and the nullish coalescing item.value ?? item properly handles prop objects with values.

components/spotify/actions/create-playlist/create-playlist.mjs (1)

7-60: _makeRequest migration looks correct and consistent

The version bump and refactor to this.spotify._makeRequest with method: "POST", the same payload, and the existing oauth_uid-based URL are consistent with other Spotify actions and preserve behavior while centralizing HTTP logic. Explicitly returning resp is also aligned with the newer pattern.

components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)

9-40: Centralized request + additional_types usage are sound

Using this.spotify._makeRequest with url: "/me/player/currently-playing" and the params object (including market and additional_types from ITEM_TYPES) matches the new shared pattern and keeps the response handling logic intact.

components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)

7-56: Refactor to _makeRequest and summary formatting look good

The move to this.spotify._makeRequest with the playlist URL derived from playlistId.value ?? playlistId is consistent with other actions, and the summary now correctly uses playlistId.label ?? playlistId while preserving the pluralization logic based on data.uris.length.

components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)

7-65: Updated request + safer response handling look good

The migration to this.spotify._makeRequest with the new category playlists URL and preserved params is consistent with other Spotify actions, and returning res.playlists?.items ?? [] plus the categoryId.label ?? categoryId summary makes the code more robust to missing fields without changing behavior.

components/spotify/actions/get-track/get-track.mjs (1)

7-42: Track fetch refactor aligns with shared _makeRequest pattern

Using this.spotify._makeRequest with url: \/tracks/${trackId.value ?? trackId}`and passingmarketviaparams` is consistent with the new shared helper and preserves the existing summary / return behavior.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1891e36 and 2f11e44.

📒 Files selected for processing (7)
  • components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (2 hunks)
  • components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (2 hunks)
  • components/spotify/actions/get-playlist-items/get-playlist-items.mjs (2 hunks)
  • components/spotify/actions/get-recommendations/get-recommendations.mjs (3 hunks)
  • components/spotify/actions/get-track/get-track.mjs (2 hunks)
  • components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (2 hunks)
  • components/spotify/spotify.app.mjs (14 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-09-25T16:13:11.505Z
Learnt from: LucBerge
Repo: PipedreamHQ/pipedream PR: 14080
File: components/nocodb/nocodb.app.mjs:133-133
Timestamp: 2024-09-25T16:13:11.505Z
Learning: When implementing pagination with an offset, incrementing `args.params.offset` within the loop ensures correct tracking of the offset, particularly when a maximum count limit (`max`) is used.

Applied to files:

  • components/spotify/spotify.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/spotify/spotify.app.mjs
  • components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.

Applied to files:

  • components/spotify/actions/get-playlist-items/get-playlist-items.mjs
  • components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs
🧬 Code graph analysis (5)
components/spotify/actions/get-recommendations/get-recommendations.mjs (5)
components/spotify/spotify.app.mjs (2)
  • params (307-312)
  • data (221-221)
components/spotify/actions/get-album-tracks/get-album-tracks.mjs (1)
  • params (45-48)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • data (42-45)
components/spotify/actions/create-playlist/create-playlist.mjs (1)
  • data (48-53)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • data (49-52)
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (3)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • data (42-45)
components/spotify/actions/create-playlist/create-playlist.mjs (1)
  • data (48-53)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • data (49-52)
components/spotify/spotify.app.mjs (1)
components/spotify/common/constants.mjs (4)
  • PAGE_SIZE (46-46)
  • PAGE_SIZE (46-46)
  • ITEM_TYPES_RESULT_NAME (37-44)
  • ITEM_TYPES_RESULT_NAME (37-44)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
components/spotify/spotify.app.mjs (3)
  • playlistId (334-337)
  • playlistId (364-368)
  • data (221-221)
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)
components/spotify/spotify.app.mjs (2)
  • artistId (405-414)
  • data (221-221)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (7)
components/spotify/actions/get-track/get-track.mjs (1)

36-46: LGTM! Proper use of the new _makeRequest pattern.

The migration to the centralized _makeRequest method is correctly implemented:

  • Properly destructures { data } from the response
  • Uses optional chaining for safe property access (data?.name)
  • Correctly handles the fallback for trackId extraction
components/spotify/actions/get-categorys-playlist/get-categorys-playlist.mjs (1)

52-65: LGTM! Clean migration to the new request pattern.

The refactoring properly:

  • Destructures { data } from the _makeRequest response
  • Uses optional chaining to safely navigate nested response properties (data?.playlists?.items)
  • Handles both object and primitive values for categoryId
components/spotify/actions/get-artist-top-tracks/get-artist-top-tracks.mjs (1)

35-46: LGTM! Response access properly fixed.

The destructuring of { data } correctly addresses the previous issue with returnFullResponse: true. The response is now properly accessed via data?.tracks instead of res.tracks.

components/spotify/spotify.app.mjs (1)

198-214: LGTM! Clean refactoring of lodash dependencies and request centralization.

The migration away from lodash utilities to native JavaScript is well-executed:

  • Array.isArray replaces isArray
  • typeof and native checks replace isString, isEmpty, isNil
  • item.value ?? item replaces get(item, "value", item)

The new _makeRequest method properly centralizes HTTP calls with consistent error handling and header management.

Also applies to: 253-270, 292-443

components/spotify/actions/get-recommendations/get-recommendations.mjs (1)

73-84: LGTM! Correct usage of the refactored API.

The call to getRecommendations({ $, ...params }) properly passes the context and parameters, and the response handling correctly accesses data?.tracks.

components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)

28-40: LGTM! Correct implementation of DELETE request.

The migration to _makeRequest is properly implemented for this DELETE operation, with correct destructuring and response handling.

components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)

60-74: LGTM! Clean refactoring with proper response handling.

The migration correctly:

  • Destructures { data } from the _makeRequest response
  • Uses optional chaining for safe access to data?.items
  • Properly passes the $ context through to the request helper

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
components/spotify/spotify.app.mjs (1)

220-239: _paginate still overwrites caller limit with PAGE_SIZE

_paginate now unconditionally sets params.limit = PAGE_SIZE, which means any explicit limit passed by callers is ignored. If any existing or future callers expect a different page size, this will silently change their behavior; otherwise, it’s fine but should be documented as fixed‑size pagination.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2f11e44 and fd2b727.

📒 Files selected for processing (8)
  • components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (2 hunks)
  • components/spotify/actions/create-playlist/create-playlist.mjs (2 hunks)
  • components/spotify/actions/get-album-tracks/get-album-tracks.mjs (3 hunks)
  • components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (2 hunks)
  • components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (2 hunks)
  • components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (3 hunks)
  • components/spotify/actions/save-track/save-track.mjs (2 hunks)
  • components/spotify/spotify.app.mjs (14 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.

Applied to files:

  • components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs
  • components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs
  • components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs
  • components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs
  • components/spotify/actions/save-track/save-track.mjs
  • components/spotify/spotify.app.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.

Applied to files:

  • components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs
📚 Learning: 2024-09-25T16:13:11.505Z
Learnt from: LucBerge
Repo: PipedreamHQ/pipedream PR: 14080
File: components/nocodb/nocodb.app.mjs:133-133
Timestamp: 2024-09-25T16:13:11.505Z
Learning: When implementing pagination with an offset, incrementing `args.params.offset` within the loop ensures correct tracking of the offset, particularly when a maximum count limit (`max`) is used.

Applied to files:

  • components/spotify/spotify.app.mjs
🧬 Code graph analysis (5)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (4)
components/spotify/actions/create-playlist/create-playlist.mjs (2)
  • resp (55-60)
  • data (48-53)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (2)
  • resp (54-59)
  • data (49-52)
components/spotify/spotify.app.mjs (3)
  • playlistId (337-340)
  • playlistId (367-371)
  • data (221-221)
components/spotify/actions/get-playlist-items/get-playlist-items.mjs (1)
  • playlistId (60-69)
components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)
components/spotify/actions/get-track/get-track.mjs (1)
  • trackId (36-42)
components/spotify/actions/create-playlist/create-playlist.mjs (2)
components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)
  • resp (47-52)
components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)
  • resp (54-59)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (4)
components/spotify/spotify.app.mjs (1)
  • res (315-319)
components/spotify/actions/save-track/save-track.mjs (1)
  • res (28-35)
components/spotify/actions/search/search.mjs (1)
  • res (77-85)
components/spotify/common/constants.mjs (2)
  • ITEM_TYPES (1-8)
  • ITEM_TYPES (1-8)
components/spotify/actions/save-track/save-track.mjs (4)
components/spotify/spotify.app.mjs (1)
  • res (315-319)
components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)
  • res (30-40)
components/spotify/actions/search/search.mjs (1)
  • res (77-85)
components/spotify/actions/remove-user-saved-tracks/remove-user-saved-tracks.mjs (1)
  • ids (26-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (11)
components/spotify/actions/create-playlist/create-playlist.mjs (1)

7-7: Create‑playlist refactor to _makeRequest looks correct

Using this.spotify._makeRequest with url: \/users/${this.spotify.$auth.oauth_uid}/playlists`and destructuring{ data: resp }` keeps the endpoint, payload, and return shape aligned with other Spotify actions; version bump is consistent with the behavioral change.

Also applies to: 55-60

components/spotify/actions/get-currently-playing-track/get-currently-playing-track.mjs (1)

9-9: Currently‑playing migration to _makeRequest is consistent and safe

The new _makeRequest call with url: "/me/player/currently-playing" and additional_types built from ITEM_TYPES is correct, and destructuring { data: res } preserves existing behavior for both active playback (JSON body) and no‑content (empty body) responses.

Also applies to: 30-40

components/spotify/actions/get-audio-features-for-a-track/get-audio-features-for-a-track.mjs (1)

7-7: Get‑audio‑features refactor aligns with shared request helper

The _makeRequest call to /audio-features/${trackId.value ?? trackId} and returning data is correct, and the updated summary (trackId.label ?? trackId) handles both dropdown‑selected and custom IDs cleanly.

Also applies to: 25-32

components/spotify/actions/add-items-to-playlist/add-items-to-playlist.mjs (1)

7-7: Add‑items action now correctly uses _makeRequest and sanitized URIs

Using this.spotify.sanitizedArray(uris) for the uris payload and calling _makeRequest with url: \/playlists/${playlistId.value ?? playlistId}/tracks`is consistent with the Spotify API, and returning{ data: resp }keeps the response shape to the JSON body while the summary correctly usesplaylistId.label ?? playlistId. Optional position` is safely passed as‑is since the platform axios strips undefined fields from the request. Based on learnings.

Also applies to: 42-45, 47-52, 55-55

components/spotify/actions/remove-items-from-playlist/remove-items-from-playlist.mjs (1)

5-7: Remove‑items action now returns response body and uses unified request helper

The updated description and version are fine, and the new _makeRequest call with url: \/playlists/${playlistId.value ?? playlistId}/tracks`plus the{ tracks, snapshot_id }payload matches the Spotify API. Destructuring{ data: resp }and returningrespkeeps only the JSON body (e.g.{ snapshot_id }`), which is preferable to returning the full HTTP response object, and the summary correctly reflects the number of removed items and playlist label.

Also applies to: 35-36, 49-52, 54-59, 62-64

components/spotify/actions/save-track/save-track.mjs (1)

5-7: Save‑track return logic now operates on the response body and matches the endpoint

Normalizing trackIds via this.spotify.sanitizedArray, calling _makeRequest with url: "/me/tracks", and basing the return on the deserialized body (res) means an empty success response now correctly falls back to returning the list of saved ids, while any non‑empty body is propagated as‑is.

Also applies to: 27-35, 40-42

components/spotify/spotify.app.mjs (5)

27-34: PAGE_SIZE‑based option loaders are consistent and match Spotify limits

Using PAGE_SIZE with offsets of PAGE_SIZE * page across playlistTracksUris, savedUserTracksId, artistId, playlistId, categoryId, trackId, and uris options, together with getPlaylistItems, getUserTracks, and getItems, standardizes paging at Spotify’s 50‑item ceiling and reduces request count while preserving option behavior.

Also applies to: 50-53, 73-78, 92-95, 110-113, 132-137, 156-164


198-214: sanitizedArray refactor looks good and simplifies value extraction

Switching to Array.isArray and typeof value === "string" checks, mapping array items via item.value ?? item, and normalizing string inputs with .replace(...).split(",") matches the expected prop shapes across actions and removes the need for lodash helpers without changing behavior.


293-323: getItems now cleanly composes search results via _makeRequest

The updated getItems validates types against ITEM_TYPES, builds a single /search call via _makeRequest, and flattens res.data?.[ITEM_TYPES_RESULT_NAME[type]]?.items ?? [] across all requested types. This removes lodash usage and returns a straightforward array of items with robust guards around missing keys.


334-387: New helper methods correctly wrap _makeRequest and normalize return shapes

The helpers getPlaylist, getPlaylists, getCategories, getUserTracks, getPlaylistItems, getGenres, getRecommendations, and search all delegate to _makeRequest with a url and spread args, then return either data, data.items, or nested items (e.g. data.categories.items) as appropriate. This centralizes HTTP behavior and keeps external callers working with plain JSON arrays / objects instead of raw axios responses.


399-446: Album‑based helpers use PAGE_SIZE and chunking consistently

fetchChunksOfAlbumsIds pages through /artists/{artistId}/albums with limit: PAGE_SIZE and offset: PAGE_SIZE * page, pushing per‑page album ID chunks until data.next is falsy, and getAllTracksByChunksOfAlbumIds then fans out /albums requests for those chunks and flattens data.albums[].tracks.items to a single track list. This matches Spotify’s paging model and aligns with the PR’s goal of efficient, batched retrieval.

lcaresia
lcaresia previously approved these changes Dec 11, 2025
Copy link
Collaborator

@lcaresia lcaresia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@lcaresia lcaresia moved this from Ready for PR Review to Ready for QA in Component (Source and Action) Backlog Dec 11, 2025
@vunguyenhung
Copy link
Collaborator

For Integration QA:

@vunguyenhung vunguyenhung moved this from Ready for QA to Changes Required in Component (Source and Action) Backlog Dec 12, 2025
@vunguyenhung
Copy link
Collaborator

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check test reports below for more information:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add Spotify 429 Rate Limit Handling (Exponential Backoff Retries)

4 participants