Documentación para desarrolladores de Lingara
Esta página está traducida del inglés. Si ambas difieren, la página en inglés es la correcta. Leer la página en inglés
Una conexión se compone de pasos, y cualquier paso puede llevar un script. El script de un paso es el cuerpo de una función. Recibe dos valores: lingara, la API de esta página, e input, los campos propios del paso junto con su cliente y los pasos enlazados antes que él. El tipo de input depende del tipo de paso, así que el script de un paso de webhook lee los campos de un paso de webhook. El script devuelve exactamente un objeto, creado por una de las funciones auxiliares de abajo.
Un script nunca ve un secreto. Cuando un paso necesita su cliente, recibe una referencia, como input.client, y la función auxiliar registra esa referencia. Lingara rellena los valores reales cuando aplicas la conexión.
Lo que un script no debe hacer
Un script se ejecuta en tu propio navegador, en un worker sin red y sin almacenamiento. Está sujeto a estos límites:
- Termina en 1 segundo como máximo.
- Una cadena que devuelve tiene como máximo 2048 caracteres.
- Una lista que devuelve tiene como máximo 64 elementos.
- Su resultado completo ocupa como máximo 16 KiB.
Un script que supera un límite, lanza una excepción o devuelve algo distinto del resultado de una función auxiliar hace fallar su paso, y «Comprobarlo» muestra qué paso y por qué.
La promesa de versión
Todo lo que hay en esta página es lingara.v1. Dentro de v1 la API solo crece: puede aparecer una función auxiliar nueva, una opción opcional nueva o un tipo de paso nuevo, pero nada de lo que puedes usar hoy se elimina, se renombra ni se restringe. Un cambio que rompería un script es una versión nueva junto a esta, y v1 se queda como está.
Las declaraciones
Cada declaración de abajo se genera a partir del mismo archivo con el que se autocompleta el editor de scripts.
NodeHandle
El id de otro paso, como "n1". Un paso dependiente nombra a su cliente por su referencia.
export type NodeHandle = string;
Scope
Un permiso que puede tener un cliente de la API. El servidor decide cuáles puede usar tu cuenta.
export type Scope = 'vocab:generate' | 'lesson_plans:read' | 'lesson_plans:write' | 'tutor:converse' | 'usage:read' | 'events:read' | 'events:write' | 'embed:mint' | 'embed:play';
AppSlot
Un lugar de la app de Lingara donde puede aparecer la tarjeta de una app.
export type AppSlot = 'plans.empty_detail' | 'home.side';
ContextSlice
Una parte del contexto del estudiante que una app puede pedir recibir.
export type ContextSlice = 'languages' | 'plan_summary' | 'review_due' | 'tutor_topic';
ClientOptions
Opciones de lingara.client.
export interface ClientOptions {
name: string;
scopes: readonly Scope[];
redirectUris?: readonly string[];
}
name(string) — El nombre del cliente, tal como lo muestra Herramientas para desarrolladores.scopes(readonly Scope[]) — Los permisos que pide el cliente.redirectUris?(readonly string[]) — Adónde puede devolver a un estudiante el flujo de código de autorización. Omítelo para un cliente de servidor a servidor.
WebhookOptions
Opciones de lingara.webhook.
export interface WebhookOptions {
client: NodeHandle;
url: string;
events: readonly string[];
}
client(NodeHandle) — El paso de cliente al que pertenece este webhook:input.client.url(string) — La dirección HTTPS a la que Lingara entrega los eventos.events(readonly string[]) — Los tipos de evento que se entregan, como"lesson_plan.ready".
ManifestOptions
Opciones de lingara.manifest, en camelCase; la función auxiliar escribe la forma de transmisión del manifiesto.
export interface ManifestOptions {
name: string | Readonly<Record<string, string>>;
description: string | Readonly<Record<string, string>>;
renderUrl: string;
slots: readonly AppSlot[];
context?: readonly ContextSlice[];
scopes?: readonly Scope[];
tutorNote?: boolean;
defaultLocale?: string;
}
name(string | Readonly<Record<string, string>>) — El nombre de la app: una cadena, o una cadena por código de idioma.description(string | Readonly<Record<string, string>>) — Una frase sobre la app: una cadena, o una cadena por código de idioma.renderUrl(string) — La dirección HTTPS a la que Lingara pide la tarjeta de la app.slots(readonly AppSlot[]) — Dónde puede aparecer la tarjeta de la app.context?(readonly ContextSlice[]) — Las partes del contexto que recibe la app. Por defecto, ninguna.scopes?(readonly Scope[]) — Los permisos que la app pide al estudiante. Por defecto, ninguno.tutorNote?(boolean) — Si la app puede dejar una nota para el tutor. Por defecto,false.defaultLocale?(string) — El idioma con el que se guarda un nombre o una descripción de cadena simple. Por defecto,"en".
AppOptions
Opciones de lingara.app.
export interface AppOptions {
client: NodeHandle;
manifest: Manifest;
}
client(NodeHandle) — El paso de cliente al que pertenece esta app:input.client.manifest(Manifest) — El manifiesto de la app, creado conlingara.manifest.
ClientSpec
Lo que crea un paso de cliente: un cliente de la API.
export interface ClientSpec {
readonly kind: 'client';
readonly name: string;
readonly scopes: readonly Scope[];
readonly redirectUris?: readonly string[];
}
kind('client') — Siempre"client".name(string) — El nombre del cliente.scopes(readonly Scope[]) — Los permisos que pide el cliente.redirectUris?(readonly string[]) — Las URI de redirección del cliente, si tiene alguna.
SecretSpec
Lo que crea un paso de secreto: un secreto nuevo para su cliente.
export interface SecretSpec {
readonly kind: 'secret';
readonly client: NodeHandle;
}
kind('secret') — Siempre"secret".client(NodeHandle) — El paso de cliente al que pertenece el secreto.
WebhookSpec
Lo que crea un paso de webhook: un endpoint de webhook.
export interface WebhookSpec {
readonly kind: 'webhook';
readonly client: NodeHandle;
readonly url: string;
readonly events: readonly string[];
}
kind('webhook') — Siempre"webhook".client(NodeHandle) — El paso de cliente al que pertenece el webhook.url(string) — La dirección a la que se entregan los eventos.events(readonly string[]) — Los tipos de evento que se entregan.
AppSpec
Lo que crea un paso de app: una app que dibuja una tarjeta dentro de Lingara.
export interface AppSpec {
readonly kind: 'app';
readonly client: NodeHandle;
readonly manifest: Manifest;
}
kind('app') — Siempre"app".client(NodeHandle) — El paso de cliente al que pertenece la app.manifest(Manifest) — El manifiesto de la app.
Manifest
Un manifiesto de app en su forma de transmisión, tal como lo guarda el servidor.
export interface Manifest {
readonly manifest_version: 1;
readonly default_locale: string;
readonly name: Readonly<Record<string, string>>;
readonly description: Readonly<Record<string, string>>;
readonly render_url: string;
readonly slots: readonly AppSlot[];
readonly context: readonly ContextSlice[];
readonly scopes: readonly Scope[];
readonly tutor_note: boolean;
}
manifest_version(1) — Siempre1.default_locale(string) — El idioma que se muestra cuando el del estudiante no tiene entrada.name(Readonly<Record<string, string>>) — El nombre de la app, por código de idioma.description(Readonly<Record<string, string>>) — Una frase sobre la app, por código de idioma.render_url(string) — La dirección HTTPS a la que Lingara pide la tarjeta de la app.slots(readonly AppSlot[]) — Dónde puede aparecer la tarjeta de la app.context(readonly ContextSlice[]) — Las partes del contexto que recibe la app.scopes(readonly Scope[]) — Los permisos que la app pide al estudiante.tutor_note(boolean) — Si la app puede dejar una nota para el tutor.
Spec
Cualquier especificación que devuelve una función auxiliar. Un script devuelve exactamente una.
export type Spec = ClientSpec | SecretSpec | WebhookSpec | AppSpec;
Upstream
La salida de cada paso directamente anterior, por referencia.
export type Upstream = Readonly<Record<NodeHandle, Spec & {
readonly handle: NodeHandle;
}>>;
ClientInput
La entrada de un paso de cliente: sus campos, que son las opciones de lingara.client.
export interface ClientInput {
readonly name: string;
readonly scopes: readonly Scope[];
readonly redirectUris?: readonly string[];
readonly upstream: Upstream;
}
name(string) — El nombre del cliente.scopes(readonly Scope[]) — Los permisos que pide el cliente.redirectUris?(readonly string[]) — Las URI de redirección del cliente, si el paso tiene alguna.upstream(Upstream) — La salida de cada paso directamente anterior.
SecretInput
La entrada de un paso de secreto. client es el único paso de cliente enlazado a este.
export interface SecretInput {
readonly client: NodeHandle;
readonly upstream: Upstream;
}
client(NodeHandle) — El paso de cliente enlazado a este.upstream(Upstream) — La salida de cada paso directamente anterior.
WebhookInput
La entrada de un paso de webhook: sus campos, más el cliente enlazado.
export interface WebhookInput {
readonly client: NodeHandle;
readonly url: string;
readonly events: readonly string[];
readonly upstream: Upstream;
}
client(NodeHandle) — El paso de cliente enlazado a este.url(string) — La dirección que indican los campos del paso.events(readonly string[]) — Los tipos de evento que indican los campos del paso.upstream(Upstream) — La salida de cada paso directamente anterior.
AppInput
La entrada de un paso de app: los campos de su manifiesto, más el cliente enlazado.
export interface AppInput {
readonly client: NodeHandle;
readonly manifest: ManifestOptions;
readonly upstream: Upstream;
}
client(NodeHandle) — El paso de cliente enlazado a este.manifest(ManifestOptions) — El manifiesto que describen los campos del paso.upstream(Upstream) — La salida de cada paso directamente anterior.
InputFor
La entrada que recibe un script del tipo de paso indicado.
export type InputFor<K extends Spec['kind']> = K extends 'client' ? ClientInput : K extends 'secret' ? SecretInput : K extends 'webhook' ? WebhookInput : AppInput;
LingaraV1
Las funciones auxiliares a las que llama un script. Cada una devuelve una especificación congelada, y una opción de tipo incorrecto lanza un TypeError que la nombra.
export interface LingaraV1 {
readonly version: 'v1';
client(options: ClientOptions): ClientSpec;
secret(client: NodeHandle): SecretSpec;
webhook(options: WebhookOptions): WebhookSpec;
app(options: AppOptions): AppSpec;
manifest(options: ManifestOptions): Manifest;
}
version('v1') — Siempre"v1".client(options: ClientOptions): ClientSpec— Un cliente de la API.secret(client: NodeHandle): SecretSpec— Un secreto nuevo para un paso de cliente.webhook(options: WebhookOptions): WebhookSpec— Un endpoint de webhook en un paso de cliente.app(options: AppOptions): AppSpec— Una app en un paso de cliente.manifest(options: ManifestOptions): Manifest— Un manifiesto en su forma de transmisión, con las opciones que v1 deja como opcionales ya rellenadas.
return lingara.client({ name: input.name, scopes: input.scopes })
return lingara.secret(input.client)
return lingara.webhook({ client: input.client, url: input.url, events: input.events })
return lingara.app({ client: input.client, manifest: lingara.manifest(input.manifest) })
NodeScript
El script de un paso es el cuerpo de esta función: return lingara.webhook({ client: input.client, url: input.url, events: input.events }).
export type NodeScript<K extends Spec['kind']> = (lingara: LingaraV1, input: InputFor<K>) => Spec;