Pular para o conteúdo

Cliente TypeScript (@dustid/apid-client)

@dustid/apid-client é o cliente TypeScript tipado para a API DUST. É o mesmo cliente que a aplicação Web DICE utiliza em produção, e os respetivos tipos de pedido/resposta são gerados diretamente a partir da especificação OpenAPI da API, pelo que se mantém totalmente sincronizado com o servidor.

O pacote não está publicado no registo público do npm. É distribuído pela DUST e disponibilizado aos clientes de integração mediante pedido (contacte support@dustidentity.com). npm install @dustid/apid-client não o encontrará.

Se preferir não adicionar esta dependência, pode obter a mesma segurança de tipos gerando tipos a partir da especificação OpenAPI — é exatamente assim que os tipos deste cliente são produzidos — e chamar a API com fetch simples. O guia de início rápido utiliza esta abordagem para poder ser executado sem qualquer instalação.

Verifique estes requisitos antes de planear a utilização do cliente:

RequisitoDetalhe
Ambiente de execuçãoUm fetch global: Node.js 18+, Bun ou Deno. Pode injetar a sua própria implementação através da opção fetcher (proxies, novas tentativas, objetos simulados para testes).
Cadeia de ferramentas TypeScriptOs pontos de entrada do pacote são resolvidos para código-fonte TypeScript, não para JavaScript compilado. O seu empacotador ou ambiente de execução tem de o transpilar — executar simplesmente node dist/app.js com código-fonte não transpilado não funcionará.
Dependências de execuçãoO cliente não está isento de dependências: declara arktype (utilizado para validar conteúdos de erro), além de pacotes auxiliares internos da DUST, incluídos na distribuição. Tenha-os em conta em qualquer inclusão local de dependências, análise de licenças ou instalação num ambiente isolado.
Local de execuçãoApenas no lado do servidor — consulte o aviso no final desta 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
});

O tipo completo das opçõ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 e teamId correspondem aos cabeçalhos de contexto; quando teamId é omitido, o servidor utiliza por predefinição a equipa raiz da organização. Utilize defaultHeaders para qualquer informação adicional que pretenda incluir em todos os pedidos — por exemplo, mensagens de erro localizadas:

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

Os clientes são imutáveis; dois métodos auxiliares devolvem uma cópia reconfigurada, tornando simples a definição do âmbito por pedido ou por utilizador:

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

O cliente agrupa os endpoints em recursos: client.me, client.threads, client.bundles, client.files, client.tags (operações de Identificadores — os 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 e client.certificateForms.

Os nomes dos métodos correspondem aos da referência. Dois exemplos reais com registos:

// 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 devolve a resposta em lote sem processamento ({ created, uploadResponses }); threads.createOne é um método prático que devolve created[0] e lança um erro se o servidor não tiver criado nada.

Todos os tipos de pedido e resposta são exportados a partir da raiz do pacote (ThreadCreateRequest, ThreadQueryResponse, ThreadGetResponse, …), juntamente com os tipos paths / components / operations gerados diretamente a partir da especificação.

Os métodos devolvem a resposta JSON analisada em caso de sucesso e lançam ApiError para qualquer estado que não seja 2xx. ApiError contém o corpo de erro padrão da 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
}
}

Existem dois comportamentos em casos-limite que importa conhecer: as respostas 204/205 são resolvidas como undefined, e uma resposta que não seja JSON válido lança um Error simples (não um ApiError). Se fornecer um logger, todos os pedidos sem êxito são registados com o respetivo x-request-id, para permitir a correlação pelo suporte.

A API disponibiliza a sua especificação OpenAPI 3 em https://apid.dustid.io/api/openapi.json. O openapi-typescript transforma-a numa definição paths/components totalmente tipada, que pode utilizar com fetch simples ou qualquer invólucro de fetch baseado na especificação:

Terminal window
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"];

Não se esqueça de definir os cabeçalhos Authorization, Dust-Ctx-Org-Id e Dust-Ctx-Team-Id — consulte Convenções dos pedidos. Volte a gerar os tipos sempre que adotar novas funcionalidades da API; a especificação em /api/openapi.json está sempre atualizada para o servidor a partir do qual a obteve.