/** * Notion Integration for WORKWAY * * Demonstrates the SDK patterns with DUAL StandardData outputs: * - StandardDocument for pages * - StandardTask for database items with task properties * * This validates the narrow waist pattern across multiple data types. * * @example * ```typescript * import { Notion } from '@workwayco/integrations/notion'; * * const notion = new Notion({ accessToken: tokens.notion.access_token }); * * // Search pages * const pages = await notion.search({ query: 'Project' }); * * // Get a page * const page = await notion.getPage({ pageId: 'abc123' }); * * // Create a page in a database * const created = await notion.createPage({ * parentDatabaseId: 'db123', * properties: { Name: { title: [{ text: { content: 'New Task' } }] } } * }); * * // Query a database * const items = await notion.queryDatabase({ databaseId: 'db123' }); * ``` */ import { ActionResult } from '@workwayco/sdk'; import { BaseAPIClient } from '../core/index.js'; /** * Notion rich text object */ export interface NotionRichText { type: 'text' | 'mention' | 'equation'; text?: { content: string; link?: { url: string; } | null; }; mention?: { type: string; [key: string]: unknown; }; annotations?: { bold: boolean; italic: boolean; strikethrough: boolean; underline: boolean; code: boolean; color: string; }; plain_text: string; href?: string | null; } /** * Notion page object */ export interface NotionPage { object: 'page'; id: string; created_time: string; last_edited_time: string; created_by: { object: 'user'; id: string; }; last_edited_by: { object: 'user'; id: string; }; parent: { type: 'database_id'; database_id: string; } | { type: 'page_id'; page_id: string; } | { type: 'workspace'; workspace: true; }; archived: boolean; properties: Record; url: string; icon?: { type: 'emoji'; emoji: string; } | { type: 'external'; external: { url: string; }; } | null; cover?: { type: 'external'; external: { url: string; }; } | null; } /** * Notion database object */ export interface NotionDatabase { object: 'database'; id: string; title: NotionRichText[]; description: NotionRichText[]; created_time: string; last_edited_time: string; icon?: { type: 'emoji'; emoji: string; } | { type: 'external'; external: { url: string; }; } | null; cover?: { type: 'external'; external: { url: string; }; } | null; properties: Record; parent: { type: 'page_id'; page_id: string; } | { type: 'workspace'; workspace: true; }; url: string; archived: boolean; } /** * Notion property value (in a page) */ export interface NotionProperty { id: string; type: string; title?: NotionRichText[]; rich_text?: NotionRichText[]; number?: number | null; select?: { id: string; name: string; color: string; } | null; multi_select?: Array<{ id: string; name: string; color: string; }>; date?: { start: string; end?: string | null; time_zone?: string | null; } | null; checkbox?: boolean; url?: string | null; email?: string | null; phone_number?: string | null; status?: { id: string; name: string; color: string; } | null; people?: Array<{ object: 'user'; id: string; }>; files?: Array<{ name: string; type: string; file?: { url: string; }; external?: { url: string; }; }>; relation?: Array<{ id: string; }>; formula?: { type: string; [key: string]: unknown; }; rollup?: { type: string; [key: string]: unknown; }; created_time?: string; created_by?: { object: 'user'; id: string; }; last_edited_time?: string; last_edited_by?: { object: 'user'; id: string; }; } /** * Notion property schema (in a database) */ export interface NotionPropertySchema { id: string; name: string; type: string; [key: string]: unknown; } /** * Notion block object (content blocks) */ export interface NotionBlock { object: 'block'; id: string; type: string; created_time: string; last_edited_time: string; has_children: boolean; archived: boolean; [key: string]: unknown; } /** * Notion integration configuration */ export interface NotionConfig { /** Integration token or OAuth access token */ accessToken: string; /** Notion API version (default: '2022-06-28') */ notionVersion?: string; /** Optional: Override API endpoint (for testing) */ apiUrl?: string; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; } /** * Options for searching */ export interface SearchOptions { /** Search query */ query?: string; /** Filter by object type: 'page' or 'database' */ filter?: { property: 'object'; value: 'page' | 'database'; }; /** Sort direction */ sort?: { direction: 'ascending' | 'descending'; timestamp: 'last_edited_time'; }; /** Pagination cursor */ start_cursor?: string; /** Page size (default: 100, max: 100) */ page_size?: number; } /** * Options for getting a page */ export interface GetPageOptions { /** Page ID */ pageId: string; } /** * Options for creating a page */ export interface CreatePageOptions { /** Parent database ID (mutually exclusive with parentPageId) */ parentDatabaseId?: string; /** Parent page ID (mutually exclusive with parentDatabaseId) */ parentPageId?: string; /** Page properties */ properties: Record; /** Page content (blocks) */ children?: NotionBlock[]; /** Page icon */ icon?: { type: 'emoji'; emoji: string; } | { type: 'external'; external: { url: string; }; }; /** Page cover */ cover?: { type: 'external'; external: { url: string; }; }; } /** * Options for updating a page */ export interface UpdatePageOptions { /** Page ID */ pageId: string; /** Properties to update */ properties?: Record; /** Archive the page */ archived?: boolean; /** Update icon */ icon?: { type: 'emoji'; emoji: string; } | { type: 'external'; external: { url: string; }; } | null; /** Update cover */ cover?: { type: 'external'; external: { url: string; }; } | null; } /** * Options for querying a database */ export interface QueryDatabaseOptions { /** Database ID */ databaseId: string; /** Filter conditions */ filter?: Record; /** Sort conditions */ sorts?: Array<{ property: string; direction: 'ascending' | 'descending'; } | { timestamp: 'created_time' | 'last_edited_time'; direction: 'ascending' | 'descending'; }>; /** Pagination cursor */ start_cursor?: string; /** Page size (default: 100, max: 100) */ page_size?: number; } /** * Options for getting page content */ export interface GetBlockChildrenOptions { /** Block or page ID */ blockId: string; /** Pagination cursor */ start_cursor?: string; /** Page size (default: 100, max: 100) */ page_size?: number; } /** * Notion Integration * * Weniger, aber besser: Extends BaseAPIClient for shared HTTP logic. */ export declare class Notion extends BaseAPIClient { private notionVersion; constructor(config: NotionConfig); /** Get Notion-specific headers */ private get notionHeaders(); /** * Search pages and databases * * @returns ActionResult with search results */ search(options?: SearchOptions): Promise>>; /** * Get a page by ID * * @returns ActionResult with page data and StandardDocument format */ getPage(options: GetPageOptions): Promise>; /** * Create a new page * * @returns ActionResult with created page */ createPage(options: CreatePageOptions): Promise>; /** * Update a page * * @returns ActionResult with updated page */ updatePage(options: UpdatePageOptions): Promise>; /** * Query a database * * @returns ActionResult with database items (pages) */ queryDatabase(options: QueryDatabaseOptions): Promise>; /** * Get a database schema * * @returns ActionResult with database metadata */ getDatabase(databaseId: string): Promise>; /** * Get page content (blocks) * * @returns ActionResult with block children */ getBlockChildren(options: GetBlockChildrenOptions): Promise>; /** * Append children blocks to a page or block * * Use this to add content to an existing page after creation. * Respects Notion's 100-block limit per request. * * @returns ActionResult with appended blocks */ appendBlockChildren(options: { blockId: string; children: NotionBlock[]; }): Promise>; /** * Append blocks to a page in batches * * Automatically splits large block arrays into batches of 100 (Notion's limit). * Includes rate limiting between batches. * * @param pageId - The page ID to append blocks to * @param blocks - Array of blocks to append * @param batchSize - Max blocks per request (default: 100) * @param delayMs - Delay between batches in ms (default: 350) */ appendBlocksInBatches(pageId: string, blocks: NotionBlock[], batchSize?: number, delayMs?: number): Promise>; /** * Get a database item as a task (with StandardTask transformation) * * Use this when querying task/project management databases * * @returns ActionResult with page and StandardTask format */ getTask(pageId: string): Promise>; /** * Query tasks from a database (with StandardTask transformations) * * @returns ActionResult with tasks */ queryTasks(options: QueryDatabaseOptions): Promise>; /** * Get capabilities for Notion actions */ private getCapabilities; /** * Extract title from a page or database */ private extractTitle; /** * Convert rich text array to plain text */ private richTextToPlain; /** * Convert Notion page to StandardDocument format */ private toStandardDocument; /** * Convert Notion page (from task database) to StandardTask format * * Attempts to map common property names to StandardTask fields */ private toStandardTask; /** * Create a document from a template * * Zuhandenheit: Developer thinks "create a standup summary" not * "construct 100 lines of Notion block objects" * * @example * ```typescript * // BEFORE: 100+ lines of block construction * await notion.createPage({ * children: [ * { object: 'block', type: 'heading_2', heading_2: { rich_text: [...] } }, * // ... 100 more lines * ] * }); * * // AFTER: Template-based * await notion.createDocument({ * database: 'db123', * template: 'summary', * data: { * title: 'Standup - 2024-01-15', * summary: 'Team made progress on...', * sections: { * themes: ['API work', 'Testing'], * blockers: ['Waiting on design'], * actionItems: ['Review PR #123'] * } * } * }); * ``` */ createDocument(options: { database: string; template: 'summary' | 'report' | 'notes' | 'article' | 'meeting' | 'feedback' | 'custom'; data: { title: string; summary?: string; date?: string; mood?: 'positive' | 'neutral' | 'concerned'; properties?: Record; sections?: Record; content?: string; metadata?: Record; }; customBlocks?: any[]; }): Promise>; /** * Build summary template blocks (standup, meeting notes, etc.) */ private buildSummaryBlocks; /** * Build report template blocks */ private buildReportBlocks; /** * Build notes template blocks */ private buildNotesBlocks; /** * Build article template blocks */ private buildArticleBlocks; /** * Build meeting template blocks (optimized for meeting transcripts) */ private buildMeetingBlocks; /** * Build feedback template blocks (customer feedback analysis) */ private buildFeedbackBlocks; /** * Format section name for display */ private formatSectionName; } //# sourceMappingURL=index.d.ts.map