Improve type gates

This commit is contained in:
DrMint 2024-05-23 13:24:21 +02:00
parent a4ad2d0f21
commit d5132e9e25
15 changed files with 138 additions and 190 deletions

View File

@ -3,7 +3,7 @@ import { Collections } from "../../../constants";
import { EndpointAudio, PayloadMedia } from "../../../sdk"; import { EndpointAudio, PayloadMedia } from "../../../sdk";
import { Audio } from "../../../types/collections"; import { Audio } from "../../../types/collections";
import { CollectionEndpoint } from "../../../types/payload"; import { CollectionEndpoint } from "../../../types/payload";
import { isNotEmpty, isValidPayloadImage, isValidPayloadMedia } from "../../../utils/asserts"; import { isAudio, isMediaThumbnail, isNotEmpty } from "../../../utils/asserts";
import { import {
convertAttributesToEndpointAttributes, convertAttributesToEndpointAttributes,
convertCreditsToEndpointCredits, convertCreditsToEndpointCredits,
@ -36,7 +36,7 @@ export const getByID: CollectionEndpoint = {
id: req.params.id, id: req.params.id,
}); });
if (!isValidPayloadMedia(result)) { if (!isAudio(result)) {
return res.sendStatus(404); return res.sendStatus(404);
} }
@ -78,7 +78,7 @@ export const convertAudioToEndpointAudio = ({
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}), ...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
})) ?? [], })) ?? [],
duration, duration,
...(isValidPayloadImage(thumbnail) ...(isMediaThumbnail(thumbnail)
? { thumbnail: convertMediaThumbnailToEndpointMediaThumbnail(thumbnail) } ? { thumbnail: convertMediaThumbnailToEndpointMediaThumbnail(thumbnail) }
: {}), : {}),
credits: convertCreditsToEndpointCredits(credits), credits: convertCreditsToEndpointCredits(credits),

View File

@ -3,13 +3,15 @@ import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
import { EndpointCollectible } from "../../../sdk"; import { EndpointCollectible } from "../../../sdk";
import { Collectible } from "../../../types/collections"; import { Collectible } from "../../../types/collections";
import { import {
isAudio,
isDefined, isDefined,
isImage,
isNotEmpty, isNotEmpty,
isPayloadArrayType, isPayloadArrayType,
isPayloadType, isPayloadType,
isPublished, isPublished,
isValidPayloadImage, isScan,
isValidPayloadMedia, isVideo,
} from "../../../utils/asserts"; } from "../../../utils/asserts";
import { import {
convertAttributesToEndpointAttributes, convertAttributesToEndpointAttributes,
@ -67,10 +69,8 @@ export const convertCollectibleToEndpointCollectible = ({
languages: languages:
languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [], languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [],
...(isDefined(releaseDate) ? { releaseDate } : {}), ...(isDefined(releaseDate) ? { releaseDate } : {}),
...(isValidPayloadImage(thumbnail) ...(isImage(thumbnail) ? { thumbnail: convertImageToEndpointImage(thumbnail) } : {}),
? { thumbnail: convertImageToEndpointImage(thumbnail) } ...(isImage(backgroundImage)
: {}),
...(isValidPayloadImage(backgroundImage)
? { backgroundImage: convertImageToEndpointImage(backgroundImage) } ? { backgroundImage: convertImageToEndpointImage(backgroundImage) }
: {}), : {}),
attributes: convertAttributesToEndpointAttributes(attributes), attributes: convertAttributesToEndpointAttributes(attributes),
@ -143,7 +143,7 @@ const handlePageInfo = (
const handleGallery = (gallery: Collectible["gallery"]): EndpointCollectible["gallery"] => { const handleGallery = (gallery: Collectible["gallery"]): EndpointCollectible["gallery"] => {
const thumbnail = gallery?.[0]?.image; const thumbnail = gallery?.[0]?.image;
if (!thumbnail || !isValidPayloadImage(thumbnail)) return; if (!thumbnail || !isImage(thumbnail)) return;
return { count: gallery.length, thumbnail: convertImageToEndpointImage(thumbnail) }; return { count: gallery.length, thumbnail: convertImageToEndpointImage(thumbnail) };
}; };
@ -158,20 +158,21 @@ const handleScans = (scans: Collectible["scans"]): EndpointCollectible["scans"]
const result = const result =
scans?.pages?.flatMap(({ image, page }) => { scans?.pages?.flatMap(({ image, page }) => {
if (!isValidPayloadImage(image)) return []; if (!isScan(image)) return [];
return { image, index: page.toString() }; return { image, index: page.toString() };
}) ?? []; }) ?? [];
if (isValidPayloadImage(scans?.cover?.front)) { if (isScan(scans?.cover?.front)) {
result.push({ image: scans.cover.front, index: "cover-front" }); result.push({ image: scans.cover.front, index: "cover-front" });
} }
if (isValidPayloadImage(scans?.dustjacket?.front)) { if (isScan(scans?.dustjacket?.front)) {
result.push({ image: scans.dustjacket.front, index: "dustjacket-front" }); result.push({ image: scans.dustjacket.front, index: "dustjacket-front" });
} }
const thumbnail = result?.[0]; const thumbnail = result?.[0];
if (!thumbnail || !isValidPayloadImage(thumbnail.image)) return; if (!thumbnail) return;
return { return {
count: totalCount, count: totalCount,
thumbnail: convertScanToEndpointScanImage(thumbnail.image, thumbnail.index), thumbnail: convertScanToEndpointScanImage(thumbnail.image, thumbnail.index),
@ -233,12 +234,12 @@ const handleContents = (contents: Collectible["contents"]): EndpointCollectible[
: undefined; : undefined;
case Collections.Audios: case Collections.Audios:
return isPayloadType(content.value) && isValidPayloadMedia(content.value) return isAudio(content.value)
? { relationTo: Collections.Audios, value: convertAudioToEndpointAudio(content.value) } ? { relationTo: Collections.Audios, value: convertAudioToEndpointAudio(content.value) }
: undefined; : undefined;
case Collections.Videos: case Collections.Videos:
return isPayloadType(content.value) && isValidPayloadMedia(content.value) return isVideo(content.value)
? { relationTo: Collections.Videos, value: convertVideoToEndpointVideo(content.value) } ? { relationTo: Collections.Videos, value: convertVideoToEndpointVideo(content.value) }
: undefined; : undefined;

View File

@ -1,7 +1,7 @@
import { Collections } from "../../../constants"; import { Collections } from "../../../constants";
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint"; import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
import { EndpointCollectibleGallery } from "../../../sdk"; import { EndpointCollectibleGallery } from "../../../sdk";
import { isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts"; import { isImage, isNotEmpty, isPayloadType } from "../../../utils/asserts";
import { convertSourceToEndpointSource } from "../../../utils/endpoints"; import { convertSourceToEndpointSource } from "../../../utils/endpoints";
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID"; import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
@ -22,12 +22,10 @@ export const getBySlugEndpointGallery = createGetByEndpoint({
...(isNotEmpty(subtitle) ? { subtitle } : {}), ...(isNotEmpty(subtitle) ? { subtitle } : {}),
...(isNotEmpty(description) ? { description } : {}), ...(isNotEmpty(description) ? { description } : {}),
})) ?? [], })) ?? [],
...(isValidPayloadImage(thumbnail) ...(isImage(thumbnail) ? { thumbnail: convertImageToEndpointImage(thumbnail) } : {}),
? { thumbnail: convertImageToEndpointImage(thumbnail) }
: {}),
images: images:
gallery?.flatMap(({ image }) => gallery?.flatMap(({ image }) =>
isValidPayloadImage(image) ? convertImageToEndpointImage(image) : [] isImage(image) ? convertImageToEndpointImage(image) : []
) ?? [], ) ?? [],
parentPages: convertSourceToEndpointSource({ collectibles: [collectible] }), parentPages: convertSourceToEndpointSource({ collectibles: [collectible] }),
}; };

View File

@ -3,7 +3,7 @@ import { Collections } from "../../../constants";
import { EndpointCollectibleGalleryImage } from "../../../sdk"; import { EndpointCollectibleGalleryImage } from "../../../sdk";
import { Collectible, Image } from "../../../types/collections"; import { Collectible, Image } from "../../../types/collections";
import { CollectionEndpoint } from "../../../types/payload"; import { CollectionEndpoint } from "../../../types/payload";
import { isDefined, isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts"; import { isDefined, isImage, isNotEmpty, isPayloadType } from "../../../utils/asserts";
import { convertSourceToEndpointSource } from "../../../utils/endpoints"; import { convertSourceToEndpointSource } from "../../../utils/endpoints";
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID"; import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
@ -43,7 +43,7 @@ export const getBySlugEndpointGalleryImage: CollectionEndpoint = {
const image = getImageFromIndex(index, collectible.gallery); const image = getImageFromIndex(index, collectible.gallery);
if (!image || !isValidPayloadImage(image)) { if (!isImage(image)) {
return res.sendStatus(404); return res.sendStatus(404);
} }
@ -54,7 +54,7 @@ export const getBySlugEndpointGalleryImage: CollectionEndpoint = {
image: convertImageToEndpointImage(image), image: convertImageToEndpointImage(image),
parentPages: convertSourceToEndpointSource({ gallery: [collectible] }), parentPages: convertSourceToEndpointSource({ gallery: [collectible] }),
slug, slug,
...(isValidPayloadImage(collectible.thumbnail) ...(isImage(collectible.thumbnail)
? { thumbnail: convertImageToEndpointImage(collectible.thumbnail) } ? { thumbnail: convertImageToEndpointImage(collectible.thumbnail) }
: {}), : {}),
translations: translations:

View File

@ -3,7 +3,7 @@ import { Collections } from "../../../constants";
import { EndpointCollectibleScanPage } from "../../../sdk"; import { EndpointCollectibleScanPage } from "../../../sdk";
import { Collectible, Scan } from "../../../types/collections"; import { Collectible, Scan } from "../../../types/collections";
import { CollectionEndpoint } from "../../../types/payload"; import { CollectionEndpoint } from "../../../types/payload";
import { isDefined, isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts"; import { isDefined, isImage, isNotEmpty, isPayloadType, isScan } from "../../../utils/asserts";
import { import {
convertScanToEndpointScanImage, convertScanToEndpointScanImage,
convertSourceToEndpointSource, convertSourceToEndpointSource,
@ -44,9 +44,9 @@ export const getBySlugEndpointScanPage: CollectionEndpoint = {
return res.sendStatus(404); return res.sendStatus(404);
} }
const image = getImageFromIndex(index, collectible.scans); const scan = getScanFromIndex(index, collectible.scans);
if (!image || !isValidPayloadImage(image)) { if (!isScan(scan)) {
return res.sendStatus(404); return res.sendStatus(404);
} }
@ -54,10 +54,10 @@ export const getBySlugEndpointScanPage: CollectionEndpoint = {
const nextIndex = getNextIndex(index, collectible.scans); const nextIndex = getNextIndex(index, collectible.scans);
const scanPage: EndpointCollectibleScanPage = { const scanPage: EndpointCollectibleScanPage = {
image: convertScanToEndpointScanImage(image, index), image: convertScanToEndpointScanImage(scan, index),
parentPages: convertSourceToEndpointSource({ scans: [collectible] }), parentPages: convertSourceToEndpointSource({ scans: [collectible] }),
slug, slug,
...(isValidPayloadImage(collectible.thumbnail) ...(isImage(collectible.thumbnail)
? { thumbnail: convertImageToEndpointImage(collectible.thumbnail) } ? { thumbnail: convertImageToEndpointImage(collectible.thumbnail) }
: {}), : {}),
translations: translations:
@ -102,7 +102,7 @@ const getNextIndex = (
return page.page.toString(); return page.page.toString();
}; };
const getImageFromIndex = ( const getScanFromIndex = (
index: string, index: string,
scans: NonNullable<Collectible["scans"]> scans: NonNullable<Collectible["scans"]>
): string | Scan | null | undefined => { ): string | Scan | null | undefined => {

View File

@ -2,7 +2,7 @@ import { Collections } from "../../../constants";
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint"; import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
import { EndpointCollectibleScans } from "../../../sdk"; import { EndpointCollectibleScans } from "../../../sdk";
import { Collectible } from "../../../types/collections"; import { Collectible } from "../../../types/collections";
import { isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts"; import { isImage, isNotEmpty, isPayloadType, isScan } from "../../../utils/asserts";
import { import {
convertCreditsToEndpointCredits, convertCreditsToEndpointCredits,
convertScanToEndpointScanImage, convertScanToEndpointScanImage,
@ -27,9 +27,7 @@ export const getBySlugEndpointScans = createGetByEndpoint({
...(isNotEmpty(subtitle) ? { subtitle } : {}), ...(isNotEmpty(subtitle) ? { subtitle } : {}),
...(isNotEmpty(description) ? { description } : {}), ...(isNotEmpty(description) ? { description } : {}),
})) ?? [], })) ?? [],
...(isValidPayloadImage(thumbnail) ...(isImage(thumbnail) ? { thumbnail: convertImageToEndpointImage(thumbnail) } : {}),
? { thumbnail: convertImageToEndpointImage(thumbnail) }
: {}),
...(scansEnabled && scans ? handleScans(scans) : { credits: [], pages: [] }), ...(scansEnabled && scans ? handleScans(scans) : { credits: [], pages: [] }),
parentPages: convertSourceToEndpointSource({ collectibles: [collectible] }), parentPages: convertSourceToEndpointSource({ collectibles: [collectible] }),
}; };
@ -52,7 +50,7 @@ const handleScans = ({
credits: convertCreditsToEndpointCredits(credits), credits: convertCreditsToEndpointCredits(credits),
pages: pages:
pages?.flatMap(({ image, page }) => pages?.flatMap(({ image, page }) =>
isValidPayloadImage(image) ? convertScanToEndpointScanImage(image, page.toString()) : [] isScan(image) ? convertScanToEndpointScanImage(image, page.toString()) : []
) ?? [], ) ?? [],
...(coverEnabled && cover ? { cover: handleCover(cover) } : {}), ...(coverEnabled && cover ? { cover: handleCover(cover) } : {}),
...(dustjacketEnabled && dustjacket ? { dustjacket: handleDustjacket(dustjacket) } : {}), ...(dustjacketEnabled && dustjacket ? { dustjacket: handleDustjacket(dustjacket) } : {}),
@ -70,35 +68,29 @@ const handleCover = ({
insideFront, insideFront,
spine, spine,
}: NonNullable<NonNullable<Collectible["scans"]>["cover"]>): EndpointCollectibleScans["cover"] => ({ }: NonNullable<NonNullable<Collectible["scans"]>["cover"]>): EndpointCollectibleScans["cover"] => ({
...(isValidPayloadImage(back) ...(isScan(back) ? { back: convertScanToEndpointScanImage(back, "cover-back") } : {}),
? { back: convertScanToEndpointScanImage(back, "cover-back") } ...(isScan(flapBack)
: {}),
...(isValidPayloadImage(flapBack)
? { flapBack: convertScanToEndpointScanImage(flapBack, "cover-flap-back") } ? { flapBack: convertScanToEndpointScanImage(flapBack, "cover-flap-back") }
: {}), : {}),
...(isValidPayloadImage(flapFront) ...(isScan(flapFront)
? { flapFront: convertScanToEndpointScanImage(flapFront, "cover-flap-front") } ? { flapFront: convertScanToEndpointScanImage(flapFront, "cover-flap-front") }
: {}), : {}),
...(isValidPayloadImage(front) ...(isScan(front) ? { front: convertScanToEndpointScanImage(front, "cover-front") } : {}),
? { front: convertScanToEndpointScanImage(front, "cover-front") } ...(isScan(insideBack)
: {}),
...(isValidPayloadImage(insideBack)
? { insideBack: convertScanToEndpointScanImage(insideBack, "cover-inside-back") } ? { insideBack: convertScanToEndpointScanImage(insideBack, "cover-inside-back") }
: {}), : {}),
...(isValidPayloadImage(insideFlapBack) ...(isScan(insideFlapBack)
? { insideFlapBack: convertScanToEndpointScanImage(insideFlapBack, "cover-inside-flap-back") } ? { insideFlapBack: convertScanToEndpointScanImage(insideFlapBack, "cover-inside-flap-back") }
: {}), : {}),
...(isValidPayloadImage(insideFlapFront) ...(isScan(insideFlapFront)
? { ? {
insideFlapFront: convertScanToEndpointScanImage(insideFlapFront, "cover-inside-flap-front"), insideFlapFront: convertScanToEndpointScanImage(insideFlapFront, "cover-inside-flap-front"),
} }
: {}), : {}),
...(isValidPayloadImage(insideFront) ...(isScan(insideFront)
? { insideFront: convertScanToEndpointScanImage(insideFront, "cover-inside-front") } ? { insideFront: convertScanToEndpointScanImage(insideFront, "cover-inside-front") }
: {}), : {}),
...(isValidPayloadImage(spine) ...(isScan(spine) ? { spine: convertScanToEndpointScanImage(spine, "cover-spine") } : {}),
? { spine: convertScanToEndpointScanImage(spine, "cover-spine") }
: {}),
}); });
const handleDustjacket = ({ const handleDustjacket = ({
@ -115,22 +107,18 @@ const handleDustjacket = ({
}: NonNullable< }: NonNullable<
NonNullable<Collectible["scans"]>["dustjacket"] NonNullable<Collectible["scans"]>["dustjacket"]
>): EndpointCollectibleScans["dustjacket"] => ({ >): EndpointCollectibleScans["dustjacket"] => ({
...(isValidPayloadImage(back) ...(isScan(back) ? { back: convertScanToEndpointScanImage(back, "dustjacket-back") } : {}),
? { back: convertScanToEndpointScanImage(back, "dustjacket-back") } ...(isScan(flapBack)
: {}),
...(isValidPayloadImage(flapBack)
? { flapBack: convertScanToEndpointScanImage(flapBack, "dustjacket-flap-back") } ? { flapBack: convertScanToEndpointScanImage(flapBack, "dustjacket-flap-back") }
: {}), : {}),
...(isValidPayloadImage(flapFront) ...(isScan(flapFront)
? { flapFront: convertScanToEndpointScanImage(flapFront, "dustjacket-flap-front") } ? { flapFront: convertScanToEndpointScanImage(flapFront, "dustjacket-flap-front") }
: {}), : {}),
...(isValidPayloadImage(front) ...(isScan(front) ? { front: convertScanToEndpointScanImage(front, "dustjacket-front") } : {}),
? { front: convertScanToEndpointScanImage(front, "dustjacket-front") } ...(isScan(insideBack)
: {}),
...(isValidPayloadImage(insideBack)
? { insideBack: convertScanToEndpointScanImage(insideBack, "dustjacket-inside-back") } ? { insideBack: convertScanToEndpointScanImage(insideBack, "dustjacket-inside-back") }
: {}), : {}),
...(isValidPayloadImage(insideFlapBack) ...(isScan(insideFlapBack)
? { ? {
insideFlapBack: convertScanToEndpointScanImage( insideFlapBack: convertScanToEndpointScanImage(
insideFlapBack, insideFlapBack,
@ -138,7 +126,7 @@ const handleDustjacket = ({
), ),
} }
: {}), : {}),
...(isValidPayloadImage(insideFlapFront) ...(isScan(insideFlapFront)
? { ? {
insideFlapFront: convertScanToEndpointScanImage( insideFlapFront: convertScanToEndpointScanImage(
insideFlapFront, insideFlapFront,
@ -146,13 +134,11 @@ const handleDustjacket = ({
), ),
} }
: {}), : {}),
...(isValidPayloadImage(insideFront) ...(isScan(insideFront)
? { insideFront: convertScanToEndpointScanImage(insideFront, "dustjacket-inside-front") } ? { insideFront: convertScanToEndpointScanImage(insideFront, "dustjacket-inside-front") }
: {}), : {}),
...(isValidPayloadImage(spine) ...(isScan(spine) ? { spine: convertScanToEndpointScanImage(spine, "dustjacket-spine") } : {}),
? { spine: convertScanToEndpointScanImage(spine, "dustjacket-spine") } ...(isScan(insideSpine)
: {}),
...(isValidPayloadImage(insideSpine)
? { insideSpine: convertScanToEndpointScanImage(insideSpine, "dustjacket-inside-spine") } ? { insideSpine: convertScanToEndpointScanImage(insideSpine, "dustjacket-inside-spine") }
: {}), : {}),
}); });
@ -169,32 +155,28 @@ const handleObi = ({
insideSpine, insideSpine,
spine, spine,
}: NonNullable<NonNullable<Collectible["scans"]>["obi"]>): EndpointCollectibleScans["obi"] => ({ }: NonNullable<NonNullable<Collectible["scans"]>["obi"]>): EndpointCollectibleScans["obi"] => ({
...(isValidPayloadImage(back) ? { back: convertScanToEndpointScanImage(back, "obi-back") } : {}), ...(isScan(back) ? { back: convertScanToEndpointScanImage(back, "obi-back") } : {}),
...(isValidPayloadImage(flapBack) ...(isScan(flapBack)
? { flapBack: convertScanToEndpointScanImage(flapBack, "obi-flap-back") } ? { flapBack: convertScanToEndpointScanImage(flapBack, "obi-flap-back") }
: {}), : {}),
...(isValidPayloadImage(flapFront) ...(isScan(flapFront)
? { flapFront: convertScanToEndpointScanImage(flapFront, "obi-flap-front") } ? { flapFront: convertScanToEndpointScanImage(flapFront, "obi-flap-front") }
: {}), : {}),
...(isValidPayloadImage(front) ...(isScan(front) ? { front: convertScanToEndpointScanImage(front, "obi-front") } : {}),
? { front: convertScanToEndpointScanImage(front, "obi-front") } ...(isScan(insideBack)
: {}),
...(isValidPayloadImage(insideBack)
? { insideBack: convertScanToEndpointScanImage(insideBack, "obi-inside-back") } ? { insideBack: convertScanToEndpointScanImage(insideBack, "obi-inside-back") }
: {}), : {}),
...(isValidPayloadImage(insideFlapBack) ...(isScan(insideFlapBack)
? { insideFlapBack: convertScanToEndpointScanImage(insideFlapBack, "obi-inside-flap-back") } ? { insideFlapBack: convertScanToEndpointScanImage(insideFlapBack, "obi-inside-flap-back") }
: {}), : {}),
...(isValidPayloadImage(insideFlapFront) ...(isScan(insideFlapFront)
? { insideFlapFront: convertScanToEndpointScanImage(insideFlapFront, "obi-inside-flap-front") } ? { insideFlapFront: convertScanToEndpointScanImage(insideFlapFront, "obi-inside-flap-front") }
: {}), : {}),
...(isValidPayloadImage(insideFront) ...(isScan(insideFront)
? { insideFront: convertScanToEndpointScanImage(insideFront, "obi-inside-front") } ? { insideFront: convertScanToEndpointScanImage(insideFront, "obi-inside-front") }
: {}), : {}),
...(isValidPayloadImage(spine) ...(isScan(spine) ? { spine: convertScanToEndpointScanImage(spine, "obi-spine") } : {}),
? { spine: convertScanToEndpointScanImage(spine, "obi-spine") } ...(isScan(insideSpine)
: {}),
...(isValidPayloadImage(insideSpine)
? { insideSpine: convertScanToEndpointScanImage(insideSpine, "obi-inside-spine") } ? { insideSpine: convertScanToEndpointScanImage(insideSpine, "obi-inside-spine") }
: {}), : {}),
}); });

View File

@ -3,12 +3,13 @@ import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
import { EndpointFolder } from "../../../sdk"; import { EndpointFolder } from "../../../sdk";
import { Folder, Language } from "../../../types/collections"; import { Folder, Language } from "../../../types/collections";
import { import {
isAudio,
isDefined, isDefined,
isImage,
isNotEmpty, isNotEmpty,
isPayloadType, isPayloadType,
isPublished, isPublished,
isValidPayloadImage, isVideo,
isValidPayloadMedia,
} from "../../../utils/asserts"; } from "../../../utils/asserts";
import { convertSourceToEndpointSource, getLanguageId } from "../../../utils/endpoints"; import { convertSourceToEndpointSource, getLanguageId } from "../../../utils/endpoints";
import { convertAudioToEndpointAudio } from "../../Audios/endpoints/getByID"; import { convertAudioToEndpointAudio } from "../../Audios/endpoints/getByID";
@ -76,13 +77,13 @@ export const convertFolderToEndpointFolder = ({
return [{ relationTo: Collections.Pages, value: convertPageToEndpointPage(value) }]; return [{ relationTo: Collections.Pages, value: convertPageToEndpointPage(value) }];
// TODO: handle media type files // TODO: handle media type files
case Collections.Images: case Collections.Images:
if (!isValidPayloadImage(value)) return []; if (!isImage(value)) return [];
return [{ relationTo: Collections.Images, value: convertImageToEndpointImage(value) }]; return [{ relationTo: Collections.Images, value: convertImageToEndpointImage(value) }];
case Collections.Audios: case Collections.Audios:
if (!isValidPayloadMedia(value)) return []; if (!isAudio(value)) return [];
return [{ relationTo: Collections.Audios, value: convertAudioToEndpointAudio(value) }]; return [{ relationTo: Collections.Audios, value: convertAudioToEndpointAudio(value) }];
case Collections.Videos: case Collections.Videos:
if (!isValidPayloadMedia(value)) return []; if (!isVideo(value)) return [];
return [{ relationTo: Collections.Videos, value: convertVideoToEndpointVideo(value) }]; return [{ relationTo: Collections.Videos, value: convertVideoToEndpointVideo(value) }];
default: default:
return []; return [];

View File

@ -3,12 +3,12 @@ import { Collections } from "../../../constants";
import { EndpointImage, PayloadImage } from "../../../sdk"; import { EndpointImage, PayloadImage } from "../../../sdk";
import { Image } from "../../../types/collections"; import { Image } from "../../../types/collections";
import { CollectionEndpoint } from "../../../types/payload"; import { CollectionEndpoint } from "../../../types/payload";
import { isNotEmpty, isValidPayloadImage } from "../../../utils/asserts"; import { isImage, isNotEmpty, isPayloadImage } from "../../../utils/asserts";
import { import {
convertAttributesToEndpointAttributes, convertAttributesToEndpointAttributes,
convertCreditsToEndpointCredits, convertCreditsToEndpointCredits,
convertRTCToEndpointRTC, convertRTCToEndpointRTC,
convertSizesToEndpointImageSize, convertSizesToPayloadImages,
getLanguageId, getLanguageId,
} from "../../../utils/endpoints"; } from "../../../utils/endpoints";
@ -36,7 +36,7 @@ export const getByID: CollectionEndpoint = {
id: req.params.id, id: req.params.id,
}); });
if (!isValidPayloadImage(result)) { if (!isImage(result)) {
return res.sendStatus(404); return res.sendStatus(404);
} }
@ -81,7 +81,7 @@ export const convertImageToEndpointImage = ({
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}), ...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
})) ?? [], })) ?? [],
credits: convertCreditsToEndpointCredits(credits), credits: convertCreditsToEndpointCredits(credits),
sizes: convertSizesToEndpointImageSize( sizes: convertSizesToPayloadImages(
[ [
sizes?.["200w"], sizes?.["200w"],
sizes?.["320w"], sizes?.["320w"],

View File

@ -9,7 +9,7 @@ import {
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint"; import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
import { EndpointPage, TableOfContentEntry } from "../../../sdk"; import { EndpointPage, TableOfContentEntry } from "../../../sdk";
import { Page } from "../../../types/collections"; import { Page } from "../../../types/collections";
import { isNotEmpty, isPayloadType, isValidPayloadImage } from "../../../utils/asserts"; import { isImage, isNotEmpty, isPayloadType } from "../../../utils/asserts";
import { import {
convertAttributesToEndpointAttributes, convertAttributesToEndpointAttributes,
convertCreditsToEndpointCredits, convertCreditsToEndpointCredits,
@ -38,8 +38,8 @@ export const convertPageToEndpointPage = ({
updatedBy, updatedBy,
}: Page): EndpointPage => ({ }: Page): EndpointPage => ({
slug, slug,
...(isValidPayloadImage(thumbnail) ? { thumbnail: convertImageToEndpointImage(thumbnail) } : {}), ...(isImage(thumbnail) ? { thumbnail: convertImageToEndpointImage(thumbnail) } : {}),
...(isValidPayloadImage(backgroundImage) ...(isImage(backgroundImage)
? { backgroundImage: convertImageToEndpointImage(backgroundImage) } ? { backgroundImage: convertImageToEndpointImage(backgroundImage) }
: {}), : {}),
attributes: convertAttributesToEndpointAttributes(attributes), attributes: convertAttributesToEndpointAttributes(attributes),

View File

@ -3,7 +3,7 @@ import { Collections } from "../../../constants";
import { EndpointRecorder } from "../../../sdk"; import { EndpointRecorder } from "../../../sdk";
import { Recorder } from "../../../types/collections"; import { Recorder } from "../../../types/collections";
import { CollectionEndpoint } from "../../../types/payload"; import { CollectionEndpoint } from "../../../types/payload";
import { isPayloadType, isValidPayloadImage } from "../../../utils/asserts"; import { isImage, isPayloadType } from "../../../utils/asserts";
import { convertRTCToEndpointRTC } from "../../../utils/endpoints"; import { convertRTCToEndpointRTC } from "../../../utils/endpoints";
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID"; import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
@ -49,7 +49,7 @@ export const convertRecorderToEndpointRecorder = ({
id, id,
languages: languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [], languages: languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [],
username: anonymize ? `Recorder#${id.substring(0, 5)}` : username, username: anonymize ? `Recorder#${id.substring(0, 5)}` : username,
...(isValidPayloadImage(avatar) ? { avatar: convertImageToEndpointImage(avatar) } : {}), ...(isImage(avatar) ? { avatar: convertImageToEndpointImage(avatar) } : {}),
translations: translations:
translations?.map(({ language, biography }) => ({ translations?.map(({ language, biography }) => ({
language: isPayloadType(language) ? language.id : language, language: isPayloadType(language) ? language.id : language,

View File

@ -6,11 +6,11 @@ import { CollectionEndpoint } from "../../../types/payload";
import { import {
isDefined, isDefined,
isEmpty, isEmpty,
isMediaThumbnail,
isNotEmpty, isNotEmpty,
isPayloadType, isPayloadType,
isUndefined, isUndefined,
isValidPayloadImage, isVideo,
isValidPayloadMedia,
} from "../../../utils/asserts"; } from "../../../utils/asserts";
import { import {
convertAttributesToEndpointAttributes, convertAttributesToEndpointAttributes,
@ -44,7 +44,7 @@ export const getByID: CollectionEndpoint = {
id: req.params.id, id: req.params.id,
}); });
if (!isValidPayloadMedia(result)) { if (!isVideo(result)) {
return res.sendStatus(404); return res.sendStatus(404);
} }
@ -89,7 +89,7 @@ export const convertVideoToEndpointVideo = ({
})) ?? [], })) ?? [],
duration, duration,
...(isValidPayloadImage(thumbnail) ...(isMediaThumbnail(thumbnail)
? { thumbnail: convertMediaThumbnailToEndpointMediaThumbnail(thumbnail) } ? { thumbnail: convertMediaThumbnailToEndpointMediaThumbnail(thumbnail) }
: {}), : {}),
...(platformEnabled && isDefined(platform) && isPayloadType(platform.channel) ...(platformEnabled && isDefined(platform) && isPayloadType(platform.channel)

View File

@ -2,7 +2,7 @@ import payload from "payload";
import { Collections } from "../../../constants"; import { Collections } from "../../../constants";
import { EndpointWebsiteConfig } from "../../../sdk"; import { EndpointWebsiteConfig } from "../../../sdk";
import { CollectionEndpoint } from "../../../types/payload"; import { CollectionEndpoint } from "../../../types/payload";
import { isPayloadType, isValidPayloadImage } from "../../../utils/asserts"; import { isImage, isPayloadType } from "../../../utils/asserts";
import { convertFolderToEndpointFolder } from "../../Folders/endpoints/getBySlugEndpoint"; import { convertFolderToEndpointFolder } from "../../Folders/endpoints/getBySlugEndpoint";
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID"; import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
@ -50,7 +50,7 @@ export const getConfigEndpoint: CollectionEndpoint = {
const endpointWebsiteConfig: EndpointWebsiteConfig = { const endpointWebsiteConfig: EndpointWebsiteConfig = {
home: { home: {
...(isValidPayloadImage(homeBackgroundImage) ...(isImage(homeBackgroundImage)
? { backgroundImage: convertImageToEndpointImage(homeBackgroundImage) } ? { backgroundImage: convertImageToEndpointImage(homeBackgroundImage) }
: {}), : {}),
folders: folders:
@ -58,17 +58,17 @@ export const getConfigEndpoint: CollectionEndpoint = {
if (!isPayloadType(folder)) return []; if (!isPayloadType(folder)) return [];
return { return {
...convertFolderToEndpointFolder(folder), ...convertFolderToEndpointFolder(folder),
...(isValidPayloadImage(darkThumbnail) ...(isImage(darkThumbnail)
? { darkThumbnail: convertImageToEndpointImage(darkThumbnail) } ? { darkThumbnail: convertImageToEndpointImage(darkThumbnail) }
: {}), : {}),
...(isValidPayloadImage(lightThumbnail) ...(isImage(lightThumbnail)
? { lightThumbnail: convertImageToEndpointImage(lightThumbnail) } ? { lightThumbnail: convertImageToEndpointImage(lightThumbnail) }
: {}), : {}),
}; };
}) ?? [], }) ?? [],
}, },
timeline: { timeline: {
...(isValidPayloadImage(timelineBackgroundImage) ...(isImage(timelineBackgroundImage)
? { backgroundImage: convertImageToEndpointImage(timelineBackgroundImage) } ? { backgroundImage: convertImageToEndpointImage(timelineBackgroundImage) }
: {}), : {}),
breaks: timeline?.breaks ?? [], breaks: timeline?.breaks ?? [],
@ -83,7 +83,7 @@ export const getConfigEndpoint: CollectionEndpoint = {
}; };
}) ?? [], }) ?? [],
}, },
...(isValidPayloadImage(defaultOpenGraphImage) ...(isImage(defaultOpenGraphImage)
? { defaultOpenGraphImage: convertImageToEndpointImage(defaultOpenGraphImage) } ? { defaultOpenGraphImage: convertImageToEndpointImage(defaultOpenGraphImage) }
: {}), : {}),
}; };

View File

@ -346,7 +346,7 @@ export type EndpointCollectibleScanPage = {
export type EndpointScanImage = PayloadImage & { export type EndpointScanImage = PayloadImage & {
index: string; index: string;
sizes: EndpointImageSize[]; sizes: PayloadImage[];
}; };
export type TableOfContentEntry = { export type TableOfContentEntry = {
@ -411,17 +411,10 @@ export type EndpointMedia = {
credits: EndpointCredit[]; credits: EndpointCredit[];
}; };
export type EndpointImageSize = {
width: number;
height: number;
url: string;
wSize: number;
};
export type EndpointImage = EndpointMedia & { export type EndpointImage = EndpointMedia & {
width: number; width: number;
height: number; height: number;
sizes: EndpointImageSize[]; sizes: PayloadImage[];
}; };
export type EndpointAudio = EndpointMedia & { export type EndpointAudio = EndpointMedia & {
@ -451,7 +444,7 @@ export type EndpointVideo = EndpointMedia & {
}; };
export type EndpointMediaThumbnail = PayloadImage & { export type EndpointMediaThumbnail = PayloadImage & {
sizes: EndpointImageSize[]; sizes: PayloadImage[];
}; };
export type PayloadMedia = { export type PayloadMedia = {

View File

@ -1,6 +1,6 @@
import { RichTextContent, isNodeParagraphNode } from "../constants"; import { RichTextContent, isNodeParagraphNode } from "../constants";
import { PayloadImage, PayloadMedia } from "../sdk"; import { PayloadImage, PayloadMedia } from "../sdk";
import { Image } from "../types/collections"; import { Audio, Image, MediaThumbnail, Scan, Video } from "../types/collections";
export const isDefined = <T>(value: T | null | undefined): value is T => export const isDefined = <T>(value: T | null | undefined): value is T =>
value !== null && value !== undefined; value !== null && value !== undefined;
@ -24,32 +24,6 @@ const isEmptyRichText = (value: RichTextContent) =>
export const hasDuplicates = <T>(list: T[]): boolean => list.length !== new Set(list).size; export const hasDuplicates = <T>(list: T[]): boolean => list.length !== new Set(list).size;
export const isValidPayloadImage = (
image: string | Image | null | undefined
): image is Image & PayloadImage => {
if (typeof image === "string") return false;
if (!isValidPayloadMedia(image)) return false;
if (isUndefined(image.width)) return false;
if (isUndefined(image.height)) return false;
return true;
};
export const isValidPayloadMedia = (
media:
| Partial<{ [K in keyof PayloadMedia]: null | undefined | PayloadMedia[K] }>
| undefined
| null
| string
): media is PayloadMedia => {
if (isUndefined(media)) return false;
if (typeof media === "string") return false;
if (isEmpty(media.filename)) return false;
if (isEmpty(media.url)) return false;
if (isEmpty(media.mimeType)) return false;
if (isUndefined(media.filesize)) return false;
return true;
};
export const isPayloadType = <T extends Object>(value: string | T): value is T => export const isPayloadType = <T extends Object>(value: string | T): value is T =>
typeof value === "object"; typeof value === "object";
@ -61,31 +35,35 @@ export const isPublished = <T extends { _status?: ("draft" | "published") | null
object: T object: T
): boolean => object._status === "published"; ): boolean => object._status === "published";
export type ImageSize = { export const isImage = (image: string | Image | null | undefined): image is PayloadImage & Image =>
url?: string | null; isPayloadImage(image);
width?: number | null;
height?: number | null;
mimeType?: string | null;
filesize?: number | null;
filename?: string | null;
};
export type ValidImageSize = { export const isScan = (image: string | Scan | null | undefined): image is PayloadImage & Scan =>
url: string; isPayloadImage(image);
width: number;
height: number;
mimeType: string;
filesize: number;
filename: string;
};
export const isValidImageSize = (size: ImageSize | undefined): size is ValidImageSize => { export const isMediaThumbnail = (
if (isUndefined(size)) return false; image: string | MediaThumbnail | null | undefined
if (isUndefined(size.url)) return false; ): image is PayloadImage & MediaThumbnail => isPayloadImage(image);
if (isUndefined(size.width)) return false;
if (isUndefined(size.height)) return false; export const isPayloadImage = (image: unknown): image is PayloadImage => {
if (isUndefined(size.mimeType)) return false; if (!isPayloadMedia(image)) return false;
if (isUndefined(size.filesize)) return false; if (!("width" in image) || typeof image.width !== "number") return false;
if (isUndefined(size.filename)) return false; if (!("height" in image) || typeof image.height !== "number") return false;
return true;
};
export const isVideo = (video: string | Video | null | undefined): video is PayloadMedia & Video =>
isPayloadMedia(video);
export const isAudio = (video: string | Audio | null | undefined): video is PayloadMedia & Audio =>
isPayloadMedia(video);
const isPayloadMedia = (media: unknown): media is PayloadMedia => {
if (typeof media !== "object") return false;
if (isUndefined(media)) return false;
if (!("url" in media) || typeof media.url !== "string") return false;
if (!("mimeType" in media) || typeof media.mimeType !== "string") return false;
if (!("filename" in media) || typeof media.filename !== "string") return false;
if (!("filesize" in media) || typeof media.filesize !== "number") return false;
return true; return true;
}; };

View File

@ -22,7 +22,6 @@ import {
import { import {
EndpointAttribute, EndpointAttribute,
EndpointCredit, EndpointCredit,
EndpointImageSize,
EndpointMediaThumbnail, EndpointMediaThumbnail,
EndpointRole, EndpointRole,
EndpointScanImage, EndpointScanImage,
@ -47,16 +46,15 @@ import {
Video, Video,
} from "../types/collections"; } from "../types/collections";
import { import {
ImageSize, isAudio,
ValidImageSize,
isDefined, isDefined,
isEmpty, isEmpty,
isImage,
isPayloadArrayType, isPayloadArrayType,
isPayloadImage,
isPayloadType, isPayloadType,
isPublished, isPublished,
isValidImageSize, isVideo,
isValidPayloadImage,
isValidPayloadMedia,
} from "./asserts"; } from "./asserts";
const convertTagToEndpointTag = ({ slug, page, translations }: Tag): EndpointTag => ({ const convertTagToEndpointTag = ({ slug, page, translations }: Tag): EndpointTag => ({
@ -109,21 +107,21 @@ export const convertRTCToEndpointRTC = (
}; };
if (isUploadNodeImageNode(node)) { if (isUploadNodeImageNode(node)) {
const value = node.value as unknown as Image | string; const value = node.value as unknown as Image | string;
if (!isPayloadType(value) || !isValidPayloadImage(value)) return errorUploadNode; if (!isImage(value)) return errorUploadNode;
return { return {
...node, ...node,
value: convertImageToEndpointImage(value), value: convertImageToEndpointImage(value),
}; };
} else if (isUploadNodeAudioNode(node)) { } else if (isUploadNodeAudioNode(node)) {
const value = node.value as unknown as Audio | string; const value = node.value as unknown as Audio | string;
if (!isPayloadType(value) || !isValidPayloadMedia(value)) return errorUploadNode; if (!isAudio(value)) return errorUploadNode;
return { return {
...node, ...node,
value: convertAudioToEndpointAudio(value), value: convertAudioToEndpointAudio(value),
}; };
} else if (isUploadNodeVideoNode(node)) { } else if (isUploadNodeVideoNode(node)) {
const value = node.value as unknown as Video | string; const value = node.value as unknown as Video | string;
if (!isPayloadType(value) || !isValidPayloadMedia(value)) return errorUploadNode; if (!isVideo(value)) return errorUploadNode;
return { return {
...node, ...node,
value: convertVideoToEndpointVideo(value), value: convertVideoToEndpointVideo(value),
@ -282,14 +280,16 @@ const convertAttributeToEndpointAttribute = (
} }
}; };
export const convertSizesToEndpointImageSize = ( type Nullable<T> = { [P in keyof T]?: T[P] | undefined | null };
sizes: (ImageSize | undefined)[],
targetSizes: number[]
): EndpointImageSize[] => {
if (!sizes) return [];
const processedSizes = sizes.filter(isValidImageSize);
const targetBins: { min: number; target: number; max: number; image: ValidImageSize }[] = []; export const convertSizesToPayloadImages = (
sizes: (Nullable<PayloadImage> | undefined)[],
targetSizes: number[]
): PayloadImage[] => {
if (!sizes) return [];
const processedSizes = sizes.filter(isPayloadImage);
const images: PayloadImage[] = [];
for (let index = 0; index < targetSizes.length; index++) { for (let index = 0; index < targetSizes.length; index++) {
const previous = targetSizes[index - 1]; const previous = targetSizes[index - 1];
const current = targetSizes[index]!; const current = targetSizes[index]!;
@ -305,15 +305,10 @@ export const convertSizesToEndpointImageSize = (
const smallestImage = images[0]; const smallestImage = images[0];
if (!smallestImage) continue; if (!smallestImage) continue;
targetBins.push({ min, target: current, max, image: smallestImage }); images.push(smallestImage);
} }
return targetBins.map(({ target, image: { height, width, url } }) => ({ return images;
width,
height,
url,
wSize: target,
}));
}; };
export const convertScanToEndpointScanImage = ( export const convertScanToEndpointScanImage = (
@ -327,7 +322,7 @@ export const convertScanToEndpointScanImage = (
filename, filename,
filesize, filesize,
mimeType, mimeType,
sizes: convertSizesToEndpointImageSize( sizes: convertSizesToPayloadImages(
[ [
sizes?.["200w"], sizes?.["200w"],
sizes?.["320w"], sizes?.["320w"],
@ -354,7 +349,7 @@ export const convertMediaThumbnailToEndpointMediaThumbnail = ({
filename, filename,
filesize, filesize,
mimeType, mimeType,
sizes: convertSizesToEndpointImageSize( sizes: convertSizesToPayloadImages(
[ [
sizes?.["200w"], sizes?.["200w"],
sizes?.["320w"], sizes?.["320w"],