@@ -0,0 +1,204 @@
|
||||
// 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 {
|
||||
archiveAddVersion,
|
||||
archiveCreateRetentionClass,
|
||||
archiveDisposeDocument,
|
||||
archiveFindDocuments,
|
||||
archiveGetDocument,
|
||||
archiveListDisposalDue,
|
||||
archiveListRetentionClasses,
|
||||
archiveListVersions,
|
||||
archiveRegisterDocument,
|
||||
archiveSetLegalHold,
|
||||
type Document,
|
||||
type DocumentVersion,
|
||||
type Receipt,
|
||||
type RetentionClass,
|
||||
type VersionInput,
|
||||
} from "@conusai-sdk/archive"
|
||||
import { createClient } from "@conusai-sdk/archive/client"
|
||||
import type { DocumentReceipt, DocumentView, RetentionClassView, VersionFacts, VersionView } from "../contract/index.js"
|
||||
import { ARCHIVE_SERVICE, type ArchiveReads, type ArchiveService, archiveReadsOf } from "../core/ports.js"
|
||||
|
||||
const documentView = (document: Document): DocumentView => ({
|
||||
documentId: document.id,
|
||||
title: document.title,
|
||||
kind: document.kind ?? null,
|
||||
retentionClass: document.retention_class,
|
||||
legalHold: document.legal_hold,
|
||||
status: document.status as DocumentView["status"],
|
||||
disposed: document.status !== "active" || Boolean(document.erased_at),
|
||||
revision: String(document.revision),
|
||||
createdAt: document.created_at,
|
||||
lastVersionAt: document.last_version_at,
|
||||
disposedAt: document.disposed_at ?? null,
|
||||
})
|
||||
|
||||
const versionView = (version: DocumentVersion): VersionView => ({
|
||||
versionId: version.id,
|
||||
sequence: Number(version.sequence),
|
||||
sha256: version.sha256,
|
||||
mediaType: version.media_type,
|
||||
size: String(version.size),
|
||||
createdAt: version.created_at,
|
||||
})
|
||||
|
||||
const retentionView = (retention: RetentionClass): RetentionClassView => ({
|
||||
code: retention.code,
|
||||
keepFor: retention.keep_for,
|
||||
from: retention.from as RetentionClassView["from"],
|
||||
createdAt: retention.created_at,
|
||||
})
|
||||
|
||||
const versionInput = (version: VersionFacts): VersionInput => ({
|
||||
sha256: version.sha256,
|
||||
media_type: version.mediaType,
|
||||
size: BigInt(version.size),
|
||||
blob_ref: version.blobRef,
|
||||
})
|
||||
|
||||
const receiptView = (receipt: Receipt): DocumentReceipt => ({
|
||||
documentId: receipt.id,
|
||||
revision: String(receipt.revision ?? 0),
|
||||
})
|
||||
|
||||
/** What a generated operation answered: its data, or the kit's typed app error for the refusal. */
|
||||
async function answer<T>(
|
||||
call: Promise<{ data?: T; error?: unknown; response?: Response }>,
|
||||
): Promise<Exclude<T, undefined>> {
|
||||
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<T, undefined>
|
||||
}
|
||||
|
||||
const pageQuery = (query: { after?: string; limit: number }) => ({
|
||||
...(query.after === undefined ? {} : { after: query.after }),
|
||||
limit: BigInt(query.limit),
|
||||
})
|
||||
|
||||
const pageOf = <S, T>(page: { data: S[]; next_after?: string | null }, view: (row: S) => T) => ({
|
||||
rows: page.data.map(view),
|
||||
...(page.next_after ? { after: page.next_after } : {}),
|
||||
})
|
||||
|
||||
/** The port over one client, in one organization. */
|
||||
export function sdkArchiveService(binding: { client: Client; orgSlug: string }): ArchiveService {
|
||||
const { client } = binding
|
||||
const org = { org_slug: binding.orgSlug }
|
||||
return {
|
||||
async listDocuments(query) {
|
||||
const page = await answer(
|
||||
archiveFindDocuments({
|
||||
client,
|
||||
path: org,
|
||||
query: { ...(query.q === undefined ? {} : { q: query.q }), ...pageQuery(query) },
|
||||
}),
|
||||
)
|
||||
return pageOf(page, documentView)
|
||||
},
|
||||
async getDocument(documentId) {
|
||||
return documentView(await answer(archiveGetDocument({ client, path: { ...org, document_id: documentId } })))
|
||||
},
|
||||
async listVersions(documentId, query) {
|
||||
const page = await answer(
|
||||
archiveListVersions({ client, path: { ...org, document_id: documentId }, query: pageQuery(query) }),
|
||||
)
|
||||
return pageOf(page, versionView)
|
||||
},
|
||||
async listRetentionClasses(query) {
|
||||
const page = await answer(archiveListRetentionClasses({ client, path: org, query: pageQuery(query) }))
|
||||
return pageOf(page, retentionView)
|
||||
},
|
||||
async listDisposalDue(query) {
|
||||
const page = await answer(archiveListDisposalDue({ client, path: org, query: pageQuery(query) }))
|
||||
return pageOf(page, documentView)
|
||||
},
|
||||
async registerDocument(input) {
|
||||
const receipt = await answer(
|
||||
archiveRegisterDocument({
|
||||
client,
|
||||
path: org,
|
||||
body: {
|
||||
title: input.title,
|
||||
...(input.kind === undefined ? {} : { kind: input.kind }),
|
||||
retention_class: input.retentionClass,
|
||||
version: versionInput(input.version),
|
||||
idempotency_key: input.key,
|
||||
},
|
||||
}),
|
||||
)
|
||||
return receiptView(receipt)
|
||||
},
|
||||
async addVersion(input) {
|
||||
const receipt = await answer(
|
||||
archiveAddVersion({
|
||||
client,
|
||||
path: { ...org, document_id: input.documentId },
|
||||
body: {
|
||||
revision: BigInt(input.revision),
|
||||
version: versionInput(input.version),
|
||||
idempotency_key: input.key,
|
||||
},
|
||||
}),
|
||||
)
|
||||
return receiptView(receipt)
|
||||
},
|
||||
async setLegalHold(input) {
|
||||
const receipt = await answer(
|
||||
archiveSetLegalHold({
|
||||
client,
|
||||
path: { ...org, document_id: input.documentId },
|
||||
body: { revision: BigInt(input.revision), legal_hold: input.legalHold, idempotency_key: input.key },
|
||||
}),
|
||||
)
|
||||
return receiptView(receipt)
|
||||
},
|
||||
async disposeDocument(input) {
|
||||
const receipt = await answer(
|
||||
archiveDisposeDocument({
|
||||
client,
|
||||
path: { ...org, document_id: input.documentId },
|
||||
body: { revision: BigInt(input.revision), idempotency_key: input.key },
|
||||
}),
|
||||
)
|
||||
return receiptView(receipt)
|
||||
},
|
||||
async createRetentionClass(input) {
|
||||
await answer(
|
||||
archiveCreateRetentionClass({
|
||||
client,
|
||||
path: org,
|
||||
body: { code: input.code, keep_for: input.keepFor, from: input.from, idempotency_key: input.key },
|
||||
}),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 archiveServiceOf(container: Container, kind: "effect"): ArchiveService
|
||||
export function archiveServiceOf(container: Container, kind: ProcedureKind): ArchiveReads
|
||||
export function archiveServiceOf(container: Container, kind: ProcedureKind): ArchiveReads {
|
||||
if (container.has(ARCHIVE_SERVICE)) return container.resolve(ARCHIVE_SERVICE) as ArchiveReads
|
||||
let service: ArchiveService
|
||||
try {
|
||||
const binding = requestBusinessBinding(container)
|
||||
service = sdkArchiveService({ client: binding.client(createClient), orgSlug: binding.orgSlug })
|
||||
} catch (error) {
|
||||
throw businessAppError(error)
|
||||
}
|
||||
return kind === "effect" ? service : archiveReadsOf(service)
|
||||
}
|
||||
Reference in New Issue
Block a user