/** * Notion operation enum — single source of truth across the API, Dashboard y * Message Broker. Lo usan: * - notionAction entity / DTO (api): campo `operation` + validación * - la página de detalle del dashboard * - specs de toolkit MCP, si algún día el nodo gana modo herramienta * * Mismo patrón que `google-analytics-operations.ts` y `drive-operations.ts`. * * ── Contra qué versión está escrito ── * * `Notion-Version: 2026-03-11`. Importa más de lo normal porque Notion movió * cosas de sitio dos veces seguidas y los ejemplos que hay por internet están * casi todos contra la API anterior: * * - 2025-09-03 partió `database` en database + **data source**. El query * dejó de vivir en `databases/{id}/query` y pasó a * `data_sources/{id}/query`. Una database contiene N data sources. * - 2026-03-11 quitó el alias `archived` (ahora es **`in_trash`**), cambió * el `after` de append blocks por un objeto **`position`**, y renombró el * bloque `transcription` a `meeting_notes`. * * ── Por qué hay operaciones de markdown ── * * Escribir contenido en Notion era construir un árbol de bloques a mano, que * es con diferencia lo más pesado de su API. Desde 2026-03-11 hay * `GET/PATCH /v1/pages/{id}/markdown`, disponible —lo dicen los docs con esas * palabras— para "all connection types (public, internal, and personal access * tokens)". Con eso, escribir una página es mandar texto. * * Y el markdown cubre también el añadir-sin-pisar, vía el comando * `insert_content` con `position: end`. `PATCH /v1/blocks/{id}/children` NO * acepta markdown —sólo objetos de bloque—, así que la única op de bloques que * queda es la de LEER la estructura cruda, que es lo que markdown no da. * * ── Lo que NO es una operación ── * * Listar las databases/data sources a las que la credencial tiene acceso, y * leer el esquema para pintar un selector, NO son ops del nodo: son endpoints * del controlador, como Drive alimenta su `DriveFilePicker`. Una op existe * para producir payload en una corrida; esto otro es para rellenar el * formulario. * * ── Decisiones propias de Notion (anti-n8n) ── * * - La database/data source y la página se ELIGEN de una lista viva, no se * teclean. Un id de Notion es un UUID sin guiones dentro de una URL larga; * pedirle eso al usuario es pedirle que se equivoque. * - Las propiedades de una página van en JSON crudo salvo el título, que es * el 90% de los casos y tiene campo propio. Cada tipo de propiedad de * Notion tiene una forma distinta (`rich_text`, `select`, `date`, * `relation`…) y fingir que caben en tres campos genéricos produce un 400 * que no explica nada. * - Ninguna op declarada sin implementar. El enum ES el contrato de la * pantalla: una op declarada se pinta en el desplegable y falla al * ejecutarse. Entran cuando entre su código. */ export declare const NOTION_OPERATIONS: readonly ["createPage", "getPage", "getPageMarkdown", "updatePageProperties", "updatePageMarkdown", "archivePage", "queryDataSource", "getDataSource", "appendToPage", "getBlockChildren", "search", "createComment"]; export type NotionOperation = (typeof NOTION_OPERATIONS)[number]; /** Type guard — para validar entrada no fiable (DTOs, tool calls). */ export declare function isNotionOperation(value: unknown): value is NotionOperation; export type NotionParamType = /** Selector vivo de data sources accesibles (necesita credencial). */ 'notionDataSource' /** Selector vivo de páginas accesibles; admite pegar un id o una URL. */ | 'notionPage' /** Cualquier bloque contenedor: una página vale como bloque. */ | 'notionBlock' /** Texto con autocompletado de `{{payload.*}}`. */ | 'template' /** Área de texto larga, también con autocompletado. */ | 'textarea' /** `` de `''` / `'true'` / `'false'` que se guarda como BOOLEANO, o * no se guarda si es `''`. "— sin tocar —" tiene que significar que la * clave no viaja, no que viaja en `false`. */ | 'booleanSelect' /** Área de texto para JSON crudo (propiedades, filtros, orden). */ | 'json'; export interface NotionParamSpec { /** La clave de `operationConfig`. Es lo que lee la api, no un nombre de UI. */ name: string; label: string; type: NotionParamType; required?: boolean; /** Ayuda bajo el campo. Texto plano: el paquete no lleva React. */ description?: string; placeholder?: string; /** Prerrellenado cuando la config guardada no trae valor para esta clave. */ default?: string | number; /** Obligatorio en `select` y `booleanSelect` — etiqueta y valor difieren. */ options?: ReadonlyArray<{ value: string; label: string; }>; min?: number; max?: number; /** Se pinta en la pestaña "Advanced" en vez de en "Config". */ advanced?: boolean; /** Sólo visible cuando un campo hermano vale uno de estos. */ showWhen?: { field: string; in: ReadonlyArray; }; } export interface NotionOperationSpec { /** Etiqueta de la fila en el desplegable de operación. */ label: string; /** Sub-línea bajo la etiqueta. */ description: string; /** Endpoint al que mapea, tal cual, para poder cotejarlo con los docs. */ apiMethod: string; /** Esquema de parámetros. El orden ES el orden en pantalla. */ params: NotionParamSpec[]; } /** Las condiciones del filtro simple, en el orden del desplegable. */ export declare const NOTION_FILTER_CONDITIONS: readonly ["equals", "does_not_equal", "contains", "does_not_contain", "is_empty", "is_not_empty", "after", "before", "on_or_after"]; export type NotionFilterCondition = (typeof NOTION_FILTER_CONDITIONS)[number]; /** * Qué condiciones del filtro simple acepta Notion para cada tipo de * propiedad. Un tipo que no está (fórmula, rollup, botón…) no se puede * filtrar con el filtro simple: necesita el raw JSON. */ export declare const NOTION_FILTER_CONDITIONS_BY_TYPE: Readonly>; /** * Las condiciones que valen para una propiedad de ese tipo. Sin tipo (el * esquema no se ha leído, o la propiedad viene de una plantilla) no se puede * saber: se devuelven todas. Un tipo que el filtro simple no expresa devuelve * `[]` — el filtro va en el raw JSON. */ export declare function notionFilterConditionsFor(type: string | null | undefined): readonly NotionFilterCondition[]; export declare const NOTION_OPERATION_SPECS: Record; /** * Las operaciones tal y como se listan en el desplegable. Hoy es el enum * entero; existe para que añadir una op interna (sin fila propia) no obligue * a que la página vuelva a decidir por su cuenta qué enseñar. */ export declare const NOTION_DROPDOWN_OPERATIONS: readonly NotionOperation[];