98 lines
2.9 KiB
TypeScript
98 lines
2.9 KiB
TypeScript
import {
|
|
createReferenceResource,
|
|
type ReferenceResource,
|
|
} from "../domain/reference-resource.ts";
|
|
import {
|
|
mappingFailure,
|
|
mappingSuccess,
|
|
type MappingResult,
|
|
type InstalledBoundaryMapper,
|
|
} from "../../../contracts/boundary-mapper.ts";
|
|
|
|
export type ReferenceResourceView = Readonly<{
|
|
resourceId: string;
|
|
title: string;
|
|
createdAt: string | null;
|
|
optimistic?: boolean;
|
|
}>;
|
|
|
|
function mapReferenceDto(value: unknown): MappingResult<ReferenceResource> {
|
|
if (!value || typeof value !== "object") {
|
|
return mappingFailure("MAPPING_INVARIANT_REJECTED");
|
|
}
|
|
const dto = value as Record<string, unknown>;
|
|
if (typeof dto.id !== "string" || typeof dto.name !== "string") {
|
|
return mappingFailure("MAPPING_INVARIANT_REJECTED");
|
|
}
|
|
try {
|
|
return mappingSuccess(
|
|
createReferenceResource({
|
|
id: dto.id,
|
|
displayName: dto.name,
|
|
createdAt: typeof dto.createdAt === "string" ? dto.createdAt : null,
|
|
}),
|
|
);
|
|
} catch {
|
|
return mappingFailure("MAPPING_INVARIANT_REJECTED");
|
|
}
|
|
}
|
|
|
|
export function mapReferenceOperation(
|
|
operationId: string,
|
|
payload: unknown,
|
|
): MappingResult<ReferenceResource | readonly ReferenceResource[]> {
|
|
if (operationId === "LIST_REFERENCE_RESOURCES") {
|
|
if (!Array.isArray(payload)) {
|
|
return mappingFailure("MAPPING_INVARIANT_REJECTED");
|
|
}
|
|
if (payload.length > 100) return mappingFailure("OUTPUT_LIMIT_EXCEEDED");
|
|
const output: ReferenceResource[] = [];
|
|
for (const item of payload) {
|
|
const mapped = mapReferenceDto(item);
|
|
if (!mapped.ok) return mapped;
|
|
output.push(mapped.value);
|
|
}
|
|
return mappingSuccess(Object.freeze(output));
|
|
}
|
|
if (
|
|
operationId === "CREATE_REFERENCE_RESOURCE" ||
|
|
operationId === "GET_REFERENCE_RESOURCE"
|
|
) {
|
|
return mapReferenceDto(payload);
|
|
}
|
|
return mappingFailure("MAPPING_INVARIANT_REJECTED");
|
|
}
|
|
|
|
export const REFERENCE_BOUNDARY_MAPPERS = Object.freeze({
|
|
ReferenceResourceListMapper: Object.freeze({
|
|
mapperId: "ReferenceResourceListMapper",
|
|
mapperVersion: 1,
|
|
inputSchemaId: "ReferenceResourceListPayload",
|
|
outputContractId: "ReferenceResourceList",
|
|
owner: "feature-frontend-reference-feature-vertical-slice",
|
|
maxOutputItems: 100,
|
|
map: (input: unknown) =>
|
|
mapReferenceOperation("LIST_REFERENCE_RESOURCES", input),
|
|
}),
|
|
ReferenceResourceMapper: Object.freeze({
|
|
mapperId: "ReferenceResourceMapper",
|
|
mapperVersion: 1,
|
|
inputSchemaId: "ReferenceResourcePayload",
|
|
outputContractId: "ReferenceResource",
|
|
owner: "feature-frontend-reference-feature-vertical-slice",
|
|
maxOutputItems: 1,
|
|
map: (input: unknown) =>
|
|
mapReferenceOperation("GET_REFERENCE_RESOURCE", input),
|
|
}),
|
|
} satisfies Readonly<Record<string, InstalledBoundaryMapper>>);
|
|
|
|
export function toReferenceView(
|
|
resource: ReferenceResource,
|
|
): ReferenceResourceView {
|
|
return Object.freeze({
|
|
resourceId: resource.id,
|
|
title: resource.displayName,
|
|
createdAt: resource.createdAt,
|
|
});
|
|
}
|