// Generated SDK adapter. Production dispatch requires a server-prepared request binding. import { businessAppError, type Client, canonicalActionJson, requestBusinessBinding, requiresAppActionTransport, toBusinessError, } from "@conusai-kit/business" import { type Container, forbidden, type ProcedureKind } from "@conusai-kit/core" import { type ContactPoint, type ContactValue, crmAddContactPoint, crmCreateParty, crmGetParty, crmListContactPoints, crmListParties, type Party, } from "@conusai-sdk/crm" import { createClient } from "@conusai-sdk/crm/client" import { type ContactView, type PartyView, SUBJECT_SCHEME } from "../contract/index.js" import { contactRequestBody, partyRequestBody } from "../core/action-plan.js" import { CRM_SERVICE, type CrmReads, type CrmService, crmReadsOf } from "../core/ports.js" const partyView = (party: Party): PartyView => ({ partyId: party.id, kind: party.kind, displayName: party.display_name, legalName: party.legal_name ?? null, country: party.country, status: party.status, linked: (party.identifiers ?? []).some((identifier) => identifier.scheme === SUBJECT_SCHEME), }) /** A contact value as a person reads it. */ function valueText(value: ContactValue): string { switch (value.kind) { case "postal": return [value.value.street, value.value.postal_code, value.value.city, value.value.country] .filter((part): part is string => typeof part === "string" && part !== "") .join(", ") case "peppol_endpoint": return `${value.value.eas}:${value.value.id}` default: return value.value } } const contactView = (contact: ContactPoint): ContactView => contact.fields ? { contactId: contact.id, kind: contact.fields.kind, value: valueText(contact.fields), purposes: contact.fields.purposes, isPrimary: contact.fields.is_primary, erased: contact.erased, } : // Erased: no personal value remains, only that there was a contact point. { contactId: contact.id, kind: "email", value: "", purposes: [], isPrimary: false, erased: true } /** What a generated operation answered: its data, or the kit's app error for the refusal (`businessAppError`). */ async function answer( call: Promise<{ data?: T; error?: unknown; response?: Response }>, ): Promise> { let result: { data?: T; error?: unknown; response?: Response } try { result = await call } catch (error) { throw businessAppError(toBusinessError(error, undefined)) } if (result.error !== undefined || result.data === undefined) { throw businessAppError(toBusinessError(result.error, result.response)) } return result.data as Exclude } /** The port over one client, in one organization of one platform project. */ export function sdkCrmService(binding: { client: Client; orgSlug: string; bindingId: string }): CrmService { const { client } = binding const org = { org_slug: binding.orgSlug } return { bindingId: binding.bindingId, async listParties(query) { const page = await answer(crmListParties({ client, path: org, query: { ...query, limit: BigInt(query.limit) } })) return { rows: page.data.map(partyView), ...(page.next_after ? { after: page.next_after } : {}) } }, async getParty(partyId) { return partyView(await answer(crmGetParty({ client, path: { ...org, id: partyId } }))) }, async listContacts(partyId, query) { const page = await answer( crmListContactPoints({ client, path: { ...org, id: partyId }, query: { ...query, limit: BigInt(query.limit) }, }), ) return { rows: page.data.map(contactView), ...(page.next_after ? { after: page.next_after } : {}) } }, async createParty(input) { const party = await answer( crmCreateParty({ client, path: org, body: partyRequestBody(input), bodySerializer: canonicalActionJson, }), ) return partyView(party) }, async addContact(input) { const contact = await answer( crmAddContactPoint({ client, path: { ...org, id: input.partyId }, body: contactRequestBody(input), bodySerializer: canonicalActionJson, }), ) return contactView(contact) }, } } /** * The service a handler of `kind` may use: the bound one (the token's view for the kind applies), or * the current verified request's, narrowed to its reads for a `read` or `write` handler as the token would. */ export function crmServiceOf(container: Container, kind: "effect"): CrmService export function crmServiceOf(container: Container, kind: ProcedureKind): CrmReads export function crmServiceOf(container: Container, kind: ProcedureKind): CrmReads { if (container.has(CRM_SERVICE)) { if (requiresAppActionTransport(container)) throw forbidden("app action requires prepared business transport") return container.resolve(CRM_SERVICE) as CrmReads } let service: CrmService try { const binding = requestBusinessBinding(container) service = sdkCrmService({ client: binding.client(createClient), orgSlug: binding.orgSlug, bindingId: binding.bindingId, }) } catch (error) { throw businessAppError(error) } return kind === "effect" ? service : crmReadsOf(service) }