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.
Disponibilidade
Seção intitulada “Disponibilidade”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.
Pré-requisitos para utilizar o cliente
Seção intitulada “Pré-requisitos para utilizar o cliente”Verifique estes requisitos antes de planear a utilização do cliente:
| Requisito | Detalhe |
|---|---|
| Ambiente de execução | Um 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 TypeScript | Os 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ção | O 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ção | Apenas no lado do servidor — consulte o aviso no final desta página. |
Construir um cliente
Seção intitulada “Construir um cliente”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" },});Mudar o contexto ou o token
Seção intitulada “Mudar o contexto ou o token”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);Recursos e chamadas
Seção intitulada “Recursos e chamadas”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 listconst 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 recordconst 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.
Tratamento de erros
Seção intitulada “Tratamento de erros”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.
Alternativa: gerar os seus próprios tipos
Seção intitulada “Alternativa: gerar os seus próprios tipos”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:
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.
Consulte também
Seção intitulada “Consulte também”- Guia de início rápido da API — o mesmo fluxo completo com
fetchsimples, para que possa executá-lo antes de decidir adicionar uma dependência. - Convenções dos pedidos — os cabeçalhos e o contrato de erros implementados pelo cliente.
- Erros e resultados de digitalização — os códigos associados a
ApiErrore as tabelas de resultados da digitalização. - Referência completa da API — todos os endpoints e esquemas.