diff --git a/apps/server/src/api/v2/reports/[id]/PUT.ts b/apps/server/src/api/v2/reports/[id]/PUT.ts
index 30b2aba0d..f300dc4ad 100644
--- a/apps/server/src/api/v2/reports/[id]/PUT.ts
+++ b/apps/server/src/api/v2/reports/[id]/PUT.ts
@@ -2,6 +2,7 @@ import type { User } from '@buster/database';
import { getUserOrganizationId, updateReport } from '@buster/database';
import type { UpdateReportRequest, UpdateReportResponse } from '@buster/server-shared/reports';
import { UpdateReportRequestSchema } from '@buster/server-shared/reports';
+import { platejsToMarkdown } from '@buster/server-utils/report';
import { zValidator } from '@hono/zod-validator';
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
@@ -29,7 +30,9 @@ async function updateReportHandler(
throw new HTTPException(403, { message: 'User does not have permission to edit asset' });
}
- const { name, content, update_version = false } = request;
+ const { name, content: contentPlateJs, update_version = false } = request;
+
+ const transformedContent = contentPlateJs ? await platejsToMarkdown(contentPlateJs) : undefined;
// Update the report in the database
await updateReport(
@@ -37,7 +40,7 @@ async function updateReportHandler(
reportId,
userId: user.id,
name,
- content,
+ content: transformedContent,
},
update_version
);
diff --git a/packages/server-utils/src/report/callout-serializer.ts b/packages/server-utils/src/report/callout-serializer.ts
index 10aff9360..762c44cb2 100644
--- a/packages/server-utils/src/report/callout-serializer.ts
+++ b/packages/server-utils/src/report/callout-serializer.ts
@@ -1,22 +1,27 @@
import {
type MdNodeParser,
convertChildrenDeserialize,
- convertNodesSerialize,
parseAttributes,
+ serializeMd,
} from '@platejs/markdown';
export const calloutSerializer: MdNodeParser<'callout'> = {
serialize: (node, options) => {
// Extract the icon from the node (assuming it's stored as an attribute)
const icon = node.icon || '💡';
- const content = convertNodesSerialize(node.children, options);
- // Return the markdown representation
+ if (!options.editor) {
+ throw new Error('Editor is required');
+ }
+
+ const content = serializeMd(options.editor, {
+ ...options,
+ value: node.children,
+ });
+
return {
- attributes: {
- icon,
- },
- children: content,
+ type: 'html',
+ value: `${content}`,
};
},
deserialize: (node, deco, options) => {
diff --git a/packages/server-utils/src/report/index.ts b/packages/server-utils/src/report/index.ts
index f0cb3b1c5..527d8a1d7 100644
--- a/packages/server-utils/src/report/index.ts
+++ b/packages/server-utils/src/report/index.ts
@@ -1,2 +1,2 @@
-export { markdownToPlatejs } from './markdown-to-platejs';
+export { markdownToPlatejs, platejsToMarkdown } from './platejs-conversions';
export { MarkdownPlugin } from './MarkdownPlugin';
diff --git a/packages/server-utils/src/report/markdown-to-platejs.test.ts b/packages/server-utils/src/report/platejs-conversion.test.ts
similarity index 62%
rename from packages/server-utils/src/report/markdown-to-platejs.test.ts
rename to packages/server-utils/src/report/platejs-conversion.test.ts
index 928b74e70..d5ddf03dc 100644
--- a/packages/server-utils/src/report/markdown-to-platejs.test.ts
+++ b/packages/server-utils/src/report/platejs-conversion.test.ts
@@ -1,5 +1,6 @@
+import type { ReportElements } from '@buster/database';
import { describe, expect, it } from 'vitest';
-import { markdownToPlatejs } from './markdown-to-platejs';
+import { markdownToPlatejs, platejsToMarkdown } from './platejs-conversions';
describe('markdownToPlatejs', () => {
it('should convert elaborate markdown to platejs', async () => {
@@ -71,3 +72,76 @@ Here's an unordered list:
expect(platejs).toBeDefined();
});
});
+
+describe('platejsToMarkdown', () => {
+ it('should convert platejs to markdown', async () => {
+ const markdown = `This is a simple paragraph.\n`;
+ const elements: ReportElements = [
+ {
+ type: 'p',
+ children: [
+ {
+ text: 'This is a simple paragraph.',
+ },
+ ],
+ },
+ ];
+ const markdown2 = await platejsToMarkdown(elements);
+ expect(markdown2).toBe(markdown);
+ });
+
+ it('should convert callout platejs element to markdown', async () => {
+ const elements: ReportElements = [
+ {
+ type: 'h1',
+ children: [
+ {
+ text: 'Main Title',
+ },
+ ],
+ },
+ {
+ type: 'p',
+ children: [
+ {
+ text: 'This paragraph has ',
+ },
+ {
+ text: 'bold text',
+ bold: true,
+ },
+ {
+ text: ' in it.',
+ },
+ ],
+ },
+ ];
+ const markdown2 = await platejsToMarkdown(elements);
+ const markdown = `# Main Title\n\nThis paragraph has **bold text** in it.\n`;
+ expect(markdown2).toBe(markdown);
+ });
+
+ it('should convert callout platejs element to markdown', async () => {
+ const elements: ReportElements = [
+ {
+ type: 'callout',
+ icon: '⚠️',
+ variant: 'warning',
+ children: [
+ {
+ type: 'p' as const,
+ children: [
+ {
+ text: 'This is a simple paragraph.',
+ },
+ ],
+ },
+ ],
+ },
+ ];
+ const markdownFromPlatejs = await platejsToMarkdown(elements);
+
+ const expectedMarkdown = `This is a simple paragraph.\n\n`;
+ expect(markdownFromPlatejs).toBe(expectedMarkdown);
+ });
+});
diff --git a/packages/server-utils/src/report/platejs-conversions.ts b/packages/server-utils/src/report/platejs-conversions.ts
new file mode 100644
index 000000000..d17eca7f9
--- /dev/null
+++ b/packages/server-utils/src/report/platejs-conversions.ts
@@ -0,0 +1,20 @@
+import { type ReportElements, ReportElementsSchema } from '@buster/database';
+import type { Descendant } from 'platejs';
+import { SERVER_EDITOR } from './server-editor';
+
+export const markdownToPlatejs = async (markdown: string) => {
+ const descendants = SERVER_EDITOR.api.markdown.deserialize(markdown);
+
+ const safeParsedElements = ReportElementsSchema.safeParse(descendants);
+
+ return {
+ error: safeParsedElements.error,
+ elements: safeParsedElements.data,
+ descendants,
+ markdown,
+ };
+};
+
+export const platejsToMarkdown = async (elements: ReportElements): Promise => {
+ return SERVER_EDITOR.api.markdown.serialize({ value: elements as Descendant[] });
+};
diff --git a/packages/server-utils/src/report/markdown-to-platejs.ts b/packages/server-utils/src/report/server-editor.ts
similarity index 70%
rename from packages/server-utils/src/report/markdown-to-platejs.ts
rename to packages/server-utils/src/report/server-editor.ts
index 52b06374d..985f0c02b 100644
--- a/packages/server-utils/src/report/markdown-to-platejs.ts
+++ b/packages/server-utils/src/report/server-editor.ts
@@ -1,4 +1,3 @@
-import { type ReportElements, ReportElementsSchema } from '@buster/database';
import { AutoformatPlugin } from '@platejs/autoformat';
import {
BaseBasicBlocksPlugin,
@@ -50,19 +49,6 @@ const serverNode = [
MarkdownPlugin,
];
-const SERVER_EDITOR = createSlateEditor({
+export const SERVER_EDITOR = createSlateEditor({
plugins: serverNode,
});
-
-export const markdownToPlatejs = async (markdown: string) => {
- const descendants = SERVER_EDITOR.api.markdown.deserialize(markdown);
-
- const safeParsedElements = ReportElementsSchema.safeParse(descendants);
-
- return {
- error: safeParsedElements.error,
- elements: safeParsedElements.data,
- descendants,
- markdown,
- };
-};