

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# AWS AppSync JavaScript características de tiempo de ejecución para resolutores y funciones
<a name="resolver-util-reference-js"></a>

El entorno `APPSYNC_JS` de ejecución proporciona una funcionalidad similar a la [versión 6.0 de ECMAScript (ES)](https://262.ecma-international.org/6.0/). Es compatible con un subconjunto de sus características y proporciona algunos métodos adicionales (utilidades) que no forman parte de las especificaciones de ES. En los siguientes temas se mencionan todas las características de lenguaje admitidas:
+  [Características del tiempo de ejecución compatibles](https://docs.aws.amazon.com/appsync/latest/devguide/supported-features.html): obtenga más información sobre las características principales compatibles, los objetos primitivos, los objetos y funciones integrados, etc.
+  [Utilidades integradas](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html): la variable util contiene métodos de utilidad generales que ayudan a trabajar con los datos. A menos que se especifique lo contrario, todas las utilidades usan el juego de caracteres UTF-8.
+  [Módulos integrados](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html): obtén más información sobre cómo los módulos integrados pueden ayudar a escribir JavaScript resolutores y funciones.
+  [Utilidades del tiempo de ejecución](https://docs.aws.amazon.com/appsync/latest/devguide/runtime-utils-js.html): la biblioteca del tiempo de ejecución proporciona utilidades para controlar o modificar las propiedades de tiempo de ejecución de sus solucionadores y funciones.
+  [Aplicaciones auxiliares de tiempo en util.time](https://docs.aws.amazon.com/appsync/latest/devguide/time-helpers-in-util-time-js.html): la variable util.time contiene métodos de fecha y hora útiles para ayudar a generar marcas de tiempo, convertir entre formatos de fecha y hora, y analizar cadenas de fecha y hora. La sintaxis de los formatos de fecha y hora se basa en ella [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html), y puede consultarla para obtener más documentación.
+  [Aplicaciones auxiliares de DynamoDB en util.dynamodb](https://docs.aws.amazon.com/appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html): util.dynanodb contiene métodos auxiliares que facilitan la escritura y la lectura de datos en Amazon DynamoDB, como el mapeo y el formato automáticos de tipos de datos.
+  [Aplicaciones auxiliares de HTTP en util.http](https://docs.aws.amazon.com/appsync/latest/devguide/http-helpers-in-utils-http-js.html): la utilidad util.http proporciona métodos auxiliares que puede utilizar para gestionar parámetros de solicitud HTTP y agregar encabezados de respuesta.
+  [Aplicaciones auxiliares de transformación en util.transform](https://docs.aws.amazon.com/appsync/latest/devguide/transformation-helpers-in-utils-transform-js.html): util.transform contiene métodos auxiliares que facilitan las operaciones complejas sobre orígenes de datos.
+  [Aplicaciones auxiliares de cadena en util.str](https://docs.aws.amazon.com/appsync/latest/devguide/str-helpers-in-util-str-js.html): util.str contiene métodos para ayudar con operaciones de cadena comunes.
+  [Extensiones](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html): extensions contiene un conjunto de métodos para realizar acciones adicionales en sus solucionadores.
+  [Aplicaciones auxiliares de XML en util.xml](https://docs.aws.amazon.com/appsync/latest/devguide/xml-helpers-in-util-xml-js.html): util.xml contiene métodos para ayudar con la conversión de cadenas XML.

**nota**  
Actualmente, esta referencia solo se aplica a la versión ejecutable **1.0.0**.

# Características de la versión ejecutable compatibles
<a name="supported-features"></a>

En las siguientes secciones se describe el conjunto de características compatibles de la versión ejecutable APPSYNC\$1JS.

## Características principales
<a name="core-features"></a>

Se admiten las siguientes características principales.

------
#### [ Types ]

Se admiten los siguientes tipos:
+ números
+ cadenas
+ booleanos
+ objetos
+ matrices
+ funciones

------
#### [ Operators ]

Se admiten operadores, entre los que se incluyen:
+ operadores matemáticos estándar (`+`, `-`, `/`, `%`, `*`, etc.)
+ operador de fusión de NULL (`??`)
+ Encadenamiento opcional (`?.`)
+ operadores Bitwise
+ operadores `void` y `typeof`
+ operadores de distribución (`...`)

No se admiten los siguientes operadores:
+ operadores unarios (`++`, `--`, y `~`)
+ operador `in`
**nota**  
Utilice el operador `Object.hasOwn` para comprobar si la propiedad especificada está en el objeto especificado.

------
#### [ Statements ]

Se admiten las siguientes instrucciones:
+ `const`
+ `let`
+ `var`
+ `break`
+ `else`
+ `for-in`
+ `for-of` 
+ `if`
+ `return`
+ `switch`
+ sintaxis de distribución

No se admiten las siguientes:
+ `catch`
+ `continue`
+ `do-while`
+ `finally`
+ `for(initialization; condition; afterthought)`
**nota**  
Las excepciones son las expresiones `for-in` y `for-of`, que son compatibles.
+ `throw`
+ `try`
+ `while`
+ instrucciones etiquetadas

------
#### [ Literals ]

Se admiten los siguientes [literales de plantilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) de ES 6:
+ Cadenas de varias líneas
+ Interpolación de expresiones
+ Plantillas de anidamiento

------
#### [ Functions ]

Se admite la sintaxis de la función siguiente:
+ Se admiten las declaraciones de funciones.
+ Se admiten las funciones de flecha de ES 6.
+ Se admite la sintaxis del parámetro rest de ES 6.

------
#### [ Strict mode ]

Las funciones operan en modo estricto de forma predeterminada, por lo que no necesita agregar una instrucción `use_strict` en su código de función. Esto no se puede cambiar.

------

## Objetos primitivos
<a name="primitive-objects"></a>

Se admiten los siguientes objetos primitivos de ES y sus funciones.

------
#### [ Object ]

Los siguientes objetos son compatibles:
+ `Object.assign()`
+ `Object.entries()` 
+ `Object.hasOwn()`
+ `Object.keys()` 
+ `Object.values()`
+ `delete` 

------
#### [ String ]

Se admiten las siguientes cadenas:
+  `String.prototype.length()` 
+  `String.prototype.charAt()` 
+  `String.prototype.concat()` 
+  `String.prototype.endsWith()` 
+  `String.prototype.indexOf()` 
+  `String.prototype.lastIndexOf()` 
+  `String.raw()` 
+  `String.prototype.replace()`
**nota**  
No se admiten expresiones regulares.   
Sin embargo, en el parámetro proporcionado se admiten constructos de expresiones regulares con estilo Java. Para obtener más información, consulte [Patrón](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html).
+ `String.prototype.replaceAll()`
**nota**  
No se admiten expresiones regulares.  
Sin embargo, en el parámetro proporcionado se admiten constructos de expresiones regulares con estilo Java. Para obtener más información, consulte [Patrón](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html).
+  `String.prototype.slice()` 
+  `String.prototype.split()` 
+  `String.prototype.startsWith()` 
+  `String.prototype.toLowerCase()` 
+  `String.prototype.toUpperCase()` 
+  `String.prototype.trim()` 
+  `String.prototype.trimEnd()` 
+  `String.prototype.trimStart()` 

------
#### [ Number ]

Se admiten los siguientes números:
+  `Number.isFinite` 
+  `Number.isNaN` 

------

## Objetos y funciones integrados
<a name="built-in-objects-functions"></a>

Se admiten las siguientes funciones y objetos.

------
#### [ Math ]

Las siguientes funciones matemáticas son compatibles:
+  `Math.random()` 
+  `Math.min()` 
+  `Math.max()` 
+  `Math.round()` 
+  `Math.floor()` 
+  `Math.ceil()` 

------
#### [ Array ]

Se admiten los siguientes métodos de matriz:
+ `Array.prototype.length` 
+ `Array.prototype.concat()` 
+ `Array.prototype.fill()` 
+ `Array.prototype.flat()` 
+ `Array.prototype.indexOf()` 
+ `Array.prototype.join()` 
+ `Array.prototype.lastIndexOf()` 
+ `Array.prototype.pop()` 
+ `Array.prototype.push()` 
+ `Array.prototype.reverse()` 
+ `Array.prototype.shift()` 
+ `Array.prototype.slice()` 
+ `Array.prototype.sort()`
**nota**  
`Array.prototype.sort()` no admite argumentos.
+ `Array.prototype.splice()` 
+ `Array.prototype.unshift()`
+ `Array.prototype.forEach()`
+ `Array.prototype.map()`
+ `Array.prototype.flatMap()`
+ `Array.prototype.filter()`
+ `Array.prototype.reduce()`
+ `Array.prototype.reduceRight()`
+ `Array.prototype.find()`
+ `Array.prototype.some()`
+ `Array.prototype.every()`
+ `Array.prototype.findIndex()`
+ `Array.prototype.findLast()`
+ `Array.prototype.findLastIndex()`
+ `delete` 

------
#### [ Console ]

El objeto de la consola está disponible para su depuración. Durante la ejecución de la consulta en tiempo real, log/error las instrucciones de la consola se envían a Amazon CloudWatch Logs (si el registro está activado). Durante la evaluación de código con `evaluateCode`, las instrucciones de registro se devuelven en la respuesta del comando.
+ `console.error()`
+ `console.log()`

------
#### [ Function ]
+ No se admiten los métodos `apply`, `bind` y `call`.
+ Los constructores de funciones no son compatibles.
+ No se admite la transferencia de una función como argumento.
+ No se admiten llamadas a funciones recursivas.

------
#### [ JSON ]

Se admiten los siguientes métodos JSON:
+ `JSON.parse()`
**nota**  
Devuelve una cadena en blanco si la cadena analizada no es un JSON válido.
+ `JSON.stringify()`

------
#### [ Promises ]

No se admiten promesas ni procesos asíncronos.

**nota**  
No se admite el acceso a la red y al sistema de archivos durante el `APPSYNC_JS` tiempo de ejecución AWS AppSync. AWS AppSync gestiona todas las operaciones de E/S en función de las solicitudes realizadas por el AWS AppSync solucionador o la AWS AppSync función.

------

## Globals
<a name="globals"></a>

Se admiten las siguientes constantes globales:
+  `NaN` 
+  `Infinity` 
+  `undefined`
+ [https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html)
+ [https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)
+ `runtime`

## Tipos de error
<a name="error-types"></a>

No se admite la generación de errores con `throw`. Puede devolver un error mediante la función `util.error()`. Puede incluir un error en su respuesta de GraphQL mediante la función `util.appendError`.

Para obtener más información, consulte la sección sobre [utilidades de error](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html#utility-helpers-in-error-js).

# Utilidades integradas
<a name="built-in-util-js"></a>

La variable `util` contiene métodos de utilidad generales que ayudan a trabajar con los datos. A menos que se especifique lo contrario, todas las utilidades usan el juego de caracteres UTF-8.

## Utilidades de codificación
<a name="utility-helpers-in-encoding"></a>

### Lista de utilidades de codificación
<a name="utility-helpers-in-encoding-list-js"></a>

 **`util.urlEncode(String)`**  
Devuelve la cadena de entrada como una cadena `application/x-www-form-urlencoded` codificada.

 **`util.urlDecode(String)`**  
Descodifica una cadena `application/x-www-form-urlencoded` codificada y la devuelve a su forma no codificada.

**`util.base64Encode(string) : string`**  
Codifica la entrada en una cadena codificada en base64.

**`util.base64Decode(string) : string`**  
Descodifica los datos de una cadena codificada en base64.

## Utilidades de generación de ID
<a name="utility-helpers-in-id-gen-js"></a>

### Lista de utilidades de generación de ID
<a name="utility-helpers-in-id-gen-list-js"></a>

 **`util.autoId()`**  
Devuelve un UUID de 128 bits generado de forma aleatoria.

**`util.autoUlid()`**  
Devuelve un ULID (identificador ordenable lexicográficamente único y universal) de 128 bits generado de forma aleatoria.

**`util.autoKsuid()`**  
Devuelve un KSUID (identificador único ordenable por K) de 128 bits generado de forma aleatoria codificado en base62 como una cadena con una longitud de 27.

## Utilidades de error
<a name="utility-helpers-in-error-js"></a>

### Lista de utilidades de error
<a name="utility-helpers-in-error-list-js"></a>

 **`util.error(String, String?, Object?, Object?)`**  
Genera un error personalizado. Se puede utilizar en las plantillas de mapeo de solicitud o de respuesta si la plantilla detecta un error en la solicitud o en el resultado de la invocación. También se pueden especificar los campos `errorType`, `data` y `errorInfo`. El valor de `data` se añadirá al bloque `error` correspondiente dentro de `errors` en la respuesta de GraphQL.  
`data` se filtrará en función de la selección de consulta establecida. El valor de `errorInfo` se añadirá al bloque `error` correspondiente dentro de `errors` en la respuesta de GraphQL.  
`errorInfo` **no** se filtrará en función de la selección de consulta establecida.

 **`util.appendError(String, String?, Object?, Object?)`**  
Adjunta un error personalizado. Se puede utilizar en las plantillas de mapeo de solicitud o de respuesta si la plantilla detecta un error en la solicitud o en el resultado de la invocación. También se pueden especificar los campos `errorType`, `data` y `errorInfo`. A diferencia de `util.error(String, String?, Object?, Object?)`, la evaluación de la plantilla no se interrumpirá, de modo podrán devolverse datos al intermediario. El valor de `data` se añadirá al bloque `error` correspondiente dentro de `errors` en la respuesta de GraphQL.  
`data` se filtrará en función de la selección de consulta establecida. El valor de `errorInfo` se añadirá al bloque `error` correspondiente dentro de `errors` en la respuesta de GraphQL.  
`errorInfo` **no** se filtrará en función de la selección de consulta establecida.

## Utilidades de coincidencia de tipos y patrones
<a name="utility-helpers-in-patterns-js"></a>

### Lista de utilidades de coincidencia de tipos y patrones
<a name="utility-helpers-in-patterns-js-list"></a>

**`util.matches(String, String) : Boolean`**  
Devuelve un valor true si el patrón especificado en el primer argumento coincide con los datos proporcionados en el segundo argumento. El patrón tiene que ser una expresión regular, por ejemplo `util.matches("a*b", "aaaaab")`. La funcionalidad se basa en [Pattern](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html), que puede consultar para obtener más información.

 **`util.authType()`**   
Devuelve una cadena que describe el tipo de autenticación múltiple que utiliza una solicitud y devuelve "Autorización de IAM", "Autorización del grupo de usuarios", "Autorización de Open ID Connect" o "Autorización de la clave de API".

## Utilidades de comportamiento del valor devuelto
<a name="utility-helpers-in-cloudwatch-logs-list-js"></a>

### Lista de utilidades de comportamiento del valor devuelto
<a name="utility-helpers-in-behavior-list-js"></a>

 **`util.escapeJavaScript(String)`**  
Devuelve la cadena de entrada como cadena de JavaScript escape.

## Utilidades de autorización del solucionador
<a name="utility-helpers-in-resolver-auth-js"></a>

### Lista de utilidades de autorización del solucionador
<a name="utility-helpers-in-resolver-auth-list-js"></a>

 **`util.unauthorized()`**  
Genera el código `Unauthorized` para el campo que se está resolviendo. Utilícela en las plantillas de mapeo de solicitudes o de respuestas para determinar si se debe permitir al intermediario que resuelva el campo.

# Módulos integrados
<a name="built-in-modules-js"></a>

Los módulos son parte del `APPSYNC_JS` tiempo de ejecución y proporcionan utilidades para ayudar a escribir JavaScript resoluciones y funciones. Para ver ejemplos y ejemplos, consulta el [aws-appsync-resolver-samples](https://github.com/aws-samples/aws-appsync-resolver-samples) GitHub repositorio.

## Funciones del módulo de DynamoDB
<a name="built-in-ddb-modules"></a>

Las funciones del módulo de DynamoDB proporcionan una experiencia mejorada al interactuar con los orígenes de datos de DynamoDB. Puede realizar solicitudes a sus orígenes de datos de DynamoDB mediante las funciones y sin añadir asignación de tipos. 

Los módulos se importan mediante `@aws-appsync/utils/dynamodb`:

```
// Modules are imported using @aws-appsync/utils/dynamodb
import * as ddb from '@aws-appsync/utils/dynamodb';
```

### Funciones
<a name="built-in-ddb-modules-functions"></a>

#### Lista de funciones
<a name="built-in-ddb-modules-functions-list"></a>

 **` get<T>(payload: GetInput): DynamoDBGetItemRequest`**  
Consulte [Entradas](#built-in-ddb-modules-inputs) para obtener información acerca de GetInput.
Genera un `DynamoDBGetItemRequest` objeto para realizar una [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-getitem)solicitud a DynamoDB.  

```
import { get } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	return get({ key: { id: ctx.args.id } });
}
```

 **`put<T>(payload): DynamoDBPutItemRequest`**  
Genera un `DynamoDBPutItemRequest` objeto para realizar una [PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem)solicitud a DynamoDB.  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	return ddb.put({ key: { id: util.autoId() }, item: ctx.args });
}
```

**`remove<T>(payload): DynamoDBDeleteItemRequest`**  
Genera un `DynamoDBDeleteItemRequest` objeto para realizar una [DeleteItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-deleteitem)solicitud a DynamoDB.  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	return ddb.remove({ key: { id: ctx.args.id } });
}
```

**`scan<T>(payload): DynamoDBScanRequest`**  
Genera un objeto `DynamoDBScanRequest` para realizar una solicitud [Scan](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) a DynamoDB.  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken } = ctx.args;
	return ddb.scan({ limit, nextToken });
}
```

**`sync<T>(payload): DynamoDBSyncRequest`**  
Genera un objeto `DynamoDBSyncRequest` para realizar una solicitud [Sync](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-sync). La solicitud solo recibe los datos modificados desde la última consulta (actualizaciones delta). Las solicitudes solo se pueden realizar a orígenes de datos de DynamoDB con control de versiones.  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken, lastSync } = ctx.args;
	return ddb.sync({ limit, nextToken, lastSync });
}
```

**`update<T>(payload): DynamoDBUpdateItemRequest`**  
Genera un `DynamoDBUpdateItemRequest` objeto para realizar una [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-updateitem)solicitud a DynamoDB.

### Operaciones
<a name="built-in-ddb-modules-operations"></a>

Las aplicaciones auxiliares de operación permiten realizar acciones específicas en partes de sus datos durante las actualizaciones. Para empezar, importe `operations` desde `@aws-appsync/utils/dynamodb`:

```
// Modules are imported using operations
import {operations} from '@aws-appsync/utils/dynamodb';
```

#### Lista de operaciones
<a name="built-in-ddb-modules-operations-list"></a>

 **`add<T>(payload)`**  
Función auxiliar que añade un nuevo elemento de atributo al actualizar DynamoDB.  
**Ejemplo**  
Para añadir una dirección (calle, ciudad y código postal) a un elemento de DynamoDB existente mediante el valor de ID:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		address: operations.add({
			street1: '123 Main St',
			city: 'New York',
			zip: '10001',
		}),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`append <T>(payload)`**  
Función auxiliar que añade una carga a la lista existente en DynamoDB.  
**Ejemplo**  
Para añadir un amigo IDs (`newFriendIds`) recién agregado a una lista de amigos existente (`friendsIds`) durante una actualización:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.append(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`decrement (by?)`**  
Función auxiliar que reduce el valor del atributo existente en el elemento al actualizar DynamoDB.  
**Ejemplo**  
Para reducir un contador de amigos (`friendsCount`) en 10:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.decrement(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`increment (by?)`**  
Función auxiliar que incrementa el valor del atributo existente en el elemento al actualizar DynamoDB.  
**Ejemplo**  
Para incrementar un contador de amigos (`friendsCount`) en 10:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.increment(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`prepend <T>(payload)`**  
Función auxiliar que se antepone a la lista existente en DynamoDB.  
**Ejemplo**  
Para añadir un amigo IDs (`newFriendIds`) recién añadido a una lista de amigos existente (`friendsIds`) durante una actualización:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.prepend(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`replace <T>(payload)`**  
Función auxiliar que sustituye un atributo existente al actualizar un elemento en DynamoDB. Esto resulta útil cuando se desea actualizar todo el objeto o subobjeto en el atributo y no solo las claves en la carga.  
**Ejemplo**  
Para sustituir una dirección (calle, ciudad y código postal) en un objeto `info`:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		info: {
			address: operations.replace({
				street1: '123 Main St',
				city: 'New York',
				zip: '10001',
			}),
		},
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`updateListItem <T>(payload, index)`**  
Función auxiliar que sustituye un elemento en una lista.  
**Ejemplo**  
En el ámbito de la actualización (`newFriendIds`), en este ejemplo se utiliza `updateListItem` para actualizar los valores de ID del segundo elemento (índice: `1`, nuevo ID: `102`) y del tercer elemento (índice: `2`, nuevo ID: `112`) en una lista (`friendsIds`).  

```
import { update, operations as ops } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [
		ops.updateListItem('102', 1), ops.updateListItem('112', 2)
	];
	const updateObj = { friendsIds: newFriendIds };
	return update({ key: { id: 1 }, update: updateObj });
}
```

### Entradas
<a name="built-in-ddb-modules-inputs"></a>

#### Lista de entradas
<a name="built-in-ddb-modules-inputs-list"></a>

 **`Type GetInput<T>`**  

```
GetInput<T>: { 
    consistentRead?: boolean; 
    key: DynamoDBKey<T>; 
}
```
**Declaración de tipo**  
+ `consistentRead?: boolean` (opcional)

  Valor booleano opcional para especificar si desea realizar una lectura altamente coherente con DynamoDB.
+ `key: DynamoDBKey<T>` (obligatorio)

  Parámetro obligatorio que especifica la clave del elemento en DynamoDB. Los elementos de DynamoDB pueden tener una sola clave hash o claves hash y de ordenación.

**`Type PutInput<T>`**  

```
PutInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T> | null; 
    customPartitionKey?: string; 
    item: Partial<T>; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**Declaración de tipo**  
+ `_version?: number` (opcional)
+ `condition?: DynamoDBFilterObject<T> | null` (opcional)

  Al colocar un objeto en una tabla de DynamoDB, puede especificar opcionalmente una expresión condicional que determine si la solicitud se debe atender o no en función del estado del objeto que ya está en DynamoDB antes de ejecutar la operación.
+ `customPartitionKey?: string` (opcional)

  Cuando se habilita, este valor de cadena modifica el formato de los registros `ds_sk` y `ds_pk` que utiliza la tabla Delta Sync una vez habilitado el control de versiones. Cuando se habilita, también lo hace el procesamiento de la entrada `populateIndexFields`. 
+ `item: Partial<T>` (obligatorio)

  El resto de los atributos del elemento que deben incluirse en DynamoDB.
+ `key: DynamoDBKey<T>` (obligatorio)

  Parámetro obligatorio que especifica la clave del elemento en DynamoDB donde se realizará la operación put. Los elementos de DynamoDB pueden tener una sola clave hash o claves hash y de ordenación.
+ `populateIndexFields?: boolean` (opcional)

  Valor booleano que, cuando se habilita junto con la `customPartitionKey`, crea nuevas entradas para cada registro de la tabla Delta Sync, específicamente en las columnas `gsi_ds_pk` y `gsi_ds_sk`. Para obtener más información, consulte el artículo sobre [detección de conflictos y sincronización](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html) en la *Guía para desarrolladores de AWS AppSync *.

**`Type QueryInput<T>`**  

```
QueryInput<T>: ScanInput<T> & { 
    query: DynamoDBKeyCondition<Required<T>>; 
}
```
**Declaración de tipo**  
+ `query: DynamoDBKeyCondition<Required<T>>` (obligatorio)

  Especifica una condición clave que describe los elementos que se van a consultar. Para un índice determinado, la condición de una clave de partición debe ser una igualdad y la clave de ordenación una comparación o un elemento `beginsWith` (cuando es una cadena). Solo se admiten los tipos Number y String para las claves de partición y ordenación.

  **Ejemplo**

  Tome el tipo `User` a continuación:

  ```
  type User = {
    id: string;
    name: string;
    age: number;
    isVerified: boolean;
    friendsIds: string[] 
  }
  ```

  La consulta solo puede incluir los campos siguientes: `id`, `name` y `age`:

  ```
  const query: QueryInput<User> = {
      name: { eq: 'John' },
      age: { gt: 20 },
  }
  ```

**`Type RemoveInput<T>`**  

```
RemoveInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**Declaración de tipo**  
+ `_version?: number` (opcional)
+ `condition?: DynamoDBFilterObject<T>` (opcional)

  Al quitar un objeto en DynamoDB, puede especificar opcionalmente una expresión condicional que determine si la solicitud se debe atender o no en función del estado del objeto que ya está en DynamoDB antes de ejecutar la operación.

  **Ejemplo**

  El siguiente ejemplo es una expresión `DeleteItem` que contiene una condición que permite que la operación se realice correctamente solo si el propietario del documento coincide con el usuario que realiza la solicitud.

  ```
  type Task = {
    id: string;
    title: string;
    description: string;
    owner: string;
    isComplete: boolean;
  }
  const condition: DynamoDBFilterObject<Task> = {
    owner: { eq: 'XXXXXXXXXXXXXXXX' },
  }
  
  remove<Task>({
     key: {
       id: 'XXXXXXXXXXXXXXXX',
    },
    condition,
  });
  ```
+ `customPartitionKey?: string` (opcional)

  Cuando se habilita, el valor `customPartitionKey` modifica el formato de los registros `ds_sk` y `ds_pk` que utiliza la tabla Delta Sync una vez habilitado el control de versiones. Cuando se habilita, también lo hace el procesamiento de la entrada `populateIndexFields`. 
+ `key: DynamoDBKey<T>` (obligatorio)

  Parámetro obligatorio que especifica la clave del elemento de DynamoDB que se va a quitar. Los elementos de DynamoDB pueden tener una sola clave hash o claves hash y de ordenación.

  **Ejemplo**

  Si un `User` solo tiene la clave hash con un `id` de usuario, la clave tendría el siguiente aspecto:

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  }
  const key: DynamoDBKey<User> = {
  	id: 1,
  }
  ```

  Si el usuario de la tabla tiene una clave hash (`id`) y una clave de ordenación (`name`), la clave tendría el siguiente aspecto:

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  	friendsIds: string[]
  }
  
  const key: DynamoDBKey<User> = {
  	id: 1,
  	name: 'XXXXXXXXXX',
  }
  ```
+ `populateIndexFields?: boolean` (opcional)

  Valor booleano que, cuando se habilita junto con la `customPartitionKey`, crea nuevas entradas para cada registro de la tabla Delta Sync, específicamente en las columnas `gsi_ds_pk` y `gsi_ds_sk`.

**`Type ScanInput<T>`**  

```
ScanInput<T>: { 
    consistentRead?: boolean | null; 
    filter?: DynamoDBFilterObject<T> | null; 
    index?: string | null; 
    limit?: number | null; 
    nextToken?: string | null; 
    scanIndexForward?: boolean | null; 
    segment?: number; 
    select?: DynamoDBSelectAttributes; 
    totalSegments?: number; 
}
```
**Declaración de tipo**  
+ `consistentRead?: boolean | null` (opcional)

  Valor booleano opcional para indicar lecturas coherentes al consultar DynamoDB. El valor predeterminado es `false`.
+ `filter?: DynamoDBFilterObject<T> | null` (opcional)

  Filtro opcional para aplicar a los resultados después de recuperarlos de la tabla.
+ `index?: string | null` (opcional)

  Nombre opcional del índice a examinar.
+ `limit?: number | null` (opcional)

  Número máximo opcional de resultados a devolver.
+ `nextToken?: string | null` (opcional)

  Token de paginación opcional para continuar una consulta anterior. Se debe obtener de una consulta anterior.
+ `scanIndexForward?: boolean | null` (opcional)

  Valor booleano opcional para indicar si la consulta se realiza en orden ascendente o descendente. De forma predeterminada, este valor se establece en `true`.
+ `segment?: number` (opcional)
+ `select?: DynamoDBSelectAttributes` (opcional)

  Atributos que se devolverán de DynamoDB. De forma predeterminada, el solucionador de AWS AppSync DynamoDB solo devuelve los atributos que se proyectan en el índice. Los valores admitidos son:
  + `ALL_ATTRIBUTES`

    Devuelve todos los atributos de elementos de la tabla o el índice especificados. Si consulta un índice secundario local, DynamoDB recupera todo el elemento de la tabla principal para cada elemento coincidente en el índice. Si el índice está configurado para proyectar todos los atributos de los elementos, todos los datos se pueden obtener del índice secundario local y no es necesario efectuar una recuperación.
  + `ALL_PROJECTED_ATTRIBUTES`

    Devuelve todos los atributos que se han proyectado en el índice. Si el índice está configurado para proyectar todos los atributos, este valor de retorno equivale a especificar `ALL_ATTRIBUTES`.
  + `SPECIFIC_ATTRIBUTES`

    Devuelve solo los atributos que aparecen en `ProjectionExpression`. Este valor devuelto equivale a especificar `ProjectionExpression` sin especificar ningún valor para `AttributesToGet`.
+ `totalSegments?: number` (opcional)

**`Type DynamoDBSyncInput<T>`**  

```
DynamoDBSyncInput<T>: { 
    basePartitionKey?: string; 
    deltaIndexName?: string; 
    filter?: DynamoDBFilterObject<T> | null; 
    lastSync?: number; 
    limit?: number | null; 
    nextToken?: string | null; 
}
```
**Declaración de tipo**  
+ `basePartitionKey?: string` (opcional)

  Clave de partición de la tabla base que se utilizará al realizar una operación Sync. Este campo permite realizar una operación Sync cuando la tabla utiliza una clave de partición personalizada.
+ `deltaIndexName?: string` (opcional)

  Índice utilizado para la operación Sync. Este índice es necesario para habilitar una operación Sync en toda la tabla de almacenamiento Delta cuando la tabla utiliza una clave de partición personalizada. La operación Sync se realizará en el GSI (creado en `gsi_ds_pk` y `gsi_ds_sk`).
+ `filter?: DynamoDBFilterObject<T> | null` (opcional)

  Filtro opcional para aplicar a los resultados después de recuperarlos de la tabla.
+ `lastSync?: number` (opcional)

  Momento, en milisegundos transcurridos desde la fecha de inicio, en el que comenzó la última operación Sync que se ha realizado correctamente. Si se especifica, solo se devuelven los elementos que han cambiado después de `lastSync`. Este campo solo debe rellenarse después de haber recuperado todas las páginas de una operación Sync inicial. Si se omite, se devolverán los resultados de la tabla base. De lo contrario, se devolverán los resultados de la tabla Delta.
+ `limit?: number | null` (opcional)

  Número máximo opcional de elementos que se evalúan en una sola vez. Si se omite, el límite predeterminado se establecerá en `100` elementos. El valor máximo de este campo son `1000` elementos.
+ `nextToken?: string | null` (opcional)

**`Type DynamoDBUpdateInput<T>`**  

```
DynamoDBUpdateInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
    update: DynamoDBUpdateObject<T>; 
}
```
**Declaración de tipo**  
+ `_version?: number` (opcional)
+ `condition?: DynamoDBFilterObject<T>` (opcional)

  Al actualizar un objeto en DynamoDB, puede especificar opcionalmente una expresión condicional que determine si la solicitud se debe atender o no en función del estado del objeto que ya está en DynamoDB antes de ejecutar la operación.
+ `customPartitionKey?: string` (opcional)

  Cuando se habilita, el valor `customPartitionKey` modifica el formato de los registros `ds_sk` y `ds_pk` que utiliza la tabla Delta Sync una vez habilitado el control de versiones. Cuando se habilita, también lo hace el procesamiento de la entrada `populateIndexFields`. 
+ `key: DynamoDBKey<T>` (obligatorio)

  Parámetro obligatorio que especifica la clave del elemento de DynamoDB que se actualiza. Los elementos de DynamoDB pueden tener una sola clave hash o claves hash y de ordenación.
+ `populateIndexFields?: boolean` (opcional)

  Valor booleano que, cuando se habilita junto con la `customPartitionKey`, crea nuevas entradas para cada registro de la tabla Delta Sync, específicamente en las columnas `gsi_ds_pk` y `gsi_ds_sk`. 
+ `update: DynamoDBUpdateObject<T>`

  Objeto que especifica los atributos que se van a actualizar junto con sus nuevos valores. El objeto de actualización se puede utilizar con `add`, `remove`, `replace`, `increment`, `decrement`, `append`, `prepend` y `updateListItem`.

## Funciones del módulo Amazon RDS
<a name="built-in-rds-modules"></a>

Las funciones del módulo Amazon RDS ofrecen una experiencia mejorada al interactuar con bases de datos configuradas con la API de datos de Amazon RDS. El módulo se importa mediante `@aws-appsync/utils/rds`: 

```
import * as rds from '@aws-appsync/utils/rds';
```

Las funciones también se pueden importar de forma individual. Por ejemplo, la importación siguiente utiliza `sql`:

```
import { sql } from '@aws-appsync/utils/rds';
```

### Funciones
<a name="built-in-rds-modules-functions"></a>

Puede utilizar las utilidades auxiliares del módulo AWS AppSync RDS para interactuar con la base de datos.

#### Select
<a name="built-in-rds-modules-functions-select"></a>

La utilidad `select` crea una instrucción `SELECT` para consultar la base de datos relacional. 

**Uso básico**

En su forma básica, puede especificar la tabla que desea consultar:

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

Tenga en cuenta que también puede especificar el esquema en el identificador de la tabla:

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**Especificación de columnas**

Puede especificar columnas con la propiedad `columns`. Si no se establece en un valor, el valor predeterminado es `*`:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

También puede especificar la tabla de una columna:

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**Límites y desplazamientos**

Puede aplicar `limit` y `offset` a la consulta:

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**Ordenar por**

Puede ordenar los resultados con la propiedad `orderBy`. Proporcione una matriz de objetos especificando la columna y una propiedad `dir` opcional:

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**Filtros**

Puede crear filtros con el objeto de condición especial:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

También puede combinar filtros:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

También puede crear instrucciones `OR`:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

También puede negar una condición con `not`:

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

También puede utilizar los siguientes operadores para comparar valores:


| 
| 
| Operador | Description (Descripción) | Tipos de valor posibles | 
| --- |--- |--- |
| eq | Igualdad | número, cadena, booleano | 
| ne | Desigualdad | número, cadena, booleano | 
| una mentira | Menor que o igual a | número, cadena | 
| lt | Menor que | número, cadena | 
| edad | Mayor que o igual a | número, cadena | 
| gt | Mayor que | número, cadena | 
| contains | Como | cadena | 
| no contiene | No como | cadena | 
| Empieza con | Empieza con el prefijo | cadena | 
| entre | Entre dos valores | número, cadena | 
| El atributo existe | El atributo no es nulo | número, cadena, booleano | 
| tamaño | comprueba la longitud del elemento | cadena | 

#### Inserción
<a name="built-in-rds-modules-functions-insert"></a>

La utilidad `insert` ofrece una forma sencilla de insertar elementos de una sola fila en la base de datos con la operación `INSERT`.

**Inserciones de un solo elemento**

Para insertar un elemento, especifique la tabla y, a continuación, transfiera su objeto de valores. Las claves de objetos se asignan a las columnas de la tabla. Los nombres de las columnas se escapan automáticamente y los valores se envían a la base de datos mediante el mapa de variables:

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**Caso de uso de MySQL**

Puede combinar un `insert` seguido de un `select` para recuperar la fila insertada:

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Caso de uso de Postgres**

Con Postgres, puede usar [https://www.postgresql.org/docs/current/dml-returning.html](https://www.postgresql.org/docs/current/dml-returning.html) para obtener datos de la fila que insertó. Acepta `*` o una matriz de nombres de columna:

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

#### Actualización
<a name="built-in-rds-modules-functions-update"></a>

La utilidad `update` permite actualizar las filas existentes. Puede utilizar el objeto de condición para aplicar cambios a las columnas especificadas en todas las filas que cumplan la condición. Por ejemplo, supongamos que tenemos un esquema que nos permite realizar esta mutación. Queremos actualizar el `name` de `Person` con el valor `id` de `3`, pero solo si los conocemos (`known_since`) desde el año `2000`:

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

Nuestro solucionador de actualización tendrá este aspecto:

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

Podemos añadir una comprobación a nuestra condición para asegurarnos de que solo se actualice la fila en la que la clave principal `3` sea igual a `id`. Del mismo modo, en el caso de `inserts` de Postgres, se puede utilizar `returning` para devolver los datos modificados. 

#### Quitar
<a name="built-in-rds-modules-functions-remove"></a>

La utilidad `remove` permite eliminar las filas existentes. Puede utilizar el objeto de condición en todas las filas que cumplan la condición. Tenga en cuenta que `delete` es una palabra clave reservada en JavaScript. `remove`debería usarse en su lugar:

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

### Conversión
<a name="built-in-rds-modules-casting"></a>

En algunos casos, es posible que desee más especificidad sobre el tipo de objeto correcto para usar en su instrucción. Puede utilizar las sugerencias de tipo proporcionadas para especificar el tipo de parámetros. AWS AppSync admite las [mismas sugerencias de tipo](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint) que la API de datos. Puede convertir sus parámetros mediante las `typeHint` funciones del AWS AppSync `rds` módulo. 

En el siguiente ejemplo puede enviar una matriz como un valor que se convierte en un objeto JSON. Usamos el operador `->` para recuperar el elemento en el `index` `2` en la matriz JSON:

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

La conversión también resulta útil al manipular y comparar `DATE`, `TIME` y `TIMESTAMP`:

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

Aquí se muestra otro ejemplo de cómo puede enviar la fecha y hora actuales:

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**Sugerencias de tipos disponibles**
+ `typeHint.DATE`: el parámetro correspondiente se envía como un objeto de tipo `DATE` a la base de datos. El formato aceptado es `YYYY-MM-DD`.
+ `typeHint.DECIMAL`: el parámetro correspondiente se envía como un objeto de tipo `DECIMAL` a la base de datos.
+ `typeHint.JSON`: el parámetro correspondiente se envía como un objeto de tipo `JSON` a la base de datos.
+ `typeHint.TIME`: el valor del parámetro de cadena correspondiente se envía como un objeto de tipo `TIME` a la base de datos. El formato aceptado es `HH:MM:SS[.FFF]`. 
+ `typeHint.TIMESTAMP`: el valor del parámetro de cadena correspondiente se envía como un objeto de tipo `TIMESTAMP` a la base de datos. El formato aceptado es `YYYY-MM-DD HH:MM:SS[.FFF]`.
+ `typeHint.UUID`: el valor del parámetro de cadena correspondiente se envía como un objeto de tipo `UUID` a la base de datos.

# Utilidades de tiempo de ejecución
<a name="runtime-utils-js"></a>

La biblioteca de `runtime` proporciona utilidades para controlar o modificar las propiedades de tiempo de ejecución de sus solucionadores y funciones.

## Lista de utilidades de tiempo de ejecución
<a name="runtime-utils-list-js"></a>

 **`runtime.earlyReturn(obj?: unknown, returnOptions?: {skipTo: 'END' | 'NEXT'}): never`**  
Al invocar esta función, se detendrá la ejecución del controlador, AWS AppSync función o resolución actual (Unit o Pipeline Resolver) según el contexto actual. El objeto especificado se devuelve como resultado.  
+ Cuando se llama en un controlador de solicitudes de AWS AppSync función, se omiten la fuente de datos y el controlador de respuestas y se llama al siguiente controlador de solicitudes de función (o al controlador de respuestas del solucionador de canalización si esta fue la última función). AWS AppSync 
+ Cuando se llama a un controlador de solicitudes del solucionador de AWS AppSync canalizaciones, se omite la ejecución de la canalización y se llama inmediatamente al controlador de respuesta del solucionador de canalizaciones.
+ Cuando `returnOptions` se suministra con el valor `skipTo` establecido en “FINAL”, se omite la ejecución de la canalización y se llama inmediatamente al controlador de respuestas del solucionador de canalización.
+ Cuando `returnOptions` se suministra con el valor `skipTo` establecido en “SIGUIENTE”, se omite la ejecución de la función y se llama al siguiente controlador de canalización.
**Ejemplo**  

```
import { runtime } from '@aws-appsync/utils'

export function request(ctx) {
  runtime.earlyReturn({ hello: 'world' })
  // code below is not executed
  return ctx.args
}

// never called because request returned early
export function response(ctx) {
  return ctx.result
}
```

# Aplicaciones auxiliares de tiempo en util.time
<a name="time-helpers-in-util-time-js"></a>

La variable `util.time` contiene métodos de fecha y hora útiles para ayudar a generar marcas de tiempo, convertir entre formatos de fecha y hora y analizar cadenas de fecha y hora. Puedes consultar la sintaxis de los formatos de fecha y hora para obtener más documentación. [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)

## Lista de utilidades de tiempo
<a name="utility-helpers-in-time-list-js"></a>

 **`util.time.nowISO8601()`**  
[Devuelve una representación en cadena de UTC en ISO8601 formato String.](https://en.wikipedia.org/wiki/ISO_8601)

 **`util.time.nowEpochSeconds()`**  
Devuelve el número de segundos desde la fecha de inicio de 1970-01-01T00:00:00Z hasta ahora.

 **`util.time.nowEpochMilliSeconds()`**  
Devuelve el número de milisegundos desde la fecha de inicio de 1970-01-01T00:00:00Z hasta ahora.

 **`util.time.nowFormatted(String)`**  
Devuelve una cadena con la marca de tiempo actual en UTC utilizando el formato especificado en un tipo de entrada String.

 **`util.time.nowFormatted(String, String)`**  
Devuelve una cadena con la marca de tiempo actual de una zona horaria utilizando el formato y la zona horaria especificados en tipos de entrada String.

 **`util.time.parseFormattedToEpochMilliSeconds(String, String)`**  
Analiza una marca de tiempo pasada como cadena junto con un formato que contiene una zona horaria y, a continuación, la devuelve como milisegundos transcurridos desde la fecha de inicio.

 **`util.time.parseFormattedToEpochMilliSeconds(String, String, String)`**  
Analiza una marca de tiempo pasada como cadena junto con un formato y una zona horaria y, a continuación, la devuelve como milisegundos transcurridos desde la fecha de inicio.

 **`util.time.parseISO8601ToEpochMilliSeconds(String)`**  
Analiza una ISO8601 marca de tiempo pasada como cadena y, a continuación, devuelve la marca de tiempo en milisegundos desde la época.

 **`util.time.epochMilliSecondsToSeconds(long)`**  
Convierte una marca de tiempo en milisegundos desde la fecha de inicio en una marca de tiempo en segundos de la fecha de inicio.

 **`util.time.epochMilliSecondsToISO8601(long)`**  
Convierte una marca de tiempo de milisegundos de época en una marca de tiempo. ISO8601

 **`util.time.epochMilliSecondsToFormatted(long, String)`**  
Convierte una marca de tiempo en milisegundos desde la fecha de inicio, pasada como tipo long, en una marca de tiempo UTC con el formato suministrado.

 **`util.time.epochMilliSecondsToFormatted(long, String, String)`**  
Convierte una marca de tiempo en milisegundos desde la fecha de inicio, pasada como tipo long, en una marca de tiempo para la zona horaria y con el formato suministrados.

# Aplicaciones auxiliares de DynamoDB en util.dynamodb
<a name="dynamodb-helpers-in-util-dynamodb-js"></a>

`util.dynamodb` contiene métodos auxiliares que facilitan la escritura y la lectura de datos en Amazon DynamoDB, como el mapeo y el formato automáticos de los tipos de datos. 

## toDynamoDB
<a name="utility-helpers-in-toDynamoDB-js"></a>

### Lista de utilidades toDynamoDB
<a name="utility-helpers-in-toDynamoDB-list-js"></a>

 **`util.dynamodb.toDynamoDB(Object)`**   
Herramienta de conversión general de objetos para DynamoDB que convierte objetos de entrada en la representación de DynamoDB correspondiente. Es algo inflexible en cuanto al modo en que representa algunos tipos: por ejemplo, utiliza listas ("L") en lugar de conjuntos ("SS", "NS" "BS"). Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  
**Ejemplo de cadena**  

```
Input:      util.dynamodb.toDynamoDB("foo")
Output:     { "S" : "foo" }
```
**Ejemplo de número**  

```
Input:      util.dynamodb.toDynamoDB(12345)
Output:     { "N" : 12345 }
```
**Ejemplo de booleano**  

```
Input:      util.dynamodb.toDynamoDB(true)
Output:     { "BOOL" : true }
```
**Ejemplo de lista**  

```
Input:      util.dynamodb.toDynamoDB([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```
**Ejemplo de mapa**  

```
Input:      util.dynamodb.toDynamoDB({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

## Utilidades toString
<a name="utility-helpers-in-toString-js"></a>

### Lista de utilidades toString
<a name="utility-helpers-in-toString-list-js"></a>

**`util.dynamodb.toString(String)`**  
Convierte una cadena de entrada al formato de cadena de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toString("foo")
Output:     { "S" : "foo" }
```

 **`util.dynamodb.toStringSet(List<String>)`**  
Convierte una lista con cadenas al formato de conjunto de cadenas de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toStringSet([ "foo", "bar", "baz" ])
Output:     { "SS" : [ "foo", "bar", "baz" ] }
```

## Utilidades toNumber
<a name="utility-helpers-in-toNumber-js"></a>

### Lista de utilidades toNumber
<a name="utility-helpers-in-toNumber-list-js"></a>

 **`util.dynamodb.toNumber(Number)`**  
Convierte un número al formato de número de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toNumber(12345)
Output:     { "N" : 12345 }
```

 **`util.dynamodb.toNumberSet(List<Number>)`**  
Convierte una lista de números al formato de conjunto de números de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toNumberSet([ 1, 23, 4.56 ])
Output:     { "NS" : [ 1, 23, 4.56 ] }
```

## Utilidades toBinary
<a name="utility-helpers-in-toBinary-js"></a>

### Lista de utilidades toBinary
<a name="utility-helpers-in-toBinary-list-js"></a>

 **`util.dynamodb.toBinary(String)`**  
Convierte datos binarios codificados como una cadena en base64 al formato binario de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toBinary("foo")
Output:     { "B" : "foo" }
```

 **`util.dynamodb.toBinarySet(List<String>)`**  
Convierte una lista de datos binarios codificados como cadenas en base64 al formato de conjunto binario de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toBinarySet([ "foo", "bar", "baz" ])
Output:     { "BS" : [ "foo", "bar", "baz" ] }
```

## Utilidades toBoolean
<a name="utility-helpers-in-toBoolean-js"></a>

### Lista de utilidades toBoolean
<a name="utility-helpers-in-toBoolean-list-js"></a>

 **`util.dynamodb.toBoolean(Boolean)`**  
Convierte un valor booleano al formato booleano correspondiente de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toBoolean(true)
Output:     { "BOOL" : true }
```

## Utilidades toNull
<a name="utility-helpers-in-toNull-js"></a>

### Lista de utilidades toNull
<a name="utility-helpers-in-toNull-list-js"></a>

 **`util.dynamodb.toNull()`**  
Devuelve un valor nulo con el formato nulo de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toNull()
Output:     { "NULL" : null }
```

## Utilidades toList
<a name="utility-helpers-in-toList-js"></a>

### Lista de utilidades toList
<a name="utility-helpers-in-toList-list-js"></a>

**`util.dynamodb.toList(List)`**  
Convierte una lista de objetos al formato de lista de DynamoDB. Cada elemento de la lista se convierte también al formato correspondiente de DynamoDB. Es algo inflexible en cuanto al modo en que representa algunos objetos anidados: por ejemplo, utiliza listas ("L") en lugar de conjuntos ("SS", "NS" "BS"). Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toList([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```

## Utilidades toMap
<a name="utility-helpers-in-toMap-js"></a>

### Lista de utilidades toMap
<a name="utility-helpers-in-toMap-list-js"></a>

 **`util.dynamodb.toMap(Map)`**  
Convierte un mapa al formato de mapa de DynamoDB. Cada valor del mapa se convierte también al formato de DynamoDB correspondiente. Es algo inflexible en cuanto al modo en que representa algunos objetos anidados: por ejemplo, utiliza listas ("L") en lugar de conjuntos ("SS", "NS" "BS"). Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toMap({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

 **`util.dynamodb.toMapValues(Map)`**  
Crea una copia del mapa en la que cada valor se convierte al formato correspondiente de DynamoDB. Es algo inflexible en cuanto al modo en que representa algunos objetos anidados: por ejemplo, utiliza listas ("L") en lugar de conjuntos ("SS", "NS" "BS").  

```
Input:      util.dynamodb.toMapValues({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "foo"  : { "S" : "bar" },
               "baz"  : { "N" : 1234 },
               "beep" : {
                   "L" : [
                       { "S" : "boop" }
                   ]
               }
           }
```
Esto es ligeramente diferente de `util.dynamodb.toMap(Map)`, ya que solo devuelve el contenido del valor de atributo de DynamoDB y no todo el valor de atributo en sí. Por ejemplo, las siguientes instrucciones son exactamente lo mismo:  

```
util.dynamodb.toMapValues(<map>)
util.dynamodb.toMap(<map>)("M")
```

## Utilidades S3Object
<a name="utility-helpers-in-S3Object-js"></a>

### Lista de utilidades S3Object
<a name="utility-helpers-in-S3Object-list-js"></a>

**`util.dynamodb.toS3Object(String key, String bucket, String region)`**  
Convierte la clave, el bucket y la región a la representación de objeto de S3 de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toS3Object("foo", "bar", region = "baz")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo", \"bucket\" : \"bar", \"region\" : \"baz" } }" }
```

**`util.dynamodb.toS3Object(String key, String bucket, String region, String version)`**  
Convierte la clave, el bucket, la región y la versión opcional a la representación de objeto de S3 de DynamoDB. Esto devuelve un objeto que describe el valor del atributo de DynamoDB.  

```
Input:      util.dynamodb.toS3Object("foo", "bar", "baz", "beep")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" }
```

 **`util.dynamodb.fromS3ObjectJson(String)`**  
Acepta el valor de cadena de un objeto de S3 de DynamoDB y devuelve un mapa que contiene la clave, el bucket, la región y la versión opcional.  

```
Input:      util.dynamodb.fromS3ObjectJson({ "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" })
Output:     { "key" : "foo", "bucket" : "bar", "region" : "baz", "version" : "beep" }
```

# Aplicaciones auxiliares para HTTP en util.http
<a name="http-helpers-in-utils-http-js"></a>

La utilidad `util.http` proporciona métodos auxiliares que puede utilizar para gestionar parámetros de solicitud HTTP y añadir encabezados de respuesta.

## Lista de utilidades util.http
<a name="http-helpers-in-utils-http-list-js"></a>

 **`util.http.copyHeaders(headers)`**  
Copia los encabezados del mapa, excluidos los siguientes encabezados HTTP restringidos:  
+ transfer-encoding
+ connection
+ host
+ expect
+ keep-alive
+ upgrade
+ proxy-authenticate
+ proxy-authorization
+ te
+ content-length

**`util.http.addResponseHeader(String, Object)`**  
Añade un único encabezado personalizado con el nombre (`String`) y el valor (`Object`) de la respuesta. Se aplican las siguientes restricciones:  
+ Además de la lista de encabezados restringidos para `copyHeaders(headers)`, los nombres del encabezado no pueden coincidir con ninguno de los siguientes:
  + Access-Control-Allow-Credentials
  + Access-Control-Allow-Origin
  + Access-Control-Expose-Headers
  + Access-Control-Max-Age
  + Access-Control-Allow-Methods
  + Access-Control-Allow-Headers
  + Vary
  + Content-Type
+ Los nombres del encabezado no pueden comenzar por los prefijos restringidos `x-amzn-` o `x-amz-`.
+ El tamaño de los encabezados de respuesta personalizada no puede superar los 4 KB. Esto incluye los nombres y valores del encabezado.
+ Debe definir cada encabezado de respuesta una vez por operación de GraphQL. Sin embargo, si define un encabezado personalizado con el mismo nombre varias veces, la definición más reciente aparecerá en la respuesta. Todos los encabezados se contabilizan para el límite de tamaño del encabezado independientemente de los nombres.
+ Los encabezados con un nombre vacío o restringido `(String)` o un valor nulo `(Object)` se ignorarán y generarán un error `ResponseHeaderError` que se agregará al resultado `errors` de la operación.

```
export function request(ctx) {
  util.http.addResponseHeader('itemsCount', 7)
  util.http.addResponseHeader('render', ctx.args.render)
  return {}
}
```

**`util.http.addResponseHeaders(Map)`**  
Agrega varios encabezados de respuesta a la respuesta desde el mapa de nombres `(String)` y los valores `(Object)` especificados. Las mismas limitaciones enumeradas para el método `addResponseHeader(String, Object)` también se aplican a este método.  

```
export function request(ctx) {
  const headers = {
    headerInt: 12,
    headerString: 'stringValue',
    headerObject: {
      field1: 7,
      field2: 'string'
    }
  }
  util.http.addResponseHeaders(headers)
  return {}
}
```

# Aplicaciones auxiliares de transformación en util.transform
<a name="transformation-helpers-in-utils-transform-js"></a>

`util.transform` contiene métodos auxiliares que facilitan las operaciones complejas sobre orígenes de datos.

## Lista de utilidades de aplicaciones auxiliares de transformación
<a name="transformation-helpers-in-utils-transform-js-list"></a>

**`util.transform.toDynamoDBFilterExpression(filterObject: DynamoDBFilterObject) : string`**  
Convierte una cadena de entrada en una expresión de filtro que puede usarse en DynamoDB. Recomendamos usar `toDynamoDBFilterExpression` con las [funciones del módulo integradas](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html).

**`util.transform.toElasticsearchQueryDSL(object: OpenSearchQueryObject) : string`**  
Convierte la entrada dada en su expresión DSL de OpenSearch consulta equivalente y la devuelve como una cadena JSON.  
**Ejemplo de entrada:**  

```
util.transform.toElasticsearchQueryDSL({
    "upvotes":{
        "ne":15,
        "range":[
            10,
            20
        ]
    },
    "title":{
        "eq":"hihihi",
        "wildcard":"h*i"
    }
  })
```
**Ejemplo de salida:**  

```
{
    "bool":{
      "must":[
          {
            "bool":{
              "must":[
                  {
                    "bool":{
                      "must_not":{
                        "term":{
                          "upvotes":15
                        }
                      }
                    }
                  },
                  {
                    "range":{
                      "upvotes":{
                        "gte":10,
                        "lte":20
                      }
                    }
                  }
              ]
            }
          },
          {
            "bool":{
              "must":[
                  {
                    "term":{
                      "title":"hihihi"
                    }
                  },
                  {
                  "wildcard":{
                      "title":"h*i"
                    }
                  }
              ]
            }
          }
      ]
    }
}
```
Se entiende que el operador predeterminado es AND.

**`util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`**  
Convierte un objeto de entrada `Map` en un objeto de expresión `SubscriptionFilter`. El método `util.transform.toSubscriptionFilter` se utiliza como entrada a la extensión `extensions.setSubscriptionFilter()`. Para obtener más información, consulte el artículo sobre [extensiones](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html).  
Los parámetros y la instrucción return se indican a continuación:  
*Parámetros*  
+ `objFilter`: `SubscriptionFilterObject`

  Objeto de entrada `Map` que se convierte en el objeto de expresión `SubscriptionFilter`.
+ `ignoredFields`: `SubscriptionFilterExcludeKeysType` (opcional)

  `List` de nombres de campo en el primer objeto que se omitirán.
+ `rules`: `SubscriptionFilterRuleObject` (opcional)

  Objeto de entrada `Map` con reglas estrictas que se incluye al construir el objeto de expresión `SubscriptionFilter`. Estas reglas estrictas se incluirán en el objeto de expresión `SubscriptionFilter` de tal forma que se cumpla al menos una de las reglas para pasar el filtro de suscripción.
*Respuesta*  
Devuelve `[SubscriptionFilter](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)`.

**`util.transform.toSubscriptionFilter(Map, List)`**  
Convierte un objeto de entrada `Map` en un objeto de expresión `SubscriptionFilter`. El método `util.transform.toSubscriptionFilter` se utiliza como entrada a la extensión `extensions.setSubscriptionFilter()`. Para obtener más información, consulte el artículo sobre [extensiones](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html).  
El primer argumento es el objeto de entrada `Map` que se convierte en el objeto de expresión `SubscriptionFilter`. El segundo argumento es una `List` de nombres de campo que se omiten en el primer objeto de entrada `Map` al construir el objeto de expresión `SubscriptionFilter`.

**`util.transform.toSubscriptionFilter(Map, List, Map)`**  
Convierte un objeto de entrada `Map` en un objeto de expresión `SubscriptionFilter`. El método `util.transform.toSubscriptionFilter` se utiliza como entrada a la extensión `extensions.setSubscriptionFilter()`. Para obtener más información, consulte el artículo sobre [extensiones](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html). 

**`util.transform.toDynamoDBConditionExpression(conditionObject)`**  
Crea una expresión de condición de DynamoDB.

## Argumentos de filtro de suscripción
<a name="subscription-filter-arguments-js"></a>

En la siguiente tabla se explica cómo se definen los argumentos de las siguientes utilidades:
+ `Util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`

------
#### [ Argument 1: Map ]

El argumento 1 es un objeto `Map` con los siguientes valores clave:
+ nombres de los campos
+ "and"
+ "or"

En el caso de los nombres de campo como claves, las condiciones de las entradas de estos campos adoptan la forma de `"operator" : "value"`. 

En el siguiente ejemplo se muestra cómo se pueden añadir entradas a `Map`:

```
"field_name" : {
                    "operator1" : value             
               }

## We can have multiple conditions for the same field_name: 

"field_name" : {
                    "operator1" : value             
                    "operator2" : value
                    .
                    .
                    .                  
               }
```

Cuando un campo tiene dos o más condiciones, se considera que todas estas condiciones utilizan la operación OR.

La entrada `Map` también puede tener "and" y "or" como claves, lo que implica que todas las entradas que incluyen deben unirse con la lógica AND u OR, según la clave. Los valores clave "and" y "or" esperan una matriz de condiciones.

```
"and" : [
            
            {
                "field_name1" : {
                    "operator1" : value             
                }
             },
             
             {
                "field_name2" : {
                    "operator1" : value             
                }
             },
             .
             .
        ].
```

Tenga en cuenta que puede anidar "and" y "or". Es decir, puede tener "and" y "or" anidados dentro de otro bloque "and" y "or". Sin embargo, no funciona para campos simples.

```
"and" : [
            
            {
                "field_name1" : {
                    "operator" : value             
                }
             },
             
             {
                "or" : [
                            {
                                "field_name2" : {
                                    "operator" : value             
                                }
                            },
                            
                            {
                                "field_name3" : {
                                    "operator" : value             
                                }
                            }
              
                        ].
```

En el siguiente ejemplo se muestra una entrada de *argumento 1* con `util.transform.toSubscriptionFilter(Map) : Map`.

**Entradas**

Argumento 1: mapa:

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 2000
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

**Salida**

El resultado es un objeto `Map`:

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 2: List ]

El argumento 2 contiene una `List` de nombres de campo que no deberían tenerse en cuenta en la entrada `Map` (argumento 1) al construir el objeto de expresión `SubscriptionFilter`. `List` también puede estar vacía.

En el siguiente ejemplo se muestran las entradas de argumento 1 y argumento 2 con `util.transform.toSubscriptionFilter(Map, List) : Map`.

**Entradas**

Argumento 1: mapa:

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

Argumento 2: lista:

```
["percentageUp", "author"]
```

**Salida**

El resultado es un objeto `Map`:

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 3: Map ]

El argumento 3 es un objeto `Map` que tiene nombres de campo como valores clave (no puede tener "and" u "or"). En el caso de los nombres de campo como claves, las condiciones de estos campos son entradas en forma de `"operator" : "value"`. A diferencia del argumento 1, el argumento 3 no puede tener varias condiciones en la misma clave. Además, el argumento 3 no tiene una cláusula "and" u "or", por lo que tampoco hay anidamiento involucrado.

El argumento 3 representa una lista de reglas estrictas, que se añaden al objeto de expresión `SubscriptionFilter` para que se cumpla **al menos una** de estas condiciones para pasar el filtro.

```
{
  "fieldname1": {
    "operator": value
  },
  "fieldname2": {
    "operator": value
  }
}
.
.
.
```

En el siguiente ejemplo se muestran las entradas de *argumento 1*, *argumento 2* y *argumento 3* con `util.transform.toSubscriptionFilter(Map, List, Map) : Map`.

**Entradas**

Argumento 1: mapa:

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "lt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

Argumento 2: lista:

```
["percentageUp", "author"]
```

Argumento 3: mapa:

```
{
  "upvotes": {
    "gte": 250
  },
  "author": {
    "eq": "Person1"
  }
}
```

**Salida**

El resultado es un objeto `Map`:

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "upvotes",
          "operator": "gte",
          "value": 250
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Person1"
        }
      ]
    }
  ]
}
```

------

# Aplicaciones auxiliares de cadena en util.str
<a name="str-helpers-in-util-str-js"></a>

 `util.str` contiene métodos para ayudar con operaciones de cadena comunes. 

## Lista de utilidades util.str
<a name="str-helpers-in-util-str-list-js"></a>

 **`util.str.normalize(String, String)`**  
Normaliza una cadena con uno de los cuatro formatos de normalización de Unicode: NFC, NFD, NFKC o NFKD. El primer argumento es la cadena que se va a normalizar. El segundo argumento es "nfc", "nfd", "nfkc" o "nfkd" y especifica el tipo de normalización que se utilizará en el proceso de normalización.

# Extensiones
<a name="extensions-js"></a>

`extensions` contiene un conjunto de métodos para realizar acciones adicionales en sus solucionadores.

## Almacenamiento en caché de extensiones
<a name="caching-extensions-js-list"></a>

**`extensions.evictFromApiCache(typeName: string, fieldName: string, keyValuePair: Record<string, any>) : Object`**  
Expulsa un elemento de la memoria caché del AWS AppSync servidor. El primer argumento es el nombre de tipo. El segundo argumento es el nombre de campo. El tercer argumento es un objeto que contiene elementos de pares clave-valor que especifican el valor clave de almacenamiento en caché. Debe colocar los elementos del objeto en el mismo orden que las claves de almacenamiento en caché del elemento `cachingKey` del solucionador almacenado en caché. Para obtener más información acerca del almacenamiento en caché, consulte la sección sobre el [comportamiento de almacenamiento en caché](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html#caching-behavior).  
**Ejemplo 1:**  
En este ejemplo, se expulsan los elementos que se almacenaron en caché para un solucionador llamado `Query.allClasses` en el que se usó una clave de almacenamiento en caché denominada `context.arguments.semester`. Cuando se llama a la mutación y se ejecuta el solucionador, si una entrada se borra correctamente, la respuesta contiene un valor `apiCacheEntriesDeleted` en el objeto de extensiones que muestra cuántas entradas se eliminaron.  

```
import { util, extensions } from '@aws-appsync/utils';

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
	extensions.evictFromApiCache('Query', 'allClasses', {
		'context.arguments.semester': ctx.args.semester,
	});
	return null;
}
```
Esta función **solo** funciona para mutaciones, no para consultas.

## Extensiones de suscripción
<a name="subscription-extensions-js-list"></a>

**`extensions.setSubscriptionFilter(filterJsonObject)`**  
Define filtros de suscripción mejorados. Cada evento de notificación de suscripción se evalúa con respecto a los filtros de suscripción proporcionados y envía notificaciones a los clientes si todos los filtros se evalúan como `true`. El argumento es `filterJsonObject` (puede encontrar más información sobre este argumento a continuación, en la filterJsonObject sección *Argumento:*). Consulte el artículo sobre [filtrado de suscripciones mejorado](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html).  
Puede usar esta función de extensión solo en el controlador de respuestas de un solucionador de suscripción. Además, recomendamos usar `util.transform.toSubscriptionFilter` para crear su filtro.

**`extensions.setSubscriptionInvalidationFilter(filterJsonObject)`**  
Define los filtros de invalidación de suscripciones. Los filtros de suscripción se evalúan con respecto a la carga de invalidación y, a continuación, invalidan una suscripción determinada si los filtros se evalúan como `true`. El argumento es `filterJsonObject` (puede encontrar más información sobre este argumento a continuación, en la filterJsonObject sección *Argumento:*). Consulte el artículo sobre [filtrado de suscripciones mejorado](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html).  
Puede usar esta función de extensión solo en el controlador de respuestas de un solucionador de suscripción. Además, recomendamos usar `util.transform.toSubscriptionFilter` para crear su filtro.

**`extensions.invalidateSubscriptions(invalidationJsonObject)`**  
Se utiliza para iniciar la invalidación de una suscripción a partir de una mutación. El argumento es `invalidationJsonObject` (puede encontrar más información sobre este argumento a continuación, en la invalidationJsonObject sección *Argumento:*).  
Esta extensión solo se puede usar en las plantillas de mapeo de respuestas de los solucionadores de mutaciones.  
Solo puede usar como máximo cinco llamadas al método `extensions.invalidateSubscriptions()` únicas en una sola solicitud. Si supera este límite, recibirá un error de GraphQL.

## Argumento: filterJsonObject
<a name="extensions-filterJsonObject-js"></a>

El objeto JSON define los filtros de suscripción o invalidación. Es una matriz de filtros en un `filterGroup`. Cada filtro es una colección de filtros individuales.

```
{
    "filterGroup": [
        {
           "filters" : [
                 {
                    "fieldName" : "userId",
                    "operator" : "eq",
                    "value" : 1
                }
           ]
           
        },
        {
           "filters" : [
                {
                    "fieldName" : "group",
                    "operator" : "in",
                    "value" : ["Admin", "Developer"]
                }
           ]
           
        }
    ]
}
```

Cada filtro tiene tres atributos: 
+ `fieldName`: campo de esquema de GraphQL.
+ `operator`: tipo de operador.
+ `value`: valores que se van a comparar con el valor `fieldName` de notificación de suscripción.

A continuación se muestra un ejemplo de asignación de estos atributos:

```
{
 "fieldName" : "severity",
 "operator" : "le",
 "value" : context.result.severity
}
```

## Argumento: invalidationJsonObject
<a name="extensions-invalidationJsonObject-js"></a>

El `invalidationJsonObject` define lo siguiente:
+ `subscriptionField`: suscripción del esquema de GraphQL a invalidar. Se baraja la posibilidad de invalidar una suscripción única, definida como cadena en el `subscriptionField`.
+ `payload`: lista de pares clave-valor que se utiliza como entrada para la invalidación de suscripciones si el filtro de invalidación se evalúa como `true` en comparación con sus valores.

  En el siguiente ejemplo se invalida a los clientes suscritos y conectados que utilizan la suscripción `onUserDelete` cuando el filtro de invalidación definido en el solucionador de suscripción se evalúa como `true` en comparación con el valor `payload`.

  ```
  export const request = (ctx) => ({ payload: null });
  
  export function response(ctx) {
  	extensions.invalidateSubscriptions({
  		subscriptionField: 'onUserDelete',
  		payload: { group: 'Developer', type: 'Full-Time' },
  	});
  	return ctx.result;
  }
  ```

# Aplicaciones auxiliares para XML en util.xml
<a name="xml-helpers-in-util-xml-js"></a>

 `util.xml` contiene métodos para ayudar con la conversión de cadena XML. 

## Lista de utilidades util.xml
<a name="xml-helpers-in-util-xml-list-js"></a>

 **`util.xml.toMap(String) : Object`**  
Convierte una cadena XML a un diccionario.  
**Ejemplo 1:**  

```
Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
    <id>1</id>
    <title>Getting started with GraphQL</title>
</post>
</posts>

Output (object):

{
    "posts":{
      "post":{
        "id":1,
        "title":"Getting started with GraphQL"
      }
    }
}
```
**Ejemplo 2:**  

```
Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
  <id>1</id>
  <title>Getting started with GraphQL</title>
</post>
<post>
  <id>2</id>
  <title>Getting started with AppSync</title>
</post>
</posts>

Output (JavaScript object):

{
    "posts":{
    "post":[
        {
            "id":1,
            "title":"Getting started with GraphQL"
        },
        {
            "id":2,
            "title":"Getting started with AppSync"
        }
    ]
    }
}
```

**`util.xml.toJsonString(String, Boolean?) : String`**  
Convierte una cadena XML en una cadena JSON. Esto es similar a `toMap`, salvo que el resultado es una cadena. Esto resulta útil si se desea convertir directamente y devolver la respuesta XML de un objeto HTTP a JSON. Puede establecer un parámetro booleano opcional para determinar si desea codificar la cadena JSON.