Ir al contenido

Cliente TypeScript (@dustid/apid-client)

@dustid/apid-client es el cliente TypeScript tipado para la API de DUST. Es el mismo cliente que utiliza la aplicación web DICE en producción, y sus tipos de solicitud y respuesta se generan directamente a partir de la especificación OpenAPI de la API, por lo que se mantiene totalmente sincronizado con el servidor.

El paquete no está publicado en el registro público de npm. DUST se encarga de distribuirlo y está disponible previa solicitud para los clientes de integración (contacte con support@dustidentity.com). npm install @dustid/apid-client no lo encontrará.

Si prefiere no incorporar esta dependencia, puede obtener la misma seguridad de tipos generando tipos a partir de la especificación OpenAPI —así es exactamente como se generan los tipos de este cliente— y llamar a la API con fetch sin ninguna biblioteca adicional. La guía de inicio rápido lo hace de esa manera para que pueda ejecutarse sin instalar nada.

Compruebe lo siguiente antes de planificar el uso del cliente:

RequisitoDetalle
Entorno de ejecuciónUn fetch global: Node.js 18+, Bun o Deno. Puede inyectar su propia implementación mediante la opción fetcher (proxies, reintentos y dobles de prueba).
Cadena de herramientas de TypeScriptLos puntos de entrada del paquete se resuelven como código fuente TypeScript, no como JavaScript compilado. Su empaquetador o entorno de ejecución debe transpilarlo; ejecutar simplemente node dist/app.js con código fuente sin transpilar no funcionará.
Dependencias en tiempo de ejecuciónEl cliente no está libre de dependencias: declara arktype (utilizado para validar las cargas útiles de error), además de paquetes auxiliares internos de DUST que se incluyen con la distribución. Téngalos en cuenta en cualquier proceso de incorporación de dependencias al repositorio, revisión de licencias o instalación aislada de la red.
Lugar de ejecuciónSolo del lado del servidor; consulte la advertencia al final de esta página.
import { ApidClient } from "@dustid/apid-client";
const client = new ApidClient({
baseUrl: "https://apid.dustid.io",
bearerToken: token, // Authorization: Bearer <token>
organizationId: orgId, // sent as Dust-Ctx-Org-Id
teamId: teamId, // sent as Dust-Ctx-Team-Id
});

El tipo completo de las opciones es:

type ApidClientOptions = {
baseUrl: string;
bearerToken?: string;
organizationId?: string; // Dust-Ctx-Org-Id header
teamId?: string; // Dust-Ctx-Team-Id header
fetcher?: typeof globalThis.fetch; // custom fetch (proxies, testing)
defaultHeaders?: HeadersInit | (() => HeadersInit); // e.g. Dust-Ctx-Locale
logger?: Logger; // debug/error request logging
};

organizationId y teamId se corresponden con los encabezados de contexto; cuando se omite teamId, el servidor utiliza de forma predeterminada el equipo raíz de la organización. Utilice defaultHeaders para cualquier dato adicional que quiera incluir en todas las solicitudes, por ejemplo, mensajes de error localizados:

const client = new ApidClient({
baseUrl,
bearerToken,
organizationId,
defaultHeaders: { "Dust-Ctx-Locale": "zh-CN" },
});

Los clientes son inmutables; dos funciones auxiliares devuelven una copia reconfigurada, lo que permite establecer el ámbito por solicitud o por usuario con poco coste:

const asOtherTeam = client.withContext({ teamId: otherTeamId });
const asFreshToken = client.withToken(newBearerToken);

El cliente agrupa los endpoints en recursos: client.me, client.threads, client.bundles, client.files, client.tags (operaciones con Identificadores: los endpoints /api/v1/tags/*), client.teams, client.sharing, client.templates, client.events, client.relations, client.threadLinks, client.assemblies, client.transfers, client.slices, client.imports, client.fabric, client.users, client.certificates y client.certificateForms.

Los nombres de los métodos reflejan los de la referencia. Estos son dos ejemplos reales con fichas:

// GET /api/v1/threads — cursor-paginated list
const page = await client.threads.list({ pageSize: 50, q: "tire" });
for (const thread of page.threads) {
console.log(thread.threadId, thread.name);
}
if (page.next) {
const nextPage = await client.threads.list({ pageSize: 50, cursor: page.next });
}
// POST /api/v1/threads — create, unwrapped to the single created record
const created = await client.threads.createOne({
type: "single",
thread: { name: "Tire SZ3J-11-ZJ17" },
data: [{ name: "Serial Number", type: "text", value: { text: "SZ3J-11-ZJ17" } }],
});
// GET /api/v1/threads/{thread_id}
const record = await client.threads.get(created.threadId);
console.log(record.thread.name, record.events.length);

threads.create devuelve la respuesta por lotes sin procesar ({ created, uploadResponses }); threads.createOne es una función práctica que devuelve created[0] y genera una excepción si el servidor no ha creado nada.

Todos los tipos de solicitud y respuesta se exportan desde la raíz del paquete (ThreadCreateRequest, ThreadQueryResponse, ThreadGetResponse, …), junto con los tipos sin procesar paths / components / operations generados a partir de la especificación.

Los métodos devuelven la respuesta JSON analizada cuando la operación se completa correctamente y generan una excepción ApiError ante cualquier estado que no sea 2xx. ApiError contiene el cuerpo de error estándar de la API:

import { ApiError } from "@dustid/apid-client";
try {
await client.threads.get(threadId);
} catch (error) {
if (error instanceof ApiError) {
// error.code stable error code, e.g. "NOT_FOUND", "UNAUTHORIZED"
// error.status HTTP status number
// error.message localized human-readable message
// error.detail optional extra context (validation issues, etc.)
// error.body the full { code, message, status, detail } payload
if (error.code === "UNAUTHORIZED") {
// token expired — re-exchange the API key and retry
}
} else {
throw error; // network failure or non-JSON response
}
}

Conviene conocer dos comportamientos en casos límite: las respuestas 204/205 se resuelven como undefined, y una respuesta que no sea JSON válido genera un Error normal (no un ApiError). Si proporciona un logger, todas las solicitudes fallidas se registran junto con su x-request-id para poder correlacionarlas al solicitar asistencia.

La API ofrece su especificación OpenAPI 3 en https://apid.dustid.io/api/openapi.json. openapi-typescript la convierte en una definición paths/components completamente tipada que puede utilizar con fetch sin ninguna biblioteca adicional o con cualquier contenedor de fetch basado en especificaciones:

Ventana de terminal
npx openapi-typescript@7 https://apid.dustid.io/api/openapi.json -o <generated-types-file>
import type { paths } from "./dust-api";
type ThreadList =
paths["/api/v1/threads"]["get"]["responses"]["200"]["content"]["application/json"];

Recuerde configurar por su cuenta los encabezados Authorization, Dust-Ctx-Org-Id y Dust-Ctx-Team-Id; consulte Convenciones de las solicitudes. Vuelva a generar los tipos cada vez que incorpore nuevas funciones de la API; la especificación de /api/openapi.json siempre está actualizada para el servidor del que la obtuvo.