diff --git a/packages/explorer/src/content/metadata/alternates.mts b/packages/explorer/src/content/metadata/alternates.mts index 46020f50..b241bcbf 100644 --- a/packages/explorer/src/content/metadata/alternates.mts +++ b/packages/explorer/src/content/metadata/alternates.mts @@ -5,15 +5,15 @@ import type { MetadataHeaders, } from '../../types/index.mjs'; -export const alternatesHeaderBuilder = ( - documents: ContentlayerDocumentWithURL[] -) => { - const selectNonTranslatedPagesByIdentifier = (identifier: string) => - documents.filter((_d) => !_d.translationOfWork?.['@id'] && _d.identifier === identifier); - const selectDocumentsTranslationOfWorkByIdentifierOrURL = ( - identifier: string, - url: string - ) => +const nonTranslatedPagesByIdentifierSelector = + (documents: ContentlayerDocumentWithURL[]) => (identifier: string) => + documents.filter( + (_d) => !_d.translationOfWork?.['@id'] && _d.identifier === identifier + ); + +const documentsTranslationOfWorkByIdentifierOrURLSelector = + (documents: ContentlayerDocumentWithURL[]) => + (identifier: string, url: string) => documents.filter( ({ translationOfWork }) => translationOfWork?.['@id'] && @@ -21,7 +21,11 @@ export const alternatesHeaderBuilder = ( translationOfWork?.['@id'] === url) ); - const getTranslations = (document: Content) => { +const translationsSelector = (documents: ContentlayerDocumentWithURL[]) => { + const selectDocumentsTranslationOfWorkByIdentifierOrURL = + documentsTranslationOfWorkByIdentifierOrURLSelector(documents); + + return (document: Content) => { if (!document.translationOfWork) { return selectDocumentsTranslationOfWorkByIdentifierOrURL( document.identifier, @@ -34,33 +38,51 @@ export const alternatesHeaderBuilder = ( document.translationOfWork['@id'] ); }; +}; - type Translations = Array +const defaultTranslationSelector = ( + documents: ContentlayerDocumentWithURL[] +) => { + const selectNonTranslatedPagesByIdentifier = + nonTranslatedPagesByIdentifierSelector(documents); - const getDefaultTranslation = (document: Content, translations: Translations) => { + return (document: Content, translations: Translations) => { if (document.translationOfWork?.['@id']) { - const defaultPageFromTranslationOfWork = selectNonTranslatedPagesByIdentifier(document.translationOfWork['@id']) + const defaultPageFromTranslationOfWork = + selectNonTranslatedPagesByIdentifier(document.translationOfWork['@id']); if (defaultPageFromTranslationOfWork.length === 1) { return defaultPageFromTranslationOfWork[0]; } } - const defaultPageFromDefaultLanguage = translations.filter((t) => t.inLanguage === getDefaultLanguage()); + const defaultPageFromDefaultLanguage = translations.filter( + (t) => t.inLanguage === getDefaultLanguage() + ); if (defaultPageFromDefaultLanguage.length > 0) { return defaultPageFromDefaultLanguage[0]; } return document; - } + }; +}; + +type Translations = Array; + +export const alternatesHeaderBuilder = ( + documents: ContentlayerDocumentWithURL[] +) => { + const selectTranslations = translationsSelector(documents); + const selectDefaultTranslation = defaultTranslationSelector(documents); return (document: Content): MetadataHeaders['alternates'] => { - const translations: Translations = getTranslations(document); - const defaultTranslation = getDefaultTranslation(document, translations); + const translations: Translations = selectTranslations(document); + const defaultTranslation = selectDefaultTranslation(document, translations); return translations .concat(defaultTranslation) .filter((_t) => _t.inLanguage) .map((_t) => ({ href: _t.url, hreflang: _t.inLanguage as string })) + .sort((a, b) => a.hreflang.localeCompare(b.hreflang)) .concat({ href: defaultTranslation.url, hreflang: 'x-default' }); }; };