Pular para o conteúdo
CADCAMFUN
Docs

Documentação

Crie uma integração de cliente API

Use o Promise SDK, o cliente de contrato de efeito completo ou adaptadores de efeito gerados com suas entradas reais e comportamento de erro.

Traduzido automaticamente do inglês. Ver o original em inglês

Escolha um cliente

O repositório possui três superfícies de cliente relacionadas. Eles compartilham declarações de endpoint, mas sua construção, formatos de entrada, dependências de tempo de execução e canais de erro são diferentes. Escolha um deliberadamente e mantenha juntos os exemplos dessa superfície.

SuperfíciePonto de entradaExecução
Promessa SDK@cadcamfun/api/sdk, exportado CadCam.makePromessas de resultados comuns; iteráveis assíncronos para SSE. Usa uma busca fornecida ou global.
Cliente com contrato completoApiClient de @cadcamfun/apiServiço de efeito com middleware de transporte e portador fornecido por sua camada.
Adaptadores de efeitos geradospackages/api/src/client/generated/index.tsMétodos achatados em torno do cliente contratado; o chamador fornece o transporte e o middleware necessários.

O pacote API é um espaço de trabalho privado com exportações de origem. As importações abaixo destinam-se a este monorepo ou a uma distribuição que realmente fornece essas exportações; esta página não reivindica um pacote npm público disponível separadamente. Clientes independentes podem usar o Documento OpenAPI ou HTTP simples.

Para uma primeira solicitação sem configuração de biblioteca cliente, comece com o passo a passo HTTP capturado. Estabelece como os órgãos de sucesso e fracasso diferem entre as operações.

Resolva a conexão

Use o URL e o token de portador do aplicativo pertencente à inicialização do sidecar atual. Tauri os obtém através get_sidecar_endpoint. Um processo de desenvolvimento manual imprime sua porta atribuída em um evento pronto. A origem deve apontar para o sidecar ou gateway complementar admitido, e não para o site de documentação ou ativos do Vite.

Após a reinicialização do sidecar, resolva a conexão novamente. A reutilização da porta anterior pode produzir recusa de conexão ou abordar acidentalmente outro processo. A reutilização de um token de inicialização obsoleto produz uma falha de autorização. Uma resposta de saúde pública bem sucedida não prova que um pedido protegido será admitido.

A seleção de conta, a admissão de aplicativos, a admissão de dispositivos e o acesso de agente externo são distintos. O opcional x-session-token seleciona uma conta após a admissão do aplicativo. Um token de ponte com escopo de projeto é limitado aos pontos de extremidade da ponte de ação. Um token de telefone funciona por meio da lista de permissões do gateway. Siga o referência de autenticação antes de escolher a conexão para uma integração.

Promessa SDK

O namespace exportado é CadCam, e seu construtor é make. Forneça um URL base e cabeçalhos padrão. Os métodos create e get abaixo usam campos nivelados em vez de campos aninhados payload ou params objeto.

Dentro de um espaço de trabalho consumindo @cadcamfun/api
import { CadCam } from "@cadcamfun/api/sdk"

const client = CadCam.make({
  baseUrl,
  headers: { Authorization: "Bearer " + token },
})

const projects = await client.projects.list()
const created = await client.projects.create({
  name: "Fixture plate",
  description: "An integration-created project",
})
const detail = await client.projects.get({ id: created.id })
console.log(projects.length, detail.name, detail._count.drawings)

Cada chamada é resolvida diretamente para a carga de sucesso desse endpoint. projects.list() retorna uma matriz; projects.create() retorna uma linha do projeto. Não existe universal { data, error } invólucro e não throwOnError opção de construtor neste SDK. Algumas cargas úteis de endpoint contêm data ou success porque esse é o contrato HTTP deles.

O SDK prepara uma URL a partir do caminho do endpoint e da URL base configurada, codifica identificadores de caminho, serializa a entrada JSON declarada e verifica o status exato de sucesso declarado da operação. Em seguida, ele analisa JSON e retorna seu valor digitado. O tempo de execução do Promise não aplica um decodificador de esquema Effect a cada carga retornada; Os tipos de saída TypeScript não validam uma implementação de servidor arbitrária.

Erros declarados e de transporte

As falhas HTTP declaradas são rejeitadas com o corpo da resposta decodificado. Esse valor pode ser um objeto simples marcado em vez de uma instância de erro de JavaScript. Falhas de transporte e protocolo usam o SDK ClientError.

Lidar com ambos os canais de erro
import { ClientError } from "@cadcamfun/api/sdk"

try {
  await client.projects.create({})
} catch (error) {
  if (error instanceof ClientError) {
    console.error(error.reason, error.message)
  } else if (error && typeof error === "object" && "message" in error) {
    console.error(String(error.message))
  } else {
    console.error("Unrecognized API failure", error)
  }
}
Motivo do erro do clienteInterpretação
TransportBuscar configuração, conexão, anulação ou falha de leitura de fluxo. Inspecione sua causa e a conexão atual.
UnexpectedStatusO servidor retornou um status fora dos status de sucesso e falha declarados da operação.
UnsupportedContentTypeUma resposta de fluxo não tinha o tipo de conteúdo de fluxo de evento esperado.
MalformedResponseJSON ou um fluxo de resposta esperado não pôde ser decodificado.
SseEventTooLargeO buffer do fluxo de eventos excedeu o frame guard do tempo de execução gerado.

Por exemplo, um nome de projeto ausente é uma falha comercial HTTP 400, mesmo que o tipo de entrada create permita a omissão. Uma redefinição de conexão durante a criação de um projeto é diferente: deixa o cliente incerto se a gravação foi concluída. Leia o estado do recurso antes de repetir uma mutação. O SDK não adiciona um protocolo de idempotência para todo o aplicativo nem tenta repetir automaticamente cada chamada rejeitada.

Cancelamento e cabeçalhos

ClientOptions aceita baseUrl, uma implementação de busca opcional e cabeçalhos padrão. Por chamada RequestOptions aceita um sinal e cabeçalhos extras. Para métodos sem entrada de endpoint, as opções de solicitação são o primeiro argumento; métodos com entrada recebem opções de solicitação depois dela.

Cancelamento por chamada e seleção de conta
const controller = new AbortController()
const pending = client.projects.get(
  { id: projectId },
  {
    signal: controller.signal,
    headers: { "x-session-token": accountSessionToken },
  },
)
// Call controller.abort() when the operation is no longer needed.
const project = await pending

O construtor de solicitação aplica cabeçalhos padrão, cabeçalhos declarados por endpoint e, em seguida, cabeçalhos por chamada. Um valor por chamada pode substituir um padrão; evite substituir acidentalmente a Autorização ao adicionar cabeçalhos de conta ou de rastreamento. Não coloque credenciais em URLs de endpoint copiados em logs.

Injetando fetch suporta um transporte de teste em processo ou um adaptador controlado. O adaptador ainda deve respeitar cabeçalhos de solicitação, corpo, cancelamento, tipos de conteúdo e semântica de status de resposta. A integração do Effect do próprio desktop e o transporte nativo fixado do telefone fazem um trabalho adicional; substituir uma busca arbitrária não reproduz esses limites nativos.

Cliente de efeito completo

ApiClient.layer constrói o cliente HttpApi completo, transporte de busca e middleware de portador. Ele expõe métodos de endpoint com o formato de solicitação HttpApi subjacente. A carga útil de uma mutação desaparece payload, e os valores do caminho vão abaixo params.

Cliente com contrato completo
import { ApiClient } from "@cadcamfun/api"
import { Effect } from "effect"

const createProject = Effect.gen(function* () {
  const api = yield* ApiClient
  return yield* api.projects.create({
    payload: { name: "Fixture plate" },
  })
}).pipe(Effect.provide(ApiClient.layer({ baseUrl, token })))

const project = await Effect.runPromise(createProject)

Este cliente deriva de toda a declaração da API e é a opção para endpoints omitidos dos destinos gerados. Ele preserva o canal de erro digitado do Effect e o transporte com reconhecimento de esquema. A vida útil do recurso, a interrupção do fluxo e o fornecimento da camada pertencem ao programa Effect de chamada; criar um efeito não o executa.

A camada reutilizável fornece o token do aplicativo. A área de trabalho constrói sua própria camada em apps/desktop/src/app/client.ts para anexar o estado opcional da sessão da conta e o transporte injetado. Reutilize essa integração ao trabalhar dentro do desktop em vez de criar uma segunda conexão/tempo de execução por componente.

Adaptadores de efeitos gerados

O cliente Effect gerado importa os esquemas reais e adapta métodos em campos nivelados. Isso é CadCam.make retorna um Efeito que constrói o cliente adaptado. Ele não fornece seu próprio transporte de busca ou camada de autorização de aplicativo, portanto, o chamador deve fornecer os serviços e middleware correspondentes.

O adaptador de erro gerado mapeia falhas de transporte/esquema/SSE em um arquivo marcado ClientError enquanto retém falhas de domínio declaradas. Essa classe de erro é separada da classe de erro JavaScript do Promise SDK com um reason corda. A semelhança de nomes não torna seu manuseio intercambiável.

Mantenha os exemplos de entrada explícitos. Os formulários Promessa e Efeito gerado usam projects.get({ id }); o formulário de contrato bruto usa projects.get({ params: { id } }). Evite passar o objeto de entrada de uma superfície para outra por meio de uma asserção de tipo não verificada.

Transmissão

As operações Promise SSE retornam iteráveis assíncronos. A configuração da rede ocorre quando a iteração começa. O tempo de execução verifica o status de sucesso e o tipo de conteúdo do fluxo de eventos, lê dados UTF-8 incrementais, normaliza os limites do quadro e decodifica quadros de dados em JSON. Um quadro malformado falha na iteração; a limpeza do leitor é executada quando a iteração termina ou termina.

A guarda do tempo de execução é 16 * 1024 * 1024 unidades de string JavaScript armazenadas em buffer. Limita a acumulação antes do limite do quadro; não é uma promessa que cada carga útil arbitrária de 16 MB seja útil ou válida para os esquemas de eventos do aplicativo.

Consumir eventos de IA de acordo com seus discriminadores e preservar o identificador de sessão. Um transporte finalizado não é prova de um evento de conversação de terminal. Usar Streaming e recuperação de IA para comportamento de fila, anulação, permissão, pergunta e recuperação de estado. EventSource não é um substituto imediato para uma solicitação POST com cabeçalhos de autorização e um corpo JSON.

Cobertura e regeneração

O gerador possui listas de omissões explícitas para formas que não pode representar. As omissões compartilhadas incluem uploads de perfil/plugin multiparte, criação de MCP com vários esquemas de sucesso, nomes de entrada em colisão e serviço de plug-in com cabeçalhos de resposta em seu fluxo. Omissões adicionais do Promise incluem webhooks assinados brutos, bootstrap de plug-in JavaScript, download binário e solicitações de gerador de formato livre.

Leia as listas atuais exatas em packages/api/scripts/generate-clients.ts e o Visão geral da API. Um método gerado ausente não estabelece que o terminal do servidor está indisponível. Utilize o cliente de contrato completo ou transporte bruto adequado para essa operação.

Raiz do repositório
bun run generate
bun run generate:check
bun run --filter @cadcamfun/web generate:api-reference
bun run --filter @cadcamfun/web check:api-reference

A regeneração do cliente e a regeneração da documentação são resultados separados do mesmo contrato. Mantenha ambos atualizados após alterações no endpoint. Não edite os corpos dos métodos gerados para alterar os requisitos de entrada do servidor.

O código gerado é escrito em packages/api/src/client/generated e packages/api/src/sdk/generated. Não edite esses arquivos manualmente; alterar o contrato e regenerar.

Verificação de integração

O comportamento de criação/leitura/resultado simples do Promise e a falha declarada lançada mostradas aqui foram exercidos na pilha real do manipulador sidecar usando um banco de dados descartável migrado. O passo a passo HTTP contém as respostas observadas correspondentes. Repita as verificações focadas ao alterar os esquemas do gerador, da autenticação ou do terminal.

For an integration acceptance check, verify public health; a protected request without a token; the same request with the current token; a valid create/read cycle; a declared validation failure; a cancelled request; and a stream whose terminal state is checked. Use a disposable project and never infer successful persistence from a frontend fixture alone.

As fontes de implementação são packages/api/src/sdk/generated/client.ts, isso é client-error.ts, packages/api/src/client.ts, packages/api/src/client/generated, e packages/httpapi-codegen/src/index.ts. O gerador e as saídas confirmadas estabelecem juntos o comportamento real do cliente.

Referência de opções do Promise SDK

OpçãoOndeEffect
baseUrlCadCam.makeResolvido com new URL(path, baseUrl); inclua o esquema e a porta.
fetchCadCam.makeSubstitua o transporte, por exemplo, para adicionar log ou para injetar um teste duplo. O padrão é globalThis.fetch.
headersCadCam.makeEnviado com cada solicitação. Colocar authorization aqui.
signalpor chamadaAborta a solicitação; a rejeição é ClientError("Transport").
headerspor chamadaSubstitua ou adicione cabeçalhos para uma chamada, como x-session-token. Os valores por chamada vencem os valores do cliente.

Quando um corpo está presente e não content-type cabeçalho foi definido, o SDK define application/json e serializa com JSON.stringify. Parâmetros de caminho são sempre passados encodeURIComponent, então uma chave como docs.walkthrough.units ou um contendo / permanece um único segmento.

Razões do erro do cliente

RazãoCriado quandoResposta típica
Transportfetch lançado (recusado, redefinido, DNS, abortado) ou uma leitura de fluxo falhouResolva novamente o URL secundário; tente ler novamente; releia o estado antes de tentar novamente as gravações.
UnexpectedStatusO status não é o status de sucesso nem o status de erro declarado. A causa mantém { status }.Trate como incompatibilidade de contrato, geralmente uma versão de servidor diferente.
UnsupportedContentTypeUma operação de fluxo respondeu com algo diferente de text/event-streamou uma operação JSON com um tipo não JSONVerifique os proxies e a versão do servidor.
MalformedResponseJSON vazio ou inválido, corpo ausente ou SSE data: bloco que não é JSONRegistrar a resposta bruta; denuncie.
SseEventTooLargeO buffer SSE não analisado excedeu 16 MiBO evento é recusado; reinicie o fluxo.

A mensagem de um ClientError é o motivo seguido pela mensagem de causa (por exemplo Transport: fetch failed), então registrando error.message por si só já é diagnóstico.

Tentando novamente apenas leituras idempotentes
import { CadCam, ClientError } from "@cadcamfun/api/sdk"

async function withRetry<T>(read: () => Promise<T>, attempts = 3): Promise<T> {
  for (let attempt = 1; ; attempt++) {
    try {
      return await read()
    } catch (error) {
      const transient = error instanceof ClientError && error.reason === "Transport"
      if (!transient || attempt >= attempts) throw error
      await new Promise((resolve) => setTimeout(resolve, 250 * 2 ** attempt))
    }
  }
}

const projects = await withRetry(() => client.projects.list())

Não tente escrever novamente cegamente

Uma gravação que falhou com Transport pode ter sido aplicado. Leia o recurso novamente e reenvie somente quando ele não estiver lá; a API não possui chaves de idempotência.

Consumindo um stream com o SDK

Iterar eventos de assistente
const controller = new AbortController()
const events = client.ai.chatStream(
  { message: "Pocket the 40 x 30 rectangle, 3 mm deep", projectId },
  { signal: controller.signal },
)

for await (const event of events) {
  switch (event.type) {
    case "delta": render(event); break
    case "permission_request": askUser(event); break
    case "done": finish(event); break
    case "error": showError(event); break
  }
}

O iterador analisa cada bloco SSE: ele se junta ao data: linhas do bloco, analisa o JSON e o produz. Comentários e bloqueios sem data: são ignorados. Saindo do loop mais cedo (break, uma exceção ou anulação) cancela o leitor e libera a conexão. O evento type os valores são os listados no guia de streaming do assistente; verifique o gerado AiChatStreamOutput digite para a união exata.

Exemplo: preferências por meio do SDK

Viagem de ida e volta do valor-chave
const key = "docs.walkthrough.units"

try {
  await client.kv.get({ key })
} catch (error) {
  if ((error as { _tag?: string })._tag !== "NotFound") throw error   // first run: 404
}

const saved = await client.kv.set({ key, value: { units: "mm" } })
// saved: { key, value: { units: "mm" }, updatedAt: "2026-…" }

const { entries } = await client.kv.list({ prefix: "docs." })
await client.kv.remove({ key })   // { message: "…" }

As chaves são limitadas a 512 caracteres e devem conter texto sem espaços em branco; os valores devem ser compatíveis com JSON (sem ciclos, funções ou números não finitos).

Em 3D

O que os clientes cobrem Arraste para orbitar · role para ampliar · arraste com o botão direito para deslocar
Every API group as a column, height = operations counted from the generated OpenAPI document (270 in total). Rows are the six sidebar categories; ai (34), history (22) and costs (21) are the largest groups.