Removed preview types and added media to RTC, collectibles and folders
This commit is contained in:
parent
b15fe7a0ce
commit
40e54ea2a0
|
@ -5,6 +5,7 @@ import { tagsField } from "../../fields/tagsField/tagsField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
import { createEditor } from "../../utils/editor";
|
import { createEditor } from "../../utils/editor";
|
||||||
|
import { getByID } from "./endpoints/getByID";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
filename: "filename",
|
filename: "filename",
|
||||||
|
@ -38,6 +39,7 @@ export const Audios = buildCollectionConfig({
|
||||||
mimeTypes: ["audio/*"],
|
mimeTypes: ["audio/*"],
|
||||||
disableLocalStorage: true,
|
disableLocalStorage: true,
|
||||||
},
|
},
|
||||||
|
endpoints: [getByID],
|
||||||
fields: [
|
fields: [
|
||||||
rowField([
|
rowField([
|
||||||
{ name: fields.duration, type: "number", min: 0, required: true },
|
{ name: fields.duration, type: "number", min: 0, required: true },
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
import payload from "payload";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { EndpointAudio, PayloadMedia } from "../../../sdk";
|
||||||
|
import { Audio } from "../../../types/collections";
|
||||||
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
|
import { isNotEmpty, isValidPayloadImage, isValidPayloadMedia } from "../../../utils/asserts";
|
||||||
|
import {
|
||||||
|
convertRTCToEndpointRTC,
|
||||||
|
convertTagsEndpointTagsGroups,
|
||||||
|
getLanguageId,
|
||||||
|
} from "../../../utils/endpoints";
|
||||||
|
|
||||||
|
export const getByID: CollectionEndpoint = {
|
||||||
|
method: "get",
|
||||||
|
path: "/id/:id",
|
||||||
|
handler: async (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.status(403).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "You are not allowed to perform this action.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.params.id) {
|
||||||
|
return res.status(400).send({ errors: [{ message: "Missing 'id' query params" }] });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await payload.findByID({
|
||||||
|
collection: Collections.Audios,
|
||||||
|
id: req.params.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isValidPayloadMedia(result)) {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).json(convertAudioToEndpointAudio(result));
|
||||||
|
} catch {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertAudioToEndpointAudio = ({
|
||||||
|
url,
|
||||||
|
tags,
|
||||||
|
translations,
|
||||||
|
mimeType,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
duration,
|
||||||
|
id,
|
||||||
|
thumbnail,
|
||||||
|
}: Audio & PayloadMedia): EndpointAudio => ({
|
||||||
|
url,
|
||||||
|
tagGroups: convertTagsEndpointTagsGroups(tags),
|
||||||
|
createdAt,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
id,
|
||||||
|
mimeType,
|
||||||
|
updatedAt,
|
||||||
|
translations:
|
||||||
|
translations?.map(({ language, title, description }) => ({
|
||||||
|
language: getLanguageId(language),
|
||||||
|
title,
|
||||||
|
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
|
||||||
|
})) ?? [],
|
||||||
|
duration,
|
||||||
|
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
||||||
|
});
|
|
@ -4,9 +4,10 @@ import { EndpointChronologyEvent, EndpointSource } from "../../../sdk";
|
||||||
import { ChronologyEvent, CollectibleBlock } from "../../../types/collections";
|
import { ChronologyEvent, CollectibleBlock } from "../../../types/collections";
|
||||||
import { CollectionEndpoint } from "../../../types/payload";
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
import { isDefined, isNotEmpty, isPayloadArrayType, isPayloadType } from "../../../utils/asserts";
|
import { isDefined, isNotEmpty, isPayloadArrayType, isPayloadType } from "../../../utils/asserts";
|
||||||
import { getDomainFromUrl, handleRecorder } from "../../../utils/endpoints";
|
import { getDomainFromUrl } from "../../../utils/endpoints";
|
||||||
import { convertCollectibleToPreview } from "../../Collectibles/endpoints/getBySlugEndpoint";
|
import { convertCollectibleToEndpointCollectible } from "../../Collectibles/endpoints/getBySlugEndpoint";
|
||||||
import { convertPageToPreview } from "../../Pages/endpoints/getBySlugEndpoint";
|
import { convertPageToEndpointPage } from "../../Pages/endpoints/getBySlugEndpoint";
|
||||||
|
import { convertRecorderToEndpointRecorder } from "../../Recorders/endpoints/getByUsername";
|
||||||
|
|
||||||
export const getAllEndpoint: CollectionEndpoint = {
|
export const getAllEndpoint: CollectionEndpoint = {
|
||||||
method: "get",
|
method: "get",
|
||||||
|
@ -82,9 +83,15 @@ export const eventToEndpointEvent = ({
|
||||||
...(isNotEmpty(title) ? { title } : {}),
|
...(isNotEmpty(title) ? { title } : {}),
|
||||||
...(isNotEmpty(description) ? { description } : {}),
|
...(isNotEmpty(description) ? { description } : {}),
|
||||||
...(isNotEmpty(notes) ? { notes } : {}),
|
...(isNotEmpty(notes) ? { notes } : {}),
|
||||||
proofreaders: isPayloadArrayType(proofreaders) ? proofreaders.map(handleRecorder) : [],
|
proofreaders: isPayloadArrayType(proofreaders)
|
||||||
transcribers: isPayloadArrayType(transcribers) ? transcribers.map(handleRecorder) : [],
|
? proofreaders.map(convertRecorderToEndpointRecorder)
|
||||||
translators: isPayloadArrayType(translators) ? translators.map(handleRecorder) : [],
|
: [],
|
||||||
|
transcribers: isPayloadArrayType(transcribers)
|
||||||
|
? transcribers.map(convertRecorderToEndpointRecorder)
|
||||||
|
: [],
|
||||||
|
translators: isPayloadArrayType(translators)
|
||||||
|
? translators.map(convertRecorderToEndpointRecorder)
|
||||||
|
: [],
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
sources: handleSources(sources),
|
sources: handleSources(sources),
|
||||||
|
@ -100,7 +107,7 @@ const handleSources = (sources: ChronologyEvent["events"][number]["sources"]): E
|
||||||
if (!isPayloadType(source.collectible)) return [];
|
if (!isPayloadType(source.collectible)) return [];
|
||||||
return {
|
return {
|
||||||
type: "collectible",
|
type: "collectible",
|
||||||
collectible: convertCollectibleToPreview(source.collectible),
|
collectible: convertCollectibleToEndpointCollectible(source.collectible),
|
||||||
...(isDefined(range) ? { range } : {}),
|
...(isDefined(range) ? { range } : {}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,7 +115,7 @@ const handleSources = (sources: ChronologyEvent["events"][number]["sources"]): E
|
||||||
if (!isPayloadType(source.page)) return [];
|
if (!isPayloadType(source.page)) return [];
|
||||||
return {
|
return {
|
||||||
type: "page",
|
type: "page",
|
||||||
page: convertPageToPreview(source.page),
|
page: convertPageToEndpointPage(source.page),
|
||||||
};
|
};
|
||||||
|
|
||||||
case "urlBlock":
|
case "urlBlock":
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { CollectibleNature, Collections } from "../../../constants";
|
import { CollectibleNature, Collections } from "../../../constants";
|
||||||
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
|
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
|
||||||
import { EndpointCollectible, EndpointCollectiblePreview, PayloadImage } from "../../../sdk";
|
import { EndpointCollectible, PayloadImage } from "../../../sdk";
|
||||||
import { Collectible } from "../../../types/collections";
|
import { Collectible } from "../../../types/collections";
|
||||||
import {
|
import {
|
||||||
isDefined,
|
isDefined,
|
||||||
|
@ -9,52 +9,76 @@ import {
|
||||||
isPayloadType,
|
isPayloadType,
|
||||||
isPublished,
|
isPublished,
|
||||||
isValidPayloadImage,
|
isValidPayloadImage,
|
||||||
|
isValidPayloadMedia,
|
||||||
} from "../../../utils/asserts";
|
} from "../../../utils/asserts";
|
||||||
import { convertTagsToGroups, getDomainFromUrl, handleParentPages } from "../../../utils/endpoints";
|
import {
|
||||||
import { convertPageToPreview } from "../../Pages/endpoints/getBySlugEndpoint";
|
convertSourceToEndpointSource,
|
||||||
|
convertTagsEndpointTagsGroups,
|
||||||
|
getDomainFromUrl,
|
||||||
|
} from "../../../utils/endpoints";
|
||||||
|
import { convertAudioToEndpointAudio } from "../../Audios/endpoints/getByID";
|
||||||
|
import { convertPageToEndpointPage } from "../../Pages/endpoints/getBySlugEndpoint";
|
||||||
|
import { convertVideoToEndpointVideo } from "../../Videos/endpoints/getByID";
|
||||||
|
|
||||||
export const getBySlugEndpoint = createGetByEndpoint({
|
export const getBySlugEndpoint = createGetByEndpoint({
|
||||||
collection: Collections.Collectibles,
|
collection: Collections.Collectibles,
|
||||||
attribute: "slug",
|
attribute: "slug",
|
||||||
depth: 3,
|
depth: 3,
|
||||||
handler: (collectible: Collectible): EndpointCollectible => {
|
handler: (collectible) => convertCollectibleToEndpointCollectible(collectible),
|
||||||
const {
|
});
|
||||||
nature,
|
|
||||||
urls,
|
|
||||||
subitems,
|
|
||||||
gallery,
|
|
||||||
contents,
|
|
||||||
priceEnabled,
|
|
||||||
price,
|
|
||||||
size,
|
|
||||||
sizeEnabled,
|
|
||||||
weight,
|
|
||||||
weightEnabled,
|
|
||||||
pageInfo,
|
|
||||||
pageInfoEnabled,
|
|
||||||
parentItems,
|
|
||||||
folders,
|
|
||||||
backgroundImage,
|
|
||||||
} = collectible;
|
|
||||||
|
|
||||||
return {
|
export const convertCollectibleToEndpointCollectible = ({
|
||||||
...convertCollectibleToPreview(collectible),
|
nature,
|
||||||
...(isValidPayloadImage(backgroundImage) ? { backgroundImage } : {}),
|
urls,
|
||||||
contents: handleContents(contents),
|
subitems,
|
||||||
gallery: handleGallery(gallery),
|
gallery,
|
||||||
scans: handleScans(collectible.scans),
|
contents,
|
||||||
nature: nature === "Physical" ? CollectibleNature.Physical : CollectibleNature.Digital,
|
priceEnabled,
|
||||||
parentPages: handleParentPages({ collectibles: parentItems, folders }),
|
price,
|
||||||
subitems: isPayloadArrayType(subitems)
|
size,
|
||||||
? subitems.filter(isPublished).map(convertCollectibleToPreview)
|
sizeEnabled,
|
||||||
: [],
|
weight,
|
||||||
urls: urls?.map(({ url }) => ({ url, label: getDomainFromUrl(url) })) ?? [],
|
weightEnabled,
|
||||||
...(weightEnabled && isDefined(weight) ? { weight: weight.amount } : {}),
|
pageInfo,
|
||||||
...handleSize(size, sizeEnabled),
|
pageInfoEnabled,
|
||||||
...handlePageInfo(pageInfo, pageInfoEnabled),
|
parentItems,
|
||||||
...handlePrice(price, priceEnabled),
|
folders,
|
||||||
};
|
backgroundImage,
|
||||||
},
|
slug,
|
||||||
|
thumbnail,
|
||||||
|
translations,
|
||||||
|
releaseDate,
|
||||||
|
languages,
|
||||||
|
scans,
|
||||||
|
tags,
|
||||||
|
}: Collectible): EndpointCollectible => ({
|
||||||
|
slug,
|
||||||
|
languages: languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [],
|
||||||
|
...(isDefined(releaseDate) ? { releaseDate } : {}),
|
||||||
|
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
||||||
|
tagGroups: convertTagsEndpointTagsGroups(tags),
|
||||||
|
translations:
|
||||||
|
translations?.map(({ language, title, description, pretitle, subtitle }) => ({
|
||||||
|
language: isPayloadType(language) ? language.id : language,
|
||||||
|
title,
|
||||||
|
...(isNotEmpty(pretitle) ? { pretitle } : {}),
|
||||||
|
...(isNotEmpty(subtitle) ? { subtitle } : {}),
|
||||||
|
...(isNotEmpty(description) ? { description } : {}),
|
||||||
|
})) ?? [],
|
||||||
|
...(isValidPayloadImage(backgroundImage) ? { backgroundImage } : {}),
|
||||||
|
contents: handleContents(contents),
|
||||||
|
gallery: handleGallery(gallery),
|
||||||
|
scans: handleScans(scans),
|
||||||
|
nature: nature === "Physical" ? CollectibleNature.Physical : CollectibleNature.Digital,
|
||||||
|
parentPages: convertSourceToEndpointSource({ collectibles: parentItems, folders }),
|
||||||
|
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),
|
||||||
});
|
});
|
||||||
|
|
||||||
const handlePrice = (
|
const handlePrice = (
|
||||||
|
@ -173,10 +197,10 @@ const handleContents = (contents: Collectible["contents"]): EndpointCollectible[
|
||||||
|
|
||||||
const handleContent = (): EndpointCollectible["contents"][number]["content"] | undefined => {
|
const handleContent = (): EndpointCollectible["contents"][number]["content"] | undefined => {
|
||||||
switch (content.relationTo) {
|
switch (content.relationTo) {
|
||||||
case "generic-contents":
|
case Collections.GenericContents:
|
||||||
return isPayloadType(content.value)
|
return isPayloadType(content.value)
|
||||||
? {
|
? {
|
||||||
relationTo: "generic-contents",
|
relationTo: Collections.GenericContents,
|
||||||
value: {
|
value: {
|
||||||
translations: content.value.translations.map(({ language, name }) => ({
|
translations: content.value.translations.map(({ language, name }) => ({
|
||||||
language: isPayloadType(language) ? language.id : language,
|
language: isPayloadType(language) ? language.id : language,
|
||||||
|
@ -186,9 +210,19 @@ const handleContents = (contents: Collectible["contents"]): EndpointCollectible[
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
case "pages":
|
case Collections.Pages:
|
||||||
return isPayloadType(content.value) && isPublished(content.value)
|
return isPayloadType(content.value) && isPublished(content.value)
|
||||||
? { relationTo: "pages", value: convertPageToPreview(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;
|
: undefined;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -203,29 +237,3 @@ const handleContents = (contents: Collectible["contents"]): EndpointCollectible[
|
||||||
return [{ content: newContent, range }];
|
return [{ content: newContent, range }];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const convertCollectibleToPreview = ({
|
|
||||||
slug,
|
|
||||||
thumbnail,
|
|
||||||
translations,
|
|
||||||
releaseDate,
|
|
||||||
languages,
|
|
||||||
tags,
|
|
||||||
}: Collectible): EndpointCollectiblePreview => {
|
|
||||||
return {
|
|
||||||
slug,
|
|
||||||
languages:
|
|
||||||
languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [],
|
|
||||||
...(isDefined(releaseDate) ? { releaseDate } : {}),
|
|
||||||
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
|
||||||
tagGroups: convertTagsToGroups(tags),
|
|
||||||
translations:
|
|
||||||
translations?.map(({ language, title, description, pretitle, subtitle }) => ({
|
|
||||||
language: isPayloadType(language) ? language.id : language,
|
|
||||||
title,
|
|
||||||
...(isNotEmpty(pretitle) ? { pretitle } : {}),
|
|
||||||
...(isNotEmpty(subtitle) ? { subtitle } : {}),
|
|
||||||
...(isNotEmpty(description) ? { description } : {}),
|
|
||||||
})) ?? [],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,79 +1,95 @@
|
||||||
import { Collections } from "../../../constants";
|
import { Collections } from "../../../constants";
|
||||||
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
|
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
|
||||||
import { EndpointFolder, EndpointFolderPreview } from "../../../sdk";
|
import { EndpointFolder } from "../../../sdk";
|
||||||
import { Folder, Language } from "../../../types/collections";
|
import { Folder, Language } from "../../../types/collections";
|
||||||
import { isDefined, isNotEmpty, isPayloadType, isPublished } from "../../../utils/asserts";
|
import {
|
||||||
import { handleParentPages } from "../../../utils/endpoints";
|
isDefined,
|
||||||
import { convertCollectibleToPreview } from "../../Collectibles/endpoints/getBySlugEndpoint";
|
isNotEmpty,
|
||||||
import { convertPageToPreview } from "../../Pages/endpoints/getBySlugEndpoint";
|
isPayloadType,
|
||||||
|
isPublished,
|
||||||
|
isValidPayloadImage,
|
||||||
|
isValidPayloadMedia,
|
||||||
|
} from "../../../utils/asserts";
|
||||||
|
import { convertSourceToEndpointSource, getLanguageId } from "../../../utils/endpoints";
|
||||||
|
import { convertAudioToEndpointAudio } from "../../Audios/endpoints/getByID";
|
||||||
|
import { convertCollectibleToEndpointCollectible } from "../../Collectibles/endpoints/getBySlugEndpoint";
|
||||||
|
import { convertImageToEndpointImage } from "../../Images/endpoints/getByID";
|
||||||
|
import { convertPageToEndpointPage } from "../../Pages/endpoints/getBySlugEndpoint";
|
||||||
|
import { convertVideoToEndpointVideo } from "../../Videos/endpoints/getByID";
|
||||||
|
|
||||||
export const getBySlugEndpoint = createGetByEndpoint({
|
export const getBySlugEndpoint = createGetByEndpoint({
|
||||||
collection: Collections.Folders,
|
collection: Collections.Folders,
|
||||||
attribute: "slug",
|
attribute: "slug",
|
||||||
depth: 3,
|
depth: 3,
|
||||||
handler: (folder: Folder): EndpointFolder => {
|
handler: (folder) => convertFolderToEndpointFolder(folder),
|
||||||
const { sections, files, parentFolders } = folder;
|
|
||||||
return {
|
|
||||||
...convertFolderToPreview(folder),
|
|
||||||
sections:
|
|
||||||
sections?.length === 1
|
|
||||||
? {
|
|
||||||
type: "single",
|
|
||||||
subfolders:
|
|
||||||
sections[0]?.subfolders?.filter(isPayloadType).map(convertFolderToPreview) ?? [],
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
type: "multiple",
|
|
||||||
sections:
|
|
||||||
sections?.filter(isValidSection).map(({ translations, subfolders }) => ({
|
|
||||||
translations: translations.map(({ language, name }) => ({
|
|
||||||
language: getLanguageId(language),
|
|
||||||
name,
|
|
||||||
})),
|
|
||||||
subfolders: subfolders.map(convertFolderToPreview),
|
|
||||||
})) ?? [],
|
|
||||||
},
|
|
||||||
files:
|
|
||||||
files?.flatMap<EndpointFolder["files"][number]>(({ relationTo, value }) => {
|
|
||||||
if (!isPayloadType(value) || ("_status" in value && !isPublished(value))) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (relationTo) {
|
|
||||||
case "collectibles":
|
|
||||||
return [{ relationTo, value: convertCollectibleToPreview(value) }];
|
|
||||||
case "pages":
|
|
||||||
return [{ relationTo, value: convertPageToPreview(value) }];
|
|
||||||
// TODO: handle media type files
|
|
||||||
case "images":
|
|
||||||
return [];
|
|
||||||
case "audios":
|
|
||||||
return [];
|
|
||||||
case "videos":
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}) ?? [],
|
|
||||||
parentPages: handleParentPages({ folders: parentFolders }),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const convertFolderToPreview = ({
|
export const convertFolderToEndpointFolder = ({
|
||||||
slug,
|
slug,
|
||||||
translations,
|
|
||||||
icon,
|
icon,
|
||||||
}: Folder): EndpointFolderPreview => {
|
translations,
|
||||||
return {
|
sections,
|
||||||
slug,
|
files,
|
||||||
...(isDefined(icon) ? { icon } : {}),
|
parentFolders,
|
||||||
translations:
|
}: Folder): EndpointFolder => ({
|
||||||
translations?.map(({ language, name, description }) => ({
|
slug,
|
||||||
language: getLanguageId(language),
|
...(isDefined(icon) ? { icon } : {}),
|
||||||
name,
|
translations:
|
||||||
...(isNotEmpty(description) ? { description } : {}),
|
translations?.map(({ language, name, description }) => ({
|
||||||
})) ?? [],
|
language: getLanguageId(language),
|
||||||
};
|
name,
|
||||||
};
|
...(isNotEmpty(description) ? { description } : {}),
|
||||||
|
})) ?? [],
|
||||||
|
sections:
|
||||||
|
sections?.length === 1
|
||||||
|
? {
|
||||||
|
type: "single",
|
||||||
|
subfolders:
|
||||||
|
sections[0]?.subfolders?.filter(isPayloadType).map(convertFolderToEndpointFolder) ?? [],
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: "multiple",
|
||||||
|
sections:
|
||||||
|
sections?.filter(isValidSection).map(({ translations, subfolders }) => ({
|
||||||
|
translations: translations.map(({ language, name }) => ({
|
||||||
|
language: getLanguageId(language),
|
||||||
|
name,
|
||||||
|
})),
|
||||||
|
subfolders: subfolders.map(convertFolderToEndpointFolder),
|
||||||
|
})) ?? [],
|
||||||
|
},
|
||||||
|
files:
|
||||||
|
files?.flatMap<EndpointFolder["files"][number]>(({ relationTo, value }) => {
|
||||||
|
if (!isPayloadType(value) || ("_status" in value && !isPublished(value))) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (relationTo) {
|
||||||
|
case Collections.Collectibles:
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
relationTo: Collections.Collectibles,
|
||||||
|
value: convertCollectibleToEndpointCollectible(value),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
case Collections.Pages:
|
||||||
|
return [{ relationTo: Collections.Pages, value: convertPageToEndpointPage(value) }];
|
||||||
|
// TODO: handle media type files
|
||||||
|
case Collections.Images:
|
||||||
|
if (!isValidPayloadImage(value)) return [];
|
||||||
|
return [{ relationTo: Collections.Images, value: convertImageToEndpointImage(value) }];
|
||||||
|
case Collections.Audios:
|
||||||
|
if (!isValidPayloadMedia(value)) return [];
|
||||||
|
return [{ relationTo: Collections.Audios, value: convertAudioToEndpointAudio(value) }];
|
||||||
|
case Collections.Videos:
|
||||||
|
if (!isValidPayloadMedia(value)) return [];
|
||||||
|
return [{ relationTo: Collections.Videos, value: convertVideoToEndpointVideo(value) }];
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}) ?? [],
|
||||||
|
parentPages: convertSourceToEndpointSource({ folders: parentFolders }),
|
||||||
|
});
|
||||||
|
|
||||||
const isValidSection = (section: {
|
const isValidSection = (section: {
|
||||||
translations?:
|
translations?:
|
||||||
|
@ -100,6 +116,3 @@ const isValidSection = (section: {
|
||||||
}
|
}
|
||||||
return section.subfolders.every(isPayloadType);
|
return section.subfolders.every(isPayloadType);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLanguageId = (language: string | Language) =>
|
|
||||||
typeof language === "object" ? language.id : language;
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { tagsField } from "../../fields/tagsField/tagsField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { createEditor } from "../../utils/editor";
|
import { createEditor } from "../../utils/editor";
|
||||||
import { buildImageCollectionConfig } from "../../utils/imageCollectionConfig";
|
import { buildImageCollectionConfig } from "../../utils/imageCollectionConfig";
|
||||||
|
import { getByID } from "./endpoints/getByID";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
filename: "filename",
|
filename: "filename",
|
||||||
|
@ -36,6 +37,7 @@ export const Images = buildImageCollectionConfig({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
endpoints: [getByID],
|
||||||
fields: [
|
fields: [
|
||||||
translatedFields({
|
translatedFields({
|
||||||
name: fields.translations,
|
name: fields.translations,
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
import payload from "payload";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { EndpointImage, PayloadImage } from "../../../sdk";
|
||||||
|
import { Image } from "../../../types/collections";
|
||||||
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
|
import { isNotEmpty, isValidPayloadImage } from "../../../utils/asserts";
|
||||||
|
import {
|
||||||
|
convertRTCToEndpointRTC,
|
||||||
|
convertTagsEndpointTagsGroups,
|
||||||
|
getLanguageId,
|
||||||
|
} from "../../../utils/endpoints";
|
||||||
|
|
||||||
|
export const getByID: CollectionEndpoint = {
|
||||||
|
method: "get",
|
||||||
|
path: "/id/:id",
|
||||||
|
handler: async (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.status(403).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "You are not allowed to perform this action.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.params.id) {
|
||||||
|
return res.status(400).send({ errors: [{ message: "Missing 'id' query params" }] });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await payload.findByID({
|
||||||
|
collection: Collections.Images,
|
||||||
|
id: req.params.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isValidPayloadImage(result)) {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).json(convertImageToEndpointImage(result));
|
||||||
|
} catch {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertImageToEndpointImage = ({
|
||||||
|
url,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
tags,
|
||||||
|
translations,
|
||||||
|
mimeType,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
id,
|
||||||
|
}: Image & PayloadImage): EndpointImage => ({
|
||||||
|
url,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
tagGroups: convertTagsEndpointTagsGroups(tags),
|
||||||
|
createdAt,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
id,
|
||||||
|
mimeType,
|
||||||
|
updatedAt,
|
||||||
|
translations:
|
||||||
|
translations?.map(({ language, title, description }) => ({
|
||||||
|
language: getLanguageId(language),
|
||||||
|
title,
|
||||||
|
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
|
||||||
|
})) ?? [],
|
||||||
|
});
|
|
@ -2,15 +2,13 @@ import {
|
||||||
BreakBlockType,
|
BreakBlockType,
|
||||||
Collections,
|
Collections,
|
||||||
PageType,
|
PageType,
|
||||||
RichTextBreakBlock,
|
|
||||||
RichTextContent,
|
RichTextContent,
|
||||||
RichTextSectionBlock,
|
|
||||||
isBlockNodeBreakBlock,
|
isBlockNodeBreakBlock,
|
||||||
isBlockNodeSectionBlock,
|
isBlockNodeSectionBlock,
|
||||||
isNodeBlockNode,
|
isNodeBlockNode,
|
||||||
} from "../../../constants";
|
} from "../../../constants";
|
||||||
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
|
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
|
||||||
import { EndpointPage, EndpointPagePreview, TableOfContentEntry } from "../../../sdk";
|
import { EndpointPage, TableOfContentEntry } from "../../../sdk";
|
||||||
import { Page } from "../../../types/collections";
|
import { Page } from "../../../types/collections";
|
||||||
import {
|
import {
|
||||||
isNotEmpty,
|
isNotEmpty,
|
||||||
|
@ -18,85 +16,70 @@ import {
|
||||||
isPayloadType,
|
isPayloadType,
|
||||||
isValidPayloadImage,
|
isValidPayloadImage,
|
||||||
} from "../../../utils/asserts";
|
} from "../../../utils/asserts";
|
||||||
import { convertTagsToGroups, handleParentPages, handleRecorder } from "../../../utils/endpoints";
|
import {
|
||||||
|
convertRTCToEndpointRTC,
|
||||||
|
convertSourceToEndpointSource,
|
||||||
|
convertTagsEndpointTagsGroups,
|
||||||
|
} from "../../../utils/endpoints";
|
||||||
|
import { convertRecorderToEndpointRecorder } from "../../Recorders/endpoints/getByUsername";
|
||||||
|
|
||||||
export const getBySlugEndpoint = createGetByEndpoint({
|
export const getBySlugEndpoint = createGetByEndpoint({
|
||||||
collection: Collections.Pages,
|
collection: Collections.Pages,
|
||||||
attribute: "slug",
|
attribute: "slug",
|
||||||
handler: (page: Page): EndpointPage => {
|
handler: (page) => convertPageToEndpointPage(page),
|
||||||
const { translations, collectibles, folders, backgroundImage } = page;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...convertPageToPreview(page),
|
|
||||||
...(isValidPayloadImage(backgroundImage) ? { backgroundImage } : {}),
|
|
||||||
translations: translations.map(
|
|
||||||
({
|
|
||||||
content,
|
|
||||||
language,
|
|
||||||
sourceLanguage,
|
|
||||||
title,
|
|
||||||
pretitle,
|
|
||||||
subtitle,
|
|
||||||
proofreaders,
|
|
||||||
summary,
|
|
||||||
transcribers,
|
|
||||||
translators,
|
|
||||||
}) => ({
|
|
||||||
language: isPayloadType(language) ? language.id : language,
|
|
||||||
sourceLanguage: isPayloadType(sourceLanguage) ? sourceLanguage.id : sourceLanguage,
|
|
||||||
...(isNotEmpty(pretitle) ? { pretitle } : {}),
|
|
||||||
title,
|
|
||||||
...(isNotEmpty(subtitle) ? { subtitle } : {}),
|
|
||||||
...(isNotEmpty(summary) ? { summary } : {}),
|
|
||||||
content: handleContent(content),
|
|
||||||
toc: handleToc(content),
|
|
||||||
translators: isPayloadArrayType(translators) ? translators.map(handleRecorder) : [],
|
|
||||||
transcribers: isPayloadArrayType(transcribers) ? transcribers.map(handleRecorder) : [],
|
|
||||||
proofreaders: isPayloadArrayType(proofreaders) ? proofreaders.map(handleRecorder) : [],
|
|
||||||
})
|
|
||||||
),
|
|
||||||
parentPages: handleParentPages({ collectibles, folders }),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleContent = (
|
export const convertPageToEndpointPage = ({
|
||||||
{ root: { children, ...others } }: RichTextContent,
|
translations,
|
||||||
parentPrefix = ""
|
collectibles,
|
||||||
): RichTextContent => {
|
folders,
|
||||||
let index = 0;
|
backgroundImage,
|
||||||
return {
|
authors,
|
||||||
root: {
|
slug,
|
||||||
...others,
|
tags,
|
||||||
children: children.map((node) => {
|
thumbnail,
|
||||||
if (isNodeBlockNode(node)) {
|
type,
|
||||||
if (isBlockNodeSectionBlock(node)) {
|
}: Page): EndpointPage => ({
|
||||||
index++;
|
slug,
|
||||||
const anchorHash = `${parentPrefix}${index}.`;
|
type: type as PageType,
|
||||||
const newNode: RichTextSectionBlock = {
|
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
||||||
...node,
|
tagGroups: convertTagsEndpointTagsGroups(tags),
|
||||||
fields: {
|
authors: isPayloadArrayType(authors) ? authors.map(convertRecorderToEndpointRecorder) : [],
|
||||||
...node.fields,
|
...(isValidPayloadImage(backgroundImage) ? { backgroundImage } : {}),
|
||||||
content: handleContent(node.fields.content, anchorHash),
|
translations: translations.map(
|
||||||
},
|
({
|
||||||
anchorHash,
|
content,
|
||||||
};
|
language,
|
||||||
return newNode;
|
sourceLanguage,
|
||||||
} else if (isBlockNodeBreakBlock(node)) {
|
title,
|
||||||
index++;
|
pretitle,
|
||||||
const anchorHash = `${parentPrefix}${index}.`;
|
subtitle,
|
||||||
const newNode: RichTextBreakBlock = {
|
proofreaders,
|
||||||
...node,
|
summary,
|
||||||
anchorHash,
|
transcribers,
|
||||||
};
|
translators,
|
||||||
return newNode;
|
}) => ({
|
||||||
}
|
language: isPayloadType(language) ? language.id : language,
|
||||||
}
|
sourceLanguage: isPayloadType(sourceLanguage) ? sourceLanguage.id : sourceLanguage,
|
||||||
return node;
|
...(isNotEmpty(pretitle) ? { pretitle } : {}),
|
||||||
}),
|
title,
|
||||||
},
|
...(isNotEmpty(subtitle) ? { subtitle } : {}),
|
||||||
};
|
...(isNotEmpty(summary) ? { summary } : {}),
|
||||||
};
|
content: convertRTCToEndpointRTC(content),
|
||||||
|
toc: handleToc(content),
|
||||||
|
translators: isPayloadArrayType(translators)
|
||||||
|
? translators.map(convertRecorderToEndpointRecorder)
|
||||||
|
: [],
|
||||||
|
transcribers: isPayloadArrayType(transcribers)
|
||||||
|
? transcribers.map(convertRecorderToEndpointRecorder)
|
||||||
|
: [],
|
||||||
|
proofreaders: isPayloadArrayType(proofreaders)
|
||||||
|
? proofreaders.map(convertRecorderToEndpointRecorder)
|
||||||
|
: [],
|
||||||
|
})
|
||||||
|
),
|
||||||
|
parentPages: convertSourceToEndpointSource({ collectibles, folders }),
|
||||||
|
});
|
||||||
|
|
||||||
const handleToc = (content: RichTextContent, parentPrefix = ""): TableOfContentEntry[] => {
|
const handleToc = (content: RichTextContent, parentPrefix = ""): TableOfContentEntry[] => {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
@ -150,24 +133,3 @@ const handleToc = (content: RichTextContent, parentPrefix = ""): TableOfContentE
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const convertPageToPreview = ({
|
|
||||||
authors,
|
|
||||||
slug,
|
|
||||||
translations,
|
|
||||||
tags,
|
|
||||||
thumbnail,
|
|
||||||
type,
|
|
||||||
}: Page): EndpointPagePreview => ({
|
|
||||||
slug,
|
|
||||||
type: type as PageType,
|
|
||||||
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
|
||||||
tagGroups: convertTagsToGroups(tags),
|
|
||||||
translations: translations.map(({ language, title, pretitle, subtitle }) => ({
|
|
||||||
language: isPayloadType(language) ? language.id : language,
|
|
||||||
...(isNotEmpty(pretitle) ? { pretitle } : {}),
|
|
||||||
title,
|
|
||||||
...(isNotEmpty(subtitle) ? { subtitle } : {}),
|
|
||||||
})),
|
|
||||||
authors: isPayloadArrayType(authors) ? authors.map(handleRecorder) : [],
|
|
||||||
});
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { imageField } from "../../fields/imageField/imageField";
|
||||||
import { rowField } from "../../fields/rowField/rowField";
|
import { rowField } from "../../fields/rowField/rowField";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
import { getAllEndpoint } from "./endpoints/getAllEndpoint";
|
import { getAllEndpoint } from "./endpoints/getAllEndpoint";
|
||||||
|
import { getByUsernameEndpoint } from "./endpoints/getByUsername";
|
||||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||||
import { beforeLoginMustHaveAtLeastOneRole } from "./hooks/beforeLoginMustHaveAtLeastOneRole";
|
import { beforeLoginMustHaveAtLeastOneRole } from "./hooks/beforeLoginMustHaveAtLeastOneRole";
|
||||||
|
|
||||||
|
@ -74,7 +75,7 @@ export const Recorders = buildCollectionConfig({
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeLogin: [beforeLoginMustHaveAtLeastOneRole],
|
beforeLogin: [beforeLoginMustHaveAtLeastOneRole],
|
||||||
},
|
},
|
||||||
endpoints: [importFromStrapi, getAllEndpoint],
|
endpoints: [importFromStrapi, getAllEndpoint, getByUsernameEndpoint],
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
fields: [
|
fields: [
|
||||||
rowField([
|
rowField([
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint";
|
||||||
|
import { EndpointRecorder } from "../../../sdk";
|
||||||
|
import { Recorder } from "../../../types/collections";
|
||||||
|
import { isPayloadType, isValidPayloadImage } from "../../../utils/asserts";
|
||||||
|
|
||||||
|
export const getByUsernameEndpoint = createGetByEndpoint({
|
||||||
|
collection: Collections.Recorders,
|
||||||
|
attribute: "username",
|
||||||
|
handler: (recorder) => convertRecorderToEndpointRecorder(recorder),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const convertRecorderToEndpointRecorder = ({
|
||||||
|
id,
|
||||||
|
languages,
|
||||||
|
username,
|
||||||
|
avatar,
|
||||||
|
anonymize,
|
||||||
|
}: Recorder): EndpointRecorder => ({
|
||||||
|
id,
|
||||||
|
languages: languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [],
|
||||||
|
username: anonymize ? `Recorder#${id.substring(0, 5)}` : username,
|
||||||
|
...(isValidPayloadImage(avatar) ? { avatar } : {}),
|
||||||
|
});
|
|
@ -6,6 +6,7 @@ import { tagsField } from "../../fields/tagsField/tagsField";
|
||||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||||
import { createEditor } from "../../utils/editor";
|
import { createEditor } from "../../utils/editor";
|
||||||
|
import { getByID } from "./endpoints/getByID";
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
filename: "filename",
|
filename: "filename",
|
||||||
|
@ -47,13 +48,13 @@ export const Videos = buildCollectionConfig({
|
||||||
mimeTypes: ["video/*"],
|
mimeTypes: ["video/*"],
|
||||||
disableLocalStorage: true,
|
disableLocalStorage: true,
|
||||||
},
|
},
|
||||||
|
endpoints: [getByID],
|
||||||
fields: [
|
fields: [
|
||||||
rowField([
|
rowField([
|
||||||
{ name: fields.duration, type: "number", min: 0, required: true },
|
{ name: fields.duration, type: "number", min: 0, required: true },
|
||||||
imageField({
|
imageField({
|
||||||
name: fields.thumbnail,
|
name: fields.thumbnail,
|
||||||
relationTo: Collections.MediaThumbnails,
|
relationTo: Collections.MediaThumbnails,
|
||||||
required: true,
|
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
translatedFields({
|
translatedFields({
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
import payload from "payload";
|
||||||
|
import { Collections } from "../../../constants";
|
||||||
|
import { EndpointVideo, PayloadMedia } from "../../../sdk";
|
||||||
|
import { Video } from "../../../types/collections";
|
||||||
|
import { CollectionEndpoint } from "../../../types/payload";
|
||||||
|
import {
|
||||||
|
isDefined,
|
||||||
|
isEmpty,
|
||||||
|
isNotEmpty,
|
||||||
|
isPayloadType,
|
||||||
|
isUndefined,
|
||||||
|
isValidPayloadImage,
|
||||||
|
isValidPayloadMedia,
|
||||||
|
} from "../../../utils/asserts";
|
||||||
|
import {
|
||||||
|
convertRTCToEndpointRTC,
|
||||||
|
convertTagsEndpointTagsGroups,
|
||||||
|
getLanguageId,
|
||||||
|
} from "../../../utils/endpoints";
|
||||||
|
|
||||||
|
export const getByID: CollectionEndpoint = {
|
||||||
|
method: "get",
|
||||||
|
path: "/id/:id",
|
||||||
|
handler: async (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.status(403).send({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message: "You are not allowed to perform this action.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req.params.id) {
|
||||||
|
return res.status(400).send({ errors: [{ message: "Missing 'id' query params" }] });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await payload.findByID({
|
||||||
|
collection: Collections.Videos,
|
||||||
|
id: req.params.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isValidPayloadMedia(result)) {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).json(convertVideoToEndpointVideo(result));
|
||||||
|
} catch {
|
||||||
|
return res.sendStatus(404);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertVideoToEndpointVideo = ({
|
||||||
|
url,
|
||||||
|
tags,
|
||||||
|
translations,
|
||||||
|
mimeType,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
duration,
|
||||||
|
id,
|
||||||
|
thumbnail,
|
||||||
|
platform,
|
||||||
|
platformEnabled,
|
||||||
|
}: Video & PayloadMedia): EndpointVideo => ({
|
||||||
|
url,
|
||||||
|
tagGroups: convertTagsEndpointTagsGroups(tags),
|
||||||
|
createdAt,
|
||||||
|
filename,
|
||||||
|
filesize,
|
||||||
|
id,
|
||||||
|
mimeType,
|
||||||
|
updatedAt,
|
||||||
|
translations:
|
||||||
|
translations?.map(({ language, title, description }) => ({
|
||||||
|
language: getLanguageId(language),
|
||||||
|
title,
|
||||||
|
...(isNotEmpty(description) ? { description: convertRTCToEndpointRTC(description) } : {}),
|
||||||
|
})) ?? [],
|
||||||
|
|
||||||
|
duration,
|
||||||
|
...(isValidPayloadImage(thumbnail) ? { thumbnail } : {}),
|
||||||
|
...(platformEnabled && isDefined(platform) && isPayloadType(platform.channel)
|
||||||
|
? {
|
||||||
|
platform: {
|
||||||
|
channel: platform.channel,
|
||||||
|
publishedDate: platform.publishedDate,
|
||||||
|
url: platform.url,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
subtitles:
|
||||||
|
translations.flatMap(({ language, subfile }) => {
|
||||||
|
if (
|
||||||
|
isUndefined(subfile) ||
|
||||||
|
!isPayloadType(subfile) ||
|
||||||
|
isUndefined(subfile.url) ||
|
||||||
|
isEmpty(subfile.url)
|
||||||
|
)
|
||||||
|
return [];
|
||||||
|
return { language: getLanguageId(language), url: subfile.url };
|
||||||
|
}) ?? [],
|
||||||
|
});
|
|
@ -29,7 +29,7 @@ export const VideosChannels: CollectionConfig = buildCollectionConfig({
|
||||||
{ name: fields.url, type: "text", required: true, unique: true },
|
{ name: fields.url, type: "text", required: true, unique: true },
|
||||||
rowField([
|
rowField([
|
||||||
{ name: fields.title, type: "text", required: true },
|
{ name: fields.title, type: "text", required: true },
|
||||||
{ name: fields.subscribers, type: "number" },
|
{ name: fields.subscribers, type: "number", required: true },
|
||||||
]),
|
]),
|
||||||
backPropagationField({
|
backPropagationField({
|
||||||
name: fields.videos,
|
name: fields.videos,
|
||||||
|
|
|
@ -3,7 +3,7 @@ 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 { isPayloadType, isValidPayloadImage } from "../../../utils/asserts";
|
||||||
import { convertFolderToPreview } from "../../Folders/endpoints/getBySlugEndpoint";
|
import { convertFolderToEndpointFolder } from "../../Folders/endpoints/getBySlugEndpoint";
|
||||||
|
|
||||||
export const getConfigEndpoint: CollectionEndpoint = {
|
export const getConfigEndpoint: CollectionEndpoint = {
|
||||||
method: "get",
|
method: "get",
|
||||||
|
@ -46,7 +46,7 @@ export const getConfigEndpoint: CollectionEndpoint = {
|
||||||
homeFolders?.flatMap(({ folder, darkThumbnail, lightThumbnail }) => {
|
homeFolders?.flatMap(({ folder, darkThumbnail, lightThumbnail }) => {
|
||||||
if (!isPayloadType(folder)) return [];
|
if (!isPayloadType(folder)) return [];
|
||||||
return {
|
return {
|
||||||
...convertFolderToPreview(folder),
|
...convertFolderToEndpointFolder(folder),
|
||||||
...(isValidPayloadImage(darkThumbnail) ? { darkThumbnail } : {}),
|
...(isValidPayloadImage(darkThumbnail) ? { darkThumbnail } : {}),
|
||||||
...(isValidPayloadImage(lightThumbnail) ? { lightThumbnail } : {}),
|
...(isValidPayloadImage(lightThumbnail) ? { lightThumbnail } : {}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
import type {
|
import { EndpointAudio, EndpointImage, EndpointVideo } from "./sdk";
|
||||||
Audio,
|
import type { BreakBlock, SectionBlock, TranscriptBlock } from "./types/collections";
|
||||||
BreakBlock,
|
|
||||||
Image,
|
|
||||||
SectionBlock,
|
|
||||||
TranscriptBlock,
|
|
||||||
Video,
|
|
||||||
} from "./types/collections";
|
|
||||||
|
|
||||||
// END MOCKING SECTION
|
// END MOCKING SECTION
|
||||||
|
|
||||||
|
@ -149,17 +143,17 @@ export interface RichTextUploadNode extends RichTextNode {
|
||||||
|
|
||||||
export interface RichTextUploadImageNode extends RichTextUploadNode {
|
export interface RichTextUploadImageNode extends RichTextUploadNode {
|
||||||
relationTo: Collections.Images;
|
relationTo: Collections.Images;
|
||||||
value: Image;
|
value: EndpointImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RichTextUploadVideoNode extends RichTextUploadNode {
|
export interface RichTextUploadVideoNode extends RichTextUploadNode {
|
||||||
relationTo: Collections.Videos;
|
relationTo: Collections.Videos;
|
||||||
value: Video;
|
value: EndpointVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RichTextUploadAudioNode extends RichTextUploadNode {
|
export interface RichTextUploadAudioNode extends RichTextUploadNode {
|
||||||
relationTo: Collections.Audios;
|
relationTo: Collections.Audios;
|
||||||
value: Audio;
|
value: EndpointAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RichTextTextNode extends RichTextNode {
|
export interface RichTextTextNode extends RichTextNode {
|
||||||
|
|
|
@ -35,7 +35,7 @@ const configuredFtpAdapter = sftpAdapter({
|
||||||
privateKey: process.env.SFTP_PRIVATE_KEY,
|
privateKey: process.env.SFTP_PRIVATE_KEY,
|
||||||
},
|
},
|
||||||
destinationPathRoot: process.env.SFTP_DESTINATION_PATH_ROOT ?? "",
|
destinationPathRoot: process.env.SFTP_DESTINATION_PATH_ROOT ?? "",
|
||||||
publicEndpoint: process.env.FTP_BASE_URL ?? "",
|
publicEndpoint: process.env.SFTP_BASE_URL ?? "",
|
||||||
});
|
});
|
||||||
|
|
||||||
export default buildConfig({
|
export default buildConfig({
|
||||||
|
|
128
src/sdk.ts
128
src/sdk.ts
|
@ -96,7 +96,7 @@ const request = async (url: string, init?: RequestInit): Promise<Response> => {
|
||||||
|
|
||||||
// SDK and Types
|
// SDK and Types
|
||||||
|
|
||||||
export type EndpointFolderPreview = {
|
export type EndpointFolder = {
|
||||||
slug: string;
|
slug: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
translations: {
|
translations: {
|
||||||
|
@ -104,33 +104,42 @@ export type EndpointFolderPreview = {
|
||||||
name: string;
|
name: string;
|
||||||
description?: RichTextContent;
|
description?: RichTextContent;
|
||||||
}[];
|
}[];
|
||||||
};
|
|
||||||
|
|
||||||
export type EndpointFolder = EndpointFolderPreview & {
|
|
||||||
sections:
|
sections:
|
||||||
| { type: "single"; subfolders: EndpointFolderPreview[] }
|
| { type: "single"; subfolders: EndpointFolder[] }
|
||||||
| {
|
| {
|
||||||
type: "multiple";
|
type: "multiple";
|
||||||
sections: {
|
sections: {
|
||||||
translations: { language: string; name: string }[];
|
translations: { language: string; name: string }[];
|
||||||
subfolders: EndpointFolderPreview[];
|
subfolders: EndpointFolder[];
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
files: (
|
files: (
|
||||||
| {
|
| {
|
||||||
relationTo: "collectibles";
|
relationTo: Collections.Collectibles;
|
||||||
value: EndpointCollectiblePreview;
|
value: EndpointCollectible;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
relationTo: "pages";
|
relationTo: Collections.Pages;
|
||||||
value: EndpointPagePreview;
|
value: EndpointPage;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
relationTo: Collections.Images;
|
||||||
|
value: EndpointImage;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
relationTo: Collections.Audios;
|
||||||
|
value: EndpointAudio;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
relationTo: Collections.Videos;
|
||||||
|
value: EndpointVideo;
|
||||||
}
|
}
|
||||||
)[];
|
)[];
|
||||||
parentPages: EndpointSource[];
|
parentPages: EndpointSource[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointWebsiteConfig = {
|
export type EndpointWebsiteConfig = {
|
||||||
homeFolders: (EndpointFolderPreview & {
|
homeFolders: (EndpointFolder & {
|
||||||
lightThumbnail?: PayloadImage;
|
lightThumbnail?: PayloadImage;
|
||||||
darkThumbnail?: PayloadImage;
|
darkThumbnail?: PayloadImage;
|
||||||
})[];
|
})[];
|
||||||
|
@ -178,23 +187,18 @@ export type EndpointTagsGroup = {
|
||||||
tags: EndpointTag[];
|
tags: EndpointTag[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointPagePreview = {
|
export type EndpointPage = {
|
||||||
slug: string;
|
slug: string;
|
||||||
type: PageType;
|
type: PageType;
|
||||||
thumbnail?: PayloadImage;
|
thumbnail?: PayloadImage;
|
||||||
authors: EndpointRecorder[];
|
authors: EndpointRecorder[];
|
||||||
tagGroups: EndpointTagsGroup[];
|
tagGroups: EndpointTagsGroup[];
|
||||||
|
backgroundImage?: PayloadImage;
|
||||||
translations: {
|
translations: {
|
||||||
language: string;
|
language: string;
|
||||||
pretitle?: string;
|
pretitle?: string;
|
||||||
title: string;
|
title: string;
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
}[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EndpointPage = EndpointPagePreview & {
|
|
||||||
backgroundImage?: PayloadImage;
|
|
||||||
translations: (EndpointPagePreview["translations"][number] & {
|
|
||||||
sourceLanguage: string;
|
sourceLanguage: string;
|
||||||
summary?: RichTextContent;
|
summary?: RichTextContent;
|
||||||
content: RichTextContent;
|
content: RichTextContent;
|
||||||
|
@ -202,11 +206,11 @@ export type EndpointPage = EndpointPagePreview & {
|
||||||
translators: EndpointRecorder[];
|
translators: EndpointRecorder[];
|
||||||
proofreaders: EndpointRecorder[];
|
proofreaders: EndpointRecorder[];
|
||||||
toc: TableOfContentEntry[];
|
toc: TableOfContentEntry[];
|
||||||
})[];
|
}[];
|
||||||
parentPages: EndpointSource[];
|
parentPages: EndpointSource[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointCollectiblePreview = {
|
export type EndpointCollectible = {
|
||||||
slug: string;
|
slug: string;
|
||||||
thumbnail?: PayloadImage;
|
thumbnail?: PayloadImage;
|
||||||
translations: {
|
translations: {
|
||||||
|
@ -219,9 +223,6 @@ export type EndpointCollectiblePreview = {
|
||||||
tagGroups: EndpointTagsGroup[];
|
tagGroups: EndpointTagsGroup[];
|
||||||
releaseDate?: string;
|
releaseDate?: string;
|
||||||
languages: string[];
|
languages: string[];
|
||||||
};
|
|
||||||
|
|
||||||
export type EndpointCollectible = EndpointCollectiblePreview & {
|
|
||||||
backgroundImage?: PayloadImage;
|
backgroundImage?: PayloadImage;
|
||||||
nature: CollectibleNature;
|
nature: CollectibleNature;
|
||||||
gallery: PayloadImage[];
|
gallery: PayloadImage[];
|
||||||
|
@ -242,15 +243,23 @@ export type EndpointCollectible = EndpointCollectiblePreview & {
|
||||||
bindingType?: CollectibleBindingTypes;
|
bindingType?: CollectibleBindingTypes;
|
||||||
pageOrder?: CollectiblePageOrders;
|
pageOrder?: CollectiblePageOrders;
|
||||||
};
|
};
|
||||||
subitems: EndpointCollectiblePreview[];
|
subitems: EndpointCollectible[];
|
||||||
contents: {
|
contents: {
|
||||||
content:
|
content:
|
||||||
| {
|
| {
|
||||||
relationTo: "pages";
|
relationTo: Collections.Pages;
|
||||||
value: EndpointPagePreview;
|
value: EndpointPage;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
relationTo: "generic-contents";
|
relationTo: Collections.Audios;
|
||||||
|
value: EndpointAudio;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
relationTo: Collections.Videos;
|
||||||
|
value: EndpointVideo;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
relationTo: Collections.GenericContents;
|
||||||
value: {
|
value: {
|
||||||
translations: {
|
translations: {
|
||||||
language: string;
|
language: string;
|
||||||
|
@ -315,21 +324,72 @@ export type EndpointSource =
|
||||||
| { type: "url"; url: string; label: string }
|
| { type: "url"; url: string; label: string }
|
||||||
| {
|
| {
|
||||||
type: "collectible";
|
type: "collectible";
|
||||||
collectible: EndpointCollectiblePreview;
|
collectible: EndpointCollectible;
|
||||||
range?:
|
range?:
|
||||||
| { type: "page"; page: number }
|
| { type: "page"; page: number }
|
||||||
| { type: "timestamp"; timestamp: string }
|
| { type: "timestamp"; timestamp: string }
|
||||||
| { type: "custom"; translations: { language: string; note: string }[] };
|
| { type: "custom"; translations: { language: string; note: string }[] };
|
||||||
}
|
}
|
||||||
| { type: "page"; page: EndpointPagePreview }
|
| { type: "page"; page: EndpointPage }
|
||||||
| { type: "folder"; folder: EndpointFolderPreview };
|
| { type: "folder"; folder: EndpointFolder };
|
||||||
|
|
||||||
export type PayloadImage = {
|
export type EndpointMedia = {
|
||||||
|
id: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
filename: string;
|
||||||
|
mimeType: string;
|
||||||
|
filesize: number;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
tagGroups: EndpointTagsGroup[];
|
||||||
|
translations: {
|
||||||
|
language: string;
|
||||||
|
title: string;
|
||||||
|
description?: RichTextContent;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EndpointImage = EndpointMedia & {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EndpointAudio = EndpointMedia & {
|
||||||
|
thumbnail?: PayloadImage;
|
||||||
|
duration: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EndpointVideo = EndpointMedia & {
|
||||||
|
thumbnail?: PayloadImage;
|
||||||
|
subtitles: {
|
||||||
|
language: string;
|
||||||
|
url: string;
|
||||||
|
}[];
|
||||||
|
platform?: {
|
||||||
|
channel: {
|
||||||
|
url: string;
|
||||||
|
title: string;
|
||||||
|
subscribers: number;
|
||||||
|
};
|
||||||
|
views?: number;
|
||||||
|
likes?: number;
|
||||||
|
dislikes?: number;
|
||||||
|
url: string;
|
||||||
|
publishedDate: string;
|
||||||
|
};
|
||||||
|
duration: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PayloadMedia = {
|
||||||
|
url: string;
|
||||||
mimeType: string;
|
mimeType: string;
|
||||||
filename: string;
|
filename: string;
|
||||||
|
filesize: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PayloadImage = PayloadMedia & {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const payload = {
|
export const payload = {
|
||||||
|
@ -353,4 +413,10 @@ export const payload = {
|
||||||
await (await request(payloadApiUrl(Collections.ChronologyEvents, `all`))).json(),
|
await (await request(payloadApiUrl(Collections.ChronologyEvents, `all`))).json(),
|
||||||
getChronologyEventByID: async (id: string): Promise<EndpointChronologyEvent> =>
|
getChronologyEventByID: async (id: string): Promise<EndpointChronologyEvent> =>
|
||||||
await (await request(payloadApiUrl(Collections.ChronologyEvents, `id/${id}`))).json(),
|
await (await request(payloadApiUrl(Collections.ChronologyEvents, `id/${id}`))).json(),
|
||||||
|
getImageByID: async (id: string): Promise<EndpointImage> =>
|
||||||
|
await (await request(payloadApiUrl(Collections.Images, `id/${id}`))).json(),
|
||||||
|
getAudioByID: async (id: string): Promise<EndpointAudio> =>
|
||||||
|
await (await request(payloadApiUrl(Collections.Audios, `id/${id}`))).json(),
|
||||||
|
getVideoByID: async (id: string): Promise<EndpointVideo> =>
|
||||||
|
await (await request(payloadApiUrl(Collections.Videos, `id/${id}`))).json(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -603,7 +603,7 @@ export interface MediaThumbnail {
|
||||||
export interface Video {
|
export interface Video {
|
||||||
id: string;
|
id: string;
|
||||||
duration: number;
|
duration: number;
|
||||||
thumbnail: string | MediaThumbnail;
|
thumbnail?: string | MediaThumbnail | null;
|
||||||
translations: {
|
translations: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -665,7 +665,7 @@ export interface VideosChannel {
|
||||||
id: string;
|
id: string;
|
||||||
url: string;
|
url: string;
|
||||||
title: string;
|
title: string;
|
||||||
subscribers?: number | null;
|
subscribers: number;
|
||||||
videos?: (string | Video)[] | null;
|
videos?: (string | Video)[] | null;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { RichTextContent, isNodeParagraphNode } from "../constants";
|
import { RichTextContent, isNodeParagraphNode } from "../constants";
|
||||||
import { PayloadImage } from "../sdk";
|
import { PayloadImage, PayloadMedia } from "../sdk";
|
||||||
|
|
||||||
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;
|
||||||
|
@ -7,10 +7,11 @@ export const isDefined = <T>(value: T | null | undefined): value is T =>
|
||||||
export const isUndefined = <T>(value: T | null | undefined): value is null | undefined =>
|
export const isUndefined = <T>(value: T | null | undefined): value is null | undefined =>
|
||||||
!isDefined(value);
|
!isDefined(value);
|
||||||
|
|
||||||
export const isNotEmpty = (value: string | null | undefined | RichTextContent): value is string =>
|
export const isNotEmpty = (
|
||||||
!isEmpty(value);
|
value: string | null | undefined | RichTextContent
|
||||||
|
): value is string | RichTextContent => !isEmpty(value);
|
||||||
|
|
||||||
export const isEmpty = (value: string | null | undefined | RichTextContent): value is string =>
|
export const isEmpty = (value: string | null | undefined | RichTextContent): boolean =>
|
||||||
isUndefined(value) ||
|
isUndefined(value) ||
|
||||||
(typeof value === "string" && isEmptyString(value)) ||
|
(typeof value === "string" && isEmptyString(value)) ||
|
||||||
(typeof value === "object" && isEmptyRichText(value));
|
(typeof value === "object" && isEmptyRichText(value));
|
||||||
|
@ -26,6 +27,7 @@ export const isValidPayloadImage = (
|
||||||
image:
|
image:
|
||||||
| {
|
| {
|
||||||
filename?: string | null;
|
filename?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
mimeType?: string | null;
|
mimeType?: string | null;
|
||||||
width?: number | null;
|
width?: number | null;
|
||||||
height?: number | null;
|
height?: number | null;
|
||||||
|
@ -42,6 +44,28 @@ export const isValidPayloadImage = (
|
||||||
if (isEmpty(image.mimeType)) return false;
|
if (isEmpty(image.mimeType)) return false;
|
||||||
if (isUndefined(image.width)) return false;
|
if (isUndefined(image.width)) return false;
|
||||||
if (isUndefined(image.height)) return false;
|
if (isUndefined(image.height)) return false;
|
||||||
|
if (isUndefined(image.filesize)) return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isValidPayloadMedia = (
|
||||||
|
media:
|
||||||
|
| {
|
||||||
|
filename?: string | null;
|
||||||
|
filesize?: number | null;
|
||||||
|
mimeType?: string | null;
|
||||||
|
url?: string | null;
|
||||||
|
}
|
||||||
|
| 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;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,32 @@
|
||||||
import { convertCollectibleToPreview } from "../collections/Collectibles/endpoints/getBySlugEndpoint";
|
import { convertAudioToEndpointAudio } from "../collections/Audios/endpoints/getByID";
|
||||||
import { convertFolderToPreview } from "../collections/Folders/endpoints/getBySlugEndpoint";
|
import { convertCollectibleToEndpointCollectible } from "../collections/Collectibles/endpoints/getBySlugEndpoint";
|
||||||
import { EndpointRecorder, EndpointSource, EndpointTag, EndpointTagsGroup } from "../sdk";
|
import { convertFolderToEndpointFolder } from "../collections/Folders/endpoints/getBySlugEndpoint";
|
||||||
import { Collectible, Folder, Recorder, Tag } from "../types/collections";
|
import { convertImageToEndpointImage } from "../collections/Images/endpoints/getByID";
|
||||||
import { isPayloadArrayType, isPayloadType, isPublished, isValidPayloadImage } from "./asserts";
|
import { convertVideoToEndpointVideo } from "../collections/Videos/endpoints/getByID";
|
||||||
|
import {
|
||||||
|
RichTextBreakBlock,
|
||||||
|
RichTextContent,
|
||||||
|
RichTextSectionBlock,
|
||||||
|
RichTextUploadNode,
|
||||||
|
isBlockNodeBreakBlock,
|
||||||
|
isBlockNodeSectionBlock,
|
||||||
|
isNodeBlockNode,
|
||||||
|
isNodeUploadNode,
|
||||||
|
isUploadNodeAudioNode,
|
||||||
|
isUploadNodeImageNode,
|
||||||
|
isUploadNodeVideoNode,
|
||||||
|
} from "../constants";
|
||||||
|
import { EndpointSource, EndpointTag, EndpointTagsGroup } from "../sdk";
|
||||||
|
import { Audio, Collectible, Folder, Image, Language, Tag, Video } from "../types/collections";
|
||||||
|
import {
|
||||||
|
isPayloadArrayType,
|
||||||
|
isPayloadType,
|
||||||
|
isPublished,
|
||||||
|
isValidPayloadImage,
|
||||||
|
isValidPayloadMedia,
|
||||||
|
} from "./asserts";
|
||||||
|
|
||||||
export const convertTagsToGroups = (
|
export const convertTagsEndpointTagsGroups = (
|
||||||
tags: (string | Tag)[] | null | undefined
|
tags: (string | Tag)[] | null | undefined
|
||||||
): EndpointTagsGroup[] => {
|
): EndpointTagsGroup[] => {
|
||||||
if (!isPayloadArrayType(tags)) {
|
if (!isPayloadArrayType(tags)) {
|
||||||
|
@ -44,7 +66,75 @@ export const convertTagsToGroups = (
|
||||||
return groups;
|
return groups;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleParentPages = ({
|
export const convertRTCToEndpointRTC = (
|
||||||
|
{ root: { children, ...others } }: RichTextContent,
|
||||||
|
parentPrefix = ""
|
||||||
|
): RichTextContent => {
|
||||||
|
let index = 0;
|
||||||
|
return {
|
||||||
|
root: {
|
||||||
|
...others,
|
||||||
|
children: children.map((node) => {
|
||||||
|
if (isNodeBlockNode(node)) {
|
||||||
|
// Add anchor hash on section block (TOC)
|
||||||
|
if (isBlockNodeSectionBlock(node)) {
|
||||||
|
index++;
|
||||||
|
const anchorHash = `${parentPrefix}${index}.`;
|
||||||
|
const newNode: RichTextSectionBlock = {
|
||||||
|
...node,
|
||||||
|
fields: {
|
||||||
|
...node.fields,
|
||||||
|
content: convertRTCToEndpointRTC(node.fields.content, anchorHash),
|
||||||
|
},
|
||||||
|
anchorHash,
|
||||||
|
};
|
||||||
|
return newNode;
|
||||||
|
// Add anchor hash on section block (TOC)
|
||||||
|
} else if (isBlockNodeBreakBlock(node)) {
|
||||||
|
index++;
|
||||||
|
const anchorHash = `${parentPrefix}${index}.`;
|
||||||
|
const newNode: RichTextBreakBlock = {
|
||||||
|
...node,
|
||||||
|
anchorHash,
|
||||||
|
};
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
} else if (isNodeUploadNode(node)) {
|
||||||
|
const errorUploadNode: RichTextUploadNode = {
|
||||||
|
type: "upload",
|
||||||
|
relationTo: "error",
|
||||||
|
version: 1,
|
||||||
|
};
|
||||||
|
if (isUploadNodeImageNode(node)) {
|
||||||
|
const value = node.value as Image | string;
|
||||||
|
if (!isPayloadType(value) || !isValidPayloadImage(value)) return errorUploadNode;
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
value: convertImageToEndpointImage(value),
|
||||||
|
};
|
||||||
|
} else if (isUploadNodeAudioNode(node)) {
|
||||||
|
const value = node.value as Audio | string;
|
||||||
|
if (!isPayloadType(value) || !isValidPayloadMedia(value)) return errorUploadNode;
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
value: convertAudioToEndpointAudio(value),
|
||||||
|
};
|
||||||
|
} else if (isUploadNodeVideoNode(node)) {
|
||||||
|
const value = node.value as Video | string;
|
||||||
|
if (!isPayloadType(value) || !isValidPayloadMedia(value)) return errorUploadNode;
|
||||||
|
return {
|
||||||
|
...node,
|
||||||
|
value: convertVideoToEndpointVideo(value),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const convertSourceToEndpointSource = ({
|
||||||
collectibles,
|
collectibles,
|
||||||
folders,
|
folders,
|
||||||
}: {
|
}: {
|
||||||
|
@ -57,7 +147,7 @@ export const handleParentPages = ({
|
||||||
collectibles.filter(isPublished).forEach((collectible) => {
|
collectibles.filter(isPublished).forEach((collectible) => {
|
||||||
result.push({
|
result.push({
|
||||||
type: "collectible",
|
type: "collectible",
|
||||||
collectible: convertCollectibleToPreview(collectible),
|
collectible: convertCollectibleToEndpointCollectible(collectible),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -66,7 +156,7 @@ export const handleParentPages = ({
|
||||||
folders.forEach((folder) => {
|
folders.forEach((folder) => {
|
||||||
result.push({
|
result.push({
|
||||||
type: "folder",
|
type: "folder",
|
||||||
folder: convertFolderToPreview(folder),
|
folder: convertFolderToEndpointFolder(folder),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -74,19 +164,6 @@ export const handleParentPages = ({
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleRecorder = ({
|
|
||||||
id,
|
|
||||||
languages,
|
|
||||||
username,
|
|
||||||
avatar,
|
|
||||||
anonymize,
|
|
||||||
}: Recorder): EndpointRecorder => ({
|
|
||||||
id,
|
|
||||||
languages: languages?.map((language) => (isPayloadType(language) ? language.id : language)) ?? [],
|
|
||||||
username: anonymize ? `Recorder#${id.substring(0, 5)}` : username,
|
|
||||||
...(isValidPayloadImage(avatar) ? { avatar } : {}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const getDomainFromUrl = (url: string): string => {
|
export const getDomainFromUrl = (url: string): string => {
|
||||||
const urlObject = new URL(url);
|
const urlObject = new URL(url);
|
||||||
let domain = urlObject.hostname;
|
let domain = urlObject.hostname;
|
||||||
|
@ -95,3 +172,6 @@ export const getDomainFromUrl = (url: string): string => {
|
||||||
}
|
}
|
||||||
return domain;
|
return domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getLanguageId = (language: string | Language) =>
|
||||||
|
typeof language === "object" ? language.id : language;
|
||||||
|
|
Loading…
Reference in New Issue