-
Notifications
You must be signed in to change notification settings - Fork 6
Markdown #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Markdown #7
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { runScript } from 'run-script' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { type Row } from 'common/supabase/utils' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { tiptapToMarkdown } from 'common/util/tiptap-to-markdown' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { chunk } from 'lodash' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { type SupabaseTransaction } from 'shared/supabase/init' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { pgp } from 'shared/supabase/init' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runScript(async ({ pg }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const messages = await pg.manyOrNone<Row<'private_user_messages'>>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `select * from private_user_messages` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const updates = messages.map((m) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: m.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: tiptapToMarkdown(m.content as any), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+8
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve type safety for content conversion. The script uses - const updates = messages.map((m) => ({
- id: m.id,
- content: tiptapToMarkdown(m.content as any),
- }))
+ const updates = messages.map((m) => ({
+ id: m.id,
+ content: typeof m.content === 'object' && m.content !== null
+ ? tiptapToMarkdown(m.content)
+ : String(m.content),
+ }))📝 Committable suggestion
Suggested change
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you're wrong There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sipec You're right, I apologize for my incorrect suggestion. I misunderstood the context of your migration script. The |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await pg.tx(async (tx) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await tx.none( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `alter table private_user_messages | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| drop column content, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| add column content text not null default ''` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const c of chunk(updates, 1000)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('updating chunk') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await bulkUpdate(tx, c) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await tx.none( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `alter table private_user_messages | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alter column content drop default` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const values = await tx.many( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `select * from private_user_messages | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| limit 10` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(values) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error(`don't commit`) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling and consider making the transaction commit optional. The script:
Consider:
await pg.tx(async (tx) => {
await tx.none(
`alter table private_user_messages
drop column content,
add column content text not null default ''`
)
+ let processedCount = 0;
for (const c of chunk(updates, 1000)) {
- console.log('updating chunk')
+ console.log(`Updating chunk ${processedCount + 1} to ${processedCount + c.length} of ${updates.length}`)
await bulkUpdate(tx, c)
+ processedCount += c.length;
}
await tx.none(
`alter table private_user_messages
alter column content drop default`
)
const values = await tx.many(
`select * from private_user_messages
limit 10`
)
console.log(values)
- throw new Error(`don't commit`)
+ // Default to not committing for safety
+ if (process.env.COMMIT_CHANGES !== 'true') {
+ console.log('Dry run completed. Set COMMIT_CHANGES=true to commit changes.')
+ throw new Error('Migration completed but not committed (dry run)')
+ }
+ console.log('Migration completed and committed successfully.')
})📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const bulkUpdate = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tx: SupabaseTransaction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updates: { id: number; content: string }[] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const values = updates | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map((u) => pgp.as.format('($(id), $(content))', u)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .join(',') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return tx.none( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `update private_user_messages p set content = v.content | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from (values ${values}) as v(id, content) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| where p.id = v.id` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| -- To preserve existing chat messages, instead run messages-to-markdown.ts | ||
| -- | ||
| -- If this errors content is already no longer jsonb | ||
| assert ( | ||
| select | ||
| count(*) > 0 | ||
| from | ||
| private_user_messages | ||
| where | ||
| content ->> 'type' = 'doc' | ||
| ), | ||
| 'No Tiptap messages found'; | ||
|
|
||
| alter table private_user_messages | ||
| drop column content; | ||
|
|
||
| alter table private_user_messages | ||
| add column content text not null default ''; | ||
|
|
||
| alter table private_user_messages | ||
| alter column content | ||
| drop default |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,19 +12,13 @@ | |||||||||||||||||||||||
| "sideEffects": false, | ||||||||||||||||||||||||
| "dependencies": { | ||||||||||||||||||||||||
| "@supabase/supabase-js": "2.38.5", | ||||||||||||||||||||||||
| "@tiptap/core": "2.3.2", | ||||||||||||||||||||||||
| "@tiptap/extension-image": "2.3.2", | ||||||||||||||||||||||||
| "@tiptap/extension-link": "2.3.2", | ||||||||||||||||||||||||
| "@tiptap/extension-mention": "2.3.2", | ||||||||||||||||||||||||
| "@tiptap/pm": "2.3.2", | ||||||||||||||||||||||||
| "@tiptap/starter-kit": "2.3.2", | ||||||||||||||||||||||||
| "@tiptap/suggestion": "2.3.2", | ||||||||||||||||||||||||
| "dayjs": "1.11.4", | ||||||||||||||||||||||||
| "lodash": "4.17.21", | ||||||||||||||||||||||||
| "string-similarity": "4.0.4", | ||||||||||||||||||||||||
| "zod": "3.21.4" | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| "devDependencies": { | ||||||||||||||||||||||||
| "@tiptap/core": "2.3.2", | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify whether `@tiptap/core` is imported as a value (non-type) in common.
# Expected: no matches if safe to keep `@tiptap/core` only in devDependencies.
rg -nP --type=ts "import\s+\{(?!\s*type\b)[^}]+\}\s+from\s+['\"]@tiptap/core['\"]" common/src
rg -nP --type=ts "import\s+[^;]*from\s+['\"]@tiptap/core['\"]" common/src -C2Repository: sipec/polylove Length of output: 1478 🏁 Script executed: cat -n common/src/util/parse.ts | head -30Repository: sipec/polylove Length of output: 1394
Restore Fix "dependencies": {
+ "@tiptap/core": "2.3.2",
"@supabase/supabase-js": "2.38.5",
"dayjs": "1.11.4",
"lodash": "4.17.21",
"string-similarity": "4.0.4",
"zod": "3.21.4"
},
"devDependencies": {
- "@tiptap/core": "2.3.2",
"@types/jest": "29.2.4",📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| "@types/jest": "29.2.4", | ||||||||||||||||||||||||
| "@types/lodash": "4.14.178", | ||||||||||||||||||||||||
| "@types/string-similarity": "4.0.0", | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,7 @@ | ||
| import { | ||
| getText, | ||
| getSchema, | ||
| getTextSerializersFromSchema, | ||
| Node, | ||
| JSONContent, | ||
| } from '@tiptap/core' | ||
| import { Node as ProseMirrorNode } from '@tiptap/pm/model' | ||
| import { StarterKit } from '@tiptap/starter-kit' | ||
| import { Image } from '@tiptap/extension-image' | ||
| import { Link } from '@tiptap/extension-link' | ||
| import { Mention } from '@tiptap/extension-mention' | ||
| import Iframe from './tiptap-iframe' | ||
| import { JSONContent } from '@tiptap/core' | ||
| import { find } from 'linkifyjs' | ||
| import { uniq } from 'lodash' | ||
| import { compareTwoStrings } from 'string-similarity' | ||
| import { tiptapToMarkdown } from './tiptap-to-markdown' | ||
|
|
||
| /** get first url in text. like "notion.so " -> "http://notion.so"; "notion" -> null */ | ||
| export function getUrl(text: string) { | ||
|
|
@@ -37,43 +25,6 @@ const checkAgainstQuery = (query: string, corpus: string) => | |
| export const searchInAny = (query: string, ...fields: string[]) => | ||
| fields.some((field) => checkAgainstQuery(query, field)) | ||
|
|
||
| /** @return user ids of all \@mentions */ | ||
| export function parseMentions(data: JSONContent): string[] { | ||
| const mentions = data.content?.flatMap(parseMentions) ?? [] //dfs | ||
| if (data.type === 'mention' && data.attrs) { | ||
| mentions.push(data.attrs.id as string) | ||
| } | ||
| return uniq(mentions) | ||
| } | ||
|
|
||
| export const extensions = [ | ||
| StarterKit, | ||
| Link, | ||
| Image.extend({ renderText: () => '[image]' }), | ||
| Mention, // user @mention | ||
| Iframe.extend({ | ||
| renderText: ({ node }) => | ||
| '[embed]' + node.attrs.src ? `(${node.attrs.src})` : '', | ||
| }), | ||
| ] | ||
|
|
||
| const extensionSchema = getSchema(extensions) | ||
| const extensionSerializers = getTextSerializersFromSchema(extensionSchema) | ||
|
|
||
| export function richTextToString(text?: JSONContent) { | ||
| if (!text) return '' | ||
| try { | ||
| const node = ProseMirrorNode.fromJSON(extensionSchema, text) | ||
| return getText(node, { | ||
| blockSeparator: '\n\n', | ||
| textSerializers: extensionSerializers, | ||
| }) | ||
| } catch (e) { | ||
| console.error('error parsing rich text', `"${text}":`, e) | ||
| return '' | ||
| } | ||
| } | ||
|
|
||
| export function parseJsonContentToText(content: JSONContent | string) { | ||
| return typeof content === 'string' ? content : richTextToString(content) | ||
| return typeof content === 'string' ? content : tiptapToMarkdown(content) | ||
|
Comment on lines
28
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep
🤖 Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t send Markdown to notification copy.
This value becomes
Notification.sourceText, andbackend/email/emails/functions/helpers.tsx:1-30forwards the same string unchanged into the email flow. UsingtiptapToMarkdown(content)here will surface raw Markdown like**bold**and# headingin notifications/emails whenever a comment uses formatting. Use a plain-text serializer for notification text.🤖 Prompt for AI Agents