import type { EncryptedDeviceRegistration } from '../../../../domain/device-registration-manifest.js' import type { DeviceHardware, DeviceId, Fingerprint, } from '../../../../domain/device.js' import type { EncryptionPublicKey, SigningPublicKey, } from '../../../../domain/keypair.js' import type { Timestamp } from '../../../../domain/timestamp.js' import type { Result } from '../../../../framework/types/result.js' import type { Infrastructure } from '../../../../infrastructure/mod.js' import { encodeJson } from '../../../../framework/json/mod.js' import { isError, makeError, makeSuccess, unwrapResult, } from '../../../../framework/types/result.js' import { DeregisterDeviceClientError, DeregisterDevicePlatformError, DeviceIsAlreadyDeregisteredError, } from './errors.js' interface Options { infrastructure: Infrastructure } export interface Dto { readonly device: Readonly<{ id: DeviceId fingerprint: Fingerprint }> } export interface ErrorResponse { readonly type: string readonly message: string } type DeregisterDeviceError = | DeviceIsAlreadyDeregisteredError | DeregisterDeviceClientError | DeregisterDevicePlatformError export function buildDeregisterDevice(options: Options) { return async function registerDevice( dto: Dto, ): Promise> { const { httpAdapter } = options.infrastructure const dtoResult = encodeJson(dto) if (isError(dtoResult)) { return makeError( new DeregisterDeviceClientError( `failed to encode the DTO: ${dtoResult.error}`, ), ) } const requestResult = await httpAdapter.request('/licensing/devices', { method: 'DELETE', body: unwrapResult(dtoResult), }) if (isError(requestResult)) { return makeError(new DeregisterDeviceClientError(requestResult.error)) } const response = unwrapResult(requestResult) const responseResult = await httpAdapter.parseResponseBody< ErrorResponse | { success: boolean } >(response) if (isError(responseResult)) { return makeError(new DeregisterDeviceClientError(responseResult.error)) } const { body, status } = unwrapResult(responseResult) if (status !== 200) { const error = body as ErrorResponse const type = error.type const message = error.message switch (status) { case 410: { return makeError(new DeviceIsAlreadyDeregisteredError(message)) } default: { return makeError(new DeregisterDevicePlatformError(message)) } } } const result = body as { success: boolean } return makeSuccess(result.success) } }