From bcc98001ec45c7964954ee5f490ebd5b0f819492 Mon Sep 17 00:00:00 2001 From: Lucy Macartney Date: Fri, 2 Oct 2026 09:36:02 +0100 Subject: [PATCH 1/2] Translate the CLI pages into Spanish --- .../build-for-developers/cli-challenges.md | 275 ++++++ .../build-for-developers/cli-collections.md | 315 ++++++ .../current/build-for-developers/cli-intro.md | 155 +++ .../current/build-for-developers/cli-sync.md | 539 +++++++++++ .../current/build-for-developers/cli-usage.md | 247 +++++ .../build-for-developers/cli-walkthrough.md | 902 ++++++++++++++++++ 6 files changed, 2433 insertions(+) create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-usage.md create mode 100644 i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md new file mode 100644 index 00000000000..6218ca1160a --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md @@ -0,0 +1,275 @@ +--- +title: Desafíos de la CLI +sidebar_label: Desafíos de la CLI +slug: /cli-challenges +translation_source_hash: 77369268e959643bb1252b91b59cf8176063c423 +translation_review_status: machine +--- + +#### Resuelve problemas reales y demuestra tus habilidades con la línea de comandos participando en nuestros desafíos de la CLI {#solve-real-world-problems-and-showcase-your-command-line-skills-by-participating-in-our-cli-challenges} + +:::tip Notas importantes + +- Un desarrollador con algo de experiencia en JavaScript debería poder escribir, + ejecutar y depurar jobs complejos de varios pasos con OpenFn, usando solo un + editor de texto y su terminal. +- Si te quedas atascado y necesitas ayuda, publica en + [community.openfn.org](https://community.openfn.org). +
+ Despliega para ver la plantilla de reporte de errores + + ```markdown + Subject: Bug Report - [Brief Description] + + **Description:** [Concise description of the bug.] + + **Steps to Reproduce:** + + 1. + 2. + 3. + + **Environment:** + + - OS: [e.g., Windows 10] + - CLI: [e.g., v0.4.11] + - Node: [e.g., v 18.17.1] + - NPM: [e.g., 8.19.2] + + **Attachments:** [Screenshots, error messages, or relevant files.] + ``` + +
+ +::: + +### 🏆 Crea un saludo personalizado {#-create-personalized-greeting} + +**Descripción general:** + +Crea un nuevo job `hello.js` que muestre un saludo personalizado con tu nombre. + +**Objetivo:** + +Escribe un job de OpenFn con el [adaptor common](/adaptors/packages/common-docs) +que muestre un mensaje de saludo con tu nombre. + +**Requisitos:** + +1. Instala la última versión del adaptor common. + + ``` + openfn repo install @openfn/language-common + ``` + +**Tareas:** + +1. Crea un archivo nuevo llamado `hello.js`. +2. Escribe un script de JavaScript en `hello.js` que genere un saludo con tu + nombre. +3. Ejecuta el job con el comando `openfn hello.js -a common -o tmp/output.json`. +4. Confirma que se ejecutó correctamente. + +**Lista de verificación:** + +- [ ] Creaste el archivo nuevo `hello.js`. +- [ ] Escribiste en `hello.js` un script de JavaScript para un saludo + personalizado. +- [ ] Ejecutaste el job con el comando indicado. +- [ ] Comprobaste que los logs de la salida de la CLI son correctos. + +--- + +### 🏆 Obtén e inspecciona datos por HTTP {#-fetch-and-inspect-data-via-http} + +**Descripción general:** + +Escribe un job que obtenga datos de usuarios de la +[API de JSONPlaceholder](https://jsonplaceholder.typicode.com/users) con el +[adaptor http](/adaptors/packages/http-docs) de OpenFn. + +**Objetivo:** + +Obtén y muestra los detalles del primer usuario de la API de JSONPlaceholder. + +**Requisitos:** + +1. Instala la última versión del adaptor http. + +```bash +openfn repo install @openfn/language-http +``` + +2. Usa la [API de JSONPlaceholder](https://jsonplaceholder.typicode.com/users). +3. Crea un archivo llamado `getUsers.js` que contenga el script. + +**Tareas:** + +1. Crea un archivo (`getUsers.js`) para el script. +2. Obtén una lista de usuarios de la API de JSONPlaceholder. +3. Muestra los detalles del primer usuario. +4. Ejecuta el job con OpenFn/cli: + `openfn getUsers.js -a http -o tmp/output.json`. +5. Comprueba que los logs de la CLI son los esperados. + +**Lista de verificación:** + +- [ ] Obtuviste los datos de los usuarios. +- [ ] Mostraste correctamente los detalles del primer usuario. +- [ ] Usaste correctamente las funciones del adaptor http de OpenFn. +- [ ] Comprobaste que los logs de la salida de la CLI son correctos. + +--- + +### 🏆 Obtén metadatos de COVID-19 {#-retrieve-covid-19-metadata} + +**Descripción general:** + +Obtén y presenta metadatos de COVID-19 con la +[API del COVID Tracking Project de The Atlantic](https://covidtracking.com/data/api). + +**Objetivo:** + +Escribe un job que obtenga datos de COVID-19 de la API y calcule algunos valores +agregados para el período que elijas. + +**Requisitos:** + +1. Instala la última versión del adaptor http. + +```bash +openfn repo install @openfn/language-http +``` + +**Tareas:** + +1. Escribe una operación de OpenFn que obtenga metadatos de COVID-19 de la + [API del COVID Tracking Project de The Atlantic](https://covidtracking.com/data/api). + - Usa `https://api.covidtracking.com` como tu **baseUrl** en + `state.configuration`. +2. Ejecuta el job con la CLI de OpenFn mediante el comando + `openfn your_operation_file.js -a http -o tmp/output.json`. +3. Evalúa la salida y prueba distintas formas de dar formato a los datos de + COVID-19 por región o de presentarlos. + +**Lista de verificación:** + +- [ ] Creaste un archivo de operación de OpenFn. +- [ ] Escribiste el código para obtener metadatos de COVID-19 de la API + indicada. +- [ ] Ejecutaste el job con el comando de la CLI indicado. +- [ ] Probaste varias opciones de formato o presentación para los datos + obtenidos. + +> Experimenta con la presentación de los datos para entenderlos mejor. ¡Buena +> suerte! 🌐🦠 + +--- + +### 🏆 Extrae nombres y correos electrónicos {#-extract-names--emails} + +**Descripción general:** + +En este desafío, usarás la API de JSONPlaceholder para obtener los comentarios +de una publicación concreta (la publicación con ID 1). Tu tarea es extraer los +campos "name" y "email" de cada comentario y registrar en el log los datos +extraídos. + +**Objetivo:** + +Escribe un job que obtenga los comentarios de la publicación con ID 1, extraiga +los campos "name" y "email" de cada comentario y registre en el log los datos +extraídos. + +**Requisitos:** + +- Conocimientos básicos de JavaScript. +- La CLI de OpenFn instalada en tu computadora. + +**Tareas:** + +1. **Obtén los comentarios de la publicación:** + + - Agrega una operación que obtenga todos los comentarios de la publicación + con ID 1 de la + [API de JSONPlaceholder](https://jsonplaceholder.typicode.com/posts/1/comments). + +2. **Extrae el nombre y el correo electrónico:** + + - Escribe una función que extraiga los campos "name" y "email" de cada + comentario. + +3. **Registra los datos extraídos:** + - Muestra en la consola los datos extraídos (nombre y correo electrónico) de + cada comentario. + +**Lista de verificación:** + +- [ ] Obtuviste los comentarios de la publicación con ID 1. +- [ ] Escribiste una función que extrae "name" y "email" de los comentarios. +- [ ] Mostraste en la consola los datos extraídos. + +--- + +### 🏆 Controla los mensajes de error {#-control-error-messages} + +Depura qué causa un error en la siguiente línea de código y muestra el mensaje +de error. + +```jsx +// Get post where id is 180 +get('posts/180'); +``` + +--- + +### 🏆 Transformación y limpieza de datos {#-data-transformation-and-cleaning} + +**Descripción general:** + +En este desafío, usarás métodos globales de arrays de JavaScript, en concreto +`Array.reduce`, `Array.filter` o `Array.map`, para crear una serie de +operaciones que obtengan publicaciones y las filtren por ID de usuario. + +**Objetivo:** + +Escribe un job que obtenga las publicaciones de un ID de usuario concreto, `1`. + +**Requisitos:** + +1. Usa la API de JSONPlaceholder `https://jsonplaceholder.typicode.com`. +2. Instala la última versión del adaptor http. + +``` +openfn repo install @openfn/language-http +``` + +**Tareas:** + +1. **Crea el archivo:** + + - Crea un archivo llamado `getPosts.js` para tu job. + +2. **Obtén todas las publicaciones:** + + - Agrega la primera operación para obtener todas las publicaciones. Usa la + API indicada o cualquier otra fuente que elijas que ofrezca una lista de + publicaciones. + +3. **Filtra las publicaciones por ID:** + + - Agrega una segunda operación con una función que filtre las publicaciones + por ID de usuario. Puedes usar `Array.filter` o cualquier otro método + adecuado. + +4. **Obtén las publicaciones del ID de usuario 1:** + + - Usa la función de la segunda operación para filtrar las publicaciones del + ID de usuario 1. + +**Lista de verificación:** + +- [ ] Creaste el archivo `getPosts.js`. +- [ ] Obtuviste todas las publicaciones. +- [ ] Escribiste una función que filtra publicaciones por ID de usuario. +- [ ] Obtuviste las publicaciones del ID de usuario 1. diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md new file mode 100644 index 00000000000..76a37a77477 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md @@ -0,0 +1,315 @@ +--- +title: Uso de colecciones con la CLI +sidebar_label: Colecciones +slug: /collections-cli +translation_source_hash: da22d0b4b6f41876daff9101ed14f28cd796084d +translation_review_status: machine +--- + +La CLI de OpenFn permite leer y escribir en +[colecciones](/build/collections.md): un almacén de clave/valor integrado en +OpenFn. + +:::caution Versiones + +La compatibilidad con colecciones se agregó a la CLI en la versión 1.9.0. + +Ejecuta `npm install -g @openfn/cli` para actualizarla o instalarla. + +::: + +Puedes usar la CLI para: + +- Explorar el contenido de las colecciones sin ejecutar un workflow +- Probar la sintaxis de consulta para obtener las claves que necesitas +- Actualizar objetos de mapeo y tablas de búsqueda a partir de archivos locales + (o bajo control de versiones) +- Eliminar datos manualmente + +:::tip + +¿Tienes comentarios? ¿Quieres más compatibilidad con colecciones en la CLI? +¡Publica una solicitud de funcionalidad en +[community.openfn.org](https://community.openfn.org/c/feature-requests)! + +::: + +Empieza a usar la API de colecciones con `openfn collections --help`. + +Necesitarás un token de acceso personal (PAT) para acceder a una colección. +También tienes que asegurarte de que la colección exista antes de poder leerla o +escribir en ella. Consulta +[Gestionar colecciones](/build/collections.md#managing-collections). + +:::info ¿Quieres usar colecciones en un workflow de la CLI? + +Esta documentación explica cómo usar el comando `openfn collections` de la CLI. + +Si ejecutas una expresión o un workflow con la CLI, tienes que usar el adaptor +de colecciones. Consulta la +[documentación del adaptor de colecciones](/adaptors/collections#cli-usage) para +más detalles + +::: + +## Obtener un PAT {#getting-a-pat} + +Los datos de las colecciones se guardan de forma segura dentro de un proyecto, y +solo pueden acceder a ellos los usuarios con acceso a ese proyecto. Así que, si +quieres acceder a una colección, tienes que decirle al servidor quién eres. + +Para eso usamos los tokens de acceso personal. Consulta +[Crear y administrar tokens de API](/manage-users/api-tokens.md#about-api-tokens) +para más detalles. + +Cuando tengas un PAT, tienes que pasárselo a la CLI. La forma más fácil es +definir la variable de entorno `OPENFN_API_KEY` o usar un archivo `.env`. La CLI +usará este valor automáticamente en todas las solicitudes. + +También puedes pasar `--token` a la CLI para reemplazar el valor cargado de tu +entorno. + +```bash +openfn collections get my-collection \* --token $MY_OPENFN_PAT +``` + +:::tip + +El resto de esta guía da por hecho que la variable de entorno `OPENFN_PAT` está +definida. Si lo está y usas un servidor que tiene una colección `my-collection`, +todos los ejemplos funcionarán. + +::: + +## Definir un servidor {#setting-a-server} + +De forma predeterminada, la CLI apunta a nuestra aplicación en la nube en +https://app.openfn.org. + +Si usas la versión de código abierto u otro despliegue, también tendrás que +indicarle a la CLI qué servidor de colecciones usar. + +Puedes hacerlo pasando `--endpoint` directamente: + +```bash +openfn collections get my-collection \* --endpoint http://localhost:4000 +``` + +O definiendo la variable de entorno `OPENFN_ENDPOINT`. + +:::tip + +Para ver qué servidor está usando la CLI, pide logs de nivel debug en la salida: + +```bash +openfn collections get my-collection \* --log debug +``` + +::: + +## Nombres únicos por proyecto {#project-name-uniqueness} + +En las versiones de Lightning anteriores a la 2.17.0, los nombres de las +colecciones eran únicos en toda la instancia. + +Desde la 2.17.0, los nombres de las colecciones son únicos dentro de un +proyecto, así que una instancia de OpenFn puede tener varias colecciones con el +mismo nombre. + +Cualquier solicitud a la API de colecciones intenta resolver un nombre de +colección a una sola colección. Pero si hay conflictos, el servidor devuelve un +código de error 409. + +Para resolverlo, pasa un id de proyecto: + +```bash +openfn collections get --project-id 1d28c76c-e4ef-4e58-ac1e-464dc479946c +``` + +También puedes definir el ID del proyecto con una variable de entorno, o usar el +atajo `-p`. + +## Obtener elementos {#fetching-items} + +Puedes obtener elementos de una colección pasando un nombre de colección y una +clave, o un patrón de claves (como `*` para "todo", o `2024*` para las claves +que empiezan por `2024`). + +```bash +openfn collections get +``` + +Por ejemplo, para obtener todo de `my-collection`, ejecuta: + +```bash +openfn collections get my-collection \* +``` + +:::tip + +En las terminales de Unix (macOS o Linux), el carácter `*` tiene un significado +especial. Así que, si quieres obtener todos los elementos, tienes que escaparlo +o ponerlo entre comillas: + +``` +openfn collections get my-collection \* +``` + +Incluir `*` en un patrón debería seguir funcionando: + +``` +openfn collections get my-collection 2024* +``` + +::: + +Los elementos de las colecciones se guardan como cadenas, pero se serializan a +JSON en la salida. + +De forma predeterminada, la CLI muestra los valores descargados en tu terminal. +Para escribirlos en disco, pasa `--output` o `-o` con una ruta de archivo +relativa a tu directorio de trabajo: + +```bash +openfn collections get my-collection \* -o /tmp/my_collection.json +``` + +Para dar formato a la salida y que sea más fácil de leer, agrega la opción +`--pretty`: + +```bash +openfn collections get my-collection \* -o /tmp/my_collection.json --pretty +``` + +Es importante entender que la salida funciona un poco distinto si obtienes un +elemento concreto con una sola clave o si obtienes muchos elementos con un +patrón de claves. + +Una sola clave siempre devuelve su valor "en bruto" o "tal cual", sin la clave. +Así que, para una clave `item-1` cuyo valor es un objeto JSON, esto: + +```bash +openfn collections get my-collection item-1 +``` + +Descargará y guardará algo como esto: + +```js +{ + "id": "item-1" + /* ... other properties of the value */ +} +``` + +Si usas un patrón de claves para obtener datos, el valor se devuelve en modo +multielemento: un objeto JSON donde la clave es la clave del elemento y el valor +es el valor del elemento. + +Así que, si obtenemos todos los elementos cuya clave empieza por `item-`: + +```bash +$ openfn collections get my-collection item-1* +``` + +Los datos resultantes se verán así: + +```json +{ + "item-1": { + "id": "item-1" + /* ... other properties of the value */ + }, + "item-10": { + "id": "item-10" + /* ... other properties of the value */ + } +} +``` + +## Subir elementos {#uploading-items} + +Puedes usar el comando `collections` para subir datos a una colección. Al subir, +los valores siempre vienen de un archivo en disco. En este ejemplo usaremos +archivos JSON, pero si subes un solo valor, no hace falta que sea JSON válido. + +El comando `set` tiene dos modos. Para subir un solo elemento, usa: + +```bash +openfn collections set +``` + +Esto lee los datos de `path/to/value.json` como una cadena y hace un upsert con +la clave indicada. No se admiten patrones de claves. + +Para hacer un upsert masivo de varios valores, usa: + +```bash +openfn collections set --items +``` + +El archivo `items.json` tiene que contener un objeto JSON donde las claves son +las claves de los elementos y los valores son los valores de los elementos +(igual que lo que devuelve el comando get multielemento): + +```json +{ + "item-1": { + "id": "item-1" + /* ... other properties of the value */ + }, + "item-10": { + "id": "item-10" + /* ... other properties of the value */ + } +} +``` + +:::tip + +Recuerda que las colecciones siempre usan una estrategia de _upsert_ al subir +elementos nuevos. + +Es decir, si una clave no existe, se crea y se le asigna un valor. Si ya existe, +se actualiza su valor. + +::: + +## Eliminar elementos {#removing-items} + +También puedes eliminar elementos de una colección con el comando +`collections remove`: + +```bash +openfn collections remove +``` + +Se admiten patrones de claves, que te permiten eliminar varias claves. + +Usa `--dry-run` para obtener una lista de las claves que se eliminarían, sin +eliminarlas realmente: + +```bash +openfn collections remove my-collection 2024* --dry-run +``` + +## Solución de problemas {#troubleshooting} + +### Error 409: varios nombres de colección coinciden {#error-409-multiple-collection-names-matched} + +Esto significa que pediste una colección por su nombre, pero el servidor tiene +varias colecciones con ese nombre. + +Tienes que limitar tu solicitud al proyecto correcto incluyendo el id del +proyecto en la solicitud. + +Puedes pasarlo directamente: + +``` +openfn collections get my-collection \* --project-id 1d28c76c-e4ef-4e58-ac1e-464dc479946c +``` + +O definir una variable de entorno (se admiten archivos `.env`): + +``` +OPENFN_PROJECT_ID=1d28c76c-e4ef-4e58-ac1e-464dc479946c +``` diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md new file mode 100644 index 00000000000..8cfb37bc989 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md @@ -0,0 +1,155 @@ +--- +title: Primeros pasos con la CLI de OpenFn +sidebar_label: Primeros pasos +slug: /cli +translation_source_hash: ca52becdb9d7d721ea9e5555863476dc2a187af0 +translation_review_status: machine +--- + +#### Crea y prueba tus workflows e integraciones automatizadas desde la línea de comandos. {#build-and-test-your-automated-workflows-and-integrations-via-the-command-line} + +La CLI de OpenFn es una herramienta para desarrolladores que te ayuda a crear, +probar y gestionar tus workflows directamente desde la línea de comandos. Es +fácil de instalar, funciona en macOS, Windows y Linux, y ofrece muchas +funcionalidades para mejorar tu experiencia de desarrollo con OpenFn. Con la CLI +de OpenFn puedes: + +- Sincronizar workflows entre OpenFn y un sistema de archivos local o GitHub +- Ejecutar workflows de OpenFn de forma segura +- Diagnosticar y depurar steps de OpenFn +- Leer y escribir datos de colecciones + +--- + +### Antes de empezar {#before-you-start} + +Antes de empezar con @openfn/cli, prepara algunas herramientas clave: + +1. **Editor de código:** asegúrate de tener un editor de código instalado en tu + computadora. Puedes usar editores populares como + [VS Code](https://code.visualstudio.com/) o + [Sublime](https://www.sublimetext.com/). +2. **Node.js:** instala Node.js (versión 24 o posterior). En Linux, Windows o + macOS, usa un gestor de versiones como [nvm](https://github.com/nvm-sh/nvm) o + [asdf](https://asdf-vm.com/guide/getting-started.html). También puedes + [instalar Node.js directamente](https://kinsta.com/blog/how-to-install-node-js/) + siguiendo esta guía. + +También deberías **entender los conceptos básicos de OpenFn**, en particular los +steps y los adaptors. Consulta la +[sección de introducción](/get-started/home.md) de este sitio para ponerte al +día. + +--- + +### Instalar la CLI {#install-the-cli} + +Para descargar la última versión de +[@openfn/cli](https://www.npmjs.com/package/@openfn/cli), ejecuta el siguiente +comando en la línea de comandos. + +```bash +npm install -g @openfn/cli +``` + +Comprueba que todo funciona ejecutando el workflow de prueba incluido: + +```bash +openfn test +``` + +La palabra `openfn` invoca la CLI. La palabra `test` invoca el comando de +prueba. + +
+Despliega para ver la salida esperada + +``` +[CLI] ♦ Versions: + ▸ node.js 18.12.1 + ▸ cli 1.0.0 +[CLI] ℹ Running test workflow... +[CLI] ℹ Execution plan: +[CLI] ℹ { + "options": { + "start": "start" + }, + "workflow": { + "steps": [ + { + "id": "start", + "state": { + "data": { + "defaultAnswer": 42 + } + "expression": "const fn = () => (state) => { console.log('Starting computer...'); return state; }; fn()", + "next": { + "calculate": "!state.error" + } + }, + { + "id": "calculate", + "expression": "const fn = () => (state) => { console.log('Calculating to life, the universe, and everything..'); return state }; fn()", + "next": { + "result": true + } + }, + { + "id": "result", + "expression": "const fn = () => (state) => ({ data: { answer: state.data.answer || state.data.defaultAnswer } }); fn()" + } + ] + } +} + +[CLI] ✔ Compiled all expressions in workflow +[R/T] ℹ Executing undefined +[R/T] ℹ Starting step start +[JOB] ℹ Starting computer... +[R/T] ✔ Completed step start in 1ms +[R/T] ℹ Starting step calculate +[JOB] ℹ Calculating to life, the universe, and everything.. +[R/T] ✔ Completed step calculate in 1ms +[R/T] ℹ Starting step result +[R/T] ✔ Completed step result in 0ms +[CLI] ✔ Result: 42 +``` + +
+ +El resto de la salida es la CLI contándonos lo que hace internamente. + +**Consultar la versión** + +```bash +openfn -v +``` + +**Obtener ayuda** + +```bash +openfn help +``` + +--- + +### Actualizar la CLI {#updating-the-cli} + +Para instalar una versión nueva directamente sobre la que tienes instalada, +ejecuta el siguiente comando. + +```bash +npm install -g @openfn/cli +``` + +--- + +### Solución de problemas {#troubleshooting} + +Si tienes problemas con la instalación, prueba a desinstalar primero la versión +actual y luego vuelve a instalarla. + +```bash +npm uninstall -g @openfn/cli +npm install -g @openfn/cli +``` diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md new file mode 100644 index 00000000000..75e3c94d437 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md @@ -0,0 +1,539 @@ +--- +title: OpenFn Sync +sidebar_label: Sync +slug: /sync +translation_source_hash: e4dbcbf31dd1975afc33be952424a6476b240f73 +translation_review_status: machine +--- + +Los proyectos de OpenFn son totalmente portables, es decir, se pueden mover a +otros lugares. + +Puedes crear un proyecto en la aplicación, descargarlo a tu computadora para +desarrollar sin conexión, volver a subirlo a la aplicación o incluso desplegarlo +en otro servidor de OpenFn. + +A esto lo llamamos OpenFn Sync, y es una de las funciones más potentes que +ofrecen los proyectos de OpenFn. + +## ¿Qué es un proyecto? {#what-is-a-project} + +Un proyecto es un conjunto de workflows que resuelve, automatiza o integra +alguna función de negocio. + +Un proyecto vive en la aplicación de OpenFn (ya sea en la instancia SaaS en la +nube o en una instancia desplegada de forma privada), pero también puede existir +como archivos en un sistema de archivos. + +Cada proyecto lleva asociados algunos metadatos (como un nombre y una +descripción) y cierta configuración, como credenciales y colecciones. + +Dentro de la aplicación de OpenFn, un proyecto es una entidad de nivel superior +facturable, y todos sus workflows y su configuración se guardan en tablas de la +base de datos. + +El proyecto de la aplicación incluye muchas cosas más: la configuración de +canales, el historial de runs, los dataclips guardados y las sesiones de chat +con el asistente de IA. + +El proyecto también puede existir en un sistema de archivos local. En ese caso, +es un conjunto de archivos que la CLI puede leer y ejecutar. Esta representación +local de un proyecto es bastante básica: aquí solo encontrarás workflows y +código. + +En el sistema de archivos pueden existir a la vez varios proyectos relacionados. +Cada uno vive en un único archivo de proyecto. Puedes hacer "checkout" o +"expandir" un proyecto a la vez en una carpeta local, lo que crea un archivo por +cada workflow y un archivo por cada step. + +Es habitual que un mismo proyecto conceptual (es decir, el código y la +configuración que impulsan una función de negocio) exista en varios lugares a la +vez. Puede tener varias representaciones en la aplicación a través de sandboxes, +tener una copia de seguridad en GitHub, ejecutarse localmente en la computadora +de un desarrollador y distribuirse a varias instancias remotas para ejecutarse +en producción. + +A veces llamamos espacio de trabajo a este conjunto de todos los proyectos +conocidos, relacionados y distribuidos. El problema de la sincronización +consiste en cómo se copian, despliegan o replican el código y la configuración +entre las instancias de un proyecto. + +No todos los elementos de un proyecto se incluyen en una sincronización. Por lo +general, sincronizamos los workflows del proyecto y algunas de sus opciones. +Pero no sincronizamos los datos asociados, los valores de las credenciales, el +historial de uso ni las sesiones de IA. + +## Estructura del proyecto {#project-structure} + +OpenFn Sync escribe un proyecto en el sistema de archivos siguiendo una serie de +convenciones. Tanto si usas la CLI como GitHub Sync, un proyecto tiene la +siguiente estructura: + +``` +├── openfn.yaml +├── .projects +│ ├── main@app.openfn.org.yaml +└── workflows + ├── my-workflow + │ ├── my-workflow.yaml + │ ├── my-step.js +``` + +En resumen, estos archivos son: + +- `openfn.yaml` declara que esta carpeta es un proyecto de OpenFn y contiene + metadatos y ajustes +- La carpeta `.projects` contiene una representación YAML completa de cada + proyecto +- La carpeta `workflows` muestra el contenido del proyecto: los steps, las + conexiones, etc. + +Veamos esta estructura con un poco más de detalle. + +### project.yaml {#projectyaml} + +El archivo de proyecto guarda una copia de todo el estado de un proyecto tal +como está guardado en la aplicación. Si lo abres, verás los workflows +representados como texto plano. + +El nombre de un archivo de proyecto tiene la forma `@.yaml`. El +alias es un nombre local que sirve para referirse a una versión concreta del +proyecto. El dominio es el de la instancia de OpenFn desde la que se descargó el +proyecto. + +No deberías editar el archivo de proyecto localmente, porque cualquier cambio se +perderá en la siguiente obtención. + +Puedes obtener tantos proyectos como quieras, y cada uno se guardará en su +propio archivo project.yaml. + +La carpeta `.projects` puede y debe incluirse en el control de versiones. + +### workflows {#workflows} + +Tener todo el proyecto dentro de un único archivo no es una buena forma de leer +o editar workflows. Por eso la CLI puede hacer "checkout" o "expandir" un +archivo de proyecto en el sistema de archivos. + +Hacer checkout es el proceso de escribir cada workflow en un archivo +workflow.yaml y cada step en un archivo step.js. Todo esto vive en el directorio +`workflows`. + +Aquí puedes editar los archivos todo lo que quieras, y los cambios se +registrarán cuando subas o despliegues de nuevo a la aplicación. + +Solo puedes hacer checkout de un proyecto a la vez. En realidad, esto viene muy +bien para trabajar con git, porque puedes hacer checkout de dos proyectos en +ramas distintas y compararlos o fusionarlos directamente entre sí. + +### workflow.yaml {#workflowyaml} + +Un archivo workflow.yaml define los steps de un workflow y las conexiones que +los unen. + +``` +id: my-workflow +name: My Workflow +start: webhook +steps: + - id: my-step + name: My Step + adaptor: '@openfn/language-http@7.2.9' + expression: ./my-step.js + - id: webhook + type: webhook + enabled: true + next: + my-step: + disabled: false + condition: always +``` + +La clave `next` de cada step define las conexiones de salida de ese step, es +decir, los steps que se ejecutan a continuación. En el ejemplo anterior, el step +`webhook` se ejecuta primero (lo determina la clave `start`) y define una única +conexión a `my-step`, que se ejecuta siempre. + +El código de cada step vive en su propio archivo .js. Puedes modificar el código +libremente y sincronizarlo de nuevo con el servidor en cualquier momento. Si +quieres cambiar el nombre de un step, asegúrate de actualizar el nombre del +archivo del step y la ruta de la clave `expression` en `workflow.yaml`. + +### openfn.yaml {#openfnyaml} + +Es un archivo de configuración de nivel superior que, en general, puedes +ignorar. Las herramientas de OpenFn lo usan para reconocer la carpeta raíz de un +proyecto. También contiene opciones de configuración para todos los proyectos +locales y metadatos sobre el proyecto con checkout actual. + +## Autorización {#authorization} + +Antes de usar la CLI para obtener algo de la aplicación, tendrás que +proporcionar una autorización. + +La mejor forma de hacerlo es definir una variable de entorno llamada +`OPENFN_API_KEY`. Dale el valor de tu +[token de acceso personal](/manage-users/api-tokens.md#about-api-tokens). + +:::info Tokens de acceso personal + +Consulta [Crear y administrar tokens de API](/manage-users/api-tokens.md) para +obtener ayuda con la configuración de un token. + +::: + +Si te conectas a varios proyectos o aplicaciones de OpenFn, puedes crear un +archivo `.env` y definir ahí las variables de entorno que necesites. La CLI +cargará este archivo e indicará qué claves está usando. Los valores de tu +archivo `.env` tienen prioridad sobre los definidos en tu sistema. + +También puedes pasar `--api-key` directamente como opción en la mayoría de los +comandos. + +:::info + +Esta guía da por hecho que quieres sincronizar con nuestra aplicación SaaS +alojada en [app.openfn.org](https://app.openfn.org) + +Puedes sincronizar con otra instancia de OpenFn definiendo la variable de +entorno `OPENFN_ENDPOINT` o pasando el argumento `--endpoint` en la mayoría de +los comandos. + +::: + +## Descargar un proyecto {#downloading-a-project} + +Para descargar un proyecto de la aplicación a tu computadora, ejecuta: + +```bash +openfn project pull +``` + +Esto crea un archivo en tu directorio de trabajo llamado +`.projects/main@app.openfn.org.yaml`. + +:::info + +Cada proyecto de la aplicación tiene un identificador único, llamado UUID, que +sirve para referirse a él. Es un número de 32 dígitos con la forma +`a6cc5bdd-b04f-4413-b4b8-132a5115acac` + +Puedes copiar el UUID de un proyecto desde la URL al abrirlo en la aplicación. +Es la cadena larga que va después de `projects`. + +Por ejemplo, el UUID es la parte en negrita de: +{'https://openfn.org/projects/'}{'abc087dd-3963-4260-8d09-ced2e1ff2bb0'}{'/w'} + +::: + +Después de descargar un proyecto por primera vez, no hace falta volver a indicar +el UUID. Puedes usar el alias, el id o dejar el identificador en blanco para +usar el proyecto con checkout actual. + +El comando `project pull` hace tres cosas: + +- Si no tienes un archivo `openfn.yaml`, crea uno +- _Obtiene_ (descarga) tu proyecto de la aplicación y lo guarda en un único + archivo en `.projects/main@app.openfn.org.yaml` +- Hace _checkout_ (expande) de ese proyecto en tu sistema de archivos, con cada + workflow y cada step en su propio archivo. + +## Alias {#aliases} + +En lugar de identificar un proyecto local con un UUID o un id largo, puedes usar +un _alias_. + +Cada proyecto local se guarda en un archivo como `main@app.openfn.org.yaml`, +donde la parte `main` es el alias local del proyecto. + +Puedes descargar un proyecto y definir el alias al mismo tiempo ejecutando: + +```bash +openfn project pull --alias dev +``` + +Esto guarda el proyecto en `dev@app.openfn.org.yaml`. + +Para cambiar el alias, basta con cambiar el nombre del archivo. Lo que vaya +antes de `@` se tratará como el alias. + +## Hacer checkout {#checking-out} + +Puedes hacer checkout de un proyecto en cualquier momento con: + +```bash +openfn project checkout +``` + +Esto actualiza tu carpeta local de workflows con el proyecto indicado. + +Si un checkout va a hacer que se pierdan cambios (es decir, cambiaste un archivo +step.js pero no lo desplegaste), recibirás una advertencia. Agrega `--force` +para ignorar el cambio, o ejecuta `openfn project clean` para borrar y +restablecer la carpeta `workflows`. + +El checkout solo modifica los archivos que gestiona la CLI, básicamente los +archivos de workflows y de steps. Si tienes otros archivos en el sistema de +archivos (como archivos de state o de pruebas), no se tocan. + +## Ejecutar workflows en proyectos {#running-workflows-in-projects} + +Puedes ejecutar cualquier workflow del proyecto con checkout por su nombre: + +```bash +openfn my-workflow +``` + +La CLI busca el workflow en tu carpeta `workflows` y lo ejecuta. Puedes pasar +state con `-s` y definir los niveles de log como de costumbre. + +Al ejecutar un workflow por su nombre de esta forma, obtienes dos ventajas: + +- Las **credenciales** se cargan automáticamente desde el mapa de credenciales + de `openfn.yaml`, así que no necesitas pasar `--credential-map` +- Las **colecciones** usan el servidor configurado en `openfn.yaml`, así que no + necesitas pasar `--collections-endpoint` ni nada más. + +## Desplegar un proyecto {#deploying-a-project} + +Para subir tus cambios locales de nuevo a la aplicación, ejecuta: + +```bash +openfn project deploy +``` + +Esto toma el proyecto con checkout actual y lo sube a la aplicación. También +indica qué cambió en el proyecto local. + +Antes de subirlo, la CLI obtiene la última versión del proyecto desde la +aplicación y comprueba si hay **divergencia**, es decir, si alguno de los +workflows que cambiaste localmente también se editó en la aplicación desde la +última vez que lo descargaste. Si es así, el despliegue falla con un error para +evitar que sobrescribas por accidente el trabajo de otra persona. + +Si quieres subirlo de todos modos, pasa `--force`: + +```bash +openfn project deploy --force +``` + +Para ver qué cambiaría sin subir nada, usa `--dry-run`. Esto registra en el log +el payload final de la actualización que se enviaría a la aplicación (como una +estructura JSON). + +Puedes desplegar el proyecto con checkout como un proyecto nuevo en la +aplicación de destino agregando la opción `--new`. Solo está disponible si +tienes privilegios de superusuario en la instancia de destino. + +También puedes desplegar el proyecto con checkout en otro proyecto de la +aplicación pasando su alias, id o uuid: + +``` +openfn project deploy main +``` + +Si tienes un sandbox de desarrollo con checkout, esto lo fusionaría directamente +en el proyecto principal de la aplicación. + +Ten en cuenta que tienes que haber obtenido el proyecto de destino localmente +antes de poder desplegarlo. + +## Despliegue avanzado {#advanced-deployment} + +De forma predeterminada, `openfn project deploy` toma el proyecto con checkout y +lo sube al servidor del que vino originalmente (según lo define el archivo de +proyecto). + +Pero también puedes usar deploy para sincronizar entre proyectos. Normalmente lo +harás para promover un sandbox de desarrollo o de staging a producción. Incluso +puedes usarlo para desplegar un proyecto de la aplicación SaaS en otra instancia +de OpenFn completamente distinta. + +### Desplegar directamente desde un archivo de spec o de state {#deploy-straight-from-a-spec-or-state-file} + +Con cualquier archivo de proyecto (por ejemplo, main@app.openfn.org.yaml) o una +spec exportada (en formato v1 o v2, tal como se exporta desde la configuración +de la aplicación), puedes desplegar directamente en otra instancia sin tener que +hacer checkout de nada antes. + +Solo tienes que pasar el nombre del archivo de origen como primer argumento. Si +tienes acceso de superusuario, puedes crear un proyecto nuevo así: + +``` +openfn project deploy dev@localhost.yaml --new --endpoint https://app.openfn.org +``` + +Si ya tienes un archivo de proyecto registrado localmente (lo tendrás si lo +obtuviste o descargaste antes), puedes pasar el alias (por ejemplo, `main`) para +desplegar en esa instancia. + +``` +openfn project deploy dev@localhost.yaml main +``` + +Lo más probable es que quieras forzar el despliegue, aunque se detecte +divergencia. Para eso, pasa la opción `-f`. + +Pasa `--no-confirm` o `-y` para omitir las preguntas de confirmación (esto es +importante si ejecutas scripts automatizados). + +### Gestionar credenciales {#managing-credentials} + +Gestionar las credenciales durante un despliegue puede ser complicado. + +Las credenciales del proyecto de origen TIENEN que existir en el proyecto de +destino; de lo contrario, se producirá un error. + +Todavía no hay forma de automatizar por completo la creación de credenciales, +porque plantea muchos problemas de seguridad. + +Sin embargo, la CLI ofrece algunas opciones. + +Puedes quitar por completo las credenciales del despliegue pasando +`--credentials none`. Ten en cuenta que el workflow no se ejecutará en el +destino hasta que se conecten manualmente las credenciales a los steps que las +necesitan. + +:::tip + +El argumento `--credentials` se puede pasar como `-c` o `--cred`. + +::: + +También puedes mapear credenciales, si el propietario o el nombre de las +credenciales es distinto en el sistema de destino. + +Puedes hacerlo con la CLI pasando un mapa separado por comas: + +``` +openfn project deploy spec.yaml --credentials a:service@openfn.org|cred-a,b:service@openfn.org|cred-b +``` + +Esto toma dos credenciales, `a` y `b`, las mapea a los nombres `cred-a` y +`cred-b` y cambia el propietario a `service@openfn.org`. + +También puedes definir estos mapeos en un archivo yaml (el mismo que se usa en +la ejecución). Define la clave `alias` debajo del identificador de la +credencial: + +``` +somedev@gmail.com|a: + alias: service@openfn.org|cred-a + +somedev@gmail.com|a: + alias: service@openfn.org|cred-b + +``` + +Luego pasa la ruta del archivo a la CLI con `--credentials`: + +``` +openfn project deploy spec.yaml --credentials credentials.yaml +``` + +## Sandboxes {#sandboxes} + +La CLI es totalmente compatible con los sandboxes. Trátalos como cualquier otro +proyecto: obtenlos la primera vez con su UUID. + +Usa el comando `checkout` para cambiar entre sandboxes y proyectos localmente. +Recuerda que solo puedes tener un proyecto con checkout a la vez. La CLI te +avisará si un checkout va a hacer que pierdas cambios locales. + +Al obtener un sandbox, el alias del proyecto será, de forma predeterminada, el +nombre del sandbox. + +Puedes fusionar dos proyectos localmente con `openfn project merge` y desplegar +el proyecto resultante en la aplicación (probablemente tendrás que forzar la +subida del cambio). Esto es útil para resolver conflictos. + +## Resolver conflictos de fusión {#resolving-merge-conflicts} + +A veces, fusionar un sandbox puede sobrescribir cambios en el proyecto de +destino. Esto puede pasar si un workflow del proyecto principal cambió _después_ +de que se volviera a crear el sandbox, así que el sandbox no lo conoce. Al +fusionar, se perdería ese cambio en main. + +Puedes resolver estos conflictos localmente con la CLI y git (u otro control de +versiones equivalente) y luego subir el proyecto resuelto a la aplicación. + +:::tip + +¡No necesitas un repositorio de GitHub para usar git! + +Git es simplemente un programa que se ejecuta en la terminal de tu sistema +local. + +GitHub es una aplicación alojada en la nube que a) ofrece acceso remoto a +repositorios git y b) ofrece una interfaz completa sobre un sistema de archivos +controlado por git. + +::: + +Así se hace con git. Este ejemplo da por hecho que quieres fusionar un sandbox +`dev` en tu proyecto principal `main`. + +- Asegúrate de tener lista una carpeta local para trabajar. Tiene que ser un + repositorio git. Ejecuta `git init` en cualquier carpeta para configurar git + (no necesitas un repositorio de GitHub conectado) +- Descarga tu proyecto principal localmente: `openfn project pull ` + (da por hecho que OPENFN_API_KEY está definida) +- Haz commit de tus cambios en git: + `git add . && git commit -m "checkout main project"` +- Ahora descarga tu sandbox localmente: `openfn project pull ` +- Esto hace que tu carpeta local `workflows/` se vea como tu sandbox +- Si ahora ejecutas `git status` y `git diff`, verás todos los cambios que se + aplicarían al proyecto principal al hacer la fusión +- Comprueba que estás conforme con las diferencias. Quizás quieras revertir + algunos archivos para que queden como en main + (`git checkout main workflows/my-workflow/job.js`). O quizás quieras combinar + a mano cambios de los dos proyectos. +- Cuando termines, sube el proyecto a la aplicación con la CLI: + `openfn project deploy main` +- Si quieres, puedes hacer commit de tus cambios en git (pero para este ejemplo + no hace falta) + +Para cambios más complejos, puedes probar este enfoque: + +- Descarga `main` localmente y haz commit +- Crea una rama nueva, y descarga `dev` y haz commit en esa rama +- Vuelve a la rama principal: `git checkout main` +- Fusiona la rama `dev` en main: `git merge dev` +- Resuelve los conflictos que indique git (cada conflicto de git debería + corresponder a un lugar donde tanto main como el sandbox hicieron cambios) +- Cuando termines, usa la CLI para forzar el despliegue de tus cambios + +## GitHub {#github} + +Puedes configurar un proyecto para que se sincronice automáticamente con GitHub. +Así, los commits en GitHub despliegan automáticamente los cambios en un proyecto +de OpenFn, y al presionar Save & Sync en la aplicación se hace commit de vuelta +en GitHub. + +Internamente, GitHub Sync usa los comandos `pull` y `deploy` de la CLI, que +disparan GitHub Actions, para sincronizar tus proyectos. + +Ten en cuenta que, de forma predeterminada, GitHub Sync usa el formato antiguo, +con los archivos `state.json`, `project.yaml` y `config.json`. Al configurar un +nuevo GitHub Sync, puedes elegir el formato v2. La sincronización v2 solo sirve +para descargar un único proyecto por rama en GitHub, porque varios proyectos +sobrescribirían la misma carpeta `workflows/`. + +Consulta [Control de versiones](/manage-projects/link-to-gh.md) para obtener más +detalles sobre GitHub Sync. + +## Referencia rápida {#cheatsheet} + +| Comando | Descripción | +| ---------------------------------------- | ------------------------------------------------------------------------------------------ | +| `openfn project pull ` | Descarga un proyecto de la aplicación por primera vez | +| `openfn project pull` | Vuelve a descargar el proyecto actual | +| `openfn project pull --alias dev` | Descarga y define un alias local | +| `openfn project fetch ` | Obtiene un proyecto sin hacer checkout | +| `openfn project` | Lista todos los proyectos locales de la carpeta de trabajo actual | +| `openfn project checkout ` | Cambia a otro proyecto local | +| `openfn project deploy` | Despliega en la aplicación el proyecto con checkout | +| `openfn project deploy --dry-run` | Prueba un despliegue, pero omite el paso de subida | +| `openfn project deploy --force` | Fuerza la subida del proyecto con checkout, ignorando cualquier advertencia de divergencia | +| `openfn ` | Ejecuta un workflow del proyecto con checkout | +| `openfn project clean` | Borra la carpeta `workflows` y todo su contenido, y luego hace checkout del proyecto | diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-usage.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-usage.md new file mode 100644 index 00000000000..59153dcf141 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-usage.md @@ -0,0 +1,247 @@ +--- +title: Uso básico de la CLI de OpenFn +sidebar_label: Uso básico +slug: /cli-usage +translation_source_hash: 7f9249533167dbd2f99d20f84089330325908f60 +translation_review_status: machine +--- + +Esta página muestra ejemplos de algunos de los usos más comunes de la CLI, como: + +- obtener ayuda +- ejecutar un job +- guardar el state +- ajustar el nivel de logs +- mantener el repositorio de adaptors +- ejecutar un workflow +- cargar la documentación de un adaptor + +--- + +### Obtener ayuda {#get-help} + +```bash +openfn --help +``` + +```bash +openfn deploy --help +``` + +--- + +### Ejecutar un job {#run-a-job} + +Para ejecutar un solo job, tienes que indicar explícitamente qué adaptor usar. +Consulta los [adaptors disponibles públicamente](/adaptors). + +Si no se detecta la versión indicada, el adaptor se instala automáticamente. + +**Ejecutar un job con el adaptor http:** + +```bash +openfn path/to/job.js -a http +``` + +**Usar una versión concreta del adaptor:** + +```bash +openfn path/to/job.js -a http@2.0.0 +``` + +**Pasar la ruta de un adaptor instalado localmente:** + +```bash +openfn path/to/job.js -a http=/repo/openfn/adaptors/my-http-build +``` + +**Usar la compilación local del monorepo de adaptors:** + +```bash +openfn path/to/job.js -ma http +``` + +Tienes que indicar la ruta al monorepo en la variable de entorno +OPENFN_ADAPTORS_REPO. Por ejemplo: + +```bash +OPENFN_ADAPTORS_REPO=~/openfn/adaptors openfn job.js -ma http +``` + +Normalmente la defines en un archivo de configuración como `.profile` o +`.zshrc`. + +¡No olvides volver a compilar el adaptor antes de usarlo! + +**Ejecutar desde un step inicial concreto** + +Puedes indicar un step con su id exacto o con una parte del nombre o del id. + +```bash +openfn path/to/job.js --start cf628d9e -s path/to/input.json +``` + +Si ya guardaste en caché los resultados de este workflow, la CLI carga +automáticamente la entrada correcta desde la caché cuando omites el argumento +`-s`: + +```bash +openfn path/to/job.js --start cf628d9e +``` + +También puedes pasar `--end` para que el workflow termine antes. + +**Ejecutar un solo step** + +`--only` funciona igual que `--start` y `--end`. Puedes indicar una parte del +nombre o del id del step, y la entrada se carga automáticamente desde la caché. + +```bash +openfn path/to/job.js --only cf628d9e +``` + +--- + +### Gestionar el state de salida {#handle-output-state} + +Cuando termina el job, la CLI escribe el state resultante en el disco. De forma +predeterminada, crea un archivo `output.json` junto al archivo del job. + +**Puedes indicar rutas personalizadas para los archivos de salida y de state:** + +```bash +openfn path/to/job.js -a adaptor-name -o path/to/output.json -s path/to/state.json +``` + +**Usa `-O` para devolver la salida por stdout:** + +```bash +openfn path/to/job.js -a adaptor-name -O +``` + +**Guardar localmente los resultados de todos los steps** + +```bash +openfn path/to/workflow.json --cache-steps +``` + +Cada step escribe su salida en `./.cli-cache//.json`. +Git ignora la carpeta `.cli-cache`, y la caché se borra cuando vuelves a +ejecutar el workflow con `--cache-steps` habilitado. + +Para guardar en caché _siempre_, define la variable de entorno +`OPENFN_ALWAYS_CACHE_STEPS` como `"true"`, y pasa `--no-cache-steps` para +deshabilitarlo temporalmente. + +--- + +### Ajustar el nivel de logs {#adjust-logging-level} + +Puedes pasar `-l info` o `--log info` para obtener más información sobre lo que +ocurre durante la ejecución. Estos son los distintos niveles de logs: + +| nivel de logs | descripción | +| --------------------------------------------- | ------------------------------------------------------------ | +| `openfn path/to/job.js -a adaptor -l none` | Modo silencioso | +| `openfn path/to/job.js -a adaptor -l default` | Información general de lo que está ocurriendo | +| `openfn path/to/job.js -a adaptor -l info` | Más información sobre el runtime, la CLI y el job | +| `openfn path/to/job.js -a adaptor -l debug` | Información sobre el runtime, la CLI, el compilador y el job | + +--- + +### Mantener el repositorio de adaptors instalados automáticamente {#maintain-auto-installed-adaptors-repo} + +**Listar el contenido del repositorio:** + +```bash +openfn repo list +``` + +**Indicar la carpeta del repositorio con la variable de entorno +`OPENFN_REPO_DIR`:** + +```bash +export OPENFN_REPO_DIR=/path/to/repo +``` + +**Instalar adaptors automáticamente y comprobar si el repositorio tiene una +versión que coincida:** + +```bash +openfn path/to/job.js -a adaptor-name +``` + +**Eliminar todos los adaptors del repositorio:** + +```bash +openfn repo clean +``` + +--- + +### Ejecutar un workflow {#run-a-workflow} + +
+ Haz clic para ver la estructura JSON de un workflow de ejemplo + +```json +{ + "options": { + "start": "a" // optionally specify the start node (defaults to steps[0]) + }, + "workflow": { + "steps": [ + { + "id": "a", + "expression": "fn((state) => state)", // code or a path + "adaptor": "@openfn/language-common@1.75", // specify the adaptor to use (version optional) + "state": { + "data": {} // optionally pre-populate the data object (this will be overridden by keys in previous state) + }, + "configuration": {}, // Use this to pass credentials + "next": { + // This object defines which steps to call next + // All edges returning true will run + // If there are no next edges, the workflow will end + "b": true, + "c": { + "condition": "!state.error" // Note that this is an expression, not a function + } + } + } + ] + } +} +``` + +
+ +**Para ejecutar un workflow:** + +```bash +openfn path/to/workflow.json -o tmp/output.json +``` + +Consulta este +[tutorial](/build-for-developers/cli-walkthrough.md#7-running-workflows) +detallado sobre cómo ejecutar workflows con la CLI. + +--- + +### Cargar la documentación de un adaptor {#load-adaptor-documentation} + +La CLI puede mostrar la documentación de un adaptor en la terminal. Ten en +cuenta que primero tiene que descargar el adaptor al repositorio (si todavía no +está ahí), lo que puede tardar un momento. + +**Mostrar una lista de las funciones del adaptor** + +```bash +openfn docs http +``` + +**Mostrar la documentación de una función concreta** + +```bash +openfn docs http post +``` diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md new file mode 100644 index 00000000000..4e5581f3f12 --- /dev/null +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md @@ -0,0 +1,902 @@ +--- +title: Recorrido por la CLI +sidebar_label: Recorrido por la CLI +slug: /cli-walkthrough +translation_source_hash: a044b0a82a85cef420e88d48a916f20e81f5ddb0 +translation_review_status: machine +--- + +### 1. Primeros pasos con la CLI {#1-getting-started-with-the-cli} + +:::info Para empezar con @openfn/cli + +1. Crea una carpeta nueva para el repositorio en el que vas a trabajar con este + comando: `mkdir devchallenge && cd devchallenge` + +2. Aunque puedes guardar tus scripts de jobs en cualquier lugar, es buena + práctica guardar `state.json` y `output.json` en una carpeta `tmp`. Para + hacerlo, crea un directorio llamado `tmp` dentro de tu carpeta + `devchallenge`: `mkdir tmp` + +3. Como `state.json` y `output.json` pueden contener información de + configuración sensible y datos del proyecto, es importante no subirlos nunca + a GitHub. Para que GitHub ignore estos archivos, agrega el directorio `tmp` a + tu archivo `.gitignore`: `echo "tmp" >> .gitignore` +4. (Opcional) Usa el comando `tree` para comprobar que la estructura de + directorios es correcta. Al ejecutar `tree -a` en tu carpeta `devchallenge` + deberías ver una estructura como esta: + ```bash + devchallenge + ├── .gitignore + └── tmp + ├── state.json + └── output.json + ``` + +::: + +1. Crea un archivo de job llamado `hello.js` y escribe el siguiente código. + + ```js + console.log('Hello World!'); + ``` + +
+ ¿Qué es un job? + Un job de OpenFn es código JavaScript que sigue un conjunto concreto de convenciones. + Normalmente un job tiene una o más operaciones que realizan una tarea concreta + (como obtener información de una base de datos, crear un registro, etc.) y + devuelven el state para que lo use la siguiente operación. +
+ +
+ ¿Qué es console.log? + console.log es una función básica del lenguaje JavaScript que te + permite mostrar mensajes en la ventana de la terminal. +
+ +2. Ejecuta el job con la CLI + + ```bash + openfn hello.js -o tmp/output.json + ``` + +
+ Ver la salida esperada + + ```bash + [CLI] ⚠ WARNING: No adaptor provided! + [CLI] ⚠ This job will probably fail. Pass an adaptor with the -a flag, eg: + openfn job.js -a common + [CLI] ✔ Compiled from hello.js + [R/T] ♦ Starting job job-1 + [JOB] ℹ Hello World! + [R/T] ✔ Completed job job-1 in 1ms + [CLI] ✔ State written to tmp/output.json + [CLI] ✔ Finished in 17ms ✨ + + ``` + +
+ +Fíjate en que tu instrucción `console.log` se imprimió como +`[JOB] Hello World!`. Usar la consola así ayuda a depurar o a entender qué pasa +dentro de tus steps. + +### 2. Usar las funciones auxiliares de los adaptors {#2-using-adaptor-helper-functions} + +Los adaptors son módulos de JavaScript o +[TypeScript](https://www.typescriptlang.org/) (un superconjunto de JavaScript +con tipado fuerte) que ofrecen a los usuarios de OpenFn un conjunto de funciones +auxiliares para simplificar la comunicación con un sistema externo concreto. Más +información sobre los adaptors: [docs.openfn.org/adaptors](/adaptors/) + +#### Uso básico: {#basic-usage} + +Usemos el adaptor +[@openfn/language-http](https://www.npmjs.com/package/@openfn/language-http) +para obtener una lista de formularios de +[https://jsonplaceholder.typicode.com/](https://jsonplaceholder.typicode.com/) + +#### Tareas: {#tasks} + +1. Crea un archivo llamado `getPosts.js` y escribe el siguiente código + + ```jsx title=getPosts.js + get('https://jsonplaceholder.typicode.com/posts'); + fn(state => { + console.log(state.data[0]); + return state; + }); + ``` + +2. Ejecuta el job con este comando + +```bash +openfn getPosts.js -i -a http -o tmp/output.json +``` + +:::info Los argumentos de la CLI + +Usa `-a` para indicar el adaptor y `-i` para instalar automáticamente el adaptor +necesario + +Ejecuta `openfn help` para ver la lista completa de argumentos de la CLI. + +::: + +Como es la primera vez que usas el adaptor `http`, lo instalas con el argumento +`-i`. + +
+ 3. Expande para ver los logs esperados de la CLI + +```bash + [CLI] ✔ Installing packages... + [CLI] ✔ Installed @openfn/language-http@4.2.8 + [CLI] ✔ Installation complete in 14.555s + [CLI] ✔ Compiled from getPosts.js + [R/T] ♦ Starting job job-1 + GET request succeeded with 200 ✓ + [JOB] ℹ { + userId: 1, + id: 1, + title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', + body: 'quia et suscipit\n' + + 'suscipit recusandae consequuntur expedita et cum\n' + + 'reprehenderit molestiae ut ut quas totam\n' + + 'nostrum rerum est autem sunt rem eveniet architecto' + } + [R/T] ✔ Completed job job-1 in 872ms + [CLI] ✔ State written to tmp/output.json + [CLI] ✔ Finished in 15.518s ✨ + +``` + +
+ +:::warning Datos de ejemplo + +Los datos que aparecen en estos logs de la CLI provienen de la API de +[JSONPlaceholder](https://jsonplaceholder.typicode.com/) y no representan +información real. Solo sirven para pruebas y desarrollo. + +Para hacer pruebas precisas, considera usar datos reales de tu API o servicio. + +::: + +### 3. Entender `state` {#3-understanding-state} + +Si la expresión de un job es un conjunto de instrucciones para un chef (¿una +receta?), el state inicial son todos los ingredientes que necesita, bien atados +en un paquetito perfecto. Consulta +[It all starts with state](/articles/2021/07/05/wrapping-my-head-around-jobs/#it-all-starts-with-state) +en la base de conocimiento para más contexto. + +
+ Suele verse más o menos así + +```json +{ + "configuration": { + "hostUrl": "https://moh.kenya.gov.ke/dhis2", + "username": "someone", + "password": "something-secret" + }, + "data": { + "type": "registration", + "patient": { + "age": 24, + "gender": "M", + "nationalId": "321cs7" + } + } +} +``` + +
+ +#### `state.configuration` {#stateconfiguration} + +En esta clave van las credenciales que autorizan las conexiones con cualquier +sistema autenticado con el que interactúe el job. (Ten en cuenta que, cuando +usas la plataforma OpenFn en lugar de la CLI, esta parte de `state` suele +sobrescribirse en tiempo de ejecución con una "credencial" real). + +:::warning Importante + +Ten en cuenta que `console.log(state)` muestra todo el state, incluidos +elementos de `state.configuration` como el **nombre de usuario y la +contraseña**. Elimina este log cuando termines de depurar, para no exponer +información sensible por accidente cuando el job se despliegue en producción. + +La plataforma OpenFn tiene protecciones integradas para "limpiar" el state de +los logs, pero cuando usas la CLI directamente, ¡estás por tu cuenta! + +::: + +#### `state.data` {#statedata} + +En esta clave van los datos relacionados con un run concreto de un job. En la +plataforma, son los datos propios de la work order que vienen de una solicitud +HTTP que activa el trigger, o algún dato que se pasa de un job a otro. + +Con la CLI, `state.json` se carga automáticamente desde el directorio actual. + +También puedes indicar la ruta del archivo de state con la opción -s, +--state-path. + +Indica la ruta de tu archivo `state.json` con este comando: + +```bash +openfn hello.js -a http -s tmp/state.json -o tmp/output.json +``` + +
+ Expande para ver los logs esperados de la CLI + +``` +[CLI] ✔ Compiled job from hello.js +GET request succeeded with 200 ✓ +[R/T] ✔ Operation 1 complete in 876ms +[R/T] ✔ Operation 2 complete in 0ms +[CLI] ✔ Writing output to tmp/output.json +[CLI] ✔ Done in 1.222s! ✨ +``` + +
+ +#### ¿Cómo puedes usar el state? {#how-can-we-use-state} + +Cada adaptor tiene un esquema de configuración recomendado para tu `state.json`. +El +[esquema de configuración de http](/adaptors/packages/http-configuration-schema) +muestra cómo configurar `state.configuration` para `language-http`: + +```json +{ + "username": "name@email", + "password": "supersecret", + "baseUrl": "https://jsonplaceholder.typicode.com" +} +``` + +#### Tareas: {#tasks-1} + +1. Actualiza tu `state.json` para que quede así: + +
+ Expande para ver state.json + + ```json title=state.json + { + "configuration": { + "baseUrl": "https://jsonplaceholder.typicode.com" + } + } + ``` + +
+ +Como actualizaste la configuración en tu `state.json`, ahora puedes usar la +función auxiliar `get()` sin indicar la **baseUrl**, es decir, `get('posts')`. + +2. Actualiza tu job `getPosts.js` para que quede así: + +
+ Expande para ver getPosts.js + + ```js title="getPosts.js" + // Get all posts + get('posts'); + + fn(state => { + const posts = state.data; + console.log(posts[0]); + return state; + }); + ``` + +
+ +3. Ahora ejecuta el job con el siguiente comando + + ```bash + openfn getPosts.js -a http -s tmp/state.json -o tmp/output.json + ``` + +
+ Y comprueba que ves los logs esperados de la CLI: + + ```bash + [CLI] ✔ Compiled job from getPosts.js + GET request succeeded with 200 ✓ + [R/T] ✔ Operation 1 complete in 120ms + [JOB] ℹ { + userId: 1, + id: 1, + title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', + body: 'quia et suscipit\n' + + 'suscipit recusandae consequuntur expedita et cum\n' + + 'reprehenderit molestiae ut ut quas totam\n' + + 'nostrum rerum est autem sunt rem eveniet architecto' + } + [R/T] ✔ Operation 2 complete in 0ms + [CLI] ✔ Writing output to tmp/output.json + [CLI] ✔ Done in 470ms! ✨ + + ``` + +
+ +### 4. Limpiar y transformar datos {#4-clean--transform-data} + +En la mayoría de los casos necesitas manipular, limpiar o transformar datos en +algún step de tu workflow. Por ejemplo, después de obtener datos del registro +`https://jsonplaceholder.typicode.com`, quizás necesites agrupar las +publicaciones por id de usuario. El ejemplo de abajo muestra cómo: + +1. obtener todas las publicaciones y devolverlas en `state.data` +2. agrupar las publicaciones devueltas por `userId` +3. mostrar en el log las publicaciones con userId `1` + +
+Expande para ver el ejemplo: + +```js title="getPosts.js" +// Get all posts +get('posts'); + +// Group posts by user id +fn(state => { + const posts = state.data; + + // Group posts by userId + const groupPostsByUserId = posts.reduce((acc, post) => { + const existingValue = acc[post.userId] || []; + return { + ...acc, + [post.userId]: [...existingValue, post], + }; + }, {}); + + console.log(groupPostsByUserId); + + return { ...state, groupPostsByUserId }; +}); + +// Log posts where userId = 1 +fn(state => { + const { groupPostsByUserId } = state; + console.log('Post with userId 1', groupPostsByUserId[1]); + return state; +}); +``` + +
+ +
+¿Qué es array.reduce? +El método reduce() aplica una función a un acumulador y a cada +valor del array (de izquierda a derecha) para reducirlo a un único valor. + +Quizás el caso más fácil de entender de reduce() es devolver la +suma de todos los elementos de un array: + +##### Demostración de JavaScript: `Array.reduce()` {#javascript-demo-arrayreduce} + +``` + +// 0 + 1 + 2 + 3 + 4 +const array1 = [1, 2, 3, 4]; +const initialValue = 0; +const sumWithInitial = array1.reduce( + (accumulator, currentValue) => accumulator + currentValue, + initialValue +); + +console.log(sumWithInitial); // Expected output: 10 + +``` + +Puedes aprender más sobre `array.reduce` en la +[referencia de MDN de Array.prototype.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce). + +
+ +
+ Expande para ver los logs esperados de la CLI + +``` + +[CLI] ✔ Compiled job from getPosts.js +GET request succeeded with 200 ✓ +[R/T] ✔ Operation 1 complete in 825ms +[R/T] ✔ Operation 2 complete in 0ms +[JOB] ℹ Post with userId 1 [ //All of posts for userId 1 ] +[R/T] ✔ Operation 3 complete in 12ms +[CLI] ✔ Writing output to tmp/output.json +[CLI] ✔ Done in 1.239s! ✨ + +``` + +
+ +### 5. Depurar errores {#5-debugging-errors} + +Al depurar, es interesante y útil usar console.log para ver el contenido de los +objetos que manipulas (como state). + +Cuando quieras inspeccionar el contenido de state entre operaciones, agrega un +bloque `fn()` con un `console.log`: + +```js +// firstOperation(...); + +fn(state => { + console.log(state); + return state; +}); + +// secondOperation(...); +``` + +##### Crea **debug.js** y pega el código de abajo {#create-debugjs-and-paste-the-code-below} + +
+ + Expande para ver debug.js + +```jsx title="debug.js" +// Get all posts +get('posts'); + +// Get post by index helper function +fn(state => { + // const getPostbyIndex = (index) => dataValue(index)(state); + console.log(dataValue(1)); + + return { ...state }; +}); +``` + +
+ +##### Ejecuta **openfn debug.js -a http -s tmp/state.json** {#run-openfn-debugjs--a-http--s-tmpstatejson} + +
+ Logs esperados de la CLI + +```bash +[CLI] ✘ TypeError: path.match is not a function + at dataPath (/tmp/openfn/repo/node_modules/@openfn/language-common/dist/index.cjs:258:26) + at dataValue (/tmp/openfn/repo/node_modules/@openfn/language-common/dist/index.cjs:262:22) + at getPostbyIndex (vm:module(0):5:37) + at vm:module(0):18:36 + at /tmp/openfn/repo/node_modules/@openfn/language-common/dist/index.cjs:241:12 + at file:///home/openfn/.asdf/installs/nodejs/18.12.0/lib/node_modules/@openfn/cli/node_modules/@openfn/runtime/dist/index.js:288:26 + at process.processTicksAndRejections (node:internal/process/task_queues:95:5) + at async run (file:///home/openfn/.asdf/installs/nodejs/18.12.0/lib/node_modules/@openfn/cli/node_modules/@openfn/runtime/dist/index.js:269:18) + at async executeHandler (file:///home/openfn/.asdf/installs/nodejs/18.12.0/lib/node_modules/@openfn/cli/dist/process/runner.js:388:20) +``` + +
+ +Como ves en los logs, la función auxiliar `dataValue` tiene un TypeError. Para +solucionarlo, puedes ir a la documentación de **dataValue -> +[docs.openfn.org/adaptors/packages/common-docs/#datavalue](/adaptors/packages/common-docs/#datavalue)**. + +Según la documentación, dataValue recibe como entrada una ruta de tipo string. +Pero en tu operación pasabas un entero; por eso aparece el _TypeError_. Puedes +corregir el error pasando un string a dataValue, es decir, +`console.log(dataValue("1"))`. + +
+ Logs esperados de la CLI + +```bash +[CLI] ✔ Compiled job from debug.js +GET request succeeded with 200 ✓ +[R/T] ✔ Operation 1 complete in 722ms +[JOB] ℹ [Function (anonymous)] +[R/T] ✔ Operation 2 complete in 1ms +[CLI] ✔ Writing output to tmp/output.json +[CLI] ✔ Done in 1.102s ✨ +``` + +
+ +Si necesitas más información para depurar, puedes pasar `-l debug`. Esto +establece el nivel de log en _debug_, que registra toda la información de la +ejecución. + +Es decir, `openfn debug.js -a http -l debug`. + +### 6. Each e iteración de arrays {#6-each-and-array-iteration} + +A menudo tienes que realizar la misma operación varias veces, una por cada +elemento de un array. La mayoría de las funciones auxiliares para manipular +datos se heredan de @openfn/language-common y están disponibles en la mayoría de +los adaptors. + +##### Modifica getPosts.js para agrupar las publicaciones por ID de usuario {#modify-getpostsjs-to-group-posts-by-user-id} + +
+Expande para ver getPosts.js + +```js title="getPosts.js" +// Get all posts +get('posts'); + +// Group posts by user +fn(state => { + const posts = state.data; + + // Group posts by userId + const groupPostsByUserId = posts.reduce((acc, post) => { + const existingValue = acc[post.userId] || []; + return { ...acc, [post.userId]: [...existingValue, post] }; + }, {}); + + // console.log(groupPostsByUserId); + return { ...state, groupPostsByUserId }; +}); + +// Log posts where userId = 1 +fn(state => { + const { groupPostsByUserId } = state; + const posts = groupPostsByUserId[1]; + + // console.log("Post with userId 1", groupPostsByUserId[1]); + return { ...state, posts }; +}); + +each('posts[*]', state => { + console.log('Post', JSON.stringify(state.data, null, 2)); + return state; +}); +``` + +
+ +Fíjate en que este código usa la función `each`, una función auxiliar definida +en [language-common](/adaptors/packages/common-docs/#each) pero a la que se +accede desde este job, que usa `language-http`. La mayoría de los adaptors +importan muchas funciones de `language-common`. + +Ejecuta **openfn getPosts.js -a http -s tmp/state.json -o tmp/output.json** + +
+ Expande para ver los logs esperados de la CLI + +```bash +[CLI] ✔ Compiled job from getPosts.js +GET request succeeded with 200 ✓ +[R/T] ✔ Operation 1 complete in 730ms +[R/T] ✔ Operation 2 complete in 0ms +[R/T] ✔ Operation 3 complete in 0ms +[JOB] ℹ Posts [ +// Posts +] +[R/T] ✔ Operation 4 complete in 10ms +[CLI] ✔ Writing output to tmp/output.json +[CLI] ✔ Done in 1.091s! ✨ +``` + +
+ +### 7. Ejecutar workflows {#7-running-workflows} + +Ejecutar un workflow te permite definir una lista de steps y las reglas para +ejecutarlos. Puedes usar un workflow para orquestar el flujo de datos entre +sistemas de forma estructurada y automatizada. + +Por ejemplo, si tu workflow tiene dos steps (GET de usuarios del sistema A y +POST de usuarios al sistema B), puedes configurarlo para que ejecute todos los +steps en secuencia, de principio a fin. Esto imita los +[patrones de flow triggers](/documentation/legacy/build/triggers#flow-triggers) +de la plataforma OpenFn, donde un segundo job debe ejecutarse después de que el +primero termine con éxito, usando los datos que devolvió el primer job. + +:::info En resumen + +No tendrás que armar el state inicial del siguiente job: el state final del job +anterior se pasa automáticamente al job siguiente como state inicial. + +::: + +##### Workflow {#workflow} + +Un workflow es el plan de ejecución para correr varios steps en secuencia. Se +define como un objeto JSON con las siguientes propiedades: + +```json +{ + "options": { + "start": "a" // optionally specify the start node (defaults to steps[0]) + }, + "workflow": { + "steps": [ + { + "id": "a", + "expression": "fn((state) => state)", // code or a path + "adaptor": "@openfn/language-common@1.75", // specify the adaptor to use (version optional) + "state": { + "data": {} // optionally pre-populate the data object (this will be overridden by keys in previous state) + }, + "configuration": {}, // Use this to pass credentials + "next": { + // This object defines which steps to call next + // All edges returning true will run + // If there are no next edges, the workflow will end + "b": true, + "c": { + "condition": "!state.error" // Note that this is an expression, not a function + } + } + } + ] + } +} +``` + +###### Ejemplo de un workflow {#example-of-a-workflow} + +
+Este es un ejemplo de un workflow sencillo con tres steps: + +```json title="workflow.json" +{ + "options": { + "start": "getPatients" + }, + "workflow": { + "steps": [ + { + "id": "getPatients", + "adaptor": "http", + "expression": "getPatients.js", + "configuration": "tmp/http-creds.json", + "next": { + "getGlobalOrgUnits": true + } + }, + { + "id": "getGlobalOrgUnits", + "adaptor": "common", + "expression": "getGlobalOrgUnits.js", + "next": { + "createTEIs": true + } + }, + { + "id": "createTEIs", + "adaptor": "dhis2", + "expression": "createTEIs.js", + "configuration": "tmp/dhis2-creds.json" + } + ] + } +} +``` + +
+ +
+ tmp/http-creds.json + +```json title="tmp/http-creds.json" +{ + "baseUrl": "https://jsonplaceholder.typicode.com" +} +``` + +
+ +
+ tmp/dhis2-creds.json + +```json title="tmp/dhis2-creds.json" +{ + "hostUrl": "https://play.im.dhis2.org/dev", + "password": "district", + "username": "admin" +} +``` + +
+ +
+ getPatients.js + +```js title="getPatients.js" +// Get users from jsonplaceholder +get('users'); + +// Prepare new users as new patients +fn(state => { + const newPatients = state.data; + return { ...state, newPatients }; +}); +``` + +
+ +
+ getGlobalOrgUnits.js + +```js title="getGlobalOrgUnits.js" +// Globals: orgUnits +fn(state => { + const globalOrgUnits = [ + { + label: 'Njandama MCHP', + id: 'g8upMTyEZGZ', + source: 'Gwenborough', + }, + { + label: 'Njandama MCHP', + id: 'g8upMTyEZGZ', + source: 'Wisokyburgh', + }, + { + label: 'Njandama MCHP', + id: 'g8upMTyEZGZ', + source: 'McKenziehaven', + }, + { + label: 'Njandama MCHP', + id: 'g8upMTyEZGZ', + source: 'South Elvis', + }, + { + label: 'Ngelehun CHC', + id: 'IpHINAT79UW', + source: 'Roscoeview', + }, + { + label: 'Ngelehun CHC', + id: 'IpHINAT79UW', + source: 'South Christy', + }, + { + label: 'Ngelehun CHC', + id: 'IpHINAT79UW', + source: 'Howemouth', + }, + { + label: 'Ngelehun CHC', + id: 'IpHINAT79UW', + source: 'Aliyaview', + }, + { + label: 'Baoma Station CHP', + id: 'jNb63DIHuwU', + source: 'Bartholomebury', + }, + { + label: 'Baoma Station CHP', + id: 'jNb63DIHuwU', + source: 'Lebsackbury', + }, + ]; + + return { ...state, globalOrgUnits }; +}); +``` + +
+ +
+ createTEIs.js + +```js title="createTEIs.js" +fn(state => { + const { newPatients, globalOrgUnits } = state; + + const getOrgUnit = city => + globalOrgUnits.find(orgUnit => orgUnit.source === city).id; + + const mappedEntities = newPatients.map(patient => { + const [firstName = 'Patient', lastName = 'Test'] = ( + patient.name || '' + ).split(' '); + + const orgUnit = getOrgUnit(patient.address.city); + + const attributes = [ + { attribute: 'w75KJ2mc4zz', value: firstName }, + { attribute: 'zDhUuAYrxNC', value: lastName }, + { attribute: 'cejWyOfXge6', value: 'Male' }, + ]; + + return { ...patient, attributes: attributes, orgUnit: orgUnit }; + }); + + return { ...state, mappedEntities }; +}); + +each( + 'mappedEntities[*]', + create('trackedEntityInstances', { + orgUnit: dataValue('orgUnit'), + trackedEntityType: 'nEenWmSyUEp', + attributes: dataValue('attributes'), + }) +); +``` + +
+ +Para ejecutar el workflow, usa `openfn [path/to/workflow.json]`. + +
+ +Por ejemplo, si creaste workflow.json en la raíz del directorio de +tu proyecto, esta sería la estructura del proyecto: + + +```bash + devchallenge + ├── .gitignore + ├── getPatients.js + ├── createTEIs.js + ├── getGlobalOrgUnits.js + ├── workflow.json + └── tmp + ├── http-creds.json + ├── dhis2-creds.json + └── output.json +``` + +
+ +```bash +openfn workflow.json -o tmp/output.json +``` + +Al ejecutarse, este workflow corre primero el job `getPatients.js`. Si termina +con éxito, `getGlobalOrgUnits.js` se ejecuta con el state final de +`getPatients.js`. Si `getGlobalOrgUnits.js` termina con éxito, `createTEIs.js` +se ejecuta con el state final de `getGlobalOrgUnits.js`. + +Ten en cuenta que los adaptors indicados en `workflow.json` se instalan +automáticamente cuando ejecutas el workflow. Para ejecutar el workflow, usa este +comando: + +```bash +openfn workflow.json -o tmp/output.json +``` + +Al ejecutarlo, primero se instalan automáticamente los adaptors y luego se +ejecuta el workflow. + +:::danger Importante + +Cuando trabajes con el archivo `workflow.json`, es importante manejar de forma +segura la información sensible, como las credenciales y los datos de entrada +iniciales. Para proteger tus datos sensibles, sigue estas pautas: + +1. Clave de configuración: en el archivo `workflow.json`, indica la ruta a un + archivo de configuración ignorado por git que contenga las credenciales + necesarias para acceder al sistema de destino. Por ejemplo: + + ```json + { + ... + "configuration": "tmp/openMRS-credentials.json" + }, + ``` + +2. Clave de datos: si necesitas pasar datos iniciales a tu job, indica la ruta a + un archivo de datos ignorado por git: + ```json + { + ... + "state": { + "data": "tmp/initial-data.json", + } + } + ``` + +::: From 90509887b3f88ff334bb48e66615d3d16f1152df Mon Sep 17 00:00:00 2001 From: Lucy Macartney Date: Fri, 2 Oct 2026 09:50:16 +0100 Subject: [PATCH 2/2] Fix Spanish CLI pages after review-translation Add rules for "probar a", "Expand to see", and "correr". --- .agents/skills/translate/es.md | 1 + .../build-for-developers/cli-challenges.md | 2 +- .../build-for-developers/cli-collections.md | 4 +-- .../current/build-for-developers/cli-intro.md | 8 +++--- .../current/build-for-developers/cli-sync.md | 16 ++++++------ .../build-for-developers/cli-walkthrough.md | 16 ++++++------ translation-rules.yml | 25 +++++++++++++++++++ 7 files changed, 49 insertions(+), 23 deletions(-) diff --git a/.agents/skills/translate/es.md b/.agents/skills/translate/es.md index ccc3c28f69a..5e9cb8cb364 100644 --- a/.agents/skills/translate/es.md +++ b/.agents/skills/translate/es.md @@ -29,6 +29,7 @@ Avoid slang from any one country. | considerar | plantearse | | por ejemplo, or como before a list | p. ej. | | en campo (in the field) | en terreno | +| intentar (try to) | probar a | | entrada (input) | input | Keep `Input` when it names the panel in the app. "Payload" stays in English. diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md index 6218ca1160a..e35c7b195a4 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-challenges.md @@ -16,7 +16,7 @@ translation_review_status: machine - Si te quedas atascado y necesitas ayuda, publica en [community.openfn.org](https://community.openfn.org).
- Despliega para ver la plantilla de reporte de errores + Expande para ver la plantilla de reporte de errores ```markdown Subject: Bug Report - [Brief Description] diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md index 76a37a77477..bda63281f9b 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-collections.md @@ -205,7 +205,7 @@ Si usas un patrón de claves para obtener datos, el valor se devuelve en modo multielemento: un objeto JSON donde la clave es la clave del elemento y el valor es el valor del elemento. -Así que, si obtenemos todos los elementos cuya clave empieza por `item-`: +Así que, si obtienes todos los elementos cuya clave empieza por `item-`: ```bash $ openfn collections get my-collection item-1* @@ -229,7 +229,7 @@ Los datos resultantes se verán así: ## Subir elementos {#uploading-items} Puedes usar el comando `collections` para subir datos a una colección. Al subir, -los valores siempre vienen de un archivo en disco. En este ejemplo usaremos +los valores siempre vienen de un archivo en disco. En este ejemplo se usan archivos JSON, pero si subes un solo valor, no hace falta que sea JSON válido. El comando `set` tiene dos modos. Para subir un solo elemento, usa: diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md index 8cfb37bc989..bef188ec5b0 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-intro.md @@ -62,7 +62,7 @@ La palabra `openfn` invoca la CLI. La palabra `test` invoca el comando de prueba.
-Despliega para ver la salida esperada +Expande para ver la salida esperada ``` [CLI] ♦ Versions: @@ -117,7 +117,7 @@ prueba.
-El resto de la salida es la CLI contándonos lo que hace internamente. +El resto de la salida es la CLI contándote lo que hace internamente. **Consultar la versión** @@ -146,8 +146,8 @@ npm install -g @openfn/cli ### Solución de problemas {#troubleshooting} -Si tienes problemas con la instalación, prueba a desinstalar primero la versión -actual y luego vuelve a instalarla. +Si tienes problemas con la instalación, intenta desinstalar primero la versión +actual y luego volver a instalarla. ```bash npm uninstall -g @openfn/cli diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md index 75e3c94d437..af2cc0b0e9e 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-sync.md @@ -13,7 +13,7 @@ Puedes crear un proyecto en la aplicación, descargarlo a tu computadora para desarrollar sin conexión, volver a subirlo a la aplicación o incluso desplegarlo en otro servidor de OpenFn. -A esto lo llamamos OpenFn Sync, y es una de las funciones más potentes que +A esto lo llamamos OpenFn Sync, y es una de las funcionalidades más potentes que ofrecen los proyectos de OpenFn. ## ¿Qué es un proyecto? {#what-is-a-project} @@ -102,12 +102,12 @@ proyecto. El dominio es el de la instancia de OpenFn desde la que se descargó e proyecto. No deberías editar el archivo de proyecto localmente, porque cualquier cambio se -perderá en la siguiente obtención. +perderá la próxima vez que lo obtengas. Puedes obtener tantos proyectos como quieras, y cada uno se guardará en su propio archivo project.yaml. -La carpeta `.projects` puede y debe incluirse en el control de versiones. +La carpeta `.projects` puede y debería incluirse en el control de versiones. ### workflows {#workflows} @@ -164,7 +164,7 @@ archivo del step y la ruta de la clave `expression` en `workflow.yaml`. Es un archivo de configuración de nivel superior que, en general, puedes ignorar. Las herramientas de OpenFn lo usan para reconocer la carpeta raíz de un proyecto. También contiene opciones de configuración para todos los proyectos -locales y metadatos sobre el proyecto con checkout actual. +locales y metadatos sobre el proyecto que tienes con checkout. ## Autorización {#authorization} @@ -228,7 +228,7 @@ Por ejemplo, el UUID es la parte en negrita de: Después de descargar un proyecto por primera vez, no hace falta volver a indicar el UUID. Puedes usar el alias, el id o dejar el identificador en blanco para -usar el proyecto con checkout actual. +usar el proyecto que tienes con checkout. El comando `project pull` hace tres cosas: @@ -302,7 +302,7 @@ Para subir tus cambios locales de nuevo a la aplicación, ejecuta: openfn project deploy ``` -Esto toma el proyecto con checkout actual y lo sube a la aplicación. También +Esto toma el proyecto que tienes con checkout y lo sube a la aplicación. También indica qué cambió en el proyecto local. Antes de subirlo, la CLI obtiene la última versión del proyecto desde la @@ -510,8 +510,8 @@ Así, los commits en GitHub despliegan automáticamente los cambios en un proyec de OpenFn, y al presionar Save & Sync en la aplicación se hace commit de vuelta en GitHub. -Internamente, GitHub Sync usa los comandos `pull` y `deploy` de la CLI, que -disparan GitHub Actions, para sincronizar tus proyectos. +Internamente, GitHub Sync usa los comandos `pull` y `deploy` de la CLI, que se +ejecutan desde GitHub Actions, para sincronizar tus proyectos. Ten en cuenta que, de forma predeterminada, GitHub Sync usa el formato antiguo, con los archivos `state.json`, `project.yaml` y `config.json`. Al configurar un diff --git a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md index 4e5581f3f12..cadf6af2af8 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/build-for-developers/cli-walkthrough.md @@ -595,8 +595,8 @@ Por ejemplo, si tu workflow tiene dos steps (GET de usuarios del sistema A y POST de usuarios al sistema B), puedes configurarlo para que ejecute todos los steps en secuencia, de principio a fin. Esto imita los [patrones de flow triggers](/documentation/legacy/build/triggers#flow-triggers) -de la plataforma OpenFn, donde un segundo job debe ejecutarse después de que el -primero termine con éxito, usando los datos que devolvió el primer job. +de la plataforma OpenFn, donde un segundo job debería ejecutarse después de que +el primero termine con éxito, usando los datos que devolvió el primer job. :::info En resumen @@ -607,8 +607,8 @@ anterior se pasa automáticamente al job siguiente como state inicial. ##### Workflow {#workflow} -Un workflow es el plan de ejecución para correr varios steps en secuencia. Se -define como un objeto JSON con las siguientes propiedades: +Un workflow es el plan de ejecución de varios steps en secuencia. Se define como +un objeto JSON con las siguientes propiedades: ```json { @@ -855,10 +855,10 @@ tu proyecto, esta sería la estructura del proyecto: openfn workflow.json -o tmp/output.json ``` -Al ejecutarse, este workflow corre primero el job `getPatients.js`. Si termina -con éxito, `getGlobalOrgUnits.js` se ejecuta con el state final de -`getPatients.js`. Si `getGlobalOrgUnits.js` termina con éxito, `createTEIs.js` -se ejecuta con el state final de `getGlobalOrgUnits.js`. +Al ejecutarse, este workflow empieza por el job `getPatients.js`. Si termina con +éxito, `getGlobalOrgUnits.js` se ejecuta con el state final de `getPatients.js`. +Si `getGlobalOrgUnits.js` termina con éxito, `createTEIs.js` se ejecuta con el +state final de `getGlobalOrgUnits.js`. Ten en cuenta que los adaptors indicados en `workflow.json` se instalan automáticamente cuando ejecutas el workflow. Para ejecutar el workflow, usa este diff --git a/translation-rules.yml b/translation-rules.yml index eb1a04bf08c..769f94f2f23 100644 --- a/translation-rules.yml +++ b/translation-rules.yml @@ -120,3 +120,28 @@ rules: Triggers pages call "deshabilitados". added_by: lmac-1 added_on: 2026-10-02 + + - locale: es + kind: term + source: Expand to see + target: Expande para ver + instruction: >- + In dropdown summaries, "Expand to see..." is "Expande para ver...", not + "Despliega para ver...". + example_source: Expand to see the expected output + example_target: Expande para ver la salida esperada + reason: The CLI pages used "Despliega" on two pages and "Expande" on another. + added_by: lmac-1 + added_on: 2026-10-02 + + - locale: es + kind: avoid + source: run (the verb) + target: correr + instruction: >- + "Run" a job, step, workflow, or command is "ejecutar", not "correr". + example_source: A workflow is the execution plan for running several steps. + example_target: Un workflow es el plan de ejecución de varios steps. + reason: The CLI walkthrough mixed "correr" with "ejecutar" for the same verb. + added_by: lmac-1 + added_on: 2026-10-02