") === -1) { + if (type === 'markdown') { + return NodeHtmlMarkdown.translate(value); + } + + if (value.indexOf('
') === -1) { return value; } @@ -145,7 +151,10 @@ export const stripHtmlValidation = ( .replace(/<\/p>/gi, ''); if (replaceBold) { - return striptags(convertLinkedinMention(convertToAscii(html)), ['ul', 'li']); + return striptags(convertLinkedinMention(convertToAscii(html)), [ + 'ul', + 'li', + ]); } // Strip all other tags diff --git a/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts b/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts index d2f8140a..7bb42cb8 100644 --- a/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts @@ -467,7 +467,7 @@ export class PostsService { await Promise.all( (newPosts || []).map(async (p) => ({ id: p.id, - message: stripHtmlValidation(p.content, true), + message: stripHtmlValidation(getIntegration.editor, p.content, true), settings: JSON.parse(p.settings || '{}'), media: await this.updateMedia( p.id, diff --git a/libraries/nestjs-libraries/src/dtos/posts/providers-settings/dev.to.settings.dto.ts b/libraries/nestjs-libraries/src/dtos/posts/providers-settings/dev.to.settings.dto.ts index 7817ec3e..f1e5813b 100644 --- a/libraries/nestjs-libraries/src/dtos/posts/providers-settings/dev.to.settings.dto.ts +++ b/libraries/nestjs-libraries/src/dtos/posts/providers-settings/dev.to.settings.dto.ts @@ -43,5 +43,5 @@ export class DevToSettingsDto { @ArrayMaxSize(4) @Type(() => DevToTagsSettingsDto) @ValidateNested({ each: true }) - tags: DevToTagsSettingsDto[]; + tags: DevToTagsSettingsDto[] = []; } diff --git a/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts b/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts index 38709136..9346d4ca 100644 --- a/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts @@ -313,13 +313,13 @@ export class BlueskyProvider extends SocialAbstract implements SocialProvider { if (postDetails?.[0]?.settings?.active_thread_finisher) { const rt = new RichText({ - text: stripHtmlValidation(postDetails?.[0]?.settings?.thread_finisher, true), + text: stripHtmlValidation('normal', postDetails?.[0]?.settings?.thread_finisher, true), }); await rt.detectFacets(agent); await agent.post({ - text: stripHtmlValidation(rt.text, true), + text: stripHtmlValidation('normal', rt.text, true), facets: rt.facets, createdAt: new Date().toISOString(), embed: { @@ -460,7 +460,7 @@ export class BlueskyProvider extends SocialAbstract implements SocialProvider { if (getThread.data.thread.post?.likeCount >= +fields.likesAmount) { await timer(2000); const rt = new RichText({ - text: stripHtmlValidation(fields.post, true), + text: stripHtmlValidation('normal', fields.post, true), }); await agent.post({ diff --git a/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts b/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts index b426cfe7..37ed96fa 100644 --- a/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts @@ -502,7 +502,7 @@ export class ThreadsProvider extends SocialAbstract implements SocialProvider { const form = new FormData(); form.append('media_type', 'TEXT'); - form.append('text', stripHtmlValidation(fields.post, true)); + form.append('text', stripHtmlValidation('normal', fields.post, true)); form.append('reply_to_id', id); form.append('access_token', integration.token); diff --git a/libraries/nestjs-libraries/src/integrations/social/x.provider.ts b/libraries/nestjs-libraries/src/integrations/social/x.provider.ts index c6ac2445..574c648e 100644 --- a/libraries/nestjs-libraries/src/integrations/social/x.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/x.provider.ts @@ -152,7 +152,7 @@ export class XProvider extends SocialAbstract implements SocialProvider { await timer(2000); await client.v2.tweet({ - text: stripHtmlValidation(fields.post, true), + text: stripHtmlValidation('normal', fields.post, true), reply: { in_reply_to_tweet_id: id }, }); return true; diff --git a/package.json b/package.json index 61696e69..6b988745 100644 --- a/package.json +++ b/package.json @@ -161,6 +161,7 @@ "nestjs-real-ip": "^3.0.1", "next": "^14.2.30", "next-plausible": "^3.12.0", + "node-html-markdown": "^1.3.0", "node-telegram-bot-api": "^0.66.0", "nodemailer": "^6.9.15", "nostr-tools": "^2.10.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f63b7bd6..b4f9dc81 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -360,6 +360,9 @@ importers: next-plausible: specifier: ^3.12.0 version: 3.12.4(next@14.2.30(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.89.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + node-html-markdown: + specifier: ^1.3.0 + version: 1.3.0 node-telegram-bot-api: specifier: ^0.66.0 version: 0.66.0(request@2.88.2) @@ -9272,6 +9275,10 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + header-case@2.0.4: resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} @@ -11430,6 +11437,13 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + node-html-markdown@1.3.0: + resolution: {integrity: sha512-OeFi3QwC/cPjvVKZ114tzzu+YoR+v9UXW5RwSXGUqGb0qCl0DvP406tzdL7SFn8pZrMyzXoisfG2zcuF9+zw4g==} + engines: {node: '>=10.0.0'} + + node-html-parser@6.1.13: + resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -26406,6 +26420,8 @@ snapshots: property-information: 7.1.0 space-separated-tokens: 2.0.2 + he@1.2.0: {} + header-case@2.0.4: dependencies: capital-case: 1.0.4 @@ -29253,6 +29269,15 @@ snapshots: node-gyp-build@4.8.4: {} + node-html-markdown@1.3.0: + dependencies: + node-html-parser: 6.1.13 + + node-html-parser@6.1.13: + dependencies: + css-select: 5.2.2 + he: 1.2.0 + node-int64@0.4.0: {} node-mock-http@1.0.1: {}