2024-05-15 13:44:50 +02:00

251 lines
8.1 KiB
TypeScript

import { CollectibleNature, Collections } from "../../../constants";
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
import { EndpointCollectible } from "../../../sdk";
import { Collectible } from "../../../types/collections";
import {
isDefined,
isNotEmpty,
isPayloadArrayType,
isPayloadType,
isPublished,
isValidPayloadImage,
isValidPayloadMedia,
} from "../../../utils/asserts";
import {
convertAttributesToEndpointAttributes,
convertSourceToEndpointSource,
getDomainFromUrl,
} from "../../../utils/endpoints";
import { convertAudioToEndpointAudio } from "../../Audios/endpoints/getByID";
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
import { convertPageToEndpointPage } from "../../Pages/endpoints/getBySlugEndpoint";
import { convertRecorderToEndpointRecorder } from "../../Recorders/endpoints/getByUsername";
import { convertVideoToEndpointVideo } from "../../Videos/endpoints/getByID";
export const getBySlugEndpoint = createGetByEndpoint({
collection: Collections.Collectibles,
attribute: "slug",
depth: 3,
handler: (collectible) => convertCollectibleToEndpointCollectible(collectible),
});
export const convertCollectibleToEndpointCollectible = ({
nature,
urls,
subitems,
gallery: rawGallery,
contents,
priceEnabled,
price,
size,
sizeEnabled,
weight,
weightEnabled,
pageInfo,
pageInfoEnabled,
parentItems,
folders,
backgroundImage,
slug,
thumbnail,
translations,
releaseDate,
languages,
scans: rawScans,
attributes,
createdAt,
updatedAt,
scansEnabled,
updatedBy,
}: Collectible): EndpointCollectible => {
const gallery = handleGallery(rawGallery);
const scans = scansEnabled ? handleScans(rawScans) : undefined;
return {
slug,
languages:
languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [],
...(isDefined(releaseDate) ? { releaseDate } : {}),
...(isValidPayloadImage(thumbnail)
? { thumbnail: convertImageToEndpointImage(thumbnail) }
: {}),
...(isValidPayloadImage(backgroundImage)
? { backgroundImage: convertImageToEndpointImage(backgroundImage) }
: {}),
attributes: convertAttributesToEndpointAttributes(attributes),
translations:
translations?.map(({ language, title, description, pretitle, subtitle }) => ({
language: isPayloadType(language) ? language.id : language,
title,
...(isNotEmpty(pretitle) ? { pretitle } : {}),
...(isNotEmpty(subtitle) ? { subtitle } : {}),
...(isNotEmpty(description) ? { description } : {}),
})) ?? [],
contents: handleContents(contents),
...(gallery ? { gallery } : {}),
...(scans ? { scans } : {}),
nature: nature === "Physical" ? CollectibleNature.Physical : CollectibleNature.Digital,
subitems: isPayloadArrayType(subitems)
? subitems.filter(isPublished).map(convertCollectibleToEndpointCollectible)
: [],
urls: urls?.map(({ url }) => ({ url, label: getDomainFromUrl(url) })) ?? [],
...(weightEnabled && isDefined(weight) ? { weight: weight.amount } : {}),
...handleSize(size, sizeEnabled),
...handlePageInfo(pageInfo, pageInfoEnabled),
...handlePrice(price, priceEnabled),
createdAt,
updatedAt,
...(isPayloadType(updatedBy)
? { updatedBy: convertRecorderToEndpointRecorder(updatedBy) }
: {}),
parentPages: convertSourceToEndpointSource({ collectibles: parentItems, folders }),
};
};
const handlePrice = (
price: Collectible["price"],
enabled: Collectible["priceEnabled"]
): { price: NonNullable<EndpointCollectible["price"]> } | {} => {
if (!price || !enabled || !isPayloadType(price.currency)) return {};
return {
price: { amount: price.amount, currency: price.currency.id },
};
};
const handleSize = (
size: Collectible["size"],
enabled: Collectible["sizeEnabled"]
): { size: NonNullable<EndpointCollectible["size"]> } | {} => {
if (!size || !enabled) return {};
return {
size: {
width: size.width,
height: size.height,
...(isDefined(size.thickness) ? { thickness: size.thickness } : {}),
},
};
};
const handlePageInfo = (
pageInfo: Collectible["pageInfo"],
enabled: Collectible["pageInfoEnabled"]
): { pageInfo: NonNullable<EndpointCollectible["pageInfo"]> } | {} => {
if (!pageInfo || !enabled) return {};
return {
pageInfo: {
pageCount: pageInfo.pageCount,
...(isDefined(pageInfo.bindingType) ? { bindingType: pageInfo.bindingType } : {}),
...(isDefined(pageInfo.pageOrder) ? { pageOrder: pageInfo.pageOrder } : {}),
},
};
};
const handleGallery = (gallery: Collectible["gallery"]): EndpointCollectible["gallery"] => {
const thumbnail = gallery?.[0]?.image;
if (!thumbnail || !isValidPayloadImage(thumbnail)) return;
return { count: gallery.length, thumbnail: convertImageToEndpointImage(thumbnail) };
};
const handleScans = (scans: Collectible["scans"]): EndpointCollectible["scans"] => {
const result =
scans?.pages?.flatMap(({ image }) => {
if (!isValidPayloadImage(image)) return [];
return image;
}) ?? [];
const totalCount =
Object.keys(scans?.cover ?? {}).length +
Object.keys(scans?.dustjacket ?? {}).length +
Object.keys(scans?.obi ?? {}).length +
result.length;
if (isValidPayloadImage(scans?.cover?.front)) {
result.push(scans.cover.front);
}
if (isValidPayloadImage(scans?.dustjacket?.front)) {
result.push(scans.dustjacket.front);
}
const thumbnail = result?.[0];
if (!thumbnail || !isValidPayloadImage(thumbnail)) return;
return { count: totalCount, thumbnail };
};
const handleContents = (contents: Collectible["contents"]): EndpointCollectible["contents"] => {
if (!contents) return [];
return contents.flatMap(({ content, range: rangeArray }) => {
const handleRange = (): EndpointCollectible["contents"][number]["range"] => {
const range = rangeArray?.[0];
switch (range?.blockType) {
case "other": {
const { translations, blockType } = range;
return {
type: blockType,
translations:
translations?.map(({ language, note }) => ({
language: isPayloadType(language) ? language.id : language,
note,
})) ?? [],
};
}
case "pageRange": {
const { blockType, end, start } = range;
return { type: blockType, end, start };
}
case "timeRange": {
const { blockType, end, start } = range;
return { type: blockType, end, start };
}
default:
return undefined;
}
};
const handleContent = (): EndpointCollectible["contents"][number]["content"] | undefined => {
switch (content.relationTo) {
case Collections.GenericContents:
return isPayloadType(content.value)
? {
relationTo: Collections.GenericContents,
value: {
translations: content.value.translations.map(({ language, name }) => ({
language: isPayloadType(language) ? language.id : language,
name,
})),
},
}
: undefined;
case Collections.Pages:
return isPayloadType(content.value) && isPublished(content.value)
? { relationTo: Collections.Pages, value: convertPageToEndpointPage(content.value) }
: undefined;
case Collections.Audios:
return isPayloadType(content.value) && isValidPayloadMedia(content.value)
? { relationTo: Collections.Audios, value: convertAudioToEndpointAudio(content.value) }
: undefined;
case Collections.Videos:
return isPayloadType(content.value) && isValidPayloadMedia(content.value)
? { relationTo: Collections.Videos, value: convertVideoToEndpointVideo(content.value) }
: undefined;
default:
return undefined;
}
};
const newContent = handleContent();
const range = handleRange();
if (!newContent) return [];
return [{ content: newContent, range }];
});
};