Vai al contenuto
CADCAMFUN
Documentazione

Documentazione

Crea un'integrazione client API

Utilizza l'SDK Promise, il client del contratto Effect completo o gli adattatori Effect generati con i relativi input effettivi e il comportamento degli errori.

Tradotto automaticamente dall'inglese. Vedi l'originale in inglese

Scegli un cliente

Il repository dispone di tre superfici client correlate. Condividono le dichiarazioni degli endpoint, ma la loro costruzione, le forme di input, le dipendenze di runtime e i canali di errore differiscono. Scegline uno deliberatamente e tieni insieme gli esempi di quella superficie.

SuperficiePunto di ingressoEsecuzione
Prometti l'SDK@cadcamfun/api/sdk, esportato CadCam.makePromesse di risultati ordinari; iterabili asincroni per SSE. Utilizza un recupero fornito o globale.
Cliente con contratto completoApiClient da @cadcamfun/apiEffettuare il servizio con middleware di trasporto e portante fornito dal suo livello.
Adattatori per effetti generatipackages/api/src/client/generated/index.tsMetodi appiattiti attorno al cliente contrattuale; il chiamante fornisce il trasporto e il middleware richiesti.

Il pacchetto API è uno spazio di lavoro privato con esportazioni di origine. Le importazioni di seguito sono destinate a questo monorepo o a una distribuzione che fornisce effettivamente tali esportazioni; questa pagina non rivendica un pacchetto npm pubblico disponibile separatamente. I clienti indipendenti possono utilizzare il file Documento OpenAPI o semplice HTTP.

Per una prima richiesta senza configurazione della libreria client, iniziare con il file procedura dettagliata HTTP catturata. Stabilisce in che modo gli organismi di successo e di fallimento differiscono tra le operazioni.

Risolvere la connessione

Utilizza l'URL e il token di connessione dell'applicazione appartenenti al lancio corrente del sidecar. Tauri li ottiene get_sidecar_endpoint. Un processo di sviluppo manuale stampa la porta assegnata in un evento pronto. L'origine deve puntare al sidecar o al gateway compagno ammesso, anziché al sito di documentazione o alle risorse Vite.

Dopo un riavvio sidecar, risolvi nuovamente la connessione. Il riutilizzo della porta precedente può produrre il rifiuto della connessione o indirizzare accidentalmente un altro processo. Il riutilizzo di un token di avvio non aggiornato produce un errore di autorizzazione. Una risposta sanitaria pubblica efficace non dimostra che una richiesta protetta sarà accolta.

La selezione dell'account, l'ammissione dell'applicazione, l'ammissione del dispositivo e l'accesso dell'agente esterno sono distinti. L'opzionale x-session-token seleziona un account dopo l'ammissione della domanda. Un token bridge con ambito progetto è limitato ai relativi endpoint bridge di azione. Un token telefonico funziona tramite l'elenco consentiti del gateway. Segui il riferimento di autenticazione prima di scegliere la connessione per un'integrazione.

Prometti l'SDK

Lo spazio dei nomi esportato è CadCam, e il suo costruttore è make. Fornisci un URL di base e intestazioni predefinite. I metodi create e get riportati di seguito utilizzano campi appiattiti anziché nidificati payload o params oggetto.

All'interno di un'area di lavoro che utilizza @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)

Ogni chiamata si risolve direttamente nel payload di successo di quell'endpoint. projects.list() restituisce un array; projects.create() restituisce una riga di progetto. Non esiste un universale { data, error } involucro e n throwOnError opzione del costruttore in questo SDK. Alcuni payload degli endpoint contengono essi stessi data o success perché questo è il loro contratto HTTP.

L'SDK prepara un URL dal percorso dell'endpoint e dall'URL di base configurato, codifica gli identificatori del percorso, serializza l'input JSON dichiarato e controlla l'esatto stato di successo dichiarato dell'operazione. Quindi analizza JSON e restituisce il valore digitato. Il runtime Promise non applica un decodificatore dello schema Effect a ogni payload restituito; I tipi di output TypeScript non convalidano un'implementazione arbitraria del server.

Errori dichiarati e di trasporto

Gli errori HTTP dichiarati vengono rifiutati con il corpo della risposta decodificato. Tale valore può essere un oggetto semplice con tag anziché un'istanza di errore JavaScript. Gli errori di trasporto e protocollo utilizzano gli SDK ClientError.

Gestire entrambi i canali di errore
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 dell'errore clienteInterpretazione
TransportRecupero configurazione, connessione, interruzione o errore di lettura del flusso. Ispezionarne la causa e la connessione corrente.
UnexpectedStatusIl server ha restituito uno stato diverso dagli stati di successo e di errore dichiarati dell'operazione.
UnsupportedContentTypeUna risposta al flusso non aveva il tipo di contenuto flusso di eventi previsto.
MalformedResponseImpossibile decodificare JSON o un flusso di risposta previsto.
SseEventTooLargeIl buffer del flusso di eventi ha superato la protezione del frame del runtime generato.

Ad esempio, un nome di progetto mancante è un errore aziendale HTTP 400 anche se il tipo di input di creazione consente l'omissione. La reimpostazione della connessione durante la creazione di un progetto è diversa: lascia il client incerto se la scrittura è stata completata. Leggere lo stato della risorsa prima di ripetere una mutazione. L'SDK non aggiunge un protocollo di idempotenza a livello di applicazione né ritenta automaticamente ogni chiamata rifiutata.

Cancellazione e intestazioni

ClientOptions accetta baseUrl, un'implementazione di recupero opzionale e intestazioni predefinite. Per chiamata RequestOptions accetta un segnale e intestazioni extra. Per i metodi senza input dell'endpoint, le opzioni di richiesta sono il primo argomento; i metodi con input accettano le opzioni di richiesta dopo di esso.

Cancellazione per chiamata e selezione dell'account
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

Il generatore di richieste applica intestazioni predefinite, intestazioni dichiarate dall'endpoint e quindi intestazioni per chiamata. Un valore per chiamata può sovrascrivere un valore predefinito; evitare di sostituire accidentalmente l'autorizzazione quando si aggiungono account o intestazioni di tracciamento. Non inserire credenziali negli URL degli endpoint copiati nei log.

Iniettare fetch supporta un trasporto di prova in-process o un adattatore controllato. L'adattatore deve comunque rispettare le intestazioni della richiesta, il corpo, l'annullamento, i tipi di contenuto e la semantica dello stato della risposta. L'integrazione degli effetti del desktop e il trasporto nativo bloccato del telefono svolgono un lavoro aggiuntivo; la sostituzione di un recupero arbitrario non riproduce tali confini nativi.

Cliente a pieno effetto

ApiClient.layer costruisce il client HttpApi completo, il trasporto di recupero e il middleware di connessione. Espone i metodi dell'endpoint con la forma della richiesta HttpApi sottostante. Il carico utile di una mutazione crolla payloade i valori del percorso scendono params.

Cliente con contratto 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)

Questo client deriva dall'intera dichiarazione Api ed è l'opzione per gli endpoint omessi dalle destinazioni generate. Conserva il canale di errore digitato di Effect e il trasporto in grado di riconoscere lo schema. La durata delle risorse, l'interruzione del flusso e la fornitura dei livelli appartengono al programma Effect chiamante; la creazione di un effetto non lo esegue.

Il livello riutilizzabile fornisce il token dell'applicazione. Il desktop crea il proprio livello apps/desktop/src/app/client.ts per allegare lo stato della sessione dell'account opzionale e il trasporto inserito. Riutilizza tale integrazione quando lavori all'interno del desktop invece di creare una seconda connessione/runtime per componente.

Adattatori per effetti generati

Il client Effect generato importa gli schemi reali e adatta i metodi in campi appiattiti. Suo CadCam.make restituisce un effetto che costruisce il client adattato. Non fornisce il proprio trasporto di recupero o il livello di autorizzazione dell'applicazione, quindi il chiamante deve fornire i servizi e il middleware corrispondenti.

L'adattatore degli errori generato mappa gli errori di trasporto/schema/SSE in un file con tag ClientError pur mantenendo i guasti del dominio dichiarati. Questa classe di errore è separata dalla classe di errore JavaScript di Promise SDK con a reason corda. La somiglianza dei nomi non rende la loro gestione intercambiabile.

Mantieni espliciti gli esempi di input. Le forme Promessa ed Effetto generato utilizzano projects.get({ id }); utilizza la forma contrattuale grezza projects.get({ params: { id } }). Evitare di passare l'oggetto di input di una superficie a un'altra tramite un'asserzione di tipo non controllata.

Streaming

Promettiamo che le operazioni SSE restituiscano iterabili asincroni. La configurazione della rete avviene all'inizio dell'iterazione. Il runtime controlla lo stato di esito positivo e il tipo di contenuto del flusso di eventi, legge i dati UTF-8 incrementali, normalizza i limiti dei frame e decodifica JSON i frame di dati. Un frame non valido non supera l'iterazione; la pulizia del lettore viene eseguita quando l'iterazione termina o esce.

La guardia del runtime è 16 * 1024 * 1024 unità di stringa JavaScript bufferizzate. Limita l'accumulo prima del confine del frame; non è una promessa che ogni payload arbitrario di 16 MB sia utile o valido per gli schemi di eventi dell'applicazione.

Consuma eventi AI in base ai loro discriminatori e preserva l'identificatore di sessione. Un trasporto terminato non è la prova di un evento di conversazione terminale. Utilizzo Streaming e ripristino AI per il comportamento di coda, interruzione, autorizzazione, domanda e ripristino dello stato. EventSource non è un sostituto immediato per una richiesta POST con intestazioni di autorizzazione e un corpo JSON.

Copertura e rigenerazione

Il generatore dispone di elenchi di omissioni espliciti per le forme che non può rappresentare. Le omissioni condivise includono caricamenti di profili/plugin in più parti, creazione di MCP con più schemi di successo, nomi di input in conflitto e fornitura di plug-in con intestazioni di risposta nel relativo flusso. Ulteriori omissioni di Promise includono webhook firmati grezzi, bootstrap del plug-in JavaScript, download binario e richieste di generatori in formato libero.

Leggi gli elenchi attuali esatti in packages/api/scripts/generate-clients.ts e il Panoramica dell'API. Un metodo generato in modo assente non stabilisce che l'endpoint del server non è disponibile. Utilizzare il cliente a contratto completo o un trasporto grezzo adeguato per tale operazione.

Radice del deposito
bun run generate
bun run generate:check
bun run --filter @cadcamfun/web generate:api-reference
bun run --filter @cadcamfun/web check:api-reference

La rigenerazione del cliente e la rigenerazione della documentazione sono output separati dello stesso contratto. Mantieni entrambi aggiornati dopo le modifiche all'endpoint. Non modificare i corpi dei metodi generati per modificare i requisiti di input del server.

Viene scritto il codice generato packages/api/src/client/generated e packages/api/src/sdk/generated. Non modificare manualmente tali file; cambiare il contratto e rigenerarsi.

Verifica dell'integrazione

Il comportamento di creazione/lettura/risultato semplice di Promise e l'errore dichiarato generato qui mostrato sono stati esercitati sullo stack reale del gestore del sidecar utilizzando un database usa e getta migrato. La procedura dettagliata HTTP contiene le risposte osservate corrispondenti. Ripetere controlli mirati quando si modificano gli schemi del generatore, dell'autenticazione o dell'endpoint.

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.

Le fonti di implementazione sono packages/api/src/sdk/generated/client.ts, suo client-error.ts, packages/api/src/client.ts, packages/api/src/client/generated, e packages/httpapi-codegen/src/index.ts. Il generatore e gli output impegnati stabiliscono insieme il comportamento effettivo del client.

Riferimento alle opzioni dell'SDK Promise

OpzioneDoveEffect
baseUrlCadCam.makeRisolto con new URL(path, baseUrl); includere lo schema e il porto.
fetchCadCam.makeSostituisci il trasporto, ad esempio per aggiungere logging o per iniettare un test double. Il valore predefinito è globalThis.fetch.
headersCadCam.makeInviato con ogni richiesta. Mettere authorization qui.
signalper chiamataInterrompe la richiesta; il rifiuto è ClientError("Transport").
headersper chiamataSostituisci o aggiungi intestazioni per una chiamata, ad esempio x-session-token. I valori per chiamata vincono sui valori del cliente.

Quando un corpo è presente e no content-type è stata impostata l'intestazione, l'SDK viene impostato application/json e serializza con JSON.stringify. I parametri del percorso vengono sempre passati encodeURIComponent, quindi una chiave come docs.walkthrough.units o uno contenente / rimane un singolo segmento.

Motivi dell'errore cliente

MotivoCresciuto quandoRisposta tipica
Transportfetch ha lanciato (rifiutato, reimpostato, DNS, interrotto) o la lettura del flusso non è riuscitaRisolvi nuovamente l'URL del sidecar; riprovare la lettura; rileggere lo stato prima di riprovare la scrittura.
UnexpectedStatusLo stato non è né lo stato di successo né uno stato di errore dichiarato. La causa regge { status }.Trattalo come una mancata corrispondenza del contratto, spesso una versione del server diversa.
UnsupportedContentTypeUn'operazione di flusso ha risposto con qualcosa di diverso da text/event-streamo un'operazione JSON con un tipo non JSONControlla i proxy e la versione del server.
MalformedResponseJSON vuoto o non valido, corpo mancante o SSE data: blocco che non è JSONRegistra la risposta grezza; segnalatelo.
SseEventTooLargeIl buffer SSE non analizzato ha superato 16 MiBL'evento viene rifiutato; riavviare lo streaming.

Il messaggio di a ClientError è il motivo seguito dal messaggio di causa (es Transport: fetch failed), quindi registrazione error.message da solo è già diagnostico.

Nuovo tentativo di sola lettura idempotente
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())

Non riprovare ciecamente le scritture

Una scrittura fallita Transport potrebbe essere stato applicato. Leggi di nuovo la risorsa e inviala nuovamente solo quando non è presente; l'API non ha chiavi di idempotenza.

Utilizzo di un flusso con l'SDK

Ripeti gli eventi dell'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
  }
}

L'iteratore analizza ogni blocco SSE: si unisce al file data: righe del blocco, analizza il JSON e lo restituisce. Commenti e blocchi senza data: vengono saltati. Uscita anticipata dal ciclo (break, un'eccezione o un'interruzione) annulla il lettore e rilascia la connessione. L'evento type i valori sono quelli elencati nella guida allo streaming dell'assistente; controlla il generato AiChatStreamOutput digitare per l'unione esatta.

Esempio: preferenze tramite l'SDK

Andata e ritorno del valore-chiave
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: "…" }

Le chiavi sono limitate a 512 caratteri e devono contenere testo diverso da spazi bianchi; i valori devono essere compatibili con JSON (nessun ciclo, funzione o numero non finito).

Nel 3D

Cosa coprono i clienti Trascina per orbitare · scorri per ingrandire · trascina con il tasto destro per eseguire la panoramica
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.