import type { Client } from "@notionhq/client" import * as z from "zod" import { notionAccount, notionAction, notionOutput } from "../lib" const DATABASE_PARENT_SCHEMA = z.union([ z.strictObject({ page_id: z.string().min(1), type: z.literal("page_id") }), z.strictObject({ type: z.literal("workspace"), workspace: z.literal(true) }), ]) const DATA_SOURCE_PARENT_SCHEMA = z.strictObject({ database_id: z.string().min(1), type: z.literal("database_id").optional(), }) const COMMENT_PARENT_SCHEMA = z.union([ z.strictObject({ page_id: z.string().min(1), type: z.literal("page_id").optional(), }), z.strictObject({ block_id: z.string().min(1), type: z.literal("block_id").optional(), }), ]) const COMMENT_BASE_INPUT_SCHEMA = { attachments: z .strictObject({ file_upload_id: z.string().min(1), type: z.literal("file_upload").optional(), }) .array() .optional(), display_name: z .union([ z.strictObject({ type: z.literal("integration") }), z.strictObject({ type: z.literal("user") }), z.strictObject({ custom: z.strictObject({ name: z.string() }), type: z.literal("custom"), }), ]) .optional(), } const CREATE_COMMENT_INPUT_SCHEMA = z.union([ z.strictObject({ ...COMMENT_BASE_INPUT_SCHEMA, parent: COMMENT_PARENT_SCHEMA, rich_text: z.unknown().array(), }), z.strictObject({ ...COMMENT_BASE_INPUT_SCHEMA, markdown: z.string(), parent: COMMENT_PARENT_SCHEMA, }), z.strictObject({ ...COMMENT_BASE_INPUT_SCHEMA, discussion_id: z.string().min(1), rich_text: z.unknown().array(), }), z.strictObject({ ...COMMENT_BASE_INPUT_SCHEMA, discussion_id: z.string().min(1), markdown: z.string(), }), ]) const VIEW_TYPE_SCHEMA = z.enum([ "table", "board", "list", "calendar", "timeline", "gallery", "form", "chart", "map", "dashboard", ]) const VIEW_CONFIGURATION_TYPE_SCHEMA = z.enum([ "table", "board", "list", "calendar", "timeline", "gallery", "form", "chart", "map", ]) /** Creates a Notion database and its initial data source. */ export const createNotionDatabase = notionAction( { account: notionAccount.insertContent, allowedKeys: [ "parent", "title", "description", "is_inline", "initial_data_source", "icon", "cover", ], call: async (client, input) => await client.databases.create(input), description: "Creates a database and its initial data source.", inputSchema: z.looseObject({ parent: DATABASE_PARENT_SCHEMA }), name: "Create Notion database", replaySafety: "unsafe", output: notionOutput.entity("database"), requiredKeys: ["parent"], }, ) /** Retrieves a Notion database container. */ export const getNotionDatabase = notionAction({ account: notionAccount.readContent, allowedKeys: ["database_id"], call: async (client, input) => await client.databases.retrieve(input), description: "Retrieves one database container and its data sources.", name: "Get Notion database", replaySafety: "safe", output: notionOutput.entity("database"), requiredKeys: ["database_id"], }) /** Updates a Notion database container. */ export const updateNotionDatabase = notionAction( { account: notionAccount.updateContent, allowedKeys: [ "database_id", "parent", "title", "description", "is_inline", "icon", "cover", "in_trash", "is_locked", ], call: async (client, input) => await client.databases.update(input), description: "Updates a database's metadata, parent, lock, or trash state.", inputSchema: z.looseObject({ parent: DATABASE_PARENT_SCHEMA.optional(), }), name: "Update Notion database", replaySafety: "unsafe", output: notionOutput.entity("database"), requiredKeys: ["database_id"], }, ) /** Creates a data source beneath a Notion database. */ export const createNotionDataSource = notionAction< Client["dataSources"]["create"] >({ account: notionAccount.insertContent, allowedKeys: ["parent", "properties", "title", "icon"], call: async (client, input) => await client.dataSources.create(input), description: "Creates a data source and its property schema.", inputSchema: z.looseObject({ parent: DATA_SOURCE_PARENT_SCHEMA }), name: "Create Notion data source", replaySafety: "unsafe", output: notionOutput.entity("data_source"), requiredKeys: ["parent", "properties"], }) /** Retrieves a Notion data source. */ export const getNotionDataSource = notionAction< Client["dataSources"]["retrieve"] >({ account: notionAccount.readContent, allowedKeys: ["data_source_id"], call: async (client, input) => await client.dataSources.retrieve(input), description: "Retrieves one data source and its property schema.", name: "Get Notion data source", replaySafety: "safe", output: notionOutput.entity("data_source"), requiredKeys: ["data_source_id"], }) /** Lists page templates available for a Notion data source. */ export const listNotionDataSourceTemplates = notionAction< Client["dataSources"]["listTemplates"] >({ account: notionAccount.readContent, allowedKeys: ["data_source_id", "name", "start_cursor", "page_size"], call: async (client, input) => await client.dataSources.listTemplates(input), description: "Lists page templates available for a data source.", name: "List Notion data source templates", replaySafety: "safe", output: notionOutput.fields("templates", "has_more", "next_cursor"), requiredKeys: ["data_source_id"], }) /** Queries pages from a Notion data source. */ export const queryNotionDataSource = notionAction< Client["dataSources"]["query"], "archived" >({ account: notionAccount.readContent, allowedKeys: [ "data_source_id", "filter_properties", "sorts", "filter", "start_cursor", "page_size", "in_trash", "result_type", ], call: async (client, input) => await client.dataSources.query(input), description: "Queries data source rows with filters, sorts, and pagination.", inputSchema: z.looseObject({ result_type: z.enum(["page", "data_source"]).optional(), sorts: z .union([ z.strictObject({ direction: z.enum(["ascending", "descending"]), property: z.string(), }), z.strictObject({ direction: z.enum(["ascending", "descending"]), timestamp: z.enum(["created_time", "last_edited_time"]), }), ]) .array() .optional(), }), name: "Query Notion data source", replaySafety: "safe", output: notionOutput.list("page_or_data_source"), requiredKeys: ["data_source_id"], }) /** Updates a Notion data source. */ export const updateNotionDataSource = notionAction< Client["dataSources"]["update"], "archived" >({ account: notionAccount.updateContent, allowedKeys: [ "data_source_id", "title", "icon", "properties", "in_trash", "parent", ], call: async (client, input) => await client.dataSources.update(input), description: "Updates a data source's schema, metadata, parent, or trash state.", inputSchema: z.looseObject({ parent: DATA_SOURCE_PARENT_SCHEMA.optional(), }), name: "Update Notion data source", replaySafety: "unsafe", output: notionOutput.entity("data_source"), requiredKeys: ["data_source_id"], }) /** Creates a page or discussion comment in Notion. */ export const createNotionComment = notionAction({ account: notionAccount.insertComments, allowedKeys: [ "attachments", "display_name", "parent", "rich_text", "markdown", "discussion_id", ], call: async (client, input) => await client.comments.create(input), description: "Creates a comment on a page or in an existing discussion.", inputSchema: CREATE_COMMENT_INPUT_SCHEMA, name: "Create Notion comment", replaySafety: "unsafe", output: notionOutput.entity("comment"), }) /** Updates the text of a Notion comment. */ export const updateNotionComment = notionAction({ account: notionAccount.insertComments, allowedKeys: ["comment_id", "rich_text", "markdown"], call: async (client, input) => await client.comments.update(input), description: "Updates a comment using rich text or markdown.", inputSchema: z.union([ z.strictObject({ comment_id: z.string().min(1), markdown: z.string(), }), z.strictObject({ comment_id: z.string().min(1), rich_text: z.unknown().array(), }), ]), name: "Update Notion comment", replaySafety: "unsafe", output: notionOutput.entity("comment"), requiredKeys: ["comment_id"], }) /** Deletes a Notion comment. */ export const deleteNotionComment = notionAction({ account: notionAccount.insertComments, allowedKeys: ["comment_id"], call: async (client, input) => await client.comments.delete(input), description: "Deletes one comment.", name: "Delete Notion comment", replaySafety: "unsafe", output: notionOutput.entity("comment"), requiredKeys: ["comment_id"], }) /** Retrieves a Notion comment. */ export const getNotionComment = notionAction({ account: notionAccount.readComments, allowedKeys: ["comment_id"], call: async (client, input) => await client.comments.retrieve(input), description: "Retrieves one comment by ID.", name: "Get Notion comment", replaySafety: "safe", output: notionOutput.entity("comment"), requiredKeys: ["comment_id"], }) /** Lists comments associated with a Notion block or page. */ export const listNotionComments = notionAction({ account: notionAccount.readComments, allowedKeys: ["block_id", "start_cursor", "page_size"], call: async (client, input) => await client.comments.list(input), description: "Lists comments associated with a block or page.", name: "List Notion comments", replaySafety: "safe", output: notionOutput.list("comment"), requiredKeys: ["block_id"], }) /** Creates a Notion database view. */ export const createNotionView = notionAction({ account: notionAccount.createView, allowedKeys: [ "data_source_id", "name", "type", "database_id", "view_id", "filter", "sorts", "quick_filters", "create_database", "configuration", "position", "placement", ], call: async (client, input) => await client.views.create(input), description: "Creates a configured view for a data source.", inputSchema: z.looseObject({ configuration: z .looseObject({ type: VIEW_CONFIGURATION_TYPE_SCHEMA }) .optional(), type: VIEW_TYPE_SCHEMA, }), name: "Create Notion view", replaySafety: "unsafe", output: notionOutput.entity("view"), refine: (input) => Number("database_id" in input) + Number("view_id" in input) + Number("create_database" in input) === 1, requiredKeys: ["data_source_id", "name", "type"], }) /** Retrieves a Notion view. */ export const getNotionView = notionAction({ account: notionAccount.readContent, allowedKeys: ["view_id"], call: async (client, input) => await client.views.retrieve(input), description: "Retrieves one database view.", name: "Get Notion view", replaySafety: "safe", output: notionOutput.entity("view"), requiredKeys: ["view_id"], }) /** Lists the views in a Notion database or data source. */ export const listNotionViews = notionAction({ account: notionAccount.readContent, allowedKeys: ["database_id", "data_source_id", "start_cursor", "page_size"], call: async (client, input) => await client.views.list(input), description: "Lists views for a database or data source.", name: "List Notion views", replaySafety: "safe", output: notionOutput.list("view"), refine: (input) => Number("database_id" in input) + Number("data_source_id" in input) >= 1, }) /** Creates a materialized query for a Notion view. */ export const createNotionViewQuery = notionAction< Client["views"]["queries"]["create"] >({ account: notionAccount.readContent, allowedKeys: ["view_id", "page_size"], call: async (client, input) => await client.views.queries.create(input), description: "Creates a query for a view and returns its first results.", name: "Create Notion view query", replaySafety: "unsafe", output: notionOutput.entity("view_query", [ "id", "view_id", "expires_at", "total_count", "results", "next_cursor", "has_more", ]), requiredKeys: ["view_id"], }) /** Retrieves a page of results for a Notion view query. */ export const getNotionViewQueryResults = notionAction< Client["views"]["queries"]["results"] >({ account: notionAccount.readContent, allowedKeys: ["view_id", "query_id", "start_cursor", "page_size"], call: async (client, input) => await client.views.queries.results(input), description: "Retrieves paginated results for an existing view query.", name: "Get Notion view query results", replaySafety: "safe", output: notionOutput.list("page"), requiredKeys: ["view_id", "query_id"], }) /** Deletes a Notion view query. */ export const deleteNotionViewQuery = notionAction< Client["views"]["queries"]["delete"] >({ account: notionAccount.readContent, allowedKeys: ["view_id", "query_id"], call: async (client, input) => await client.views.queries.delete(input), description: "Deletes an existing query for a view.", name: "Delete Notion view query", replaySafety: "unsafe", output: notionOutput.entity("view_query", ["id", "deleted"]), requiredKeys: ["view_id", "query_id"], }) /** Updates a Notion view. */ export const updateNotionView = notionAction({ account: notionAccount.updateContent, allowedKeys: [ "view_id", "name", "filter", "sorts", "quick_filters", "configuration", ], call: async (client, input) => await client.views.update(input), description: "Updates a view's name, filters, sorts, or configuration.", inputSchema: z.looseObject({ configuration: z .looseObject({ type: VIEW_CONFIGURATION_TYPE_SCHEMA }) .optional(), }), name: "Update Notion view", replaySafety: "unsafe", output: notionOutput.entity("view"), requiredKeys: ["view_id"], }) /** Deletes a Notion view. */ export const deleteNotionView = notionAction({ account: notionAccount.updateContent, allowedKeys: ["view_id"], call: async (client, input) => await client.views.delete(input), description: "Deletes one database view.", name: "Delete Notion view", replaySafety: "unsafe", output: notionOutput.entity("view"), requiredKeys: ["view_id"], })