diff --git a/apps/roam/src/utils/convertRoamNodeToFullContent.example.ts b/apps/roam/src/utils/convertRoamNodeToFullContent.example.ts index f425d7d9f..85547c1a7 100644 --- a/apps/roam/src/utils/convertRoamNodeToFullContent.example.ts +++ b/apps/roam/src/utils/convertRoamNodeToFullContent.example.ts @@ -1,7 +1,7 @@ import { contentTypes } from "@repo/content-model"; import type { TreeNode } from "roamjs-components/types"; import type { CrossAppNode } from "@repo/database/crossAppContracts"; -import { buildFullMarkdown } from "./convertRoamNodeToFullContent"; +import { buildFullMarkdown } from "./roamToCrossAppConverters"; /** * Example Roam page tree used to show the markdown emitted for a `full` content diff --git a/apps/roam/src/utils/convertRoamNodeToFullContent.simple.example.ts b/apps/roam/src/utils/convertRoamNodeToFullContent.simple.example.ts index cef2e3160..c17457662 100644 --- a/apps/roam/src/utils/convertRoamNodeToFullContent.simple.example.ts +++ b/apps/roam/src/utils/convertRoamNodeToFullContent.simple.example.ts @@ -1,6 +1,6 @@ import type { TreeNode } from "roamjs-components/types"; import type { CrossAppNode } from "@repo/database/crossAppContracts"; -import { buildFullMarkdown } from "./convertRoamNodeToFullContent"; +import { buildFullMarkdown } from "./roamToCrossAppConverters"; import { contentTypes } from "@repo/content-model"; const block = (text: string, children: TreeNode[] = []): TreeNode => ({ diff --git a/apps/roam/src/utils/convertRoamNodeToFullContent.ts b/apps/roam/src/utils/convertRoamNodeToFullContent.ts index 59a056300..d1f24cba1 100644 --- a/apps/roam/src/utils/convertRoamNodeToFullContent.ts +++ b/apps/roam/src/utils/convertRoamNodeToFullContent.ts @@ -1,11 +1,5 @@ -import { toMarkdown } from "./pageToMarkdown"; -import { type DiscourseNode } from "./getDiscourseNodes"; -import getFullTreeByParentUid from "roamjs-components/queries/getFullTreeByParentUid"; -import getPageViewType from "roamjs-components/queries/getPageViewType"; -import type { TreeNode, ViewType } from "roamjs-components/types"; -import { contentTypes } from "@repo/content-model"; -import type { CrossAppNode } from "@repo/database/crossAppContracts"; import { crossAppNodeToDbContent } from "@repo/database/lib/crossAppConverters"; +import { fullContentNodeToCrossApp } from "./roamToCrossAppConverters"; import type { LocalContentDataInput } from "@repo/database/inputTypes"; export type RoamFullContentNode = { @@ -18,35 +12,6 @@ export type RoamFullContentNode = { node_title?: string; }; -const FULL_MARKDOWN_OPTS = { - refs: true, - embeds: true, - simplifiedFilename: false, - removeSpecialCharacters: false, - maxFilenameLength: 64, - linkType: "alias", - allNodes: [] as DiscourseNode[], -}; - -export const buildFullMarkdown = ({ - title, - blocks, - viewType = "bullet", -}: { - title: string; - blocks: TreeNode[]; - viewType?: ViewType; -}): string => { - const body = blocks - .filter((block) => !!block.text || !!block.children?.length) - .map((block) => - toMarkdown({ c: block, v: viewType, i: 0, opts: FULL_MARKDOWN_OPTS }), - ) - .join("\n") - .trim(); - return body ? `# ${title}\n\n${body}\n` : `# ${title}\n`; -}; - export const convertRoamNodeToFullContent = ({ nodes, }: { @@ -54,28 +19,7 @@ export const convertRoamNodeToFullContent = ({ }): LocalContentDataInput[] => nodes.flatMap((node) => { try { - const title = node.node_title ?? node.text; - const blocks = getFullTreeByParentUid(node.source_local_id).children; - const viewType = getPageViewType(title) || "bullet"; - const crossAppNode: CrossAppNode = { - authorId: node.author_local_id, - localId: node.source_local_id, - createdAt: new Date(node.created || Date.now()), - modifiedAt: new Date(node.last_modified || Date.now()), - nodeType: node.node_type_id, - content: { - direct: { - localId: node.source_local_id, - value: title, - }, - full: { - localId: node.source_local_id, - value: buildFullMarkdown({ title, blocks, viewType }), - contentType: contentTypes.roamMarkdown, - scale: "document", - }, - }, - }; + const crossAppNode = fullContentNodeToCrossApp(node); const fullContent = crossAppNodeToDbContent(crossAppNode, "full"); return fullContent === undefined ? [] : [fullContent]; } catch (error) { diff --git a/apps/roam/src/utils/roamToCrossAppConverters.ts b/apps/roam/src/utils/roamToCrossAppConverters.ts new file mode 100644 index 000000000..011069c66 --- /dev/null +++ b/apps/roam/src/utils/roamToCrossAppConverters.ts @@ -0,0 +1,66 @@ +import type { CrossAppNode } from "@repo/database/crossAppContracts"; +import type { RoamFullContentNode } from "./convertRoamNodeToFullContent"; +import type { DiscourseNode } from "./getDiscourseNodes"; +import type { TreeNode, ViewType } from "roamjs-components/types"; +import { toMarkdown } from "./pageToMarkdown"; +import getFullTreeByParentUid from "roamjs-components/queries/getFullTreeByParentUid"; +import getPageViewType from "roamjs-components/queries/getPageViewType"; +import { contentTypes } from "@repo/content-model"; + +const FULL_MARKDOWN_OPTS = { + refs: true, + embeds: true, + simplifiedFilename: false, + removeSpecialCharacters: false, + maxFilenameLength: 64, + linkType: "alias", + allNodes: [] as DiscourseNode[], +}; + +export const buildFullMarkdown = ({ + title, + blocks, + viewType = "bullet", +}: { + title: string; + blocks: TreeNode[]; + viewType?: ViewType; +}): string => { + const body = blocks + .filter((block) => !!block.text || !!block.children?.length) + .map((block) => + toMarkdown({ c: block, v: viewType, i: 0, opts: FULL_MARKDOWN_OPTS }), + ) + .join("\n") + .trim(); + return body ? `# ${title}\n\n${body}\n` : `# ${title}\n`; +}; + +export const fullContentNodeToCrossApp = ( + node: RoamFullContentNode, +): CrossAppNode => { + const title = node.node_title ?? node.text; + const blocks = getFullTreeByParentUid(node.source_local_id).children; + const viewType = getPageViewType(title) || "bullet"; + const fullText = buildFullMarkdown({ title, blocks, viewType }); + + return { + authorId: node.author_local_id, + localId: node.source_local_id, + createdAt: new Date(node.created || Date.now()), + modifiedAt: new Date(node.last_modified || Date.now()), + nodeType: node.node_type_id, + content: { + direct: { + localId: node.source_local_id, + value: node.node_title ?? node.text, + }, + full: { + localId: node.source_local_id, + value: fullText, + contentType: contentTypes.roamMarkdown, + scale: "document", + }, + }, + }; +};