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.
| Superficie | Punto de entrada | Ejecución |
|---|---|---|
| SDK de promesa | @cadcamfun/api/sdk, exportado CadCam.make | Promesas de resultados ordinarios; Iterables asíncronos para SSE. Utiliza una recuperación suministrada o global. |
| Cliente de contrato completo | ApiClient de @cadcamfun/api | Servicio de efecto con transporte y middleware portador suministrado por su capa. |
| Adaptadores de efectos generados | packages/api/src/client/generated/index.ts | Mé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.
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.
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 cliente | Interpretación |
|---|---|
Transport | Recuperación de configuración, conexión, cancelación o error de lectura de secuencia. Inspeccione su causa y la conexión actual. |
UnexpectedStatus | El servidor devolvió un estado fuera de los estados de éxito y fracaso declarados de la operación. |
UnsupportedContentType | Una respuesta de transmisión no tenía el tipo de contenido de transmisión de eventos esperado. |
MalformedResponse | No se pudo decodificar JSON o un flujo de respuesta esperado. |
SseEventTooLarge | El 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.
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.
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.
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ón | Dónde | Effect |
|---|---|---|
baseUrl | CadCam.make | Resuelto con new URL(path, baseUrl); incluye el esquema y el puerto. |
fetch | CadCam.make | Reemplace el transporte, por ejemplo para agregar registros o inyectar un doble de prueba. El valor predeterminado es globalThis.fetch. |
headers | CadCam.make | Enviado con cada solicitud. Poner authorization aquí. |
signal | por llamada | Aborta la solicitud; el rechazo es ClientError("Transport"). |
headers | por llamada | Anular 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ón | Criado cuando | Respuesta típica |
|---|---|---|
Transport | fetch lanzó (rechazado, restablecido, DNS, abortado) o falló una lectura de secuencia | Vuelva a resolver la URL del sidecar; reintentar lecturas; Vuelva a leer el estado antes de volver a intentar escribir. |
UnexpectedStatus | El 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. |
UnsupportedContentType | Una 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 JSON | Verifique los servidores proxy y la versión del servidor. |
MalformedResponse | JSON vacío o no válido, falta un cuerpo o un SSE data: bloque que no es JSON | Registre la respuesta sin procesar; reportarlo. |
SseEventTooLarge | El búfer SSE no analizado superó los 16 MiB | Se 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.
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
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
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).