Saltar al contenido
CADCAMFUN
Documentos

Documentación

Cree una integración de cliente API

Utilice el SDK de Promise, el cliente de contrato de efectos completo o los adaptadores de efectos generados con sus entradas reales y comportamiento de error.

Traducido automáticamente del inglés. Ver el original en inglés

Elige un cliente

El repositorio tiene tres superficies de cliente relacionadas. Comparten declaraciones de puntos finales, pero su construcción, formas de entrada, dependencias de tiempo de ejecución y canales de error difieren. Elija uno deliberadamente y mantenga juntos ejemplos de esa superficie.

SuperficiePunto de entradaEjecución
SDK de promesa@cadcamfun/api/sdk, exportado CadCam.makePromesas de resultados ordinarios; Iterables asíncronos para SSE. Utiliza una recuperación suministrada o global.
Cliente de contrato completoApiClient de @cadcamfun/apiServicio de efecto con transporte y middleware portador suministrado por su capa.
Adaptadores de efectos generadospackages/api/src/client/generated/index.tsMétodos aplanados en torno al cliente del contrato; La persona que llama proporciona el transporte y el middleware necesarios.

El paquete API es un espacio de trabajo privado con exportaciones de origen. Las importaciones a continuación están destinadas a este monorepo o una distribución que realmente proporcione esas exportaciones; Esta página no reclama un paquete npm público disponible por separado. Los clientes independientes pueden utilizar el Documento OpenAPI o HTTP simple.

Para una primera solicitud sin configuración de biblioteca cliente, comience con el tutorial HTTP capturado. Establece cómo los cuerpos de éxito y fracaso difieren entre operaciones.

Resolver la conexión

Utilice la URL y el token de portador de la aplicación que pertenecen al lanzamiento actual del sidecar. Tauri los obtiene a través de get_sidecar_endpoint. Un proceso de desarrollo manual imprime su puerto asignado en un evento listo. El origen debe apuntar al sidecar o puerta de enlace del acompañante admitido, y no al sitio de documentación o activos de Vite.

Después de reiniciar el sidecar, resuelva la conexión nuevamente. Reutilizar el puerto anterior puede producir rechazo de conexión o abordar accidentalmente otro proceso. La reutilización de un token de lanzamiento obsoleto produce un error de autorización. Una respuesta exitosa de salud pública no prueba que se admitirá una solicitud protegida.

La selección de cuentas, la admisión de aplicaciones, la admisión de dispositivos y el acceso de agentes externos son distintas. el opcional x-session-token selecciona una cuenta después de la admisión de la solicitud. Un token de puente con ámbito de proyecto está limitado a sus puntos finales de puente de acción. Un token de teléfono funciona a través de la lista de permitidos de la puerta de enlace. Sigue el referencia de autenticación antes de elegir la conexión para una integración.

SDK de promesa

El espacio de nombres exportado es CadCam, y su constructor es make. Proporcione una URL base y encabezados predeterminados. Los métodos de creación y obtención siguientes utilizan campos aplanados en lugar de campos anidados. payload o params objeto.

Dentro de un espacio de trabajo que consume @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 llamada se resuelve directamente en la carga útil exitosa de ese punto final. projects.list() devuelve una matriz; projects.create() devuelve una fila del proyecto. no hay universalidad { data, error } envoltorio y no throwOnError opción de constructor en este SDK. Algunas cargas útiles de endpoints contienen data o success porque ese es su contrato HTTP.

El SDK prepara una URL a partir de la ruta del punto final y la URL base configurada, codifica identificadores de ruta, serializa la entrada JSON declarada y verifica el estado exacto de éxito declarado de la operación. Luego analiza JSON y devuelve su valor escrito. El tiempo de ejecución de Promise no aplica un decodificador de esquema de efecto a cada carga útil devuelta; Los tipos de salida de TypeScript no validan una implementación de servidor arbitraria.

Errores declarados y de transporte.

Los fallos HTTP declarados se rechazan con el cuerpo de respuesta decodificado. Ese valor puede ser un objeto simple etiquetado en lugar de una instancia de error de JavaScript. Las fallas de transporte y protocolo utilizan el SDK ClientError.

Manejar ambos canales de error
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 del error del clienteInterpretación
TransportRecuperación de configuración, conexión, cancelación o error de lectura de secuencia. Inspeccione su causa y la conexión actual.
UnexpectedStatusEl servidor devolvió un estado fuera de los estados de éxito y fracaso declarados de la operación.
UnsupportedContentTypeUna respuesta de transmisión no tenía el tipo de contenido de transmisión de eventos esperado.
MalformedResponseNo se pudo decodificar JSON o un flujo de respuesta esperado.
SseEventTooLargeEl búfer de flujo de eventos superó la protección de fotogramas del tiempo de ejecución generado.

Por ejemplo, un nombre de proyecto faltante es un error empresarial HTTP 400 aunque el tipo de entrada de creación permita la omisión. Un restablecimiento de la conexión mientras se crea un proyecto es diferente: deja al cliente sin saber si la escritura se completó. Lea el estado del recurso antes de repetir una mutación. El SDK no agrega un protocolo de idempotencia para toda la aplicación ni reintenta automáticamente cada llamada rechazada.

Cancelaciones y encabezados

ClientOptions acepta baseUrl, una implementación de recuperación opcional y encabezados predeterminados. Por llamada RequestOptions acepta una señal y encabezados adicionales. Para métodos sin entrada de punto final, las opciones de solicitud son el primer argumento; Los métodos con entrada toman opciones de solicitud después.

Cancelación por llamada y selección de cuenta
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

El generador de solicitudes aplica encabezados predeterminados, encabezados declarados por puntos finales y luego encabezados por llamada. Un valor por llamada puede anular un valor predeterminado; Evite reemplazar accidentalmente la Autorización al agregar cuentas o rastrear encabezados. No coloque credenciales en las URL de los puntos finales copiadas en los registros.

inyectando fetch admite un transporte de prueba en proceso o un adaptador controlado. El adaptador aún debe respetar los encabezados de la solicitud, el cuerpo, la cancelación, los tipos de contenido y la semántica del estado de la respuesta. La propia integración de efectos del escritorio y el transporte nativo anclado del teléfono realizan un trabajo adicional; sustituir una búsqueda arbitraria no reproduce esos límites nativos.

Cliente de efecto completo

ApiClient.layer construye el cliente HttpApi completo, el transporte de recuperación y el middleware portador. Expone métodos de punto final con la forma de solicitud HttpApi subyacente. La carga útil de una mutación se hunde payload, y los valores de ruta van por debajo params.

Cliente de 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 se deriva de toda la declaración de API y es la opción para los puntos finales omitidos de los objetivos generados. Conserva el canal de error escrito de Effect y el transporte con reconocimiento de esquema. La vida útil de los recursos, la interrupción de la transmisión y la provisión de capas pertenecen al programa Effect que llama; crear un efecto no lo ejecuta.

La capa reutilizable proporciona el token de la aplicación. El escritorio construye su propia capa en apps/desktop/src/app/client.ts para adjuntar el estado de sesión de la cuenta opcional y el transporte inyectado. Reutilice esa integración cuando trabaje dentro del escritorio en lugar de crear una segunda conexión/tiempo de ejecución por componente.

Adaptadores de efectos generados

El cliente Effect generado importa los esquemas reales y adapta los métodos en campos aplanados. Es CadCam.make devuelve un Efecto que construye el cliente adaptado. No proporciona su propia capa de autorización de aplicación o transporte de recuperación, por lo que la persona que llama debe proporcionar los servicios y middleware correspondientes.

El adaptador de errores generado asigna errores de transporte/esquema/SSE en un archivo etiquetado ClientError manteniendo los fallos de dominio declarados. Esta clase de error está separada de la clase de error de JavaScript de Promise SDK con un reason cadena. La similitud de nombres no hace que su manejo sea intercambiable.

Mantenga los ejemplos de entrada explícitos. El uso de los formularios de Promesa y Efecto generado projects.get({ id }); el formulario de contrato en bruto utiliza projects.get({ params: { id } }). Evite pasar el objeto de entrada de una superficie a otra mediante una aserción de tipo no marcada.

Transmisión

Las operaciones de promesa SSE devuelven iterables asíncronos. La configuración de la red ocurre cuando comienza la iteración. El tiempo de ejecución comprueba el estado de éxito y el tipo de contenido del flujo de eventos, lee datos UTF-8 incrementales, normaliza los límites de los marcos y decodifica los marcos de datos en JSON. Un marco con formato incorrecto falla la iteración; La limpieza del lector se ejecuta cuando la iteración finaliza o finaliza.

La guardia del tiempo de ejecución es 16 * 1024 * 1024 unidades de cadena de JavaScript almacenadas en búfer. Limita la acumulación antes de un límite de marco; no es una promesa de que cada carga útil arbitraria de 16 MB sea útil o válida para los esquemas de eventos de la aplicación.

Consuma eventos de IA según sus discriminadores y conserve el identificador de sesión. Un transporte finalizado no es prueba de un evento de conversación terminal. Usar Transmisión y recuperación de IA para comportamiento de cola, aborto, permiso, pregunta y recuperación de estado. EventSource no es un reemplazo directo para una solicitud POST con encabezados de autorización y un cuerpo JSON.

Cobertura y regeneración

El generador tiene listas de omisiones explícitas para formas que no puede representar. Las omisiones compartidas incluyen cargas de perfiles/complementos de varias partes, creación de MCP con múltiples esquemas de éxito, nombres de entrada en conflicto y servicio de complementos con encabezados de respuesta en su flujo. Las omisiones adicionales de Promise incluyen webhooks firmados sin formato, arranque de complementos de JavaScript, descarga binaria y solicitudes de generador de formato libre.

Lea las listas actuales exactas en packages/api/scripts/generate-clients.ts y el Descripción general de la API. Un método generado ausente no establece que el punto final del servidor no esté disponible. Utilice el cliente con contrato completo o el transporte en bruto adecuado para esa operación.

Raíz del repositorio
bun run generate
bun run generate:check
bun run --filter @cadcamfun/web generate:api-reference
bun run --filter @cadcamfun/web check:api-reference

La regeneración de clientes y la regeneración de documentación son resultados separados del mismo contrato. Mantenga ambos actualizados después de los cambios en los puntos finales. No edite los cuerpos de los métodos generados para cambiar los requisitos de entrada del servidor.

El código generado se escribe en packages/api/src/client/generated y packages/api/src/sdk/generated. No edite esos archivos a mano; cambiar el contrato y regenerar.

Verificación de integración

El comportamiento de creación/lectura/resultado simple de Promise y el error declarado arrojado que se muestran aquí se ejercieron contra la pila de controlador de sidecar real utilizando una base de datos desechable migrada. El tutorial HTTP contiene las respuestas observadas correspondientes. Repita las comprobaciones específicas al cambiar el generador, la autenticación o los esquemas de punto final.

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.

Las fuentes de implementación son packages/api/src/sdk/generated/client.ts, es client-error.ts, packages/api/src/client.ts, packages/api/src/client/generated, y packages/httpapi-codegen/src/index.ts. El generador y las salidas comprometidas establecen juntos el comportamiento real del cliente.

Referencia de opciones de Promise SDK

OpciónDóndeEffect
baseUrlCadCam.makeResuelto con new URL(path, baseUrl); incluye el esquema y el puerto.
fetchCadCam.makeReemplace el transporte, por ejemplo para agregar registros o inyectar un doble de prueba. El valor predeterminado es globalThis.fetch.
headersCadCam.makeEnviado con cada solicitud. Poner authorization aquí.
signalpor llamadaAborta la solicitud; el rechazo es ClientError("Transport").
headerspor llamadaAnular o agregar encabezados para una llamada, como x-session-token. Los valores por llamada ganan a los valores del cliente.

Cuando un cuerpo está presente y no content-type se configuró el encabezado, el SDK establece application/json y serializa con JSON.stringify. Los parámetros de ruta siempre se pasan encodeURIComponent, por lo que una clave como docs.walkthrough.units o uno que contenga / permanece como un solo segmento.

Razones del error del cliente

RazónCriado cuandoRespuesta típica
Transportfetch lanzó (rechazado, restablecido, DNS, abortado) o falló una lectura de secuenciaVuelva a resolver la URL del sidecar; reintentar lecturas; Vuelva a leer el estado antes de volver a intentar escribir.
UnexpectedStatusEl estado no es ni el estado de éxito ni un estado de error declarado. La causa se mantiene { status }.Trátelo como una discrepancia en el contrato, a menudo una versión de servidor diferente.
UnsupportedContentTypeUna operación de transmisión respondió con algo más que text/event-stream, o una operación JSON con un tipo que no sea JSONVerifique los servidores proxy y la versión del servidor.
MalformedResponseJSON vacío o no válido, falta un cuerpo o un SSE data: bloque que no es JSONRegistre la respuesta sin procesar; reportarlo.
SseEventTooLargeEl búfer SSE no analizado superó los 16 MiBSe rechaza el evento; reiniciar la transmisión.

El mensaje de un ClientError es el motivo seguido del mensaje de causa (por ejemplo Transport: fetch failed), por lo que iniciar sesión error.message por sí solo ya es diagnóstico.

Reintentar solo lecturas 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())

No vuelvas a intentar escribir a ciegas

Una escritura que falló con Transport puede haber sido aplicado. Lea el recurso nuevamente y vuelva a enviarlo solo cuando no esté allí; la API no tiene claves de idempotencia.

Consumir una transmisión con el SDK

Iterar eventos del asistente
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
  }
}

El iterador analiza cada bloque SSE: se une al data: líneas del bloque, analiza el JSON y lo genera. Comentarios y bloques sin data: se omiten. Salir del circuito temprano (break, una excepción o aborto) cancela el lector y libera la conexión. el evento type los valores son los que figuran en la guía de transmisión del asistente; comprobar lo generado AiChatStreamOutput tipo para la unión exacta.

Ejemplo: preferencias a través del SDK

Viaje de ida y vuelta de valor clave
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: "…" }

Las claves están limitadas a 512 caracteres y deben contener texto sin espacios en blanco; los valores deben ser compatibles con JSON (sin ciclos, funciones o números no finitos).

En 3D

Lo que cubren los clientes Arrastrar para orbitar · desplazarse para hacer zoom · arrastrar con el botón derecho para desplazarse
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.