import type { ToProseElement } from 'tsprose'; import { isTopicPart } from '@erudit-js/core/content/topic'; import type { ContentPointer } from '@erudit-js/core/content/pointer'; import type { ReferenceSchema, RefSchema, } from '@erudit-js/prose/elements/link/reference/core'; import type { DependencySchema, DepSchema, } from '@erudit-js/prose/elements/link/dependency/core'; import type { LinkStorage } from '@erudit-js/prose/elements/link/storage'; export async function createLinkStorage( element: | ToProseElement | ToProseElement | ToProseElement | ToProseElement, storageKey: string, ): Promise { try { let linkStorage: LinkStorage | undefined; const storageKeyParts = storageKey.split('/'); const linkType = storageKeyParts[0]; const strProseLink = storageKeyParts.slice(1).join('/'); if (linkType === '') { linkStorage = { type: 'external', resolvedHref: strProseLink, previewRequest: { type: 'direct-link', href: strProseLink, }, }; } else if (linkType === '') { const proseLinkParts = strProseLink.split('/'); const uniquePart = proseLinkParts.pop(); if (uniquePart?.startsWith('$')) { // // Unique link // const contentPointer = await getContentPointerFor( proseLinkParts.join('/'), ); const shortId = ERUDIT.contentNav.getNodeOrThrow( contentPointer.id, ).shortId; const contentTitle = await ERUDIT.repository.content.title( contentPointer.id, ); const uniqueName = uniquePart.slice(1); const unique = await ERUDIT.repository.content.unique( contentPointer.id, contentPointer.type === 'topic' ? contentPointer.part : 'page', uniqueName, ); if (contentPointer.type === 'topic') { linkStorage = { type: 'unique', schemaName: unique.prose.schema.name, elementTitle: unique.title || undefined, content: { contentType: 'topic', contentTitle, topicPart: contentPointer.part, }, resolvedHref: PAGES.topic( contentPointer.part, shortId, unique.prose.id, ), previewRequest: { type: 'unique', contentFullId: contentPointer.id, contentType: 'topic', topicPart: contentPointer.part, uniqueName: uniqueName, }, }; } else { linkStorage = { type: 'unique', schemaName: unique.prose.schema.name, elementTitle: unique.title || undefined, content: { contentType: contentPointer.type, contentTitle, }, resolvedHref: PAGES.page(shortId, unique.prose.id), previewRequest: { type: 'unique', contentFullId: contentPointer.id, contentType: 'page', uniqueName: uniqueName, }, }; } } else { // // Content item link // const contentPointer = await getContentPointerFor(strProseLink); const shortId = ERUDIT.contentNav.getNodeOrThrow( contentPointer.id, ).shortId; const contentTitle = await ERUDIT.repository.content.title( contentPointer.id, ); if (contentPointer.type === 'topic') { linkStorage = { type: 'contentItem', content: { contentType: 'topic', contentTitle, topicPart: contentPointer.part, }, resolvedHref: PAGES.topic(contentPointer.part, shortId), previewRequest: { type: 'content-page', contentType: 'topic', topicPart: contentPointer.part, fullId: contentPointer.id, }, }; } else { linkStorage = { type: 'contentItem', content: { contentType: contentPointer.type, contentTitle, }, resolvedHref: PAGES[contentPointer.type](shortId), previewRequest: { type: 'content-page', contentType: contentPointer.type, fullId: contentPointer.id, }, }; } } } if (!linkStorage) { throw new Error( `Unable to create prose link storage for link: ${storageKey}`, ); } return linkStorage; } catch (error) { return { type: 'error', error: error instanceof Error ? error.message : String(error), }; } } async function getContentPointerFor( contentId: string, ): Promise { if (!contentId) { throw new Error(`Invalid content ID: "${contentId}"!`); } const contentNavNode = ERUDIT.contentNav.getNode(contentId); if (contentNavNode) { const hidden = await ERUDIT.repository.content.hidden( contentNavNode.fullId, ); if (hidden) { throw new Error(`Target content is hidden!`); } if (contentNavNode.type === 'topic') { const defaultTopicPart = await ERUDIT.repository.content.defaultTopicPart( contentNavNode.fullId, ); return { type: 'topic', id: contentNavNode.fullId, part: defaultTopicPart, }; } else { return { type: contentNavNode.type, id: contentNavNode.fullId, }; } } const contentIdParts = contentId.split('/'); const maybeTopicPart = contentIdParts.pop()!; if (!isTopicPart(maybeTopicPart)) { throw new Error( `Prose link part "${contentId}" must be a valid topic part!`, ); } const shortenedContentNavNode = ERUDIT.contentNav.getNode( contentIdParts.join('/'), ); if (shortenedContentNavNode) { return { type: 'topic', id: shortenedContentNavNode.fullId, part: maybeTopicPart, }; } throw new Error(`Unable to find content for prose link: "${contentId}"!`); }