Skip to content

Conversation

@GTFalcao
Copy link
Collaborator

@GTFalcao GTFalcao commented Sep 8, 2025

Closes #18212
Closes #18305

Summary by CodeRabbit

  • New Features

    • Broad support for Notion Data Sources across actions, triggers, and app UI (query, retrieve, update, create, list).
    • Added Data Source-specific constants and event summaries.
  • Refactor

    • Terminology shifted from “Database” to “Data Source” throughout the Notion integration, including inputs and labels.
    • Upgraded Notion API usage and client version.
  • Documentation

    • Updated guides and descriptions to reflect Data Source concepts.
  • Chores

    • Version bumps across multiple Notion actions/sources.
    • Package version raised to 1.0.0; Notion client dependency updated.

@vercel
Copy link

vercel bot commented Sep 8, 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 Sep 11, 2025 3:47am
pipedream-docs-redirect-do-not-edit Ignored Ignored Sep 11, 2025 3:47am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 8, 2025

Caution

Review failed

The head commit changed during the review from 85169c4 to f979469.

Walkthrough

Refactors the Notion integration from “database” to “data source” terminology and APIs, updating core app methods, constants, meta builders, actions, and sources. Includes version and metadata bumps across multiple modules, dependency upgrade to @notionhq/client ^5.0.0, and minor formatting fixes.

Changes

Cohort / File(s) Summary
Formatting only
components/apimage/apimage.app.mjs, components/devin/devin.app.mjs
Added trailing newlines; no functional changes.
Notion core API shift
components/notion/notion.app.mjs, components/notion/package.json, components/notion/common/notion-meta-properties.mjs, components/notion/sources/common/base.mjs, components/notion/sources/common/constants.mjs
Renames database→data source across public methods/propDefinitions; updates client version to 2025-09-03; dependency bump to @notionhq/client ^5.0.0; meta mappings now use data_source_id; constants add DATA_SOURCE and DATA_SOURCE_ADDED; base meta generation supports DATA_SOURCE.
Notion base page builder
components/notion/actions/common/base-page-builder.mjs
Switches meta/link building from databases to data sources; renames helper methods and child block handling accordingly.
Actions: data source migration
components/notion/actions/create-page-from-database/create-page-from-database.mjs, components/notion/actions/create-database/create-database.mjs, components/notion/actions/query-database/query-database.mjs, components/notion/actions/retrieve-database-content/retrieve-database-content.mjs, components/notion/actions/retrieve-database-schema/retrieve-database-schema.mjs, components/notion/actions/update-database/update-database.mjs, components/notion/actions/update-page/update-page.mjs, components/notion/actions/create-page-from-database/README.md
Renames names/props/docs from database→data source; updates runtime calls (e.g., queryDataSource, retrieveDataSource, updateDataSource); payload shapes adjusted where applicable (e.g., initial_data_source for create database); versions bumped.
Sources: data source migration
components/notion/sources/new-database/new-database.mjs, components/notion/sources/new-page/new-page.mjs, components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs, components/notion/sources/updated-page/updated-page.mjs, components/notion/sources/page-properties-updated-instant/page-properties-updated-instant.mjs
Switch triggers from database→data source; rename props to dataSourceId; update retrieval/query paths and parent checks; versions and descriptions updated.
Actions: version/metadata only
components/notion/actions/append-block/append-block.mjs, .../complete-file-upload/complete-file-upload.mjs, .../create-comment/create-comment.mjs, .../create-file-upload/create-file-upload.mjs, .../create-page/create-page.mjs, .../delete-block/delete-block.mjs, .../duplicate-page/duplicate-page.mjs, .../list-all-users/list-all-users.mjs, .../list-file-uploads/list-file-uploads.mjs, .../retrieve-block/retrieve-block.mjs, .../retrieve-file-upload/retrieve-file-upload.mjs, .../retrieve-page-property-item/retrieve-page-property-item.mjs, .../retrieve-page/retrieve-page.mjs, .../retrieve-user/retrieve-user.mjs, .../search/search.mjs
Bump versions and/or update names/descriptions (search now “Data Sources”); no logic changes.
Sources: version only
components/notion/sources/new-comment-created/new-comment-created.mjs, components/notion/sources/new-webhook-event-instant/new-webhook-event-instant.mjs, components/notion/sources/page-or-subpage-updated/page-or-subpage-updated.mjs, components/notion/sources/updated-page-id/updated-page-id.mjs
Version bumps only; no logic changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Action as Create Page from Data Source
  participant Notion as Notion App
  participant API as Notion API

  User->>Action: Provide dataSourceId, title, properties, blocks
  Action->>Notion: retrieveDataSource(dataSourceId)
  Notion->>API: GET /v1/data_sources/{id}
  API-->>Notion: dataSource (schema)
  Notion-->>Action: dataSource
  Action->>Action: buildDataSourceMeta + buildPageProperties
  Action->>API: POST /v1/pages (parent: data_source_id, properties, children)
  API-->>Action: page
  Action-->>User: page (created)
Loading
sequenceDiagram
  autonumber
  actor User
  participant Action as Query Data Source
  participant Notion as Notion App
  participant API as Notion API

  User->>Action: Provide dataSourceId, filter, sorts
  Action->>Notion: queryDataSource(id, params)
  Notion->>API: POST /v1/data_sources/{id}/query
  API-->>Notion: results
  Notion-->>Action: results
  Action-->>User: results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • andrewjschuang
  • michelle0927
  • jcortes

Pre-merge checks (4 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description contains only "Closes #18212" and "Closes #18305" and does not follow the repository's required template (missing the "WHY" section and a concise summary), so it lacks a high-level rationale, breaking-change notes, migration/testing guidance, and links to the Notion upgrade guide. Please update the PR description to follow the template's "WHY" section with a short summary of what changed, explicit breaking changes (e.g., databaseId → dataSourceId and API endpoint renames), the Notion upgrade guide reference and date (2025-09-03), testing or rollout instructions, and any steps consumers must take.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Notion API Update" is concise and accurately reflects the primary purpose of this PR — migrating Notion integrations from database-centric endpoints to the new data_source API and related client updates — so it is relevant and easy for teammates to scan.
Linked Issues Check ✅ Passed The changes address the linked issues: for [#18212] the codebase-wide migration from databases to data_sources is implemented (prop and method renames, Notion client/version update, package.json dependency bump, and payloads updated to use data_source_id), and for [#18305] queryDatabase/databases.query usages were replaced with queryDataSource calls and corresponding method renames, which should resolve the reported TypeError.
Out of Scope Changes Check ✅ Passed Most edits are in-scope for the Notion API migration and bug fix; the only unrelated changes observed are trivial whitespace/newline additions in components/apimage and components/devin and several metadata-only version bumps, which are low-risk but not required by the linked issues.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

A hop, a bop, I bounce through source,
From databases to data source!
New lanes to query, pages bloom,
I thump my paw—make APIs zoom.
Carrots committed, versions high,
Ship it quick—then naps nearby. 🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch notion-api-update

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.

luancazarine
luancazarine previously approved these changes Sep 9, 2025
Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

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

Hi @GTFalcao, 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: 5

Caution

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

⚠️ Outside diff range comments (7)
components/notion/actions/search/search.mjs (1)

26-29: Fix grammar and migrate Notion search filter to data_source

  • File: components/notion/actions/search/search.mjs (lines 26–29) — apply this change:
-      return `Found ${response.results?.length} object${response.results?.length === 1
-        ? ""
-        : "s"} with query search ${this.title}`;
+      return `Found ${response.results?.length} object${response.results?.length === 1 ? "" : "s"} for query "${this.title}"`;
  • Notion API v2025-09-03: search supports filtering by object: "data_source" and database-level filters are deprecated — update the search/filter handling to use data_source (or include a temporary fallback during migration).
components/notion/actions/common/base-page-builder.mjs (2)

80-88: Bug: falsy values (e.g., false, 0, empty string) get dropped when building selected props.

Use nullish coalescing, not ||, to preserve intentional falsy inputs (e.g., archived: false).

Apply:

-        .map((property) => ({
-          type: properties[property]?.type ?? property,
-          label: property,
-          value: this[property] || this.properties?.[property],
-        }));
+        .map((property) => ({
+          type: properties[property]?.type ?? property,
+          label: property,
+          value: (this[property] ?? this.properties?.[property]),
+        }));

96-103: Avoid emitting undefined meta/property entries when a converter is missing.

Currently, unknown keys become { key: undefined }, risking API errors. Guard before assignment.

Apply:

   _convertPropertiesToNotion(properties = [], NOTION_CONVERTER = {}) {
     const notionProperties = {};
     for (const property of properties) {
       const notionProperty = NOTION_CONVERTER[property.type];
-      notionProperties[property.label] = notionProperty?.convertToNotion(property);
+      if (notionProperty?.convertToNotion) {
+        const converted = notionProperty.convertToNotion(property);
+        if (converted !== undefined) {
+          notionProperties[property.label] = converted;
+        }
+      }
     }
     return notionProperties;
   },
components/notion/sources/updated-page/updated-page.mjs (2)

42-45: User-facing copy still says “database”.

Update the alert to “data source” for consistency.

Apply:

-      content: "Source not saving? Your database might be too large. If deployment takes longer than one minute, an error will occur.",
+      content: "Source not saving? Your data source might be too large. If deployment takes longer than one minute, an error will occur.",

80-84: Possible crash when state is missing/corrupted.

Buffer.from(compressed, "base64") will throw if compressed is falsy. Add a guard to return {}.

Apply:

   _getPropertyValues() {
-      const compressed = this.db.get("propertyValues");
-      const buffer = Buffer.from(compressed, "base64");
+      const compressed = this.db.get("propertyValues");
+      if (!compressed) return {};
+      const buffer = Buffer.from(compressed, "base64");
       const decompressed = zlib.inflateSync(buffer).toString();
       return JSON.parse(decompressed);
   },
components/notion/actions/update-page/update-page.mjs (1)

87-93: Do not include parent in PATCH updates — Notion API disallows changing a page’s parent

Notion (2025-09-03) does not allow changing a page’s parent via PATCH /v1/pages (you cannot set parent.data_source_id). Remove parent from the update meta produced by buildDataSourceMeta (components/notion/actions/update-page/update-page.mjs:87-93) or implement an explicit move/recreate flow when a parent/data-source change is required.

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

41-57: Remove top-level query from dataSources.query call; add client-side fallback

notion.dataSources.query (notion-sdk-js v5) does not accept a top-level string query — pass start_cursor/filter fields and filter results client-side.

File: components/notion/notion.app.mjs (lines 41-57)

-        const response = await this.queryDataSource(dataSourceId, {
-          query,
-          start_cursor: prevContext.nextPageParameters ?? undefined,
-        });
-        const options = this._extractPageTitleOptions(response.results);
-        return this._buildPaginatedOptions(options, response.next_cursor);
+        const params = {
+          start_cursor: prevContext.nextPageParameters ?? undefined,
+        };
+        const response = await this.queryDataSource(dataSourceId, params);
+        const results = query
+          ? response.results.filter((p) =>
+              this.extractPageTitle(p).toLowerCase().includes(query.toLowerCase()))
+          : response.results;
+        const options = this._extractPageTitleOptions(results);
+        return this._buildPaginatedOptions(options, response.next_cursor);
🧹 Nitpick comments (28)
components/notion/actions/retrieve-page/retrieve-page.mjs (1)

24-29: Make title extraction resilient to non-database pages and custom title property names.

Not all pages have a "Name" property (e.g., top-level/child pages or databases with renamed title prop). Prefer finding the first property of type "title" and fall back gracefully.

Apply:

   async run({ $ }) {
-    const response = await this.notion.retrievePage(this.pageId);
-    const title = response?.properties?.Name?.title[0]?.plain_text;
-    $.export("$summary", `Successfully retrieved page${title
-      ? ` "${title}"`
-      : ""}`);
+    const response = await this.notion.retrievePage(this.pageId);
+    const titleProp = Object.values(response?.properties || {}).find((p) => p?.type === "title");
+    const title = titleProp?.title?.[0]?.plain_text;
+    $.export("$summary", `Successfully retrieved page${title ? ` "${title}"` : ""}${response?.url ? ` (${response.url})` : ""}`);
     return response;
   },
components/notion/actions/append-block/append-block.mjs (3)

66-78: Protect against undefined blockTypes during prop reload.

blockTypes.includes(...) throws if blockTypes is unset on initial render. Default to an array and guard.

-  additionalProps(currentProps) {
-    const { blockTypes } = this;
+  additionalProps(currentProps) {
+    const blockTypes = Array.isArray(this.blockTypes) ? this.blockTypes : [];
@@
-    for (let prop of [
+    for (const prop of [
       "blockIds",
       "markdownContents",
       "imageUrls",
     ]) {
-      currentProps[prop].hidden = !blockTypes.includes(prop);
+      if (currentProps[prop]) {
+        currentProps[prop].hidden = !blockTypes.includes(prop);
+      }
     }

111-124: Light validation for image URLs.

Skip empty/whitespace entries and fail fast on invalid URLs to avoid 400s from Notion.

-      for (const url of this.imageUrls) {
+      for (const raw of this.imageUrls) {
+        const url = String(raw).trim();
+        if (!url) continue;
+        try { new URL(url); } catch { continue; } // or collect and warn
         children.push({
           type: "image",
           image: {
             type: "external",
             external: {
               url,
             },
           },
         });
       }

134-140: Add retry/backoff for rate limits.

Appending in chunks of 100 is correct, but Notion may return 429/409 under load. Wrap appendBlock with limited retries + exponential backoff.

components/notion/actions/complete-file-upload/complete-file-upload.mjs (1)

9-9: Version bump LGTM.

Consider surfacing response.status or upload state in the summary and handling 409/expired multipart sessions with a clearer error.

components/notion/actions/create-comment/create-comment.mjs (2)

36-39: Reject empty comments early.

Trim input and throw a config error if nothing remains.

   async run({ $ }) {
-    if ((this.pageId && this.discussionId) || (!this.pageId && !this.discussionId)) {
+    if ((this.pageId && this.discussionId) || (!this.pageId && !this.discussionId)) {
       throw new ConfigurationError("Provide either a page ID or a discussion thread ID to create the comment under");
     }
 
-    const response = await this.notion._getNotionClient().comments.create({
+    const text = (this.comment ?? "").trim();
+    if (!text) {
+      throw new ConfigurationError("Comment cannot be empty");
+    }
+    const response = await this.notion._getNotionClient().comments.create({
@@
-      rich_text: [
+      rich_text: [
         {
           text: {
-            content: this.comment,
+            content: text,
           },
         },
       ],

8-8: Route Notion comment/list calls through the app wrapper

Direct this.notion._getNotionClient() calls found — migrate to wrapper methods to avoid SDK upgrade breakage.

  • components/notion/actions/create-comment/create-comment.mjs — replace direct SDK create with wrapper:
-    const response = await this.notion._getNotionClient().comments.create({
+    const response = await this.notion.createComment({
       parent: this.pageId && {
         page_id: this.pageId,
       },
       discussion_id: this.discussionId,
       rich_text: [
         {
           text: {
-            content: this.comment,
+            content: this.comment,
           },
         },
       ],
     });
  • components/notion/sources/new-comment-created/new-comment-created.mjs — replace this.notion._getNotionClient().comments.list(...) with this.notion.listComments(...).

  • Add wrapper methods to components/notion/notion.app.mjs if missing:

async createComment(payload) { return this._getNotionClient().comments.create(payload); }
async listComments(opts = {}) { return this._getNotionClient().comments.list(opts); }
components/notion/actions/update-block/update-block.mjs (1)

30-36: Harden parsing and surface helpful errors for invalid JSON.

Wrap parseObject to provide a user-facing error when content isn’t valid JSON.

+import { ConfigurationError } from "@pipedream/platform";
@@
   async run({ $ }) {
-    const response = await this.notion.updateBlock({
-      block_id: this.blockId,
-      ...utils.parseObject(this.content),
-    });
+    let parsed;
+    try {
+      parsed = utils.parseObject(this.content);
+    } catch (err) {
+      throw new ConfigurationError(`Invalid JSON in "Content": ${err.message}`);
+    }
+    const response = await this.notion.updateBlock({
+      block_id: this.blockId,
+      ...parsed,
+    });
components/notion/actions/retrieve-block/retrieve-block.mjs (1)

53-57: Avoid possible undefined access on children.

Use optional chaining to guard .length.

-    $.export("$summary", `Successfully retrieved block${shouldRetrieveChildren
-      ? ` with ${block.children.length ?? 0} ${subpagesOnly
+    $.export("$summary", `Successfully retrieved block${shouldRetrieveChildren
+      ? ` with ${block.children?.length ?? 0} ${subpagesOnly
         ? "sub-pages"
         : "children"}`
       : ""}`);
components/notion/actions/send-file-upload/send-file-upload.mjs (2)

26-28: Generalize UI text from “Image” to “File”.

This action uploads arbitrary files, not just images. Minor copy tweak improves accuracy.

-      label: "Image File Path or URL",
-      description: "The image to process. Provide either a file URL or a path to a file in the `/tmp` directory (for example, `/tmp/myImage.jpg`).",
+      label: "File Path or URL",
+      description: "Provide either a file URL or a path to a file in the `/tmp` directory (for example, `/tmp/my-file.bin`).",

59-59: Fix summary wording to match action behavior.

-    $.export("$summary", `Successfully created file upload with ID ${response.id}`);
+    $.export("$summary", `Successfully sent file upload with ID ${response.id}`);
components/notion/sources/new-comment-created/new-comment-created.mjs (1)

61-63: Avoid reprocessing items on equal timestamps.
Use > instead of >= to prevent scanning items at the exact lastTs again on the next run. Dedupe helps, but skipping work is cleaner.

-        if (ts >= lastTs) {
+        if (ts > lastTs) {
components/notion/sources/common/base.mjs (1)

29-53: Guard against invalid or missing timestamps to avoid NaN keys.
If obj[timestamp] is missing or unparsable, Date.parse returns NaN, producing IDs like id-NaN and an invalid ts. Add a safe fallback.

-    generateMeta(obj, type, timestamp, summary, isUpdate = false) {
-      let title;
-      let {
-        id,
-        [timestamp]: lastTime,
-      } = obj;
-      const ts = Date.parse(lastTime);
+    generateMeta(obj, type, timestamp, summary, isUpdate = false) {
+      let title;
+      let { id } = obj;
+      const lastTime =
+        obj?.[timestamp] ?? obj?.created_time ?? obj?.last_edited_time ?? null;
+      const parsedTs = Date.parse(lastTime ?? "");
+      const ts = Number.isNaN(parsedTs) ? Date.now() : parsedTs;
@@
-      if (type === constants.types.DATABASE || type === constants.types.DATA_SOURCE) {
+      if (type === constants.types.DATABASE || type === constants.types.DATA_SOURCE) {
         title = this.notion.extractDataSourceTitle(obj);
       } else {
         title = this.notion.extractPageTitle(obj);
         // Create composite ID so update events for the same page have unique keys
         // See https://pipedream.com/docs/components/api/#emit
         if (isUpdate) {
-          id = `${id}-${ts}`;
+          id = `${id}-${ts}`;
         }
       }
@@
       return {
         id,
         summary: `${summary}: ${title || id}`,
-        ts,
+        ts,
       };
components/notion/actions/create-database/create-database.mjs (1)

40-48: Avoid sending an empty title payload when title is unset.
If title is undefined, sending a rich text object with undefined content can 400. Make the field conditional.

-      title: [
-        {
-          type: "text",
-          text: {
-            content: this.title,
-          },
-        },
-      ],
+      title: this.title
+        ? [{
+            type: "text",
+            text: { content: this.title },
+          }]
+        : undefined,
components/notion/actions/create-page-from-database/README.md (2)

13-13: Minor style: hyphenation.
Use “4‑minute” and simplify the note.

-[Follow this short 4 minute guide to connect your Notion account and add new Data Source pages] ...
+[Follow this short 4‑minute guide to connect your Notion account and add new data source pages] ...

3-8: Ensure datasource naming is consistent across the doc.
Double-check capitalization and plurality (Data Source vs data source) per your style guide.

components/notion/common/notion-meta-properties.mjs (1)

5-6: Update header comment to Data Source-first to avoid confusion.
Reflect the primary entity this module targets.

- * Implementation for Database Meta in Notion - https://developers.notion.com/reference/database
- * See also Data Sources - https://developers.notion.com/reference/data-source
+ * Implementation for Data Source Meta in Notion - https://developers.notion.com/reference/data-source
+ * See also Database container docs - https://developers.notion.com/reference/database
components/notion/sources/page-properties-updated-instant/page-properties-updated-instant.mjs (2)

68-76: Tighten property change detection.
Use a Set and some() to short‑circuit.

-      let propertyHasChanged = false;
-      for (const propertyName of updatedProperties) {
-        if (!this.properties || this.properties.includes(propertyName)) {
-          propertyHasChanged = true;
-        }
-      }
+      const selected = this.properties ? new Set(this.properties) : null;
+      const propertyHasChanged = !selected
+        ? true
+        : updatedProperties.some((p) => selected.has(p));

20-38: Optionally avoid noisy logs on options() errors.
Consider this.logger.debug or a shorter message to reduce console noise in user runs.

components/notion/actions/common/base-page-builder.mjs (2)

105-113: Minimize mutation and harden meta conversion for data sources.

Small refactor: avoid mutating properties in-place and reuse the new guarded converter.

Apply:

-  _buildNotionDataSourceMeta(properties = []) {
-    properties.forEach((property) => property.type = property.label);
-    return this._convertPropertiesToNotion(properties, NOTION_DATA_SOURCE_META);
-  },
+  _buildNotionDataSourceMeta(properties = []) {
+    const typed = properties.map((p) => ({ ...p, type: p.label }));
+    return this._convertPropertiesToNotion(typed, NOTION_DATA_SOURCE_META);
+  },

170-188: Nit: make video type detection case-insensitive and robust to query strings.

Lowercase the extension and strip query/fragment to avoid false negatives.

Apply:

-      const extension = url.split(".").pop();
+      const clean = url.split("?")[0].split("#")[0];
+      const extension = clean.split(".").pop()?.toLowerCase();
components/notion/actions/retrieve-database-content/retrieve-database-content.mjs (1)

19-23: Optional: include the data source ID in the summary for easier debugging.

Apply:

-    $.export("$summary", `Successfully retrieved ${results.length} object${results.length === 1
-      ? ""
-      : "s"} in data source`);
+    $.export("$summary", `Successfully retrieved ${results.length} object${results.length === 1 ? "" : "s"} in data source ${this.dataSourceId}`);
components/notion/actions/update-database/update-database.mjs (2)

44-46: Handle missing plain_text vs text.content gracefully when deriving defaults.

Use plain_text if available, falling back to text.content.

Apply:

-      props.title.default = dataSource.title.map((text) => text.text.content).join(" ");
-      props.description.default = dataSource.description.map((text) => text.plain_text).join(" ");
+      const toPlain = (rt) => rt.plain_text ?? rt.text?.content ?? "";
+      props.title.default = dataSource.title.map(toPlain).join(" ").trim();
+      props.description.default = dataSource.description.map(toPlain).join(" ").trim();

57-74: Only send fields that the user set (avoid empty updates and undefined values).

Build the payload conditionally; it also keeps existing values untouched if omitted.

Apply:

-    const response = await this.notion.updateDataSource({
-      data_source_id: this.dataSourceId,
-      title: [
-        {
-          text: {
-            content: this.title,
-          },
-        },
-      ],
-      description: [
-        {
-          text: {
-            content: this.description,
-          },
-        },
-      ],
-      properties: utils.parseObject(this.properties),
-    });
+    const payload = { data_source_id: this.dataSourceId };
+    if (this.title != null) {
+      payload.title = [{ text: { content: this.title } }];
+    }
+    if (this.description != null) {
+      payload.description = [{ text: { content: this.description } }];
+    }
+    const parsedProps = utils.parseObject(this.properties);
+    if (parsedProps && Object.keys(parsedProps).length) {
+      payload.properties = parsedProps;
+    }
+    const response = await this.notion.updateDataSource(payload);
components/notion/actions/create-page-from-database/create-page-from-database.mjs (2)

26-26: Minor copy nit

“Use this only if the data source has a title property named Name.” Consider hinting that otherwise they should set the title via Properties. Current text implies it, but a direct pointer reduces confusion.

- description: "The name of the page. Use this only if the data source has a `title` property named `Name`. Otherwise, use the `Properties` prop below to set the title property.",
+ description: "Use only if the data source’s title property is named `Name`. Otherwise, set the title via `Properties`.",

81-93: Chunked block append is correct; consider soft retries

Appending in 100-block chunks matches Notion limits. Optional: add light retry/backoff for 429s to improve reliability on large payloads.

-    while (remainingBlocks.length > 0) {
-      await this.notion.appendBlock(response.id, remainingBlocks.slice(0, MAX_BLOCKS));
+    while (remainingBlocks.length > 0) {
+      const chunk = remainingBlocks.slice(0, MAX_BLOCKS);
+      // Optional: simple backoff on rate-limit
+      try {
+        await this.notion.appendBlock(response.id, chunk);
+      } catch (err) {
+        if (err?.status === 429) {
+          await new Promise((r) => setTimeout(r, 1000));
+          await this.notion.appendBlock(response.id, chunk);
+        } else {
+          throw err;
+        }
+      }
-      remainingBlocks = remainingBlocks.slice(MAX_BLOCKS);
+      remainingBlocks = remainingBlocks.slice(MAX_BLOCKS);
     }
components/notion/notion.app.mjs (2)

106-111: Context check message can be misleading

When parentType !== "data_source", parentId is a page ID. Suggest dynamic label to reduce confusion.

-        this._checkOptionsContext(parentId, "Data Source ID");
+        this._checkOptionsContext(parentId, parentType === "data_source" ? "Data Source ID" : "Page ID");

269-277: listDataSources via search filter

Logic is coherent with the migration; same verification caveat on "data_source" as object type.

Consider adding page_size to reduce round trips when building dropdowns:

-      return this._getNotionClient().search({
+      return this._getNotionClient().search({
         filter: {
           property: "object",
           value: "data_source",
         },
-        ...params,
+        page_size: 100,
+        ...params,
       });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 212cd8b and a50e854.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (42)
  • components/apimage/apimage.app.mjs (1 hunks)
  • components/devin/devin.app.mjs (1 hunks)
  • components/notion/actions/append-block/append-block.mjs (1 hunks)
  • components/notion/actions/common/base-page-builder.mjs (6 hunks)
  • components/notion/actions/complete-file-upload/complete-file-upload.mjs (1 hunks)
  • components/notion/actions/create-comment/create-comment.mjs (1 hunks)
  • components/notion/actions/create-database/create-database.mjs (2 hunks)
  • components/notion/actions/create-file-upload/create-file-upload.mjs (1 hunks)
  • components/notion/actions/create-page-from-database/README.md (2 hunks)
  • components/notion/actions/create-page-from-database/create-page-from-database.mjs (3 hunks)
  • components/notion/actions/create-page/create-page.mjs (1 hunks)
  • components/notion/actions/delete-block/delete-block.mjs (1 hunks)
  • components/notion/actions/duplicate-page/duplicate-page.mjs (1 hunks)
  • components/notion/actions/list-all-users/list-all-users.mjs (1 hunks)
  • components/notion/actions/list-file-uploads/list-file-uploads.mjs (1 hunks)
  • components/notion/actions/query-database/query-database.mjs (2 hunks)
  • components/notion/actions/retrieve-block/retrieve-block.mjs (1 hunks)
  • components/notion/actions/retrieve-database-content/retrieve-database-content.mjs (1 hunks)
  • components/notion/actions/retrieve-database-schema/retrieve-database-schema.mjs (1 hunks)
  • components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs (1 hunks)
  • components/notion/actions/retrieve-page-property-item/retrieve-page-property-item.mjs (1 hunks)
  • components/notion/actions/retrieve-page/retrieve-page.mjs (1 hunks)
  • components/notion/actions/retrieve-user/retrieve-user.mjs (1 hunks)
  • components/notion/actions/search/search.mjs (1 hunks)
  • components/notion/actions/send-file-upload/send-file-upload.mjs (1 hunks)
  • components/notion/actions/update-block/update-block.mjs (1 hunks)
  • components/notion/actions/update-database/update-database.mjs (3 hunks)
  • components/notion/actions/update-page/update-page.mjs (4 hunks)
  • components/notion/common/notion-meta-properties.mjs (3 hunks)
  • components/notion/notion.app.mjs (9 hunks)
  • components/notion/package.json (2 hunks)
  • components/notion/sources/common/base.mjs (1 hunks)
  • components/notion/sources/common/constants.mjs (1 hunks)
  • components/notion/sources/new-comment-created/new-comment-created.mjs (1 hunks)
  • components/notion/sources/new-database/new-database.mjs (1 hunks)
  • components/notion/sources/new-page/new-page.mjs (2 hunks)
  • components/notion/sources/new-webhook-event-instant/new-webhook-event-instant.mjs (1 hunks)
  • components/notion/sources/page-or-subpage-updated/page-or-subpage-updated.mjs (1 hunks)
  • components/notion/sources/page-properties-updated-instant/page-properties-updated-instant.mjs (3 hunks)
  • components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs (2 hunks)
  • components/notion/sources/updated-page-id/updated-page-id.mjs (1 hunks)
  • components/notion/sources/updated-page/updated-page.mjs (5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-19T09:02:18.222Z
Learnt from: nurul3101
PR: PipedreamHQ/pipedream#18092
File: components/prisma_management_api/README.md:24-31
Timestamp: 2025-08-19T09:02:18.222Z
Learning: In Prisma Management API documentation, the "Create Database" section title is intentional and should not be changed to "Create Project", even though the action technically creates a complete project with database. This naming choice follows user-facing terminology preferences.

Applied to files:

  • components/notion/actions/create-database/create-database.mjs
🧬 Code graph analysis (12)
components/notion/sources/new-database/new-database.mjs (2)
components/notion/notion.app.mjs (7)
  • params (356-359)
  • params (385-385)
  • response (15-17)
  • response (30-36)
  • response (50-53)
  • response (64-64)
  • response (360-360)
components/notion/sources/new-page/new-page.mjs (4)
  • params (37-45)
  • lastCreatedTimestamp (32-32)
  • meta (60-65)
  • lastCreatedTime (69-69)
components/notion/actions/retrieve-database-schema/retrieve-database-schema.mjs (4)
components/notion/notion.app.mjs (6)
  • notion (421-421)
  • response (15-17)
  • response (30-36)
  • response (50-53)
  • response (64-64)
  • response (360-360)
components/notion/sources/new-database/new-database.mjs (1)
  • response (26-26)
components/notion/actions/query-database/query-database.mjs (1)
  • response (34-37)
components/notion/actions/update-database/update-database.mjs (1)
  • response (57-74)
components/notion/sources/new-page/new-page.mjs (2)
components/notion/sources/updated-page/updated-page.mjs (4)
  • pagesStream (54-54)
  • pagesStream (153-153)
  • params (53-53)
  • params (142-150)
components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs (2)
  • pagesStream (62-62)
  • params (52-60)
components/notion/actions/create-page-from-database/create-page-from-database.mjs (2)
components/notion/actions/create-page/create-page.mjs (3)
  • meta (55-55)
  • properties (58-58)
  • parentPage (90-90)
components/notion/actions/update-page/update-page.mjs (2)
  • meta (88-88)
  • properties (89-89)
components/notion/actions/common/base-page-builder.mjs (2)
components/notion/actions/create-page-from-database/create-page-from-database.mjs (2)
  • properties (70-70)
  • children (71-71)
components/notion/common/notion-meta-properties.mjs (2)
  • NOTION_DATA_SOURCE_META (9-40)
  • NOTION_DATA_SOURCE_META (9-40)
components/notion/actions/update-database/update-database.mjs (4)
components/notion/notion.app.mjs (6)
  • notion (421-421)
  • response (15-17)
  • response (30-36)
  • response (50-53)
  • response (64-64)
  • response (360-360)
components/notion/sources/new-database/new-database.mjs (1)
  • response (26-26)
components/notion/actions/query-database/query-database.mjs (1)
  • response (34-37)
components/notion/actions/retrieve-database-schema/retrieve-database-schema.mjs (1)
  • response (19-19)
components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs (3)
components/notion/notion.app.mjs (3)
  • notion (421-421)
  • params (356-359)
  • params (385-385)
components/notion/sources/new-page/new-page.mjs (2)
  • pagesStream (49-49)
  • params (37-45)
components/notion/sources/updated-page/updated-page.mjs (4)
  • pagesStream (54-54)
  • pagesStream (153-153)
  • params (53-53)
  • params (142-150)
components/notion/sources/common/base.mjs (4)
components/notion/notion.app.mjs (2)
  • title (227-230)
  • title (241-244)
components/notion/sources/page-properties-updated-instant/page-properties-updated-instant.mjs (1)
  • title (44-44)
components/notion/sources/updated-page/updated-page.mjs (2)
  • title (113-113)
  • obj (112-112)
components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs (2)
  • title (33-33)
  • obj (32-32)
components/notion/actions/update-page/update-page.mjs (2)
components/notion/actions/create-page/create-page.mjs (3)
  • meta (55-55)
  • page (91-91)
  • page (94-96)
components/notion/actions/create-page-from-database/create-page-from-database.mjs (2)
  • meta (68-68)
  • page (82-84)
components/notion/actions/query-database/query-database.mjs (2)
components/notion/notion.app.mjs (6)
  • notion (421-421)
  • response (15-17)
  • response (30-36)
  • response (50-53)
  • response (64-64)
  • response (360-360)
components/notion/actions/retrieve-database-schema/retrieve-database-schema.mjs (1)
  • response (19-19)
components/notion/sources/updated-page/updated-page.mjs (3)
components/notion/notion.app.mjs (3)
  • notion (421-421)
  • params (356-359)
  • params (385-385)
components/notion/sources/new-page/new-page.mjs (2)
  • pagesStream (49-49)
  • params (37-45)
components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs (2)
  • pagesStream (62-62)
  • params (52-60)
components/notion/notion.app.mjs (4)
components/notion/sources/new-database/new-database.mjs (2)
  • response (26-26)
  • params (22-22)
components/notion/actions/query-database/query-database.mjs (1)
  • response (34-37)
components/notion/actions/retrieve-database-schema/retrieve-database-schema.mjs (1)
  • response (19-19)
components/notion/actions/update-database/update-database.mjs (1)
  • response (57-74)
⏰ 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 (78)
components/notion/actions/retrieve-page/retrieve-page.mjs (2)

7-7: Patch version bump looks good.

No functional changes; safe metadata bump from 0.0.11 → 0.0.12.


1-31: No change required — retrievePage already delegates to pages.retrieve

components/notion/notion.app.mjs implements async retrievePage(pageId) and returns this._getNotionClient().pages.retrieve(...), so the call maps to pages.retrieve and is not impacted by the databases→data_sources rename (see components/notion/notion.app.mjs around lines ~321–322).

components/notion/actions/append-block/append-block.mjs (1)

10-10: Version bump LGTM — repo scan shows no .databases.query usages.

Scanned the repo with ripgrep: no matches for .databases.query(; Notion client now uses dataSources.query in components/notion/notion.app.mjs.

  • Remaining direct _getNotionClient() calls that bypass the app wrapper: components/notion/sources/new-comment-created/new-comment-created.mjs, components/notion/actions/create-comment/create-comment.mjs — consider routing these through the app methods if needed.
components/apimage/apimage.app.mjs (1)

11-11: Trailing newline only — LGTM.

components/notion/actions/update-block/update-block.mjs (1)

10-10: Version bump LGTM.

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

11-11: Trailing newline only — LGTM.

components/notion/actions/retrieve-block/retrieve-block.mjs (1)

7-7: Version bump LGTM.

components/notion/actions/retrieve-user/retrieve-user.mjs (1)

7-7: Version bump LGTM.

components/notion/actions/send-file-upload/send-file-upload.mjs (1)

11-11: Version bump only — LGTM.

No functional changes. Safe to merge.

components/notion/actions/retrieve-page-property-item/retrieve-page-property-item.mjs (1)

7-7: Version bump only — LGTM.

No logic changes detected.

components/notion/actions/create-file-upload/create-file-upload.mjs (1)

9-9: Version bump only — LGTM.

Matches the coordinated release across Notion actions.

components/notion/actions/create-page/create-page.mjs (2)

10-10: Version bump only — LGTM.


1-109: ```shell
#!/bin/bash
set -euo pipefail

echo "=== Env ==="
pwd
id -un || true
uname -a || true
echo
echo "rg version:"
rg --version 2>/dev/null || echo "rg not installed"
echo "git version:"
git --version 2>/dev/null || echo "git not available"
echo

echo "=== Top-level files ==="
ls -la | sed -n '1,200p' || true
echo

echo "=== Repo status (if a git repo) ==="
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Branch: $(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
echo "Recent commits:"
git log -n 3 --pretty=oneline || true
else
echo "Not inside a git work tree."
fi
echo

Robust ripgrep args to force searching all files (including those normally ignored)

RGARGS=(-nP -C2 -S --hidden -uu --glob '!.git/' --glob '!node_modules/')

echo "=== Legacy Notion database API usages ==="
echo "Searching for .databases.query..."
rg "${RGARGS[@]}" '.databases\s*.\s*query\b' || true

echo "Searching for retrieveDatabase | listDatabases | queryDatabase ..."
rg "${RGARGS[@]}" '\bretrieveDatabase\b|\blistDatabases\b|\bqueryDatabase\b' || true

echo "Searching for databaseId tokens..."
rg "${RGARGS[@]}" '\bdatabaseId\b' || true

echo
echo "=== New data source API usages ==="
rg "${RGARGS[@]}" '\bqueryDataSource\b|\bretrieveDataSource\b|\blistDataSources\b|\bdata_source(s)?\b|\bdataSourceId\b' || true

echo
echo "=== Fallback: search only tracked files (git ls-files) ==="
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
git ls-files | rg -nP -C2 '.databases\s*.\s*query\b|\bretrieveDatabase\b|\blistDatabases\b|\bqueryDatabase\b|\bdatabaseId\b|\bqueryDataSource\b|\bretrieveDataSource\b|\blistDataSources\b|\bdata_source(s)?\b|\bdataSourceId\b' || true
fi

echo
echo "=== package.json files & @notionhq/client occurrences ==="

Find package.json files

pkg_files=$(find . -type f -name package.json -print 2>/dev/null || true)
if [ -z "$pkg_files" ]; then
echo "No package.json found"
else
for f in $pkg_files; do
echo "---- $f ----"
if command -v jq >/dev/null 2>&1; then
jq '.name, .version, .dependencies, .devDependencies, .peerDependencies' "$f" || sed -n '1,200p' "$f"
else
sed -n '1,200p' "$f"
fi
echo
echo "Searching for @notionhq/client in this file's directory..."
rg -n --hidden -uu --glob '!.git/' --glob '!node_modules/' '"@notionhq/client"' "$(dirname "$f")" || true
done
fi

echo
echo "=== Done ==="


</blockquote></details>
<details>
<summary>components/notion/sources/new-webhook-event-instant/new-webhook-event-instant.mjs (1)</summary><blockquote>

`9-9`: **Version bump only — LGTM.**

</blockquote></details>
<details>
<summary>components/notion/actions/delete-block/delete-block.mjs (1)</summary><blockquote>

`9-9`: **Version bump only — LGTM.**

</blockquote></details>
<details>
<summary>components/notion/actions/duplicate-page/duplicate-page.mjs (1)</summary><blockquote>

`10-10`: **Version bump only — LGTM.**

</blockquote></details>
<details>
<summary>components/notion/sources/page-or-subpage-updated/page-or-subpage-updated.mjs (1)</summary><blockquote>

`10-10`: **Version bump only — LGTM.**

</blockquote></details>
<details>
<summary>components/notion/sources/new-comment-created/new-comment-created.mjs (2)</summary><blockquote>

`8-8`: **Version bump only — looks good.**
No functional changes. Safe to merge.

---

`49-55`: **No change required — notion.comments.list({ block_id }) is valid in @notionhq/client v5 (API 2025‑09‑03).** Verified the 2025‑09‑03 Notion API and client v5 still expose comments.list for listing by block/page; leave the call as-is. Optional: add a thin wrapper (e.g., notion.app.mjs → listCommentsForBlock) to insulate future SDK churn.

</blockquote></details>
<details>
<summary>components/notion/actions/list-all-users/list-all-users.mjs (1)</summary><blockquote>

`7-7`: **Version bump only — looks good.**
Runtime behavior unchanged.

</blockquote></details>
<details>
<summary>components/notion/actions/list-file-uploads/list-file-uploads.mjs (1)</summary><blockquote>

`9-9`: **Version bump only — looks good.**
No logic changes.

</blockquote></details>
<details>
<summary>components/notion/actions/retrieve-file-upload/retrieve-file-upload.mjs (1)</summary><blockquote>

`9-9`: **Version bump only — looks good.**
No functional changes.

</blockquote></details>
<details>
<summary>components/notion/sources/common/constants.mjs (1)</summary><blockquote>

`3-3`: **New DATA_SOURCE constants — looks consistent.**
The added `types.DATA_SOURCE` and `summaries.DATA_SOURCE_ADDED` align with the PR goals.



Also applies to: 9-9

</blockquote></details>
<details>
<summary>components/notion/sources/common/base.mjs (1)</summary><blockquote>

`37-39`: **extractDataSourceTitle exists — verify it handles both DATABASE and DATA_SOURCE shapes.**

Defined at components/notion/notion.app.mjs (~line 259) and called from components/notion/sources/common/base.mjs:38 — confirm _extractDataSourceTitleOptions / extractDataSourceTitle accept both Database and Data Source object shapes (or add normalization).

</blockquote></details>
<details>
<summary>components/notion/package.json (1)</summary><blockquote>

`3-3`: **SDK upgrade to @notionhq/client ^5 — verify migrations and remove old .databases.* usages**

- components/notion/notion.app.mjs:284 — still calls this._getNotionClient().databases.create(database). Confirm this is intentionally a database‑container operation (allowed under v5) or change to this._getNotionClient().dataSources.create(...) and return/use data_source_id.
- Update test fixtures that still use legacy fields: components/notion/sources/updated-page/test-event.mjs, components/notion/sources/updated-page-by-timestamp/test-event.mjs, components/notion/sources/new-page/test-event.mjs — replace database_id/type=database_id with data_source_id/type=data_source_id if they should match the new API.
- Search found no other .databases.(query|list|retrieve|update) usages in components; wrappers for listDataSources/retrieveDataSource/queryDataSource exist and are in use.

</blockquote></details>
<details>
<summary>components/notion/actions/search/search.mjs (1)</summary><blockquote>

`6-9`: **Rename to “Data Sources” — looks good.**
Metadata aligns with the broader terminology change.

</blockquote></details>
<details>
<summary>components/notion/sources/new-database/new-database.mjs (3)</summary><blockquote>

`8-11`: **Naming, docs URL, version, and info label updates look consistent.**
No issues spotted with the public surface changes.



Also applies to: 17-17

---

`39-47`: **Emission and watermarking logic LGTM after pagination fix.**
Reversal + CREATED_TIME-based meta and timestamp update are consistent with other sources.



Also applies to: 49-52

---

`9-10`: **Confirmed — Notion "Data Source" docs and fields are current (2025-09-03).** Docs include /reference/data-source and listing/management moved under /v1/data_sources (list-style endpoint exists); created_time remains the immutable ISO‑8601 creation timestamp.

</blockquote></details>
<details>
<summary>components/notion/actions/create-database/create-database.mjs (2)</summary><blockquote>

`9-10`: **Public description and version bump align with the API shift.**
Good clarity on initial data source.

---

`48-51`: **Confirmed: createDatabase supports initial_data_source.properties.**
Verified — Notion’s Create a database endpoint accepts an initial_data_source object with a properties field (same shape as data-source properties). Example payload sketch: {"parent":{"type":"page_id","page_id":"…"},"title":[{"type":"text","text":{"content":"My DB"}}],"initial_data_source":{"name":"Default","properties":{"Name":{"title":{}},"Status":{"select":{"options":[{"name":"Todo"},{"name":"Done"}]}},"Due":{"date":{}}}}} — see developers.notion.com (Create a database / Create a data source).

</blockquote></details>
<details>
<summary>components/notion/actions/create-page-from-database/README.md (1)</summary><blockquote>

`41-41`: **Copy/paste: mentions Slack instead of Notion.**
Correct the product name.


```diff
-...using any of the Slack actions within a Pipedream workflow.
+...using any of the Notion actions within a Pipedream workflow.

Likely an incorrect or invalid review comment.

components/notion/common/notion-meta-properties.mjs (2)

12-14: Parent mapping to data_source_id looks correct.
Matches the migration intent.


46-53: Spreading NOTION_DATA_SOURCE_META into NOTION_PAGE_META is fine here.
The parent override to page_id prevents leakage of the data_source parent mapping.

components/notion/sources/page-properties-updated-instant/page-properties-updated-instant.mjs (2)

14-19: Prop rename and options loader align with Data Source shape.
Using retrieveDataSource() to build property options is consistent.

Also applies to: 27-33


58-60: Gate by data_source_id: good.
This prevents cross‑datasource noise.

components/notion/sources/updated-page-id/updated-page-id.mjs (1)

10-10: Version bump only — OK.
No behavioral change.

components/notion/actions/retrieve-database-schema/retrieve-database-schema.mjs (3)

5-8: Rename to Data Source: LGTM.
Public name/description/version align with the migration.


11-16: Prop rename to dataSourceId: LGTM.
Consistent with other components.


19-21: Runtime path updated to retrieveDataSource — verified
rg shows only dataSource-based Notion calls (retrieveDataSource, queryDataSource, listDataSources, updateDataSource) under components/notion (e.g., components/notion/notion.app.mjs:278–293); no retrieveDatabase / databases.query / updateDatabase references remain.
Keep the action key stable for BC or add an alias if you plan to rename it.

components/notion/sources/new-page/new-page.mjs (4)

9-12: Public surface and prop rename: LGTM.
Consistent with other sources.

Also applies to: 15-20


36-46: Filtering and paging over data source pages looks correct.
The created_time filter mirrors other page sources; using getPages(this.dataSourceId, params) aligns with the migration.

Also applies to: 49-57


69-72: Watermark update logic: LGTM.
Updates lastCreatedTimestamp safely.


49-49: Resolved — getPages signature matches call sites. Function is defined as async *getPages(dataSourceId, opts = {}) in components/notion/notion.app.mjs, so calls using (this.dataSourceId, params) are valid.

components/notion/actions/common/base-page-builder.mjs (3)

3-5: Terminology migration looks correct (DATABASE → DATA SOURCE).

Importing NOTION_DATA_SOURCE_META aligns with the new meta converters and the rest of the PR.


137-140: LGTM: buildDataSourceMeta uses the new meta path.

The filtering and conversion chain aligns with the data source meta map.


239-242: LGTM: child_data_source mapping is consistent with the new block type.

Converting to a link avoids attempting to clone restricted blocks.

components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs (3)

9-12: Rename + version bump are appropriate for the breaking API change.


16-21: Prop rename to dataSourceId matches the new app surface.


62-62: Verified: getPages auto-paginates and callers provide descending last_edited_time sort

getPages is an async generator that paginates via start_cursor/next_cursor (components/notion/notion.app.mjs:352–371) and does not enforce sorts itself; lastUpdatedSortParam returns sorts with timestamp = LAST_EDITED_TIME and direction = DESCENDING (components/notion/sources/common/base.mjs:5–15,75–77); updated-page-by-timestamp passes that param into getPages (components/notion/sources/updated-page-by-timestamp/updated-page-by-timestamp.mjs:53–62), so the early break assuming descending last_edited_time is valid.

components/notion/actions/retrieve-database-content/retrieve-database-content.mjs (2)

5-8: Rename + version bump to data source are correct.


11-16: PropDefinition switch to dataSourceId aligns with app changes.

components/notion/actions/query-database/query-database.mjs (4)

6-9: Good: action clearly targets Data Sources and bumps version.


12-17: Prop rename to dataSourceId is consistent across the PR.


19-26: Docs updated to data-source filter/sort endpoints—nice.


34-37: Sanity check — ensure no lingering old database API calls (root cause of #18305).

Automated ripgrep in the sandbox produced no matches for databases.query / queryDatabase( / retrieveDatabase( / updateDatabase(. Run locally and paste the output of:

rg -n -C2 -e '\bdatabases\.query\b' -e '\bqueryDatabase\s*\(' -e '\bretrieveDatabase\s*\(' -e '\bupdateDatabase\s*\(' -- components | sed 's/^/LEFTOVER: /'
components/notion/actions/update-database/update-database.mjs (3)

8-11: Rename + version bump match the API change.


14-19: Prop rename to dataSourceId looks good.


76-77: Summary message reads well and matches the new entity.

components/notion/sources/updated-page/updated-page.mjs (4)

10-13: Rename + version bump are appropriate for the API shift.


17-22: Prop rename to dataSourceId is consistent.


33-36: Good: property picker now scopes to data source.


54-55: LGTM: switched to getPages(this.dataSourceId, params) in both activate and run.

Also applies to: 153-154

components/notion/actions/update-page/update-page.mjs (5)

10-10: Version bump to 2.0.0 matches the breaking prop surface.


19-27: Parent now references a data source—good alignment.


54-56: Property type scoping to data source is correct.


63-70: Good: additionalProps now reads from the data source to build dynamic inputs.


29-36: Confirm Notion propDefinition availability

pageIdInDataSource mapping in components/notion/actions/update-page/update-page.mjs (lines 29–36) passes { dataSourceId: c.parentDataSource } and appears correct. Confirm the Notion app exposes a propDefinition named "pageIdInDataSource" that accepts { dataSourceId } — repository search returned no matching definition.

components/notion/actions/create-page-from-database/create-page-from-database.mjs (4)

9-12: Rename + version bump look good

Public surface matches the data source migration; the major bump is appropriate.


15-22: Prop rename wired to data sources

Switch to parentDataSource with propDefinition: "dataSourceId" aligns with the new app API.

If you still have users selecting a database in existing workflows, confirm this action’s backward-compat behavior (key is unchanged, which is good). If needed, I can help author a short migration note shown in the UI.


32-32: Good schema guidance

The properties description is accurate and points to the right docs.


63-71: buildPage aligns with data source meta

buildDataSourceMeta and buildPageProperties(parentDataSource.properties) are consistent with the updated base builder.

Please confirm base.methods.buildPageProperties handles the separate Name prop when present (it likely does via this.Name). If not, I can provide a small patch.

components/notion/notion.app.mjs (6)

66-71: Parent type string: confirm data_source_id

For pages created before the migration, parent.type might still be database_id. Current logic gracefully falls back to response properties, but please confirm parent.type is indeed data_source_id post-upgrade.


198-205: Search filter label updated; verify backend accepts data_source

UI is fine; again, confirm the Notion Search filter supports "data_source" here; otherwise fall back to "database" for search.

-      options: [
-        "page",
-        "data_source",
-      ],
+      options: [ "page", "data_source" ], // fallback to "database" if needed

222-223: API version bump

Setting notionVersion: "2025-09-03" is required for these endpoints.


345-361: getPages generator updated correctly

Iterator now targets data sources and paginates using queryDataSource. Looks good.


10-21: dataSourceId prop + pagination wiring looks right; 'data_source' is NOT valid in Notion Search — update usage.

Notion Search filter "object" accepts only "page" or "database" (official Search docs, 2025-09-03). If you meant to enumerate data sources, call listDataSources; otherwise change any Search filter value from "data_source" to "database" or "page".

File: components/notion/notion.app.mjs Lines: 10-21 — check for Search filter usage and fix.


278-294: Approve — core data source methods look correct; no lingering databases. usages found*

Repo-wide ripgrep (-uu --hidden, excluding node_modules) found no occurrences of databases.query / databases.retrieve / databases.update; components/notion/notion.app.mjs (lines ~278–294) uses dataSources as expected.

Comment on lines +213 to 220
childDataSourceToLink(block) {
return {
object: "block",
type: "link_to_page",
link_to_page: {
type: "database_id",
database_id: block.id,
type: "data_source_id",
data_source_id: block.id,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm Notion supports link_to_page with data_source_id.

The new child type child_data_source likely maps to link_to_page: { type: "data_source_id", data_source_id }, but this API is very new. Please verify against the 2025‑09‑03 docs.


🌐 Web query:

Notion link_to_page supports which types as of 2025-09-03? Is `data_source_id` a valid type alongside `page_id` and `database_id`? Provide the exact docs section.

💡 Result:

Answer: As of 2025-09-03, the link_to_page block supports only type = "page_id" and type = "database_id". data_source_id is not listed as a valid link_to_page type. See the "Link to Page block type" section showing examples using page_id and database_id [1], and the 2025-09-03 changelog note about databases/data_sources (no change adding data_source_id to link_to_page) [2].

Sources:
[1] Notion Developers — "Synced Block, Link to Page and Template block types are now supported in the API" — Link to Page block type (example uses "type": "page_id" and mentions "database_id"). (developers.notion.com)
[2] Notion Developers — "Changes by version" (2025-09-03 entry describing /v1/databases → /v1/data_sources reorganization). (developers.notion.com)

Citations:


Replace/remove unsupported link_to_page type "data_source_id" — Notion docs (2025-09-03) list only "page_id" and "database_id".

File: components/notion/actions/common/base-page-builder.mjs
Lines: 213-220

    childDataSourceToLink(block) {
      return {
        object: "block",
        type: "link_to_page",
        link_to_page: {
          type: "data_source_id",
          data_source_id: block.id,
        },

Notion docs (Link to Page block type, 2025-09-03) do not list data_source_id; change this to use a supported type (page_id or database_id) or remove/replace the child_data_source code path and verify block.id maps to the chosen id.

🤖 Prompt for AI Agents
components/notion/actions/common/base-page-builder.mjs lines 213-220: The code
returns a link_to_page object with unsupported type "data_source_id"; update
this to a supported Notion type (either "page_id" or "database_id") or remove
the childDataSourceToLink path. Replace link_to_page.type with the chosen
supported type and rename the id property accordingly (e.g., use link_to_page: {
type: "page_id", page_id: block.id } or { type: "database_id", database_id:
block.id }), and ensure block.id actually contains the corresponding page or
database id; if block.id cannot be mapped reliably, remove/disable this code
path and add a comment explaining why.

The Notion Create Page from Data Source action allows you to add pages to a Notion Data Source.

This action features easy to use dropdowns that automatically populate your databases as well as your database's properties, also known as columns.
This action features easy to use dropdowns that automatically populate your data sources as well as your data sources's properties, also known as columns.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Grammar: fix possessive.
Use “data source’s properties” (singular possessive).

-This action features easy to use dropdowns that automatically populate your data sources as well as your data sources's properties, also known as columns.
+This action features easy-to-use dropdowns that automatically populate your data sources as well as your data source’s properties (columns).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
This action features easy to use dropdowns that automatically populate your data sources as well as your data sources's properties, also known as columns.
This action features easy-to-use dropdowns that automatically populate your data sources as well as your data source’s properties (columns).
🤖 Prompt for AI Agents
components/notion/actions/create-page-from-database/README.md around line 5: the
phrase uses an incorrect possessive "data sources's properties"; change it to
the singular possessive "data source's properties" so the sentence reads
"...automatically populate your data sources as well as your data source's
properties, also known as columns." Ensure spacing and punctuation remain
correct.

This action features easy to use dropdowns that automatically populate your data sources as well as your data sources's properties, also known as columns.

This action interacts with the [Notion create a Page API endpoint](https://developers.notion.com/reference/post-page). The Database selected in the `Parent Database ID` is used as the `parent_id` parameter to that endpoint so the page is added to your databaset .
This action interacts with the [Notion create a Page API endpoint](https://developers.notion.com/reference/post-page). The Data Source selected in the `Parent Data Source ID` is used as the `parent_id` parameter to that endpoint so the page is added to your data source.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

API terminology: Notion uses a parent object, not parent_id.
Reflect the current API (parent: { data_source_id: ... }).

-...used as the `parent_id` parameter to that endpoint...
+...used in the `parent` object (e.g., `parent: { data_source_id: "<ID>" }`) for that endpoint...
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
This action interacts with the [Notion create a Page API endpoint](https://developers.notion.com/reference/post-page). The Data Source selected in the `Parent Data Source ID` is used as the `parent_id` parameter to that endpoint so the page is added to your data source.
This action interacts with the [Notion create a Page API endpoint](https://developers.notion.com/reference/post-page). The Data Source selected in the `Parent Data Source ID` is used in the `parent` object (e.g., `parent: { data_source_id: "<ID>" }`) for that endpoint so the page is added to your data source.
🤖 Prompt for AI Agents
In components/notion/actions/create-page-from-database/README.md around line 7,
update the wording to use Notion's current API terminology: refer to a "parent"
object rather than "parent_id". Change the description to explain that the
selected Data Source ID is provided as parent: { data_source_id: "<id>" } (or
equivalent) so the page is added to that data source, and ensure examples and
parameter names in the README reflect "parent" with a nested data_source_id
field.

Comment on lines +26 to 37
const response = await this.notion.listDataSources(params);

for (const database of response.results) {
if (!this.isResultNew(database.created_time, lastCreatedTimestamp)) {
for (const dataSource of response.results) {
if (!this.isResultNew(dataSource.created_time, lastCreatedTimestamp)) {
params.start_cursor = null;
break;
}
databases.push(database);
dataSources.push(dataSource);
}

params.start_cursor = response.next_cursor;
} while (params.start_cursor);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix pagination early-stop: start_cursor gets overwritten after break.
Inside the for-loop you nullify start_cursor to stop paging, but it’s overwritten by response.next_cursor after the loop, causing extra pages to be fetched. Gate the outer loop with a flag and only advance the cursor when not stopping.

Apply:

   async run() {
-    const dataSources = [];
+    const dataSources = [];
+    let stopPaging = false;
@@
-    do {
+    do {
       const response = await this.notion.listDataSources(params);
 
       for (const dataSource of response.results) {
         if (!this.isResultNew(dataSource.created_time, lastCreatedTimestamp)) {
-          params.start_cursor = null;
-          break;
+          stopPaging = true;
+          break;
         }
         dataSources.push(dataSource);
       }
 
-      params.start_cursor = response.next_cursor;
-    } while (params.start_cursor);
+      if (!stopPaging) {
+        params.start_cursor = response.next_cursor;
+      }
+    } while (params.start_cursor && !stopPaging);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const response = await this.notion.listDataSources(params);
for (const database of response.results) {
if (!this.isResultNew(database.created_time, lastCreatedTimestamp)) {
for (const dataSource of response.results) {
if (!this.isResultNew(dataSource.created_time, lastCreatedTimestamp)) {
params.start_cursor = null;
break;
}
databases.push(database);
dataSources.push(dataSource);
}
params.start_cursor = response.next_cursor;
} while (params.start_cursor);
async run() {
const dataSources = [];
let stopPaging = false;
do {
const response = await this.notion.listDataSources(params);
for (const dataSource of response.results) {
if (!this.isResultNew(dataSource.created_time, lastCreatedTimestamp)) {
stopPaging = true;
break;
}
dataSources.push(dataSource);
}
if (!stopPaging) {
params.start_cursor = response.next_cursor;
}
} while (params.start_cursor && !stopPaging);
}
🤖 Prompt for AI Agents
In components/notion/sources/new-database/new-database.mjs around lines 26 to
37, the code sets params.start_cursor = null inside the for-loop to stop paging
but then unconditionally assigns params.start_cursor = response.next_cursor
after the loop, undoing the stop; change the logic to use a local boolean (e.g.,
stopPaging) that you set when you detect an old result in the loop, break out,
and after the for-loop only assign params.start_cursor = response.next_cursor
when stopPaging is false (otherwise leave it null to halt pagination).

@GTFalcao
Copy link
Collaborator Author

/approve

@GTFalcao GTFalcao merged commit 09bba55 into master Sep 11, 2025
10 checks passed
@GTFalcao GTFalcao deleted the notion-api-update branch September 11, 2025 19:56
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.

[BUG] Notion - Query Database throws error Notion API update 2025-09-03

3 participants