Skip to content

Conversation

@sergio-eliot-rodriguez
Copy link
Collaborator

@sergio-eliot-rodriguez sergio-eliot-rodriguez commented Dec 2, 2025

WHY

Resolves #19272

Pushes get-posts, list-posts, search-posts, requested by the user.

Summary by CodeRabbit

  • New Features

    • Added "Get Posts", "List Posts", and "Search Posts" actions to retrieve, browse, and query posts (with detailed post fields).
    • Exposed pagination controls (first/after/last/before) for Slab interactions.
    • Improved API integration with centralized request handling and paginated post option listing.
  • Chores

    • Bumped Slab component version and updated dependencies.

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

@vercel
Copy link

vercel bot commented Dec 2, 2025

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

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
pipedream-docs-redirect-do-not-edit Ignored Ignored Dec 5, 2025 3:54pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Walkthrough

Adds three Slab actions (Get Posts, List Posts, Search Posts), centralizes GraphQL request helpers and pagination propDefinitions in the Slab app, introduces query constants, and bumps package version and dependencies.

Changes

Cohort / File(s) Summary
New action modules
components/slab/actions/get-posts/get-posts.mjs, components/slab/actions/list-posts/list-posts.mjs, components/slab/actions/search-posts/search-posts.mjs
Adds three action exports that build GraphQL queries/variables, call the Slab app _makeRequest, process responses into posts/pageInfo/edges as applicable, and export run results plus a $summary.
Slab app infrastructure
components/slab/slab.app.mjs
Adds propDefinitions (first, after, last, before); adds _baseUrl(), _getHeaders(), and _makeRequest() for centralized HTTP/GraphQL requests and error handling; adds listPostsForOptions() to produce paginated option lists; removes authKeys().
Shared GraphQL queries
components/slab/common/queries.mjs
Adds exported SEARCH_POSTS_QUERY and LIST_POSTS_QUERY GraphQL query string constants with post fields, banner, owner, topics, and pagination info.
Package metadata
components/slab/package.json
Bumps version from 0.0.1 to 0.1.0 and adds dependency "@pipedream/platform": "^3.1.0".

Sequence Diagram(s)

sequenceDiagram
    participant Action as Action (get/list/search)
    participant Runtime as Runtime ($)
    participant App as Slab.app (_makeRequest)
    participant GraphQL as Slab GraphQL API

    Note over Action,Runtime: Action.run builds GraphQL query & variables
    Action->>Runtime: run({ $ })
    Runtime->>App: _makeRequest({ query, variables })
    App->>App: _getHeaders()/ _baseUrl()
    App->>GraphQL: HTTP POST (query, variables, headers)
    GraphQL-->>App: HTTP response (data / errors)
    App-->>Runtime: parsed response (or throw on errors)
    Runtime-->>Action: returns data
    Action->>Action: map/extract posts, pageInfo, edges
    Action-->>Runtime: return { posts, pageInfo, edges } and export $summary
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify GraphQL queries in components/slab/common/queries.mjs match the API schema and required fields.
  • Review _makeRequest() error handling, _getHeaders() authorization header construction, and _baseUrl() correctness in components/slab/slab.app.mjs.
  • Check pagination handling and option resolution in listPostsForOptions() and the actions' props/propDefinitions.
  • Confirm response mappings in components/slab/actions/* (edges → node.post extraction) and $summary contents.
  • Inspect components/slab/package.json bump and the new dependency for compatibility.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'new slab components' is vague and generic, lacking specificity about which components or the main change's significance. Use a more descriptive title like 'Add Slab app with get-posts, list-posts, and search-posts actions' to clarify the specific changes introduced.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description is minimal but provides issue reference and lists implemented actions; it partially follows the template structure.
Linked Issues check ✅ Passed All requested Slab actions (get-posts, list-posts, search-posts) from issue #19272 are implemented with proper pagination support and GraphQL integration.
Out of Scope Changes check ✅ Passed Changes are tightly scoped to implementing the three requested Slab actions; package.json version bump and propDefinitions are supporting changes for the core objective.
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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@pipedream-component-development
Copy link
Collaborator

Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified.

@pipedream-component-development
Copy link
Collaborator

Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:

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

♻️ Duplicate comments (1)
components/slab/actions/search-posts/search-posts.mjs (1)

42-95: Duplicate: Code duplication with list-posts.mjs.

This GraphQL query and variable construction logic is nearly identical to the implementation in list-posts.mjs. The only difference is line 90 using this.query instead of an empty string. This duplication was already flagged in the list-posts.mjs review.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2583778 and 5e9e754.

📒 Files selected for processing (5)
  • components/slab/actions/get-posts/get-posts.mjs (1 hunks)
  • components/slab/actions/list-posts/list-posts.mjs (1 hunks)
  • components/slab/actions/search-posts/search-posts.mjs (1 hunks)
  • components/slab/package.json (2 hunks)
  • components/slab/slab.app.mjs (1 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/slab/package.json
📚 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/slab/slab.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/slab/slab.app.mjs
🧬 Code graph analysis (2)
components/slab/actions/search-posts/search-posts.mjs (3)
components/slab/actions/get-posts/get-posts.mjs (4)
  • query (23-51)
  • variables (52-54)
  • response (55-61)
  • posts (62-62)
components/slab/actions/list-posts/list-posts.mjs (6)
  • query (37-83)
  • variables (84-90)
  • response (91-97)
  • edges (98-98)
  • posts (99-101)
  • pageInfo (102-102)
components/slab/slab.app.mjs (6)
  • query (61-80)
  • variables (81-84)
  • response (52-52)
  • response (85-90)
  • edges (91-91)
  • pageInfo (99-99)
components/slab/actions/get-posts/get-posts.mjs (3)
components/slab/actions/list-posts/list-posts.mjs (3)
  • query (37-83)
  • variables (84-90)
  • posts (99-101)
components/slab/actions/search-posts/search-posts.mjs (3)
  • query (42-88)
  • variables (89-95)
  • posts (104-106)
components/slab/slab.app.mjs (2)
  • query (61-80)
  • variables (81-84)
🪛 GitHub Actions: Components Checks
components/slab/package.json

[error] 1-1: Lockfile specifiers do not match package.json: "@pipedream/platform" requires '^3.1.0' but lockfile has different specifiers.

🪛 GitHub Actions: Pull Request Checks
components/slab/package.json

[error] 1-1: Cannot install with 'frozen-lockfile' because pnpm-lock.yaml is not up to date with package.json. Specifiers in the lockfile ({}) don't match specs in package.json ({"@pipedream/platform":"^3.1.0"}). Run 'pnpm install --no-frozen-lockfile' to fix. Command failed: pnpm install -r.

⏰ 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). (1)
  • GitHub Check: pnpm publish
🔇 Additional comments (10)
components/slab/actions/list-posts/list-posts.mjs (2)

9-35: LGTM!

The props are well-structured and correctly reference the pagination propDefinitions from the slab app module.


91-108: LGTM!

The response processing correctly extracts posts from the GraphQL response, handles missing data gracefully with optional chaining, and returns a well-structured result.

components/slab/actions/get-posts/get-posts.mjs (3)

11-20: LGTM!

The dynamic options implementation correctly uses the listPostsForOptions helper with pagination support via prevContext.cursor.


23-51: LGTM!

The GraphQL query is well-structured and requests an appropriate set of fields including nested objects for banner, owner, and topics.


52-64: LGTM!

The implementation correctly constructs variables, makes the GraphQL request, and processes the response with appropriate fallbacks.

components/slab/actions/search-posts/search-posts.mjs (2)

9-40: LGTM!

The props are well-defined, including the required query parameter and optional pagination controls.


96-113: LGTM!

The response processing correctly handles the GraphQL response and provides an informative summary that includes the search query.

components/slab/slab.app.mjs (3)

1-1: LGTM!

The axios import from @pipedream/platform is correct and aligns with the new dependency added in package.json.


33-41: LGTM!

The helper methods correctly construct the base URL and headers with proper authorization using the API token.


58-106: LGTM!

The listPostsForOptions method correctly implements paginated options fetching with a reasonable page size of 20 items. It properly maps posts to the Pipedream options format and returns pagination context.

jcortes
jcortes previously approved these changes Dec 2, 2025
Copy link
Collaborator

@jcortes jcortes left a comment

Choose a reason for hiding this comment

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

Hi @sergio-eliot-rodriguez I've added just a suggestion other than that lgtm! Ready for QA!

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc68933 and e98b5ec.

📒 Files selected for processing (1)
  • components/slab/common/queries.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

Comment on lines +1 to +95
export const SEARCH_POSTS_QUERY = `
query SearchPosts($query: String!, $first: Int, $after: String, $last: Int, $before: String) {
search(query: $query, types: [POST], first: $first, after: $after, last: $last, before: $before) {
edges {
node {
... on PostSearchResult {
title
highlight
content
post {
id
title
linkAccess
archivedAt
publishedAt
insertedAt
updatedAt
version
content
banner {
original
thumb
preset
}
owner {
id
name
email
}
topics {
id
name
}
}
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
`;

export const LIST_POSTS_QUERY = `
query ListPosts($query: String!, $first: Int, $after: String, $last: Int, $before: String) {
search(query: $query, types: [POST], first: $first, after: $after, last: $last, before: $before) {
edges {
node {
... on PostSearchResult {
title
highlight
content
post {
id
title
linkAccess
archivedAt
publishedAt
insertedAt
updatedAt
version
content
banner {
original
thumb
preset
}
owner {
id
name
email
}
topics {
id
name
}
}
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
`;
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Eliminate query duplication using GraphQL fragments.

SEARCH_POSTS_QUERY and LIST_POSTS_QUERY are nearly identical—same variables, endpoint, and response fields. Maintaining two separate queries violates the DRY principle and creates a maintenance burden if the schema changes.

Extract the repeated post fields and pagination structure into a GraphQL fragment, then reuse it in both queries:

-export const SEARCH_POSTS_QUERY = `
-  query SearchPosts($query: String!, $first: Int, $after: String, $last: Int, $before: String) {
-    search(query: $query, types: [POST], first: $first, after: $after, last: $last, before: $before) {
-      edges {
-        node {
-          ... on PostSearchResult {
-            title
-            highlight
-            content
-            post {
-              id
-              title
-              linkAccess
-              archivedAt
-              publishedAt
-              insertedAt
-              updatedAt
-              version
-              content
-              banner {
-                original
-                thumb
-                preset
-              }
-              owner {
-                id
-                name
-                email
-              }
-              topics {
-                id
-                name
-              }
-            }
-          }
-        }
-        cursor
-      }
-      pageInfo {
-        hasNextPage
-        hasPreviousPage
-        startCursor
-        endCursor
-      }
-    }
-  }
-`;
-
-export const LIST_POSTS_QUERY = `
-  query ListPosts($query: String!, $first: Int, $after: String, $last: Int, $before: String) {
-    search(query: $query, types: [POST], first: $first, after: $after, last: $last, before: $before) {
-      edges {
-        node {
-          ... on PostSearchResult {
-            title
-            highlight
-            content
-            post {
-              id
-              title
-              linkAccess
-              archivedAt
-              publishedAt
-              insertedAt
-              updatedAt
-              version
-              content
-              banner {
-                original
-                thumb
-                preset
-              }
-              owner {
-                id
-                name
-                email
-              }
-              topics {
-                id
-                name
-              }
-            }
-          }
-        }
-        cursor
-      }
-      pageInfo {
-        hasNextPage
-        hasPreviousPage
-        startCursor
-        endCursor
-      }
-    }
-  }
-`;
+const POST_SEARCH_FIELDS = `
+  fragment PostSearchFields on PostSearchResult {
+    title
+    highlight
+    content
+    post {
+      id
+      title
+      linkAccess
+      archivedAt
+      publishedAt
+      insertedAt
+      updatedAt
+      version
+      content
+      banner {
+        original
+        thumb
+        preset
+      }
+      owner {
+        id
+        name
+        email
+      }
+      topics {
+        id
+        name
+      }
+    }
+  }
+`;
+
+const SEARCH_EDGES_QUERY = `
+  query($query: String!, $first: Int, $after: String, $last: Int, $before: String) {
+    search(query: $query, types: [POST], first: $first, after: $after, last: $last, before: $before) {
+      edges {
+        node {
+          ...PostSearchFields
+        }
+        cursor
+      }
+      pageInfo {
+        hasNextPage
+        hasPreviousPage
+        startCursor
+        endCursor
+      }
+    }
+  }
+`;
+
+export const SEARCH_POSTS_QUERY = `${POST_SEARCH_FIELDS}\nquery SearchPosts($query: String!, $first: Int, $after: String, $last: Int, $before: String) ${SEARCH_EDGES_QUERY.split('query')[1]}`;
+
+export const LIST_POSTS_QUERY = `${POST_SEARCH_FIELDS}\nquery ListPosts($query: String!, $first: Int, $after: String, $last: Int, $before: String) ${SEARCH_EDGES_QUERY.split('query')[1]}`;

Alternatively, if the queries are truly interchangeable, consolidate them into a single exported query and use it in both actions.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In components/slab/common/queries.mjs around lines 1-95, both SEARCH_POSTS_QUERY
and LIST_POSTS_QUERY are duplicated; extract the repeated selection set (the
PostSearchResult/post fields and pagination/edges structure) into a GraphQL
fragment and reference that fragment from both queries, or if they are identical
in usage, replace the two exports with a single exported query constant and
update callers to import that one query; ensure the fragment (or single query)
includes the variables and pageInfo/edges/cursor fields so schema changes only
need one update.

@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:

@sergio-eliot-rodriguez
Copy link
Collaborator Author

sergio-eliot-rodriguez commented Dec 3, 2025

Hey @vunguyenhung, I noticed the issue with your search returning 0 results for "Postmortem". The problem is that the query isn’t specifying the first parameter, or rather is not specifying pagination parameters.

The query argument alone won’t return anything unless you include pagination parameters. Here’s how it works:

  • first works together with after → when you provide first without after, the API paginates starting from the very first result.
  • last works together with before → this lets you paginate backwards.
  • These pairs (first + after, last + before) shouldn’t be mixed.

That’s why first and any of the pagination parameters can't be made required — they’re optional but necessary depending on the pagination direction. In your case, just add first to the query and you’ll start getting results from the beginning of the dataset. See for your postmortem query example:

image

@sergio-eliot-rodriguez sergio-eliot-rodriguez moved this from Ready for PR Review to Ready for QA in Component (Source and Action) Backlog Dec 4, 2025
@vunguyenhung
Copy link
Collaborator

Hi everyone, all test cases are passed! Ready for release!

Test reports

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

Hi everyone, all test cases are passed! Ready for release!

Test reports

@jcortes jcortes self-requested a review December 5, 2025 16:05
@sergio-eliot-rodriguez sergio-eliot-rodriguez merged commit 85caf1b into PipedreamHQ:master Dec 5, 2025
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[APP] Slab

4 participants