Перейти к содержанию
CADCAMFUN
Документы

Документация

Создайте интеграцию клиента API

Используйте Promise SDK, полный клиент контракта Effect или сгенерированные адаптеры Effect с их фактическими входными данными и поведением при ошибках.

Автоматически переведено с английского. Смотреть оригинал на английском

Выберите клиента

Репозиторий имеет три связанные клиентские поверхности. У них общие объявления конечных точек, но их конструкция, формы ввода, зависимости времени выполнения и каналы ошибок различаются. Выбирайте один сознательно и храните примеры из этой области вместе.

ПоверхностьТочка входаИсполнение
Обещанный SDK@cadcamfun/api/sdk, экспортировано CadCam.makeОбещания обычных результатов; асинхронные итерации для SSE. Использует предоставленную или глобальную выборку.
Полный контрактный клиентApiClient от @cadcamfun/apiСлужба эффектов с промежуточным программным обеспечением транспорта и носителя, предоставляемым его уровнем.
Адаптеры сгенерированных эффектовpackages/api/src/client/generated/index.tsСглаженные методы для контрактного клиента; вызывающая сторона предоставляет необходимое транспортное и промежуточное программное обеспечение.

Пакет API представляет собой частное рабочее пространство с экспортом исходного кода. Приведенный ниже импорт предназначен для этого монорепозитория или дистрибутива, который фактически обеспечивает этот экспорт; на этой странице не заявлен отдельно доступный общедоступный пакет npm. Независимые клиенты могут использовать документ OpenAPI или обычный HTTP.

Для первого запроса без настройки клиентской библиотеки начните с захваченное пошаговое руководство по HTTP. Он устанавливает, как тела успеха и неудачи различаются в зависимости от операции.

Разрешить соединение

Используйте URL-адрес и токен носителя приложения, принадлежащие текущему запуску дополнительной версии. Таури получает их через get_sidecar_endpoint. Процесс разработки вручную печатает назначенный порт в событии готовности. Источник должен указывать на сайдкар или допущенный сопутствующий шлюз, а не на сайт документации или ресурсы Vite.

После перезапуска сайдкара снова разрешите соединение. Повторное использование предыдущего порта может привести к отказу в соединении или случайному обращению к другому процессу. Повторное использование устаревшего токена запуска приводит к сбою авторизации. Успешные ответные меры общественного здравоохранения не доказывают, что защищенный запрос будет принят.

Выбор учетной записи, доступ к приложениям, доступ к устройствам и доступ к внешнему агенту различны. Необязательный x-session-token выбирает аккаунт после поступления заявки. Токен моста в рамках проекта ограничен конечными точками моста действий. Телефонный токен работает через список разрешений шлюза. Следуйте ссылка на аутентификацию перед выбором соединения для интеграции.

Обещанный SDK

Экспортированное пространство имен CadCam, а его конструктор make. Укажите базовый URL-адрес и заголовки по умолчанию. В приведенных ниже методах create и get используются сглаженные поля, а не вложенные поля. payload или params объект.

Внутри рабочей области, использующей @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)

Каждый вызов напрямую преобразуется в полезные данные успеха этой конечной точки. projects.list() возвращает массив; projects.create() возвращает строку проекта. Не существует универсального { data, error } обертка и нет throwOnError опция конструктора в этом SDK. Некоторые полезные данные конечных точек сами содержат data или success потому что это их HTTP-контракт.

SDK подготавливает URL-адрес на основе пути конечной точки и настроенного базового URL-адреса, кодирует идентификаторы пути, сериализует объявленные входные данные JSON и проверяет точное объявленное состояние успеха операции. Затем он анализирует JSON и возвращает его типизированное значение. Среда выполнения Promise не применяет декодер схемы Effect к каждой возвращаемой полезной нагрузке; Типы вывода TypeScript не проверяют произвольную реализацию сервера.

Заявленные и транспортные ошибки

Объявленные ошибки HTTP отклоняются с декодированным телом ответа. Это значение может быть простым объектом с тегом, а не экземпляром ошибки JavaScript. При сбоях транспорта и протоколов используйте 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)
  }
}
Причина ошибки клиентаИнтерпретация
TransportИзвлеките настройки, соединение, прерывание или сбой потокового чтения. Проверьте причину и текущее соединение.
UnexpectedStatusСервер вернул статус, выходящий за рамки объявленных статусов успеха и неудачи операции.
UnsupportedContentTypeОтвет потока не имел ожидаемого типа контента потока событий.
MalformedResponseJSON или ожидаемый поток ответов не удалось декодировать.
SseEventTooLargeБуфер потока событий превысил защиту кадра созданной среды выполнения.

Например, отсутствие имени проекта означает сбой в работе HTTP 400, даже если тип входных данных создания допускает его пропуск. Сброс соединения при создании проекта отличается: он оставляет клиенту неуверенность в том, завершена ли запись. Прочтите состояние ресурса перед повторением мутации. SDK не добавляет протокол идемпотентности для всего приложения и не повторяет автоматически каждый отклоненный вызов.

Отмена и заголовки

ClientOptions принимает baseUrl, необязательная реализация выборки и заголовки по умолчанию. За вызов RequestOptions принимает сигнал и дополнительные заголовки. Для методов без ввода конечной точки параметры запроса являются первым аргументом; методы с вводом принимают после него параметры запроса.

Отмена каждого звонка и выбор учетной записи
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

Построитель запросов применяет заголовки по умолчанию, заголовки, объявленные конечной точкой, а затем заголовки для каждого вызова. Значение для каждого вызова может переопределить значение по умолчанию; избегайте случайной замены авторизации при добавлении заголовков учетной записи или трассировки. Не указывайте учетные данные в URL-адресах конечных точек, скопированных в журналы.

Инъекция fetch поддерживает внутрипроцессный тестовый транспорт или управляемый адаптер. Адаптер по-прежнему должен учитывать заголовки, тело запроса, отмену, типы контента и семантику статуса ответа. Собственная интеграция эффектов рабочего стола и закрепленный встроенный транспорт телефона выполняют дополнительную работу; замена произвольной выборки не воспроизводит эти собственные границы.

Полноценный клиент

ApiClient.layer создает полный клиент HttpApi, извлекает транспорт и промежуточное программное обеспечение носителя. Он предоставляет методы конечной точки с базовой формой запроса HttpApi. Полезная нагрузка мутации выходит из строя payload, а значения пути попадают под 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)

Этот клиент является производным от всего объявления API и является вариантом для конечных точек, исключенных из сгенерированных целей. Он сохраняет канал типизированных ошибок Effect и транспорт с учетом схемы. Время жизни ресурса, прерывание потока и предоставление уровня принадлежат вызывающей программе Effect; создание эффекта не приводит к его выполнению.

Многоразовый уровень предоставляет токен приложения. Рабочий стол создает свой собственный слой в apps/desktop/src/app/client.ts чтобы прикрепить дополнительное состояние сеанса учетной записи и внедренный транспорт. Используйте эту интеграцию повторно при работе внутри рабочего стола вместо создания второго соединения/среды выполнения для каждого компонента.

Адаптеры сгенерированных эффектов

Сгенерированный клиент Effect импортирует реальные схемы и адаптирует методы к плоским полям. Его CadCam.make возвращает Эффект, который создает адаптированный клиент. Он не предоставляет собственный уровень транспорта выборки или авторизации приложения, поэтому вызывающая сторона должна предоставить соответствующие службы и промежуточное программное обеспечение.

Сгенерированный адаптер ошибок отображает сбои транспорта/схемы/SSE в помеченный тег. ClientError сохраняя при этом заявленные сбои домена. Этот класс ошибок отделен от класса ошибок JavaScript Promise SDK с помощью reason нить. Сходство названий не делает их обращение взаимозаменяемым.

Делайте примеры входных данных ясными. Формы «Обещание» и «Сгенерированный эффект» используют projects.get({ id }); необработанная форма контракта использует projects.get({ params: { id } }). Избегайте передачи входного объекта одной поверхности другой через непроверяемое утверждение типа.

Потоковое вещание

Операции Promise SSE возвращают асинхронные итерации. Настройка сети происходит в начале итерации. Среда выполнения проверяет статус успеха и тип содержимого потока событий, считывает инкрементные данные UTF-8, нормализует границы кадров и декодирует кадры данных в формате JSON. Неверно сформированный кадр не проходит итерацию; Очистка считывателя запускается, когда итерация заканчивается или завершается.

Защита среды выполнения 16 * 1024 * 1024 буферизованные строковые единицы JavaScript. Это ограничивает накопление перед границей кадра; это не означает, что каждая произвольная полезная нагрузка 16 МБ полезна или действительна для схем событий приложения.

Потребляйте события AI в соответствии с их дискриминаторами и сохраняйте идентификатор сеанса. Завершенный транспорт не является доказательством события терминального разговора. Использовать Потоковая передача и восстановление AI для очереди, прерывания, разрешения, вопроса и поведения восстановления состояния. EventSource не является полной заменой запроса POST с заголовками авторизации и телом JSON.

Покрытие и регенерация

Генератор имеет явные списки пропусков для фигур, которые он не может представить. Общие упущения включают загрузку профилей/плагинов из нескольких частей, создание MCP с несколькими схемами успеха, конфликтующие имена входных данных и обслуживание плагинов с заголовками ответов в потоке. Дополнительные упущения Promise включают в себя необработанные подписанные веб-перехватчики, загрузку плагина JavaScript, двоичную загрузку и запросы генератора в свободной форме.

Точные текущие списки читайте в packages/api/scripts/generate-clients.ts и Обзор API. Отсутствующий сгенерированный метод не устанавливает, что конечная точка сервера недоступна. Для этой операции используйте клиента с полным контрактом или подходящий транспорт сырья.

Корень репозитория
bun run generate
bun run generate:check
bun run --filter @cadcamfun/web generate:api-reference
bun run --filter @cadcamfun/web check:api-reference

Регенерация клиента и регенерация документации — это отдельные результаты одного и того же контракта. Сохраняйте оба актуальными после изменения конечной точки. Не редактируйте сгенерированные тела методов, чтобы изменить входные требования сервера.

Сгенерированный код записывается в packages/api/src/client/generated и packages/api/src/sdk/generated. Не редактируйте эти файлы вручную; измените договор и перегенерируйте.

Проверка интеграции

Показанные здесь поведение Promise create/read/plain-result и выданный объявленный сбой были применены к реальному стеку обработчиков дополнительных функций с использованием перенесенной одноразовой базы данных. Пошаговое руководство по HTTP содержит соответствующие наблюдаемые ответы. Повторите целенаправленные проверки при изменении схем генератора, аутентификации или конечных точек.

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.

Источники реализации: packages/api/src/sdk/generated/client.ts, его client-error.ts, packages/api/src/client.ts, packages/api/src/client/generated, и packages/httpapi-codegen/src/index.ts. Генератор и зафиксированные выходные данные вместе определяют фактическое поведение клиента.

Справочник по опциям Promise SDK

ВариантГдеEffect
baseUrlCadCam.makeРешено с new URL(path, baseUrl); укажите схему и порт.
fetchCadCam.makeЗамените транспорт, например, чтобы добавить ведение журнала или внедрить тестовый дубль. По умолчанию globalThis.fetch.
headersCadCam.makeОтправляется с каждым запросом. Помещать authorization здесь.
signalза звонокПрерывает запрос; отказ это ClientError("Transport").
headersза звонокПереопределить или добавить заголовки для одного вызова, например x-session-token. Ценности каждого звонка преобладают над ценностями клиента.

Когда тело есть и нет content-type заголовок был установлен, SDK устанавливает application/json и сериализуется с помощью JSON.stringify. Параметры пути всегда передаются encodeURIComponent, поэтому такой ключ, как docs.walkthrough.units или тот, который содержит / остается одним сегментом.

Причины ошибки клиента

ПричинаПоднят, когдаТипичный ответ
Transportfetch выбросил (отказ, сброс, DNS, прерывание) или не удалось прочитать потокПовторно разрешить дополнительный URL-адрес; повторить чтение; перечитайте состояние перед повторной попыткой записи.
UnexpectedStatusСтатус не является ни статусом успеха, ни статусом объявленной ошибки. Причина в силе { status }.Рассматривайте это как несоответствие контракта, часто это другая версия сервера.
UnsupportedContentTypeПотоковая операция ответила чем-то отличным от text/event-streamили операция JSON с типом, отличным от JSON.Проверьте прокси и версию сервера.
MalformedResponseПустой или недействительный JSON, отсутствующее тело или SSE. data: блок, который не является JSONЗарегистрируйте необработанный ответ; сообщите об этом.
SseEventTooLargeНеобработанный буфер SSE превысил 16 МиБ.В мероприятии отказано; перезапустить поток.

Сообщение ClientError это причина, за которой следует сообщение о причине (например, Transport: fetch failed), поэтому регистрация error.message само по себе уже является диагностическим.

Повторная попытка идемпотентного чтения только
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())

Не пытайтесь слепо повторять запись

Запись, которая не удалась с Transport возможно, были применены. Прочтите ресурс еще раз и отправляйте повторно только тогда, когда его там нет; API не имеет ключей идемпотентности.

Использование потока с помощью 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
  }
}

Итератор анализирует каждый блок SSE: он объединяет data: строки блока, анализирует JSON и выдает его. Комментарии и блокировки без data: пропускаются. Досрочный выход из цикла (break, исключение или прерывание) отменяет операцию чтения и освобождает соединение. Событие type значения указаны в руководстве по потоковой передаче помощника; проверьте сгенерированный AiChatStreamOutput введите точное объединение.

Пример: настройки через 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: "…" }

Ключи ограничены символами 512 и должны содержать текст без пробелов; значения должны быть совместимы с JSON (без циклов, функций или неконечных чисел).

Через 3Д

Что покрывают клиенты Перетащите на орбиту · прокрутите, чтобы увеличить · перетащите вправо, чтобы панорамировать
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.