TypeScript SDK
Questi contenuti non sono ancora disponibili nella tua lingua.
@guestcraft/sdk is a private MIT workspace package with typed operations and Zod validators generated by Hey API from openapi/v1.json. It is not published to npm. Inside this monorepo, add it to a consuming workspace package:
pnpm --filter <your-workspace-package> add @guestcraft/sdk@workspace:*The package exports TypeScript source. Consumers need a TypeScript-capable toolchain and native fetch, or an injected compatible fetch implementation.
Signed-in browser
Section titled “Signed-in browser”Sign in through /sign-in or the separate auth route first. The SDK has no auth helper. Requests use credentials: "include", except with a bearer credential: an integration passes its workspace API key (apiKey) or organization token (organizationToken), and a front end the client session token its server minted (clientSessionToken); the client then sends no cookie (API keys and webhooks). One credential at most: two answer a TypeError before any request.
import { createGuestCraft } from "@guestcraft/sdk";
const guestcraft = createGuestCraft({ baseUrl: window.location.origin, // workspaceId, // optional when the session reaches exactly one workspace headers: { "Accept-Language": "en" },});
const health = await guestcraft.health.get(); // { status: "ok" }const { data: connection } = await guestcraft.channex.getConnection();if (connection.connected) { const { data: properties } = await guestcraft.channex.listProperties(); // properties contains Channex { id, title } objects}createGuestCraft({ baseUrl, workspaceId?, apiKey? | organizationToken? | clientSessionToken?, fetch?, headers? }) accepts an absolute HTTP(S) instance root, for example https://pms.example.com. A deployment prefix such as https://example.com/guestcraft is also preserved. Do not append /api/v1: the SDK adds that path. Credentials, query strings and fragments are not allowed in baseUrl.
workspaceId sets GuestCraft-Workspace-Id. It does not change the signed-in user’s permissions. Supply it explicitly when the session reaches more than one workspace.
Operations
Section titled “Operations”Every method accepts optional { signal: AbortSignal } as its final argument:
await guestcraft.health.get({ signal });await guestcraft.properties.get(propertyId, { signal });await guestcraft.properties.list({ limit: 20, signal });await guestcraft.properties.create({ name: "Example Hotel", time_zone: "Asia/Tokyo", currency: "JPY" }, { signal });await guestcraft.properties.update(propertyId, settings, { signal });await guestcraft.channex.getConnection({ signal });await guestcraft.channex.connect({ api_key: apiKey }, { signal });await guestcraft.channex.listProperties({ signal });connect requires the channex.configure permission, a browser session and a customer-owned Channex key of the workspace’s environment (staging for a sandbox workspace, production otherwise). It returns { data: { connected, environment, state, connected_at, property_count, account_mode, version } }; state is environment_mismatch for a sandbox key of Channex production, which GuestCraft never uses. getConnection returns the same shape when connected, or { data: { connected: false, environment } }. A key Channex refuses fails with channex.key_refused and its environment. listProperties returns { data: [{ id, title }] }; properties.get returns a GuestCraft property directly.
Channex IDs and GuestCraft property IDs are separate. No import, mapping, booking or ARI synchronization is performed by these methods. The SDK preserves wire field names such as connected_at and workspace_id.
Bundle size: send operations by tag
Section titled “Bundle size: send operations by tag”createGuestCraft references every operation it wraps, so a browser bundle that uses it carries
them all. To carry only what a page uses, send the generated operations, imported from their
OpenAPI tag’s module, through a transport:
import { createGuestCraftTransport } from "@guestcraft/sdk";import { propertiesGet } from "@guestcraft/sdk/operations/properties";
const transport = createGuestCraftTransport({ baseUrl: window.location.origin, workspaceId });const property = await transport.send(propertiesGet, { path: { id: propertyId }, signal });send answers the response data and throws GuestCraftError like the methods above. Each tag has
a module, @guestcraft/sdk/operations/<tag> in kebab case, and query factories have
@guestcraft/react/query/<tag>. See the SDK README
and ADR 0022.
Server-side requests
Section titled “Server-side requests”Native server fetch does not maintain session cookies automatically. Inject a fetch implementation with a cookie jar, or forward the signed-in caller’s cookie to your trusted GuestCraft instance. Create a client per caller so sessions cannot be shared between users. For example, inside a server request handler:
import { createGuestCraft } from "@guestcraft/sdk";
function clientForRequest(request: Request, instanceOrigin: string) { // instanceOrigin comes from trusted server configuration. return createGuestCraft({ baseUrl: instanceOrigin, fetch: (input, init) => { const headers = new Headers(init?.headers); const cookie = request.headers.get("cookie"); if (cookie) headers.set("Cookie", cookie); return fetch(input, { ...init, headers }); }, });}This forwards an existing session. It does not sign in or persist Set-Cookie from auth responses; a server login flow must handle that separately.
Errors and cancellation
Section titled “Errors and cancellation”import { GuestCraftError } from "@guestcraft/sdk";
try { await guestcraft.channex.listProperties();} catch (error) { if (error instanceof GuestCraftError) { console.error(error.kind, error.status, error.code, error.requestId); } else { throw error; }}GuestCraftError.kind distinguishes http, network and invalid_response. HTTP errors expose status and, when the response contains valid RFC 9457 problem details, problem and its stable code. requestId comes from the response header or problem body when available. A successful response that fails generated structural validation raises invalid_response.
Invalid local arguments can throw TypeError; cancellation preserves the abort reason. Use an AbortController or AbortSignal.timeout(...) to set a caller deadline. The SDK performs no automatic retries.
For SDK maintenance, regenerate the contract with pnpm --filter @guestcraft/sdk generate, or check freshness without writing with pnpm --filter @guestcraft/sdk generate:check. See the API guide for authentication, workspace selection and server error codes.
The dashboard consumes this SDK through @guestcraft/react, which owns the generated TanStack Query factories and workspace-scoped caches. Credentials never enter query keys or mutation caches.