// Generated SDK adapter. Production dispatch requires a server-prepared request binding. import { businessAppError, type Client, requestBusinessBinding, toBusinessError } from "@conusai-kit/business" import type { Container, ProcedureKind } from "@conusai-kit/core" import { type CatalogImport, catalogFindImports, catalogFindProducts, catalogGetProduct, catalogImportProducts, catalogSearchProducts, type ImportOutcome, type Product, } from "@conusai-sdk/catalog" import { createClient } from "@conusai-sdk/catalog/client" import type { ImportOutcomeView, ImportView, ProductSearchField, ProductView } from "../contract/index.js" import { CATALOG_SERVICE, type CatalogReads, type CatalogService, catalogReadsOf } from "../core/ports.js" const productView = (product: Product): ProductView => ({ productId: product.id, code: product.code, name: product.name, description: product.description ?? "", baseUnit: product.base_unit, status: product.status, groupCode: product.group_code ?? null, identifiers: (product.identifiers ?? []).map(({ kind, value }) => ({ kind, value })), revision: String(product.revision), }) const importView = (row: CatalogImport): ImportView => ({ importId: row.id, sourceName: row.source_name, format: row.format, status: row.status, revision: String(row.revision), created: Number(row.created), updated: Number(row.updated), unchanged: Number(row.unchanged), refused: Number(row.refused), }) const outcomeView = (outcome: ImportOutcome): ImportOutcomeView => ({ import: importView(outcome.import), rows: outcome.rows.map((row) => ({ sourceRow: row.source_row, outcome: row.outcome, productId: row.product_id ?? null, reason: row.reason ?? null, })), }) /** What a lookup asks the service: a code prefix or an identifier. A name goes to the ranked search. */ function searchQuery(search: { by: Exclude; q: string }) { switch (search.by) { case "code": return { code_prefix: search.q } case "gtin": case "erp": return { identifier_kind: search.by, identifier_value: search.q } } } /** 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. */ export function sdkCatalogService(binding: { client: Client; orgSlug: string }): CatalogService { const { client } = binding const org = { org_slug: binding.orgSlug } return { async listProducts({ search, after, limit }) { const page = await answer( catalogFindProducts({ client, path: org, query: { ...(search ? searchQuery(search) : {}), ...(after === undefined ? {} : { after }), limit: BigInt(limit), }, }), ) return { rows: page.data.map(productView), ...(page.next_after ? { after: page.next_after } : {}) } }, async searchProducts({ q, after, limit }) { const page = await answer( catalogSearchProducts({ client, path: org, query: { q, ...(after === undefined ? {} : { after }), limit: BigInt(limit) }, }), ) return { rows: page.data.map((hit) => productView(hit.product)), ...(page.next_after ? { after: page.next_after } : {}), } }, async getProduct(productId) { return productView(await answer(catalogGetProduct({ client, path: { ...org, product_id: productId } }))) }, async listImports({ after, limit }) { const page = await answer( catalogFindImports({ client, path: org, query: { ...(after === undefined ? {} : { after }), limit: BigInt(limit) }, }), ) return { rows: page.data.map(importView), ...(page.next_after ? { after: page.next_after } : {}) } }, async applyImport(input) { const outcome = await answer( catalogImportProducts({ client, path: org, body: { file_hash: input.fileHash, source_name: input.sourceName, format: input.format, chunk: input.chunk, final_chunk: input.finalChunk, ...(input.revision === undefined ? {} : { revision: BigInt(input.revision) }), rows: input.rows.map((row) => ({ source_row: row.sourceRow, ...(row.revision === undefined ? {} : { revision: BigInt(row.revision) }), product: { code: row.product.code, name: row.product.name, base_unit: row.product.baseUnit, ...(row.product.description === undefined ? {} : { description: row.product.description }), }, })), idempotency_key: input.key, }, }), ) return outcomeView(outcome) }, } } /** * 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 catalogServiceOf(container: Container, kind: "effect"): CatalogService export function catalogServiceOf(container: Container, kind: ProcedureKind): CatalogReads export function catalogServiceOf(container: Container, kind: ProcedureKind): CatalogReads { if (container.has(CATALOG_SERVICE)) return container.resolve(CATALOG_SERVICE) as CatalogReads let service: CatalogService try { const binding = requestBusinessBinding(container) service = sdkCatalogService({ client: binding.client(createClient), orgSlug: binding.orgSlug }) } catch (error) { throw businessAppError(error) } return kind === "effect" ? service : catalogReadsOf(service) }