Skip to content

Conversation

@michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented Nov 19, 2025

Resolves #6147

Summary by CodeRabbit

  • New Features

    • Create, retrieve, and query documents in Sanity from workflows.
    • Real-time webhook source for new document events (instant) with sample test event.
    • Payload normalization helper and dataset/default constants for safer API interactions.
  • Chores

    • Component package version bumped and platform dependency added.

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

@vercel
Copy link

vercel bot commented Nov 19, 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 Nov 21, 2025 4:22pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Nov 21, 2025 4:22pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

Walkthrough

Adds a Sanity integration: new actions (create/get/query documents), a webhook source (new-document-event) with a webhook base, shared constants and utils (parseObject), and updates the Sanity app client with API methods and prop definitions.

Changes

Cohort / File(s) Summary
Actions
components/sanity/actions/create-document/create-document.mjs, components/sanity/actions/get-document/get-document.mjs, components/sanity/actions/query-dataset/query-dataset.mjs
New action modules to create, retrieve, and query Sanity documents/datasets. Each exports a default action object with metadata, props (sanity, dataset, plus query/documentId/documentId/type/additionalFields), and a run method that calls the Sanity client, exports a success summary, and returns the API response.
Common Utilities
components/sanity/common/constants.mjs, components/sanity/common/utils.mjs
Adds API_VERSION ("v2025-02-19") and DEFAULT_LIMIT (50). Adds parseObject utility that normalizes values by parsing JSON strings and recursively processing arrays/objects, returning undefined for falsy input.
Sanity App Client
components/sanity/sanity.app.mjs
Refactors client: adds propDefinitions (dataset, documentId with async options) and internal helpers (_projectId, _baseUrl, _makeRequest) plus API methods (createWebhook, deleteWebhook, getDocument, queryDataset, createDocument). Removes authKeys.
Webhook Sources Infrastructure
components/sanity/sources/common/base.mjs
New webhook source base with lifecycle hooks (activate, deactivate), state helpers (_getHookId, _setHookId), abstract methods (getWebhookArgs, generateMeta that throw ConfigurationError), and run handling (respond 200, compute meta, emit).
New Document Source
components/sanity/sources/new-document-event/new-document-event.mjs, components/sanity/sources/new-document-event/test-event.mjs
Source that extends the base to implement getWebhookArgs() and generateMeta(event) for document events with props for on, includeDrafts, and includeAllVersions. Adds a sample test event object representing a draft post.
Package
components/sanity/package.json
Bumps package version from 0.0.1 to 0.1.0 and adds a dependency on @pipedream/platform ^3.1.1.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Workflow as Pipedream Workflow
    participant Source as New Document Source
    participant Base as Webhook Base
    participant Sanity as Sanity API

    User->>Workflow: Configure source (on, includeDrafts...)
    Workflow->>Base: activate()
    Base->>Source: getWebhookArgs()
    Base->>Sanity: createWebhook(name, url, dataset, apiVersion, webhookArgs)
    Sanity-->>Base: { id, ... }
    Base->>Base: _setHookId(id)

    Sanity->>Base: POST /hooks (document event)
    Base->>Base: run({ body }) — respond 200
    Base->>Source: generateMeta(body)
    Base->>Workflow: emit(body, meta)

    User->>Workflow: Disable source
    Workflow->>Base: deactivate()
    Base->>Base: _getHookId()
    Base->>Sanity: deleteWebhook(hookId)
    Sanity-->>Base: Success
Loading
sequenceDiagram
    participant User
    participant Action as Pipedream Action
    participant App as Sanity App Client
    participant API as Sanity API

    User->>Action: Run "Create Document" (documentId,type,additionalFields)
    Action->>App: parseObject(additionalFields)
    App->>API: POST /data/actions/{dataset} { actions: [{ actionType: "sanity.action.document.create", publishedId, document: {...} }] }
    API-->>App: response
    App-->>Action: response
    Action->>Action: $.export("$summary","Successfully created document")
    Action-->>User: Result + Summary
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • Webhook lifecycle (activate/deactivate) and state persistence (_getHookId/_setHookId).
    • Abstract base methods (getWebhookArgs, generateMeta) and subclass implementations.
    • parseObject recursion edge cases and JSON parsing behavior.
    • API client _makeRequest (URL/auth construction) and error handling.
    • Consistency of props, propDefinitions, and summary exports across actions.

Suggested labels

ai-assisted

Suggested reviewers

  • GTFalcao

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is minimal, containing only 'Resolves #6147' with no details about implementation, features added, or testing performed. Add a comprehensive description covering what was implemented, why, how it works, and any testing considerations.
Title check ❓ Inconclusive The PR title 'Sanity.io - new components' is generic and vague, providing minimal insight into specific changes beyond identifying the app name. Specify which components/features were added (e.g., 'Sanity.io - add document CRUD actions and webhook sources').
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements document CRUD actions (create, get, query) and webhook sources (new document events) that provide foundational Sanity integration, addressing issue #6147 requirements for connecting Sanity with other apps.
Out of Scope Changes check ✅ Passed All changes are within scope: new Sanity actions/sources, utility functions, constants, and base classes directly support the objective of building Sanity integration for workflows.
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 issue-6147

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29b168a and 909b661.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • components/sanity/actions/create-document/create-document.mjs (1 hunks)
  • components/sanity/actions/get-document/get-document.mjs (1 hunks)
  • components/sanity/actions/query-dataset/query-dataset.mjs (1 hunks)
  • components/sanity/common/constants.mjs (1 hunks)
  • components/sanity/common/utils.mjs (1 hunks)
  • components/sanity/package.json (2 hunks)
  • components/sanity/sanity.app.mjs (1 hunks)
  • components/sanity/sources/common/base.mjs (1 hunks)
  • components/sanity/sources/new-document-event/new-document-event.mjs (1 hunks)
  • components/sanity/sources/new-document-event/test-event.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.

Applied to files:

  • components/sanity/sources/new-document-event/test-event.mjs
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12697
File: components/salesforce_rest_api/sources/common-webhook-methods.mjs:1-71
Timestamp: 2024-10-08T15:33:38.240Z
Learning: The `common-webhook-methods.mjs` object is designed to be extended, similar to an abstract class, and intentionally does not implement certain methods like `generateWebhookMeta` and `getEventType` to enforce implementation in subclasses.

Applied to files:

  • components/sanity/sources/new-document-event/new-document-event.mjs
  • components/sanity/sources/common/base.mjs
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.

Applied to files:

  • components/sanity/sources/new-document-event/new-document-event.mjs
📚 Learning: 2025-09-12T07:58:39.628Z
Learnt from: matyascimbulka
Repo: PipedreamHQ/pipedream PR: 18308
File: components/apify/actions/run-task-synchronously/run-task-synchronously.mjs:95-0
Timestamp: 2025-09-12T07:58:39.628Z
Learning: The Apify ActorRun object always contains the defaultDatasetId property according to the official documentation, so conditional checks for its existence are not needed when calling listDatasetItems.

Applied to files:

  • components/sanity/actions/query-dataset/query-dataset.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/sanity/sanity.app.mjs
📚 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/sanity/package.json
🧬 Code graph analysis (6)
components/sanity/common/constants.mjs (1)
components/sanity/sources/common/base.mjs (1)
  • API_VERSION (42-50)
components/sanity/actions/query-dataset/query-dataset.mjs (3)
components/sanity/actions/create-document/create-document.mjs (1)
  • response (41-53)
components/sanity/actions/get-document/get-document.mjs (1)
  • response (33-37)
components/sanity/sanity.app.mjs (1)
  • response (22-27)
components/sanity/sanity.app.mjs (5)
components/sanity/actions/create-document/create-document.mjs (1)
  • response (41-53)
components/sanity/actions/get-document/get-document.mjs (1)
  • response (33-37)
components/sanity/actions/query-dataset/query-dataset.mjs (1)
  • response (30-36)
components/sanity/common/constants.mjs (2)
  • DEFAULT_LIMIT (2-2)
  • API_VERSION (1-1)
components/sanity/sources/common/base.mjs (1)
  • API_VERSION (42-50)
components/sanity/actions/get-document/get-document.mjs (3)
components/sanity/actions/create-document/create-document.mjs (1)
  • response (41-53)
components/sanity/actions/query-dataset/query-dataset.mjs (1)
  • response (30-36)
components/sanity/sanity.app.mjs (1)
  • response (22-27)
components/sanity/actions/create-document/create-document.mjs (4)
components/sanity/common/utils.mjs (1)
  • parseObject (1-27)
components/sanity/actions/get-document/get-document.mjs (1)
  • response (33-37)
components/sanity/actions/query-dataset/query-dataset.mjs (1)
  • response (30-36)
components/sanity/sanity.app.mjs (1)
  • response (22-27)
components/sanity/sources/common/base.mjs (1)
components/sanity/common/constants.mjs (1)
  • API_VERSION (1-1)
🪛 Gitleaks (8.29.0)
components/sanity/sources/new-document-event/test-event.mjs

[high] 11-11: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 14-14: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ 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: Lint Code Base
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (11)
components/sanity/package.json (1)

3-3: LGTM!

The version bump to 0.1.0 is appropriate for the addition of new actions and sources. The @pipedream/platform dependency is correctly included.

Also applies to: 15-17

components/sanity/sources/new-document-event/test-event.mjs (1)

1-24: LGTM! Static analysis false positive.

The test event structure is valid for a Sanity document. The static analysis warnings about "Generic API Keys" on lines 11 and 14 are false positives—these are Sanity document _key identifiers (e.g., EvPfkr19v0Rx2q9dajuwVI), not sensitive credentials.

components/sanity/actions/get-document/get-document.mjs (1)

1-42: LGTM!

The action is well-structured with proper prop definitions and dependencies. The documentId prop correctly depends on the dataset prop for dynamic option loading.

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

1-1: No issues found. The API version is current and recommended.

The API version "v2025-02-19" is the latest stable Sanity API version as of November 19, 2025 and is the version shown in official Sanity documentation as the default. The code is properly configured.

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

33-91: Fix webhook base URL — critical issue found.

The webhook endpoints will fail because they use the wrong base URL. Webhooks management API requires https://api.sanity.io/{apiVersion}/hooks/projects/{projectId}/..., but the code's _baseUrl() method constructs https://{projectId}.api.sanity.io/{version} for all requests.

Lines 51-66 (createWebhook, deleteWebhook): These methods need a different base URL construction. Either:

  • Create a separate method for webhook base URLs, or
  • Pass the correct base URL as a parameter to _makeRequest()

Example fix:

_webhookBaseUrl(version = API_VERSION) {
  return `https://api.sanity.io/${version}`;
}

Then use it in webhook methods:

createWebhook(opts = {}) {
  return this._makeRequest({
    baseUrl: this._webhookBaseUrl(),
    path: `/hooks/projects/${this._projectId()}`,
    method: "POST",
    ...opts,
  });
}

The other endpoints (/data/doc, /data/query, /data/actions) are correct and match the API documentation.

⛔ Skipped due to learnings
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12697
File: components/salesforce_rest_api/sources/common-webhook-methods.mjs:1-71
Timestamp: 2024-07-24T02:06:47.016Z
Learning: The `common-webhook-methods.mjs` object is designed to be extended, similar to an abstract class, and intentionally does not implement certain methods like `generateWebhookMeta` and `getEventType` to enforce implementation in subclasses.
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12697
File: components/salesforce_rest_api/sources/common-webhook-methods.mjs:1-71
Timestamp: 2024-10-08T15:33:38.240Z
Learning: The `common-webhook-methods.mjs` object is designed to be extended, similar to an abstract class, and intentionally does not implement certain methods like `generateWebhookMeta` and `getEventType` to enforce implementation in subclasses.
components/sanity/actions/create-document/create-document.mjs (3)

1-15: LGTM! Clean imports and metadata.

The imports are appropriate, and the metadata follows Pipedream conventions with clear documentation linking to Sanity's HTTP reference.


16-34: Excellent documentation in the document prop.

The comprehensive example in the description clearly demonstrates the expected structure including required fields and nested objects.


35-39: Good validation logic.

Properly validates required fields before making the API call, providing a clear error message to users.

components/sanity/sources/common/base.mjs (3)

6-24: LGTM! Standard webhook props.

The props are well-structured for webhook sources, with customResponse: true properly enabling manual response handling in the run method.


25-38: Appropriate base class pattern.

The placeholder methods that throw ConfigurationError follow the expected pattern for base modules, enforcing implementation in derived sources.

Based on learnings


39-61: Well-structured webhook lifecycle management.

The activate/deactivate hooks properly manage webhook creation and cleanup, with safe deletion checking for the stored hook ID.

jcortes
jcortes previously approved these changes Nov 20, 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 @michelle0927 lgtm! Ready for QA!

@vunguyenhung
Copy link
Collaborator

For Integration QA:

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

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f07d31b and 8381c8e.

📒 Files selected for processing (1)
  • components/sanity/actions/create-document/create-document.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".

Applied to files:

  • components/sanity/actions/create-document/create-document.mjs
🧬 Code graph analysis (1)
components/sanity/actions/create-document/create-document.mjs (3)
components/sanity/actions/query-dataset/query-dataset.mjs (1)
  • response (30-36)
components/sanity/actions/get-document/get-document.mjs (1)
  • response (33-37)
components/sanity/common/utils.mjs (1)
  • parseObject (1-27)
⏰ 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: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (3)
components/sanity/actions/create-document/create-document.mjs (3)

1-2: LGTM: Imports are clean and necessary.

Both imports are used appropriately in the code.


4-14: LGTM: Action metadata is well-configured.

The annotations correctly reflect that this action creates data via external API calls.


15-22: LGTM: Standard Pipedream prop definitions.

Using propDefinition for dataset is the correct pattern for reusing app-level prop logic.

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] Sanity.io

4 participants