From bd13e005e0227bac9ffbfb231e7d718da7427ed7 Mon Sep 17 00:00:00 2001 From: DrMint <29893320+DrMint@users.noreply.github.com> Date: Wed, 13 Mar 2024 03:15:14 +0100 Subject: [PATCH] Fix typescript errors --- docker-compose.yml | 4 +- .../endpoints/getAllEndpoint.ts | 110 ++++------ .../endpoints/importFromStrapi.ts | 5 +- .../validateEventsTranslationsDescription.ts | 2 +- .../validateEventsTranslationsTitle.ts | 2 +- .../Recorders/endpoints/importFromStrapi.ts | 9 - src/collections/Tags/Tags.ts | 2 - .../Tags/endpoints/getAllEndpoint.ts | 41 ---- src/collections/TagsGroups/TagsGroups.ts | 2 - .../TagsGroups/endpoints/getAllEndpoint.ts | 42 ---- src/collections/Weapons/Weapons.ts | 130 ------------ .../Weapons/components/AppearanceRowLabel.tsx | 36 ---- .../Weapons/endpoints/getBySlugEndpoint.ts | 155 -------------- .../Weapons/endpoints/importFromStrapi.ts | 115 ---------- .../WeaponsGroups/WeaponsGroups.ts | 39 ---- .../WeaponsThumbnails/WeaponsThumbnails.ts | 64 ------ src/constants.ts | 9 +- .../createImageRegenerationEndpoint.ts | 72 ------- src/endpoints/createStrapiImportEndpoint.ts | 3 +- src/fields/rowField/rowField.ts | 2 +- src/payload.config.ts | 6 - src/sdk.ts | 64 +----- src/types/collections.ts | 200 +++--------------- src/utils/imageCollectionConfig.ts | 2 - 24 files changed, 96 insertions(+), 1020 deletions(-) delete mode 100644 src/collections/Tags/endpoints/getAllEndpoint.ts delete mode 100644 src/collections/TagsGroups/endpoints/getAllEndpoint.ts delete mode 100644 src/collections/Weapons/Weapons.ts delete mode 100644 src/collections/Weapons/components/AppearanceRowLabel.tsx delete mode 100644 src/collections/Weapons/endpoints/getBySlugEndpoint.ts delete mode 100644 src/collections/Weapons/endpoints/importFromStrapi.ts delete mode 100644 src/collections/WeaponsGroups/WeaponsGroups.ts delete mode 100644 src/collections/WeaponsThumbnails/WeaponsThumbnails.ts delete mode 100644 src/endpoints/createImageRegenerationEndpoint.ts diff --git a/docker-compose.yml b/docker-compose.yml index 54b2e12..b3e41f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,8 @@ services: - .:/home/node/app - node_modules:/home/node/app/node_modules working_dir: /home/node/app/ - command: sh -c "npm install && npm run generate:types && npm run dev" - # command: sh -c "npm install && npm run generate:types && npm run build:payload && npm run serve" + # command: sh -c "npm install && npm run generate:types && npm run dev" + command: sh -c "npm install && npm run generate:types && npm run build && npm run serve" depends_on: - mongo environment: diff --git a/src/collections/ChronologyEras/endpoints/getAllEndpoint.ts b/src/collections/ChronologyEras/endpoints/getAllEndpoint.ts index da8cf5d..2834811 100644 --- a/src/collections/ChronologyEras/endpoints/getAllEndpoint.ts +++ b/src/collections/ChronologyEras/endpoints/getAllEndpoint.ts @@ -1,15 +1,10 @@ import payload from "payload"; import { Collections } from "../../../constants"; import { EndpointEra } from "../../../sdk"; -import { ChronologyEra, ChronologyItem, Recorder } from "../../../types/collections"; +import { ChronologyEra, ChronologyItem } from "../../../types/collections"; import { CollectionEndpoint } from "../../../types/payload"; -import { - isEmpty, - isPayloadArrayType, - isPayloadType, - isString, - isUndefined, -} from "../../../utils/asserts"; +import { isDefined, isPayloadArrayType, isPayloadType } from "../../../utils/asserts"; +import { handleRecorder } from "../../../utils/endpoints"; export const getAllEndpoint: CollectionEndpoint = { method: "get", @@ -38,16 +33,11 @@ export const getAllEndpoint: CollectionEndpoint = { startingYear, endingYear, translations: - translations?.flatMap(({ language, title, description }) => { - if (isString(language)) return []; - const translation = { - language: language.id, - title, - description, - }; - if (isEmpty(translation.description)) delete translation.description; - return translation; - }) ?? [], + translations?.map(({ language, title, description }) => ({ + language: isPayloadType(language) ? language.id : language, + title, + ...(description ? { description } : {}), + })) ?? [], items: items ?.filter(isPayloadType) @@ -63,52 +53,44 @@ export const getAllEndpoint: CollectionEndpoint = { if (aDay !== bDay) return aDay - bDay; return 0; }) - .flatMap(({ date, events, createdAt, updatedAt, updatedBy }) => { - if (isString(updatedBy)) return []; - const item = { - date, - events: events.map(({ translations }) => ({ - translations: translations.flatMap( - ({ - language, - sourceLanguage, - description, - notes, - proofreaders = [], - transcribers = [], - translators = [], - title, - }) => { - if (isString(language)) return []; - if (isString(sourceLanguage)) return []; - if (!isPayloadArrayType(proofreaders)) return []; - if (!isPayloadArrayType(transcribers)) return []; - if (!isPayloadArrayType(translators)) return []; - const event = { - language: language.id, - sourceLanguage: sourceLanguage.id, - title, - description, - notes, - proofreaders: proofreaders.map(({ id }) => id), - transcribers: transcribers.map(({ id }) => id), - translators: translators.map(({ id }) => id), - }; - if (isEmpty(title)) delete event.title; - if (isEmpty(description)) delete event.description; - if (isEmpty(notes)) delete event.notes; - return event; - } - ), - })), - createdAt: new Date(createdAt), - updatedAt: new Date(updatedAt), - updatedBy: updatedBy.id, - }; - if (isUndefined(item.date.month)) delete item.date.month; - if (isUndefined(item.date.day)) delete item.date.day; - return item; - }) ?? [], + .map(({ events, date: { year, day, month } }) => ({ + date: { + year, + ...(isDefined(day) ? { day } : {}), + ...(isDefined(month) ? { month } : {}), + }, + events: events.map(({ translations }) => ({ + translations: translations.map( + ({ + language, + sourceLanguage, + description, + notes, + proofreaders, + transcribers, + translators, + title, + }) => ({ + language: isPayloadType(language) ? language.id : language, + sourceLanguage: isPayloadType(sourceLanguage) + ? sourceLanguage.id + : sourceLanguage, + ...(title ? { title } : {}), + ...(description ? { description } : {}), + ...(notes ? { notes } : {}), + proofreaders: isPayloadArrayType(proofreaders) + ? proofreaders.map(handleRecorder) + : [], + transcribers: isPayloadArrayType(transcribers) + ? transcribers.map(handleRecorder) + : [], + translators: isPayloadArrayType(translators) + ? translators.map(handleRecorder) + : [], + }) + ), + })), + })) ?? [], }) ); diff --git a/src/collections/ChronologyEras/endpoints/importFromStrapi.ts b/src/collections/ChronologyEras/endpoints/importFromStrapi.ts index 2521648..87bb965 100644 --- a/src/collections/ChronologyEras/endpoints/importFromStrapi.ts +++ b/src/collections/ChronologyEras/endpoints/importFromStrapi.ts @@ -1,7 +1,8 @@ import { Collections } from "../../../constants"; import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint"; import { StrapiLanguage } from "../../../types/strapi"; -import { isUndefined } from "../../../utils/asserts"; +import { isDefined, isUndefined } from "../../../utils/asserts"; +import { plainTextToLexical } from "../../../utils/string"; type StrapiChronologyEra = { slug: string; @@ -29,7 +30,7 @@ export const importFromStrapi = createStrapiImportEndpoint( return { language: language.data?.attributes.code, title, - description, + ...(isDefined(description) ? { description: plainTextToLexical(description) } : {}), }; }), }), diff --git a/src/collections/ChronologyItems/validations/validateEventsTranslationsDescription.ts b/src/collections/ChronologyItems/validations/validateEventsTranslationsDescription.ts index b50daf4..210e21b 100644 --- a/src/collections/ChronologyItems/validations/validateEventsTranslationsDescription.ts +++ b/src/collections/ChronologyItems/validations/validateEventsTranslationsDescription.ts @@ -8,7 +8,7 @@ export const validateEventsTranslationsDescription: Validate< ChronologyItem["events"][number]["translations"][number], unknown > = (_, { siblingData: { description, title } }) => { - if (isEmpty(description) && isEmpty(title)) { + if (!description && isEmpty(title)) { return "This field is required if no title is set."; } return true; diff --git a/src/collections/ChronologyItems/validations/validateEventsTranslationsTitle.ts b/src/collections/ChronologyItems/validations/validateEventsTranslationsTitle.ts index 571f568..e7df06f 100644 --- a/src/collections/ChronologyItems/validations/validateEventsTranslationsTitle.ts +++ b/src/collections/ChronologyItems/validations/validateEventsTranslationsTitle.ts @@ -8,7 +8,7 @@ export const validateEventsTranslationsTitle: Validate< ChronologyItem["events"][number]["translations"][number], unknown > = (_, { siblingData: { description, title } }) => { - if (isEmpty(description) && isEmpty(title)) { + if (!description && isEmpty(title)) { return "This field is required if no description is set."; } return true; diff --git a/src/collections/Recorders/endpoints/importFromStrapi.ts b/src/collections/Recorders/endpoints/importFromStrapi.ts index 4a93f54..32d9ff2 100644 --- a/src/collections/Recorders/endpoints/importFromStrapi.ts +++ b/src/collections/Recorders/endpoints/importFromStrapi.ts @@ -47,15 +47,6 @@ export const importFromStrapi = createStrapiImportEndpoint({ anonymize, languages: languages.data?.map((language) => language.attributes.code), avatar: avatarId, - biographies: bios?.map(({ language, bio }) => { - if (isUndefined(language.data)) - throw new Error("A language is required for a Recorder biography"); - if (isUndefined(bio)) throw new Error("A bio is required for a Recorder biography"); - return { - language: language.data.attributes.code, - biography: plainTextToLexical(bio), - }; - }), }, user, }); diff --git a/src/collections/Tags/Tags.ts b/src/collections/Tags/Tags.ts index b6f48c6..a26b23a 100644 --- a/src/collections/Tags/Tags.ts +++ b/src/collections/Tags/Tags.ts @@ -5,7 +5,6 @@ import { slugField } from "../../fields/slugField/slugField"; import { translatedFields } from "../../fields/translatedFields/translatedFields"; import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo"; import { buildCollectionConfig } from "../../utils/collectionConfig"; -import { getAllEndpoint } from "./endpoints/getAllEndpoint"; const beforeChangeUpdateName: CollectionBeforeChangeHook = async ({ data }) => { let name = data.slug; @@ -45,7 +44,6 @@ export const Tags: CollectionConfig = buildCollectionConfig({ beforeDuplicate: beforeDuplicateAddCopyTo(fields.slug), }, }, - endpoints: [getAllEndpoint], hooks: { beforeChange: [beforeChangeUpdateName] }, fields: [ { name: fields.name, type: "text", admin: { readOnly: true, hidden: true } }, diff --git a/src/collections/Tags/endpoints/getAllEndpoint.ts b/src/collections/Tags/endpoints/getAllEndpoint.ts deleted file mode 100644 index 6083afc..0000000 --- a/src/collections/Tags/endpoints/getAllEndpoint.ts +++ /dev/null @@ -1,41 +0,0 @@ -import payload from "payload"; -import { Collections } from "../../../constants"; -import { EndpointTag } from "../../../sdk"; -import { CollectionEndpoint } from "../../../types/payload"; -import { isPayloadType } from "../../../utils/asserts"; - -export const getAllEndpoint: CollectionEndpoint = { - method: "get", - path: "/all", - handler: async (req, res) => { - if (!req.user) { - return res.status(403).send({ - errors: [ - { - message: "You are not allowed to perform this action.", - }, - ], - }); - } - - const tags = ( - await payload.find({ - collection: Collections.Tags, - sort: "id", - pagination: false, - }) - ).docs; - - const result = tags.map(({ slug, translations, group }) => ({ - slug, - translations: - translations?.map(({ language, name }) => ({ - language: isPayloadType(language) ? language.id : language, - name, - })) ?? [], - group: isPayloadType(group) ? group.slug : group, - })); - - res.status(200).json(result); - }, -}; diff --git a/src/collections/TagsGroups/TagsGroups.ts b/src/collections/TagsGroups/TagsGroups.ts index 512b8a3..11cea9f 100644 --- a/src/collections/TagsGroups/TagsGroups.ts +++ b/src/collections/TagsGroups/TagsGroups.ts @@ -4,7 +4,6 @@ import { iconField } from "../../fields/iconField/iconField"; import { slugField } from "../../fields/slugField/slugField"; import { translatedFields } from "../../fields/translatedFields/translatedFields"; import { buildCollectionConfig } from "../../utils/collectionConfig"; -import { getAllEndpoint } from "./endpoints/getAllEndpoint"; const fields = { slug: "slug", @@ -21,7 +20,6 @@ export const TagsGroups: CollectionConfig = buildCollectionConfig({ useAsTitle: fields.slug, defaultColumns: [fields.slug, fields.translations], }, - endpoints: [getAllEndpoint], fields: [ slugField({ name: fields.slug }), iconField({ name: fields.icon }), diff --git a/src/collections/TagsGroups/endpoints/getAllEndpoint.ts b/src/collections/TagsGroups/endpoints/getAllEndpoint.ts deleted file mode 100644 index 7fa9b89..0000000 --- a/src/collections/TagsGroups/endpoints/getAllEndpoint.ts +++ /dev/null @@ -1,42 +0,0 @@ -import payload from "payload"; -import { Collections } from "../../../constants"; -import { EndpointTagsGroup } from "../../../sdk"; -import { CollectionEndpoint } from "../../../types/payload"; -import { isPayloadType } from "../../../utils/asserts"; - -export const getAllEndpoint: CollectionEndpoint = { - method: "get", - path: "/all", - handler: async (req, res) => { - if (!req.user) { - return res.status(403).send({ - errors: [ - { - message: "You are not allowed to perform this action.", - }, - ], - }); - } - - const tags = ( - await payload.find({ - collection: Collections.TagsGroups, - sort: "id", - pagination: false, - }) - ).docs; - - const result = tags.map(({ slug, translations, icon }) => ({ - slug, - ...(icon ? { icon } : {}), - translations: - translations?.map(({ language, name }) => ({ - language: isPayloadType(language) ? language.id : language, - name, - })) ?? [], - tags: [] // TODO: Add tags, - })); - - res.status(200).json(result); - }, -}; diff --git a/src/collections/Weapons/Weapons.ts b/src/collections/Weapons/Weapons.ts deleted file mode 100644 index 1a61b29..0000000 --- a/src/collections/Weapons/Weapons.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { RowLabelArgs } from "payload/dist/admin/components/forms/RowLabel/types"; -import { CollectionGroups, Collections } from "../../constants"; -import { imageField } from "../../fields/imageField/imageField"; -import { rowField } from "../../fields/rowField/rowField"; -import { slugField } from "../../fields/slugField/slugField"; -import { translatedFields } from "../../fields/translatedFields/translatedFields"; -import { createEditor } from "../../utils/editor"; -import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig"; -import { AppearanceRowLabel } from "./components/AppearanceRowLabel"; -import { getBySlugEndpoint } from "./endpoints/getBySlugEndpoint"; -import { importFromStrapi } from "./endpoints/importFromStrapi"; - -const fields = { - slug: "slug", - thumbnail: "thumbnail", - type: "type", - group: "group", - appearances: "appearances", - appearancesCategories: "categories", - appearancesTranslations: "translations", - appearancesTranslationsName: "name", - appearancesTranslationsDescription: "description", - appearancesTranslationsLevel1: "level1", - appearancesTranslationsLevel2: "level2", - appearancesTranslationsLevel3: "level3", - appearancesTranslationsLevel4: "level4", - status: "_status", -}; - -export const Weapons = buildVersionedCollectionConfig({ - slug: Collections.Weapons, - labels: { singular: "Weapon", plural: "Weapons" }, - defaultSort: fields.slug, - admin: { - useAsTitle: fields.slug, - defaultColumns: [ - fields.thumbnail, - fields.slug, - fields.group, - fields.type, - fields.appearances, - fields.status, - ], - group: CollectionGroups.Collections, - }, - endpoints: [importFromStrapi, getBySlugEndpoint], - fields: [ - rowField([ - slugField({ name: fields.slug }), - imageField({ - name: fields.thumbnail, - relationTo: Collections.WeaponsThumbnails, - }), - ]), - rowField([ - { - name: fields.group, - type: "relationship", - relationTo: Collections.WeaponsGroups, - }, - ]), - { - name: fields.appearances, - type: "array", - required: true, - minRows: 1, - admin: { - initCollapsed: true, - components: { - RowLabel: ({ data }: RowLabelArgs) => - AppearanceRowLabel({ keyIds: data[fields.appearancesCategories] ?? [] }), - }, - }, - fields: [ - translatedFields({ - name: fields.appearancesTranslations, - required: true, - minRows: 1, - admin: { - useAsTitle: fields.appearancesTranslationsName, - hasSourceLanguage: true, - hasCredits: true, - }, - fields: [ - rowField([ - { - name: fields.appearancesTranslationsName, - type: "text", - required: true, - }, - { - name: fields.appearancesTranslationsDescription, - type: "richText", - editor: createEditor({ inlines: true }), - }, - ]), - rowField([ - { - name: fields.appearancesTranslationsLevel1, - label: "Level 1", - type: "richText", - editor: createEditor({ inlines: true }), - }, - { - name: fields.appearancesTranslationsLevel2, - label: "Level 2", - type: "richText", - editor: createEditor({ inlines: true }), - }, - ]), - rowField([ - { - name: fields.appearancesTranslationsLevel3, - label: "Level 3", - type: "richText", - editor: createEditor({ inlines: true }), - }, - { - name: fields.appearancesTranslationsLevel4, - label: "Level 4", - type: "richText", - editor: createEditor({ inlines: true }), - }, - ]), - ], - }), - ], - }, - ], -}); diff --git a/src/collections/Weapons/components/AppearanceRowLabel.tsx b/src/collections/Weapons/components/AppearanceRowLabel.tsx deleted file mode 100644 index f35ac9d..0000000 --- a/src/collections/Weapons/components/AppearanceRowLabel.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { useEffect, useState } from "react"; -import styled from "styled-components"; -import { Collections } from "../../../constants"; - -interface Props { - keyIds: string[]; -} - -const Container = styled.div` - display: flex; - place-items: center; - gap: 5px; -`; - -export const AppearanceRowLabel = ({ keyIds }: Props): JSX.Element => { - const [keySlugs, setKeySlugs] = useState([]); - useEffect(() => { - const fetchUrl = async () => { - const results = await Promise.all( - keyIds.map(async (keyId) => await (await fetch(`/api/${Collections.Keys}/${keyId}`)).json()) - ); - setKeySlugs(results.map((result) => result.name)); - }; - fetchUrl(); - }, [keyIds]); - - return ( - - {keySlugs.map((keySlug) => ( -
- {keySlug} -
- ))} -
- ); -}; diff --git a/src/collections/Weapons/endpoints/getBySlugEndpoint.ts b/src/collections/Weapons/endpoints/getBySlugEndpoint.ts deleted file mode 100644 index 26c2c11..0000000 --- a/src/collections/Weapons/endpoints/getBySlugEndpoint.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { Collections } from "../../../constants"; -import { createGetByEndpoint } from "../../../endpoints/createGetByEndpoint"; -import { EndpointBasicWeapon, EndpointWeapon, PayloadImage } from "../../../sdk"; -import { Key, Language, Recorder, Weapon, WeaponsThumbnail } from "../../../types/collections"; -import { isDefined, isUndefined, isValidPayloadImage } from "../../../utils/asserts"; - -export const getBySlugEndpoint = createGetByEndpoint( - Collections.Weapons, - "slug", - (weapon: Weapon): EndpointWeapon => { - let group: EndpointWeapon["group"] = undefined; - - // We only send the group if the group has at least 2 weapons (1 weapon beside the current one) - // The weapons are ordered alphabetically using their slugs - if ( - typeof weapon.group === "object" && - isDefined(weapon.group.weapons) && - weapon.group.weapons.length > 1 - ) { - const { slug, translations = [], weapons } = weapon.group; - - const groupWeapons: EndpointBasicWeapon[] = []; - weapons.forEach((groupWeapon) => { - if (typeof groupWeapon === "object" && groupWeapon.id !== weapon.id) { - groupWeapons.push(convertWeaponToEndpointBasicWeapon(groupWeapon)); - } - }); - - groupWeapons.sort((a, b) => a.slug.localeCompare(b.slug)); - - group = { - slug, - translations: translations.map(({ language, name }) => ({ - language: getLanguageId(language), - name, - })), - weapons: groupWeapons, - }; - } - - return { - ...convertWeaponToEndpointBasicWeapon(weapon), - appearances: weapon.appearances.map(({ categories, translations }) => ({ - categories: categories.map(getKeyId), - translations: translations.map( - ({ - language, - sourceLanguage, - transcribers = [], - translators = [], - proofreaders = [], - ...otherTranslatedProps - }) => ({ - language: getLanguageId(language), - sourceLanguage: getLanguageId(sourceLanguage), - transcribers: transcribers.map(getRecorderId), - translators: translators.map(getRecorderId), - proofreaders: proofreaders.map(getRecorderId), - ...otherTranslatedProps, - }) - ), - })), - group, - }; - } -); - -const getRecorderId = (recorder: string | Recorder) => - typeof recorder === "object" ? recorder.id : recorder; -const getKeyId = (key: string | Key) => (typeof key === "object" ? key.id : key); -const getLanguageId = (language: string | Language) => - typeof language === "object" ? language.id : language; - -const getThumbnail = (thumbnail?: string | WeaponsThumbnail): WeaponsThumbnail | undefined => { - if (isUndefined(thumbnail)) return undefined; - if (typeof thumbnail === "string") return undefined; - delete thumbnail.weapon; - return thumbnail; -}; - -const getPayloadImage = ( - image: Partial | undefined, - fallback: PayloadImage -): PayloadImage => - isValidPayloadImage(image) - ? { - filename: image.filename, - height: image.height, - mimeType: image.mimeType, - width: image.width, - url: image.url, - } - : { - filename: fallback.filename, - height: fallback.height, - mimeType: fallback.mimeType, - width: fallback.width, - url: fallback.url, - }; - -const convertWeaponToEndpointBasicWeapon = ({ - slug, - thumbnail: rawThumbnail, - type, - appearances, -}: Weapon): EndpointBasicWeapon => { - const categories = new Set(); - appearances.forEach((appearance) => - appearance.categories.forEach((category) => categories.add(getKeyId(category))) - ); - - const languages = new Set(); - appearances.forEach(({ translations }) => - translations.forEach(({ language }) => languages.add(getLanguageId(language))) - ); - - const translations: EndpointWeapon["translations"] = [...languages.values()].map( - (targetLanguage) => { - const names = new Set(); - appearances.forEach(({ translations }) => { - const translation = translations.find( - ({ language }) => getLanguageId(language) === targetLanguage - ); - if (translation) { - names.add(translation.name); - } - }); - const [name, ...aliases] = names; - - if (isUndefined(name)) - throw new Error("A weapon should always have a name for each of its translatiion"); - - return { language: targetLanguage, name: name, aliases }; - } - ); - - const thumbnail = getThumbnail(rawThumbnail); - const images: EndpointBasicWeapon["images"] = - isValidPayloadImage(thumbnail) && isDefined(thumbnail.sizes) - ? { - openGraph: getPayloadImage(thumbnail.sizes.og, thumbnail), - previewCard: getPayloadImage(thumbnail.sizes.small, thumbnail), - thumbnailHeader: getPayloadImage(thumbnail.sizes.medium, thumbnail), - lightBox: getPayloadImage(thumbnail, thumbnail), - } - : undefined; - - return { - slug, - images, - type: getKeyId(type), - categories: [...categories.values()], - translations, - }; -}; diff --git a/src/collections/Weapons/endpoints/importFromStrapi.ts b/src/collections/Weapons/endpoints/importFromStrapi.ts deleted file mode 100644 index 647e4d7..0000000 --- a/src/collections/Weapons/endpoints/importFromStrapi.ts +++ /dev/null @@ -1,115 +0,0 @@ -import payload from "payload"; -import { Collections } from "../../../constants"; -import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint"; -import { StrapiImage, StrapiLanguage } from "../../../types/strapi"; -import { isDefined, isUndefined } from "../../../utils/asserts"; -import { findCategory, findWeaponType, uploadStrapiImage } from "../../../utils/localApi"; - -type StrapiWeapon = { - slug: string; - name: { name: string; language: StrapiLanguage }[]; - weapon_group: { data?: { attributes: { slug: string } } }; - thumbnail: StrapiImage; - type: { data?: { attributes: { slug: string } } }; - stories: { - categories: { data: { attributes: { slug: string } }[] }; - translations: { - language: StrapiLanguage; - description?: string; - level_1?: string; - level_2?: string; - level_3?: string; - level_4?: string; - }[]; - }[]; -}; - -export const importFromStrapi = createStrapiImportEndpoint({ - strapi: { - collection: "weapon-stories", - params: { - populate: [ - "name.language", - "type", - "weapon_group", - "stories.categories", - "stories.translations.language", - "thumbnail", - ].join(), - }, - }, - payload: { - collection: Collections.Weapons, - import: async ({ slug, type, stories, name: names, weapon_group, thumbnail }, user) => { - let groupId: string | undefined; - if (isDefined(weapon_group.data)) { - try { - await payload.create({ - collection: Collections.WeaponsGroups, - data: { - slug: weapon_group.data.attributes.slug, - }, - user, - }); - } catch (e) {} - - const result = await payload.find({ - collection: Collections.WeaponsGroups, - where: { slug: { equals: weapon_group.data.attributes.slug } }, - }); - - if (result.docs[0]) { - groupId = result.docs[0].id; - } - } - - const thumbnailId = await uploadStrapiImage({ - collection: Collections.WeaponsThumbnails, - image: thumbnail, - }); - - if (isUndefined(type.data)) throw new Error("A type is required to create a Weapon"); - - await payload.create({ - collection: Collections.Weapons, - data: { - updatedBy: user.id, - slug, - type: await findWeaponType(type.data.attributes.slug), - group: groupId, - thumbnail: thumbnailId, - appearances: await Promise.all( - stories.map(async ({ categories, translations }) => ({ - categories: await Promise.all( - categories.data.map(({ attributes }) => findCategory(attributes.slug)) - ), - translations: translations.map( - ({ language, description, level_1, level_2, level_3, level_4 }) => { - if (isUndefined(language.data)) - throw new Error("A language is required to create a Weapon translation"); - const name = names.find( - (name) => name.language.data?.attributes.code === language.data?.attributes.code - )?.name; - if (isUndefined(name)) - throw new Error("A name is required to create a Weapon translation"); - return { - language: language.data?.attributes.code, - sourceLanguage: language.data?.attributes.code, - name, - description, - level1: level_1, - level2: level_2, - level3: level_3, - level4: level_4, - transcribers: [user.id], - }; - } - ), - })) - ), - }, - user, - }); - }, - }, -}); diff --git a/src/collections/WeaponsGroups/WeaponsGroups.ts b/src/collections/WeaponsGroups/WeaponsGroups.ts deleted file mode 100644 index 2ccb8df..0000000 --- a/src/collections/WeaponsGroups/WeaponsGroups.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { CollectionGroups, Collections } from "../../constants"; -import { backPropagationField } from "../../fields/backPropagationField/backPropagationField"; -import { slugField } from "../../fields/slugField/slugField"; -import { translatedFields } from "../../fields/translatedFields/translatedFields"; -import { buildCollectionConfig } from "../../utils/collectionConfig"; - -const fields = { - slug: "slug", - translations: "translations", - translationsName: "name", - subgroupOf: "subgroupOf", - weapons: "weapons", -}; - -export const WeaponsGroups = buildCollectionConfig({ - slug: Collections.WeaponsGroups, - labels: { singular: "Weapons Group", plural: "Weapon Groups" }, - defaultSort: fields.slug, - admin: { - useAsTitle: fields.slug, - defaultColumns: [fields.slug, fields.translations, fields.weapons, fields.subgroupOf], - group: CollectionGroups.Collections, - }, - timestamps: false, - fields: [ - slugField({ name: fields.slug }), - translatedFields({ - name: fields.translations, - admin: { useAsTitle: fields.translationsName }, - fields: [{ name: fields.translationsName, type: "text", required: true }], - }), - backPropagationField({ - name: fields.weapons, - relationTo: Collections.Weapons, - hasMany: true, - where: ({ id }) => ({ group: { equals: id } }), - }), - ], -}); diff --git a/src/collections/WeaponsThumbnails/WeaponsThumbnails.ts b/src/collections/WeaponsThumbnails/WeaponsThumbnails.ts deleted file mode 100644 index 91f8ba6..0000000 --- a/src/collections/WeaponsThumbnails/WeaponsThumbnails.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Collections } from "../../constants"; -import { backPropagationField } from "../../fields/backPropagationField/backPropagationField"; -import { buildImageCollectionConfig } from "../../utils/imageCollectionConfig"; - -const fields = { - filename: "filename", - mimeType: "mimeType", - filesize: "filesize", - weapon: "weapon", - updatedAt: "updatedAt", -} as const satisfies Record; - -export const WeaponsThumbnails = buildImageCollectionConfig({ - slug: Collections.WeaponsThumbnails, - labels: { - singular: "Weapons Thumbnail", - plural: "Weapons Thumbnails", - }, - admin: { defaultColumns: [fields.filename, fields.weapon, fields.updatedAt] }, - upload: { - imageSizes: [ - { - name: "og", - height: 512, - width: 512, - fit: "inside", - formatOptions: { - format: "jpg", - options: { progressive: true, mozjpeg: true, compressionLevel: 9, quality: 80 }, - }, - }, - { - name: "small", - height: 256, - width: 256, - fit: "contain", - background: { r: 0, g: 0, b: 0, alpha: 0 }, - formatOptions: { - format: "webp", - options: { effort: 6, quality: 70, alphaQuality: 70 }, - }, - }, - { - name: "medium", - height: 1024, - width: 1024, - fit: "contain", - background: { r: 0, g: 0, b: 0, alpha: 0 }, - formatOptions: { - format: "webp", - options: { effort: 6, quality: 80, alphaQuality: 80 }, - }, - }, - ], - }, - fields: [ - backPropagationField({ - name: fields.weapon, - hasMany: false, - relationTo: Collections.Weapons, - where: ({ id }) => ({ thumbnail: { equals: id } }), - }), - ], -}); diff --git a/src/constants.ts b/src/constants.ts index 48d633a..3cdfd84 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,7 +1,5 @@ import type { - CueBlock, Image, - LineBlock, SectionBlock, SpacerBlock, TranscriptBlock, @@ -22,9 +20,6 @@ export enum Collections { RecordersThumbnails = "recorders-thumbnails", VideosChannels = "videos-channels", Videos = "videos", - Weapons = "weapons", - WeaponsGroups = "weapons-groups", - WeaponsThumbnails = "weapons-thumbnails", Folders = "folders", FoldersThumbnails = "folders-thumbnails", Tags = "tags", @@ -275,11 +270,15 @@ export const isBlockNodeSpacerBlock = (node: RichTextBlockNode): node is RichTex /* TODO: TO BE REMOVED WHEN https://github.com/payloadcms/payload/issues/5216 is closed */ export interface CueBlock { + content: RichTextContent; + blockType: 'cueBlock'; id?: string | null; blockName?: string | null; } export interface LineBlock { + content: RichTextContent; + blockType: 'lineBlock'; id?: string | null; blockName?: string | null; } diff --git a/src/endpoints/createImageRegenerationEndpoint.ts b/src/endpoints/createImageRegenerationEndpoint.ts deleted file mode 100644 index 203d418..0000000 --- a/src/endpoints/createImageRegenerationEndpoint.ts +++ /dev/null @@ -1,72 +0,0 @@ -import payload from "payload"; -import { mustBeAdmin } from "../accesses/endpoints/mustBeAdmin"; -import { Collections } from "../constants"; -import { CollectionEndpoint } from "../types/payload"; -import { isDefined } from "../utils/asserts"; - -type Image = { - filename: string; - id: string; -}; - -export const createImageRegenerationEndpoint = (collection: Collections): CollectionEndpoint => ({ - method: "put", - path: "/regenerate", - handler: async (req, res) => { - if (!mustBeAdmin(req)) { - return res.status(403).send({ - errors: [ - { - message: "You are not allowed to perform this action.", - }, - ], - }); - } - - let page = 1; - let totalPage = 1; - let count = 0; - const errors: string[] = []; - - while (page <= totalPage) { - const images = await payload.find({ - collection, - page, - user: req.user, - }); - - await Promise.all( - images.docs.filter(isImage).map(async (image: Image) => { - try { - await payload.update({ - collection, - id: image.id, - data: {}, - filePath: `uploads/${collection}/${image.filename}`, - overwriteExistingFiles: true, - }); - } catch (e) { - console.warn(e); - if (typeof e === "object" && isDefined(e) && "name" in e) { - errors.push(`${e.name} with ${image.id}`); - } - } - }) - ); - - totalPage = images.totalPages; - count += images.docs.length; - page++; - } - - res - .status(200) - .json({ message: `${count} entries have been regenerated successfully.`, errors }); - }, -}); - -const isImage = (item: Object): item is Image => { - if (!("id" in item) || typeof item.id !== "string") return false; - if (!("filename" in item) || typeof item.filename !== "string") return false; - return true; -}; diff --git a/src/endpoints/createStrapiImportEndpoint.ts b/src/endpoints/createStrapiImportEndpoint.ts index 5ee139b..7696e2e 100644 --- a/src/endpoints/createStrapiImportEndpoint.ts +++ b/src/endpoints/createStrapiImportEndpoint.ts @@ -1,5 +1,4 @@ import payload, { GeneratedTypes } from "payload"; -import { BasePayload } from "payload/dist/payload"; import QueryString from "qs"; import { Recorder } from "../types/collections"; import { CollectionEndpoint } from "../types/payload"; @@ -43,7 +42,7 @@ type Params = { convert?: ( strapiObject: S, user: any - ) => Promise["create"]>[0]["data"]>; + ) => any; }; }; diff --git a/src/fields/rowField/rowField.ts b/src/fields/rowField/rowField.ts index 321819e..e7d1f10 100644 --- a/src/fields/rowField/rowField.ts +++ b/src/fields/rowField/rowField.ts @@ -5,5 +5,5 @@ export const rowField = (fields: Field[]): RowField => ({ fields: fields.map(({ admin, ...otherConfig }) => ({ ...otherConfig, admin: { width: "0%", ...admin }, - })), + })) as Field[], }); diff --git a/src/payload.config.ts b/src/payload.config.ts index b17f940..f463789 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -20,9 +20,6 @@ import { Tags } from "./collections/Tags/Tags"; import { TagsGroups } from "./collections/TagsGroups/TagsGroups"; import { Videos } from "./collections/Videos/Videos"; import { VideosChannels } from "./collections/VideosChannels/VideosChannels"; -import { Weapons } from "./collections/Weapons/Weapons"; -import { WeaponsGroups } from "./collections/WeaponsGroups/WeaponsGroups"; -import { WeaponsThumbnails } from "./collections/WeaponsThumbnails/WeaponsThumbnails"; import { Wordings } from "./collections/Wordings/Wordings"; import { Icon } from "./components/Icon"; import { Logo } from "./components/Logo"; @@ -49,9 +46,6 @@ export default buildConfig({ Pages, ChronologyItems, ChronologyEras, - Weapons, - WeaponsGroups, - WeaponsThumbnails, RecordersThumbnails, Notes, Videos, diff --git a/src/sdk.ts b/src/sdk.ts index f72b509..0eb86a4 100644 --- a/src/sdk.ts +++ b/src/sdk.ts @@ -41,8 +41,8 @@ const refreshToken = async () => { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ - email: import.meta.env.PAYLOAD_USER, - password: import.meta.env.PAYLOAD_PASSWORD, + email: process.env.PAYLOAD_USER, + password: process.env.PAYLOAD_PASSWORD, }), }); logResponse(loginResult); @@ -81,7 +81,7 @@ const injectAuth = async (init?: RequestInit): Promise => ({ const logResponse = (res: Response) => console.log(res.status, res.statusText, res.url); const payloadApiUrl = (collection: Collections, endpoint?: string): string => - `${import.meta.env.PAYLOAD_API_URL}/${collection}${endpoint === undefined ? "" : `/${endpoint}`}`; + `${process.env.PAYLOAD_API_URL}/${collection}${endpoint === undefined ? "" : `/${endpoint}`}`; const request = async (url: string, init?: RequestInit): Promise => { const result = await fetch(url, await injectAuth(init)); @@ -96,43 +96,6 @@ const request = async (url: string, init?: RequestInit): Promise => { // SDK and Types -export type EndpointWeapon = EndpointBasicWeapon & { - appearances: { - categories: string[]; - translations: { - language: string; - sourceLanguage: string; - name: string; - description?: string; - level1?: string; - level2?: string; - level3?: string; - level4?: string; - transcribers: string[]; - translators: string[]; - proofreaders: string[]; - }[]; - }[]; - group?: { - slug: string; - translations: { language: string; name: string }[]; - weapons: EndpointBasicWeapon[]; - }; -}; - -export type EndpointBasicWeapon = { - slug: string; - type: string; - categories: string[]; - translations: { language: string; name: string; aliases: string[] }[]; - images?: { - previewCard: PayloadImage; - thumbnailHeader: PayloadImage; - lightBox: PayloadImage; - openGraph: PayloadImage; - }; -}; - export type EndpointEra = { slug: string; startingYear: number; @@ -140,7 +103,7 @@ export type EndpointEra = { translations: { language: string; title: string; - description?: string; + description?: RichTextContent; }[]; items: { date: { @@ -153,16 +116,13 @@ export type EndpointEra = { language: string; sourceLanguage: string; title?: string; - description?: string; - notes?: string; - transcribers: string[]; - translators: string[]; - proofreaders: string[]; + description?: RichTextContent; + notes?: RichTextContent; + transcribers: EndpointRecorder[]; + translators: EndpointRecorder[]; + proofreaders: EndpointRecorder[]; }[]; }[]; - createdAt: Date; - updatedAt: Date; - updatedBy: string; }[]; }; @@ -364,8 +324,6 @@ export type PayloadImage = { }; export const payload = { - getWeapon: async (slug: string): Promise => - await (await request(payloadApiUrl(Collections.Weapons, `slug/${slug}`))).json(), getEras: async (): Promise => await (await request(payloadApiUrl(Collections.ChronologyEras, `all`))).json(), getRootFolders: async (): Promise => @@ -380,10 +338,6 @@ export const payload = { await (await request(payloadApiUrl(Collections.Wordings, `all`))).json(), getRecorders: async (): Promise => await (await request(payloadApiUrl(Collections.Recorders, `all`))).json(), - getTags: async (): Promise => - await (await request(payloadApiUrl(Collections.Tags, `all`))).json(), - getTagsGroups: async (): Promise => - await (await request(payloadApiUrl(Collections.TagsGroups, `all`))).json(), getPage: async (slug: string): Promise => await (await request(payloadApiUrl(Collections.Pages, `slug/${slug}`))).json(), getCollectible: async (slug: string): Promise => diff --git a/src/types/collections.ts b/src/types/collections.ts index 2e5fa1c..de14564 100644 --- a/src/types/collections.ts +++ b/src/types/collections.ts @@ -48,9 +48,6 @@ export interface Config { pages: Page; 'chronology-items': ChronologyItem; 'chronology-eras': ChronologyEra; - weapons: Weapon; - 'weapons-groups': WeaponsGroup; - 'weapons-thumbnails': WeaponsThumbnail; 'recorders-thumbnails': RecordersThumbnail; notes: Note; videos: Video; @@ -64,6 +61,7 @@ export interface Config { wordings: Wording; collectibles: Collectible; 'generic-contents': GenericContent; + 'background-images': BackgroundImage; 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; @@ -195,7 +193,7 @@ export interface Collectible { } | null; id?: string | null; }[]; - backgroundImage?: string | Image | null; + backgroundImage?: string | BackgroundImage | null; gallery?: | { image: string | Image; @@ -413,6 +411,31 @@ export interface TagsGroup { updatedAt: string; createdAt: string; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "background-images". + */ +export interface BackgroundImage { + id: string; + updatedAt: string; + createdAt: string; + url?: string | null; + filename?: string | null; + mimeType?: string | null; + filesize?: number | null; + width?: number | null; + height?: number | null; + sizes?: { + thumb?: { + url?: string | null; + width?: number | null; + height?: number | null; + mimeType?: string | null; + filesize?: number | null; + filename?: string | null; + }; + }; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "recorders". @@ -484,7 +507,7 @@ export interface Page { slug: string; type: 'Content' | 'Post' | 'Generic'; thumbnail?: string | Image | null; - backgroundImage?: string | Image | null; + backgroundImage?: string | BackgroundImage | null; tags?: (string | Tag)[] | null; authors?: (string | Recorder)[] | null; translations: { @@ -644,173 +667,6 @@ export interface ChronologyEra { updatedAt: string; createdAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "weapons". - */ -export interface Weapon { - id: string; - slug: string; - thumbnail?: string | WeaponsThumbnail | null; - group?: (string | null) | WeaponsGroup; - appearances: { - translations: { - language: string | Language; - sourceLanguage: string | Language; - name: string; - description?: { - root: { - children: { - type: string; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - type: string; - version: number; - }; - [k: string]: unknown; - } | null; - level1?: { - root: { - children: { - type: string; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - type: string; - version: number; - }; - [k: string]: unknown; - } | null; - level2?: { - root: { - children: { - type: string; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - type: string; - version: number; - }; - [k: string]: unknown; - } | null; - level3?: { - root: { - children: { - type: string; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - type: string; - version: number; - }; - [k: string]: unknown; - } | null; - level4?: { - root: { - children: { - type: string; - version: number; - [k: string]: unknown; - }[]; - direction: ('ltr' | 'rtl') | null; - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; - indent: number; - type: string; - version: number; - }; - [k: string]: unknown; - } | null; - transcribers?: (string | Recorder)[] | null; - translators?: (string | Recorder)[] | null; - proofreaders?: (string | Recorder)[] | null; - id?: string | null; - }[]; - id?: string | null; - }[]; - updatedBy: string | Recorder; - updatedAt: string; - createdAt: string; - _status?: ('draft' | 'published') | null; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "weapons-thumbnails". - */ -export interface WeaponsThumbnail { - id: string; - weapon?: (string | null) | Weapon; - updatedAt: string; - createdAt: string; - url?: string | null; - filename?: string | null; - mimeType?: string | null; - filesize?: number | null; - width?: number | null; - height?: number | null; - sizes?: { - thumb?: { - url?: string | null; - width?: number | null; - height?: number | null; - mimeType?: string | null; - filesize?: number | null; - filename?: string | null; - }; - og?: { - url?: string | null; - width?: number | null; - height?: number | null; - mimeType?: string | null; - filesize?: number | null; - filename?: string | null; - }; - small?: { - url?: string | null; - width?: number | null; - height?: number | null; - mimeType?: string | null; - filesize?: number | null; - filename?: string | null; - }; - medium?: { - url?: string | null; - width?: number | null; - height?: number | null; - mimeType?: string | null; - filesize?: number | null; - filename?: string | null; - }; - }; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "weapons-groups". - */ -export interface WeaponsGroup { - id: string; - slug: string; - translations?: - | { - language: string | Language; - name: string; - id?: string | null; - }[] - | null; - weapons?: (string | Weapon)[] | null; -} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "notes". diff --git a/src/utils/imageCollectionConfig.ts b/src/utils/imageCollectionConfig.ts index 5476490..dec4e99 100644 --- a/src/utils/imageCollectionConfig.ts +++ b/src/utils/imageCollectionConfig.ts @@ -2,7 +2,6 @@ import { ImageSize } from "payload/dist/uploads/types"; import { CollectionConfig } from "payload/types"; import { publicAccess } from "../accesses/publicAccess"; import { CollectionGroups } from "../constants"; -import { createImageRegenerationEndpoint } from "../endpoints/createImageRegenerationEndpoint"; import { BuildCollectionConfig, buildCollectionConfig } from "./collectionConfig"; type BuildImageCollectionConfig = Omit & { @@ -26,7 +25,6 @@ export const buildImageCollectionConfig = ({ access: { read: publicAccess, }, - endpoints: [createImageRegenerationEndpoint(otherConfig.slug)], upload: { staticDir: `../uploads/${otherConfig.slug}`, mimeTypes: ["image/*"],