/** * Word (los documentos de Microsoft 365) por Microsoft Graph — la fuente única * de sus operaciones para el api, hw-nodes, el dashboard y el servidor MCP. * * ## Por qué un nodo aparte (2026-10-01) * * Ariel pidió las integraciones de Microsoft 365 SEPARADAS, un nodo por * producto, cada uno con su action, su trigger y su AI toolkit, y una app de * Entra por servicio («HostWebhook Word»): Microsoft sólo deja revocar la app * ENTERA, así que quitarle los ficheros a HostWebhook no le quita los * documentos, ni al revés. Éste es el quinto, después de Outlook, Outlook * Calendar, OneDrive y Excel. Diseño: `plans/microsoft-word.md`. * * ## Graph no edita el contenido de un .docx * * No hay una API de párrafos como la de Google Docs: todo lo que toca el texto * se hace BAJANDO el fichero, cambiándolo en HostWebhook (el motor .docx de * `common/word-docx/` del api y de hw-nodes) y SUBIÉNDOLO otra vez. Por eso * las operaciones son de nivel fichero más lo que el nodo sabe hacer con un * .docx: * * - **Documents** — listar los de una carpeta, buscarlos, ver uno, leer su * texto (Markdown o texto) y bajarlo como fichero (.docx o PDF). * - **Create** — un documento nuevo desde Markdown o texto, y rellenar una * plantilla (`{{campo}}` escritos en Word → valores del flujo). * - **Edit** — añadir al final, buscar y reemplazar. * - **Convert & share** — una copia en PDF en OneDrive y un enlace. * * ## Se elige como un fichero de OneDrive * * El documento es un `onedriveFile` y la carpeta un `onedriveFolder`: las * MISMAS cadenas que OneDrive (`onedrive-operations.ts`), con el mismo * selector y el mismo «escribir a mano» (un ID, una ruta que empieza por `/` o * una plantilla). No hay un tipo `wordDocument` propio, ni `docPicker` (el de * Google Docs): con un tipo «de la cuenta», cambiar de credencial BORRARÍA un * `{{payload.id}}` escrito en el campo. Lo único que Word añade al selector es * `extensiones`, distintas por operación (ver {@link idDeDocumento}). * * ## Las extensiones, sin punto * * Como `EXCEL_EXTENSIONES` y como el `extension` que da `elementoResumido` de * OneDrive (`docx`, minúsculas, sin punto): el ejecutor compara una con otra * tal cual, y el selector de la api acepta las dos formas. (El diseño las * escribía con punto; manda el código que ya está en producción.) */ export declare const WORD_OPERATIONS: readonly ["listDocuments", "findDocuments", "getDocument", "readDocument", "downloadDocument", "createDocument", "fillTemplate", "appendText", "replaceText", "convertToPdf", "createShareLink"]; export type WordOperation = (typeof WORD_OPERATIONS)[number]; /** Type guard — for DTOs and AI tool calls, where the input is untrusted. */ export declare function isWordOperation(value: unknown): value is WordOperation; /** * El tipo de credencial: el OAuth de la app «HostWebhook Word» de Entra, con * `Files.ReadWrite` + `Files.Read.All` (éste sólo por el trigger en cuentas de * trabajo). Un tipo por servicio de Microsoft, porque cada uno es su propia * app: la credencial de OneDrive no sirve aquí ni al revés. */ export declare const WORD_CREDENTIAL_TYPE = "microsoft_word_oauth2"; /** El tipo MIME de un .docx: el de lo que crea el nodo y el de su `_file`. */ export declare const WORD_MIME_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; /** «List documents» y «Find documents»: lo que se puede pedir, y el defecto. */ export declare const WORD_LISTADO_MAXIMO = 100; export declare const WORD_LISTADO_POR_DEFECTO = 25; /** * «List documents»: los hijos de la carpeta que se RECORREN buscando .docx * (5 páginas × 200). Los .docx se filtran y se ordenan en casa, así que una * carpeta con miles de ficheros se corta aquí y la salida dice `truncated`. */ export declare const WORD_HIJOS_LEIDOS_MAXIMO = 1000; /** * Lo más que se baja de un .docx para leerlo, rellenarlo o editarlo EN * MEMORIA: se mira el `size` antes de bajar nada, y el cuerpo se corta en * cuanto pasa de aquí aunque `size` mienta. */ export declare const WORD_MAX_BYTES_DOCX: number; /** Lo más que se baja del PDF que convierte Microsoft («Save as PDF»), en memoria. */ export declare const WORD_MAX_BYTES_PDF: number; /** * Lo más que puede pesar un fichero de HostWebhook (`_file`): el de «Download * document» y el de «Also as a file». Es el MISMO techo de OneDrive * ({@link ONEDRIVE_DESCARGA_MAX_BYTES}, 16 MiB, el del escáner): la * confirmación de la subida BORRA lo que pase de `min(maxFileSize del plan, * 16 MiB)`, así que los 25 MB de un .docx y los 50 MB de un PDF valen para * trabajar en memoria, no para guardarlos como fichero. El tope real es * `min(este, maxFileSize del plan)` (`topeDeDescarga` de hw-nodes). * * (El diseño prometía `_file` de hasta 25 y 50 MB: no caben en HostWebhook.) */ export declare const WORD_MAX_BYTES_FICHERO: number; /** Lo más que se infla UNA parte XML del .docx (el documento, una cabecera…). */ export declare const WORD_MAX_BYTES_XML: number; /** Lo más que se infla el paquete ENTERO al reescribirlo (rellenar, añadir, reemplazar). */ export declare const WORD_MAX_BYTES_DESCOMPRIMIDO: number; /** Entradas del zip: con más, no se abre (un .docx normal tiene unas veinte). */ export declare const WORD_MAX_ENTRADAS_ZIP = 2000; /** «Read document»: los caracteres que devuelve si no se dice, y el máximo. */ export declare const WORD_CARACTERES_POR_DEFECTO = 50000; export declare const WORD_CARACTERES_MAXIMOS = 200000; /** Caracteres de Markdown o texto que se aceptan en «Create document» y «Append text». */ export declare const WORD_MAX_CONTENIDO = 1000000; /** Claves de «Fields» en «Fill template». */ export declare const WORD_MAX_CAMPOS = 500; /** * «If the name is taken». Vacío = `fail`. Nunca se pisa nada que no se pidió: * `fail` y `rename` comprueban antes y suben por sesión con * `conflictBehavior: fail` (lo documentado); sólo `replace` reemplaza. */ export declare const WORD_CONFLICTOS: readonly ["fail", "rename", "replace"]; /** «Read document»: Markdown (títulos, listas, negrita, tablas) o texto. Vacío = `markdown`. */ export declare const WORD_FORMATOS_DE_LECTURA: readonly ["markdown", "text"]; /** «Download document»: el .docx tal cual, o el PDF que convierte Microsoft. Vacío = `docx`. */ export declare const WORD_FORMATOS_DE_DESCARGA: readonly ["docx", "pdf"]; /** Lo que se escribe en «Content» / «Text to add». Vacío = `markdown`. */ export declare const WORD_FORMATOS_DE_CONTENIDO: readonly ["markdown", "text"]; /** «Create document»: el tamaño de página. Vacío = `letter`. */ export declare const WORD_TAMANOS_DE_PAGINA: readonly ["letter", "a4"]; /** * «Fill template»: los `{{campo}}` sin valor. Vacío = `keep` — el hueco se VE; * `empty` lo escondería. */ export declare const WORD_CAMPOS_SIN_VALOR: readonly ["keep", "empty", "fail"]; /** «List documents»: el orden. Vacío = `modified` (lo último cambiado primero). */ export declare const WORD_ORDENES: readonly ["modified", "name"]; /** `type` de `createLink`. Vacío = `view`. Sin `embed` (sólo personal). */ export declare const WORD_TIPOS_DE_ENLACE: readonly ["view", "edit"]; /** * `scope` de `createLink`. Vacío = el de la cuenta. `organization` sólo en * cuentas de trabajo. Sin `users`: en v1.0 `createLink` no admite * destinatarios (lo mismo que OneDrive). */ export declare const WORD_ALCANCES_DE_ENLACE: readonly ["anonymous", "organization"]; /** * Las que se LISTAN y se LEEN: el zip de Office Open XML. Las mira también el * trigger. */ export declare const WORD_EXTENSIONES_DOCX: readonly ["docx", "docm", "dotx", "dotm"]; /** * Las que se rellenan (plantilla), se amplían y se reemplazan. Sin las de * macros: un .docm reescrito y guardado como .docx lleva el tipo de contenido * de macros y Word no lo abre. */ export declare const WORD_EXTENSIONES_EDITABLES: readonly ["docx", "dotx"]; /** Las de Word que se ven, se bajan y se comparten (las antiguas también). */ export declare const WORD_EXTENSIONES_WORD: readonly ["docx", "docm", "dotx", "dotm", "doc", "dot", "odt", "rtf"]; /** * Las de Word que Graph convierte a PDF (Learn, «Convert to other formats», * tabla `pdf`: doc, docx, dot, dotx, dotm, odt, rtf). 🔥 SIN `docm`: no está * en esa tabla. Las usan «Save as PDF» y «Download document» con «As: pdf»; * un .docm da un 400 propio ANTES de llamar a Microsoft. */ export declare const WORD_EXTENSIONES_PDF: readonly ["docx", "doc", "dot", "dotx", "dotm", "odt", "rtf"]; export interface WordParamSpec { /** Field key — also the property name on operationConfig. */ name: string; label: string; /** * Param type, so the dashboard renders the right control. * - `onedriveFile` / `onedriveFolder` — los selectores de OneDrive, tal * cual (las mismas cadenas que `OnedriveParamSpec`, clase «mixto» en el * guiado: un ID se olvida al cambiar de credencial; una ruta `/…` o una * plantilla, no); * - `markdownTemplate` — el editor de Markdown con plantillas (el de Docs); * - `json` — un objeto (los valores de «Fill template»). */ type: 'string' | 'text' | 'number' | 'boolean' | 'select' | 'datetime' | 'onedriveFile' | 'onedriveFolder' | 'markdownTemplate' | 'json'; required?: boolean; description: string; /** * El hueco vacío. En un `select` opcional dice lo que pasará si se deja sin * elegir («Markdown (default)»): lo enseña, no lo marca — ningún campo nace * elegido. */ placeholder?: string; /** For `select`. */ options?: readonly string[]; /** For `number`. */ min?: number; max?: number; /** * Sólo en los `onedriveFile` (el documento y la plantilla): lo que lista el * selector de OneDrive. El ejecutor lo vuelve a comprobar con un 400. */ extensiones?: readonly string[]; } export interface WordOperationSpec { label: string; description: string; /** The Graph route this maps to, so the mapping is checkable. */ apiRoute: string; /** Changes something in OneDrive (as opposed to only reading it). */ writes?: boolean; params: WordParamSpec[]; } /** * El documento de una operación, con las extensiones que ESA operación * acepta (el filtro del selector). */ export declare const idDeDocumento: (extensiones: readonly string[], description?: string) => WordParamSpec; export declare const WORD_OPERATION_SPECS: Record;