mirror of https://github.com/buster-so/buster.git
Add markdown conversion function
This commit is contained in:
parent
a26242c46d
commit
8e31d18066
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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: `<callout icon="${icon}">${content}</callout>`,
|
||||
};
|
||||
},
|
||||
deserialize: (node, deco, options) => {
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { markdownToPlatejs } from './markdown-to-platejs';
|
||||
export { markdownToPlatejs, platejsToMarkdown } from './platejs-conversions';
|
||||
export { MarkdownPlugin } from './MarkdownPlugin';
|
||||
|
|
|
@ -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 = `<callout icon="⚠️">This is a simple paragraph.\n</callout>\n`;
|
||||
expect(markdownFromPlatejs).toBe(expectedMarkdown);
|
||||
});
|
||||
});
|
|
@ -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<string> => {
|
||||
return SERVER_EDITOR.api.markdown.serialize({ value: elements as Descendant[] });
|
||||
};
|
|
@ -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,
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue