@dinoxx/dinox-cli 1.0.18 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -34
- package/dist/cli.js +15 -1
- package/dist/commands/auth/index.d.ts +2 -0
- package/dist/commands/auth/index.js +209 -163
- package/dist/commands/boxes/index.d.ts +2 -0
- package/dist/commands/boxes/index.js +119 -75
- package/dist/commands/boxes/repo.d.ts +8 -0
- package/dist/commands/boxes/repo.js +41 -0
- package/dist/commands/config/index.d.ts +2 -0
- package/dist/commands/config/index.js +85 -36
- package/dist/commands/descriptor/register.d.ts +8 -0
- package/dist/commands/descriptor/register.js +113 -0
- package/dist/commands/descriptor/types.d.ts +37 -0
- package/dist/commands/descriptor/types.js +17 -0
- package/dist/commands/graph/index.d.ts +2 -0
- package/dist/commands/graph/index.js +143 -73
- package/dist/commands/info/index.d.ts +2 -0
- package/dist/commands/info/index.js +41 -14
- package/dist/commands/mcp/index.js +11 -10
- package/dist/commands/mcp/server.js +6 -3
- package/dist/commands/mcp/tools.js +30 -104
- package/dist/commands/mcp/types.d.ts +8 -1
- package/dist/commands/meta/index.d.ts +2 -0
- package/dist/commands/meta/index.js +64 -33
- package/dist/commands/meta/repo.d.ts +6 -0
- package/dist/commands/meta/repo.js +6 -0
- package/dist/commands/notes/actions.d.ts +10 -0
- package/dist/commands/notes/actions.js +403 -0
- package/dist/commands/notes/descriptors.d.ts +4 -0
- package/dist/commands/notes/descriptors.js +250 -0
- package/dist/commands/notes/dryRun.d.ts +31 -0
- package/dist/commands/notes/dryRun.js +130 -0
- package/dist/commands/notes/index.d.ts +2 -51
- package/dist/commands/notes/index.js +2 -581
- package/dist/commands/notes/repo.d.ts +9 -0
- package/dist/commands/notes/repo.js +56 -10
- package/dist/commands/notes/runtime.d.ts +28 -0
- package/dist/commands/notes/runtime.js +185 -0
- package/dist/commands/notes/searchOutput.d.ts +10 -2
- package/dist/commands/notes/searchOutput.js +14 -2
- package/dist/commands/notes/searchResponse.d.ts +51 -0
- package/dist/commands/notes/searchResponse.js +56 -0
- package/dist/commands/notes/searchSql.js +2 -0
- package/dist/commands/prompt/index.d.ts +2 -0
- package/dist/commands/prompt/index.js +122 -72
- package/dist/commands/prompt/repo.d.ts +7 -0
- package/dist/commands/prompt/repo.js +46 -0
- package/dist/commands/schema/commandMetadata.d.ts +2 -0
- package/dist/commands/schema/commandMetadata.js +18 -0
- package/dist/commands/schema/globalOptions.d.ts +3 -0
- package/dist/commands/schema/globalOptions.js +3 -0
- package/dist/commands/schema/index.d.ts +4 -0
- package/dist/commands/schema/index.js +109 -0
- package/dist/commands/schema/renderSkills.d.ts +6 -0
- package/dist/commands/schema/renderSkills.js +216 -0
- package/dist/commands/schema/spec.d.ts +6 -0
- package/dist/commands/schema/spec.js +40 -0
- package/dist/commands/schema/types.d.ts +47 -0
- package/dist/commands/schema/types.js +1 -0
- package/dist/commands/storage/index.d.ts +4 -0
- package/dist/commands/storage/index.js +292 -0
- package/dist/commands/storage/repo.d.ts +162 -0
- package/dist/commands/storage/repo.js +751 -0
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.js +41 -27
- package/dist/commands/tags/index.d.ts +2 -0
- package/dist/commands/tags/index.js +121 -79
- package/dist/commands/tags/repo.d.ts +7 -0
- package/dist/commands/tags/repo.js +52 -0
- package/dist/commands/todo/dryRun.d.ts +23 -0
- package/dist/commands/todo/dryRun.js +133 -0
- package/dist/commands/todo/index.d.ts +2 -0
- package/dist/commands/todo/index.js +285 -135
- package/dist/commands/todo/repo.d.ts +11 -0
- package/dist/commands/todo/repo.js +37 -9
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.js +35 -13
- package/dist/commands/writeDryRun.d.ts +62 -0
- package/dist/commands/writeDryRun.js +131 -0
- package/dist/constants/links.d.ts +1 -1
- package/dist/constants/links.js +1 -1
- package/dist/daemon/ensure.js +3 -2
- package/dist/daemon/index.js +17 -15
- package/dist/dinox.js +9 -13
- package/dist/powersync/schema/index.d.ts +27 -0
- package/dist/powersync/schema/index.js +2 -0
- package/dist/powersync/schema/note.d.ts +1 -0
- package/dist/powersync/schema/note.js +1 -0
- package/dist/powersync/schema/projects.d.ts +3 -0
- package/dist/powersync/schema/projects.js +3 -0
- package/dist/powersync/schema/storage.d.ts +24 -0
- package/dist/powersync/schema/storage.js +24 -0
- package/dist/skills/check.d.ts +6 -0
- package/dist/skills/check.js +254 -0
- package/dist/utils/bidlinkCanonicalization.d.ts +2 -0
- package/dist/utils/bidlinkCanonicalization.js +161 -0
- package/dist/utils/dryRun.d.ts +13 -0
- package/dist/utils/dryRun.js +69 -0
- package/dist/utils/output.d.ts +19 -0
- package/dist/utils/output.js +155 -1
- package/dist/utils/terminalSanitization.d.ts +2 -0
- package/dist/utils/terminalSanitization.js +33 -0
- package/dist/utils/tiptapMarkdown.d.ts +4 -1
- package/dist/utils/tiptapMarkdown.js +285 -113
- package/dist/utils/tiptapMarkdownSchema.d.ts +37 -0
- package/dist/utils/tiptapMarkdownSchema.js +577 -0
- package/dist/utils/tiptapMarkdownSchemaUtils.d.ts +74 -0
- package/dist/utils/tiptapMarkdownSchemaUtils.js +394 -0
- package/dist/utils/updateNotice.d.ts +7 -0
- package/dist/utils/updateNotice.js +64 -0
- package/package.json +25 -3
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const ANSI_ESCAPE_RE = /\x1b\[[0-9;?>=!]*[a-zA-Z]|\x1b\][^\x07]*\x07/g;
|
|
2
|
+
export function isDangerousUnicode(rune) {
|
|
3
|
+
return ((rune >= 0x200b && rune <= 0x200d) ||
|
|
4
|
+
rune === 0xfeff ||
|
|
5
|
+
(rune >= 0x202a && rune <= 0x202e) ||
|
|
6
|
+
(rune >= 0x2028 && rune <= 0x2029) ||
|
|
7
|
+
(rune >= 0x2066 && rune <= 0x2069));
|
|
8
|
+
}
|
|
9
|
+
export function sanitizeForTerminal(text) {
|
|
10
|
+
let sanitized = text;
|
|
11
|
+
if (sanitized.includes('\x1b')) {
|
|
12
|
+
sanitized = sanitized.replace(ANSI_ESCAPE_RE, '');
|
|
13
|
+
}
|
|
14
|
+
let result = '';
|
|
15
|
+
for (const char of sanitized) {
|
|
16
|
+
const code = char.codePointAt(0);
|
|
17
|
+
if (code === undefined) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (char === '\n' || char === '\t') {
|
|
21
|
+
result += char;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (code < 0x20 || code === 0x7f) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (isDangerousUnicode(code)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
result += char;
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { JSONContent } from '@tiptap/core';
|
|
2
|
+
import { createAudioNodeFromLink, createFileNodeFromLink, createImageNodeWithMetadata, createVideoNodeFromLink } from './tiptapMarkdownSchema.js';
|
|
3
|
+
import { inferMimeTypeFromHref, normalizeFileBlockAttrs } from './tiptapMarkdownSchemaUtils.js';
|
|
2
4
|
export type MarkdownConversion = {
|
|
3
5
|
contentJson: JSONContent;
|
|
4
6
|
contentText: string;
|
|
5
7
|
};
|
|
6
8
|
export declare function convertMarkdownToNoteContent(markdown: string): MarkdownConversion;
|
|
9
|
+
export { createAudioNodeFromLink, createFileNodeFromLink, createImageNodeWithMetadata, createVideoNodeFromLink, inferMimeTypeFromHref, normalizeFileBlockAttrs, };
|
|
@@ -1,109 +1,222 @@
|
|
|
1
|
-
import { Editor } from '@tiptap/core';
|
|
2
|
-
import { Image } from '@tiptap/extension-image';
|
|
3
|
-
import { ListItem } from '@tiptap/extension-list';
|
|
4
|
-
import { Markdown } from '@tiptap/markdown';
|
|
5
|
-
import { StarterKit } from '@tiptap/starter-kit';
|
|
6
|
-
import { TableKit } from '@tiptap/extension-table';
|
|
7
|
-
import { UniqueID, generateUniqueIds } from '@tiptap/extension-unique-id';
|
|
8
1
|
import { DinoxError } from './errors.js';
|
|
9
2
|
import { generateId } from './id.js';
|
|
10
|
-
|
|
3
|
+
import { createAudioNodeFromLink, createFileNodeFromLink, createImageNodeWithMetadata, createVideoNodeFromLink, getDinoxMarkdownManager, } from './tiptapMarkdownSchema.js';
|
|
4
|
+
import { inferMimeTypeFromHref, normalizeDinoxImageAttrs, normalizeFileBlockAttrs, normalizeFrontmatterRaw, parseDinoxMarkdownComment, } from './tiptapMarkdownSchemaUtils.js';
|
|
11
5
|
const CONTENT_PREVIEW_MAX_LENGTH = 400;
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
'
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
TableKit,
|
|
84
|
-
markdownExtension,
|
|
85
|
-
uniqueIdExtension,
|
|
86
|
-
];
|
|
87
|
-
function sanitizeNode(node) {
|
|
88
|
-
if (!node || typeof node !== 'object') {
|
|
6
|
+
const MEDIA_COMMENT_PATTERN = /<!--\s*({[\s\S]*?})\s*-->/g;
|
|
7
|
+
const MEDIA_COMMENT_PLACEHOLDER_PREFIX = 'DINOX_MEDIA_META_';
|
|
8
|
+
const TASK_MARKER_RE = /^\s*\[( |x|X)\]\s+/;
|
|
9
|
+
function createParagraphNode(text = '') {
|
|
10
|
+
const paragraph = {
|
|
11
|
+
type: 'paragraph',
|
|
12
|
+
attrs: { id: generateId() },
|
|
13
|
+
};
|
|
14
|
+
if (text) {
|
|
15
|
+
paragraph.content = [{ type: 'text', text }];
|
|
16
|
+
}
|
|
17
|
+
return paragraph;
|
|
18
|
+
}
|
|
19
|
+
function createEmptyDocument() {
|
|
20
|
+
return {
|
|
21
|
+
type: 'doc',
|
|
22
|
+
content: [],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function createFallbackDocument(input) {
|
|
26
|
+
const text = typeof input === 'string' ? input : String(input || '');
|
|
27
|
+
if (!text.trim()) {
|
|
28
|
+
return createEmptyDocument();
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
type: 'doc',
|
|
32
|
+
content: [createParagraphNode(text)],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function normalizeTaskItemContent(content) {
|
|
36
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
37
|
+
return [createParagraphNode('')];
|
|
38
|
+
}
|
|
39
|
+
const hasParagraph = content.some((child) => child?.type === 'paragraph');
|
|
40
|
+
return hasParagraph ? content : [createParagraphNode(''), ...content];
|
|
41
|
+
}
|
|
42
|
+
function tryConvertListItemToTaskItem(node) {
|
|
43
|
+
if (node.type !== 'listItem' || !Array.isArray(node.content) || node.content.length === 0) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const firstParagraph = node.content.find((child) => child?.type === 'paragraph');
|
|
47
|
+
if (!firstParagraph ||
|
|
48
|
+
!Array.isArray(firstParagraph.content) ||
|
|
49
|
+
firstParagraph.content.length === 0) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const firstInline = firstParagraph.content[0];
|
|
53
|
+
if (firstInline?.type !== 'text' || typeof firstInline.text !== 'string') {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const match = firstInline.text.match(TASK_MARKER_RE);
|
|
57
|
+
if (!match) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
firstInline.text = firstInline.text.slice(match[0].length);
|
|
61
|
+
return {
|
|
62
|
+
...node,
|
|
63
|
+
type: 'taskItem',
|
|
64
|
+
attrs: { checked: match[1].toLowerCase() === 'x', id: generateId() },
|
|
65
|
+
content: normalizeTaskItemContent(node.content),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function normalizeTaskLists(node) {
|
|
69
|
+
if (!Array.isArray(node.content) || node.content.length === 0) {
|
|
70
|
+
return node;
|
|
71
|
+
}
|
|
72
|
+
node.content = node.content.map((child) => normalizeTaskLists(child));
|
|
73
|
+
if (node.type !== 'bulletList' && node.type !== 'orderedList') {
|
|
74
|
+
return node;
|
|
75
|
+
}
|
|
76
|
+
if (node.content.length === 0 || node.content.some((child) => child?.type !== 'listItem')) {
|
|
89
77
|
return node;
|
|
90
78
|
}
|
|
91
|
-
const
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
79
|
+
const taskItems = node.content.map((child) => tryConvertListItemToTaskItem(child));
|
|
80
|
+
if (taskItems.some((child) => child == null)) {
|
|
81
|
+
return node;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
...node,
|
|
85
|
+
type: 'taskList',
|
|
86
|
+
attrs: undefined,
|
|
87
|
+
content: taskItems,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function validateAndCleanDocument(doc) {
|
|
91
|
+
if (!doc || doc.type !== 'doc') {
|
|
92
|
+
return createEmptyDocument();
|
|
93
|
+
}
|
|
94
|
+
if (!Array.isArray(doc.content)) {
|
|
95
|
+
doc.content = [];
|
|
96
96
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
doc.content = doc.content.filter((node) => node && typeof node === 'object' && typeof node.type === 'string');
|
|
98
|
+
const normalizedContent = [];
|
|
99
|
+
let frontmatterNode = null;
|
|
100
|
+
for (const node of doc.content) {
|
|
101
|
+
if (node.type === 'frontmatter') {
|
|
102
|
+
const raw = normalizeFrontmatterRaw(node.attrs?.raw);
|
|
103
|
+
if (!raw || frontmatterNode) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
frontmatterNode = {
|
|
107
|
+
...node,
|
|
108
|
+
attrs: {
|
|
109
|
+
...(node.attrs || {}),
|
|
110
|
+
raw,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
continue;
|
|
101
114
|
}
|
|
102
|
-
|
|
103
|
-
|
|
115
|
+
normalizedContent.push(node);
|
|
116
|
+
}
|
|
117
|
+
doc.content = frontmatterNode ? [frontmatterNode, ...normalizedContent] : normalizedContent;
|
|
118
|
+
if (doc.content.length === 0 ||
|
|
119
|
+
(doc.content.length === 1 && doc.content[0]?.type === 'frontmatter')) {
|
|
120
|
+
doc.content.push(createParagraphNode(''));
|
|
121
|
+
}
|
|
122
|
+
return normalizeTaskLists(doc);
|
|
123
|
+
}
|
|
124
|
+
function preprocessMarkdownMediaComments(markdown) {
|
|
125
|
+
const metadataByPlaceholder = new Map();
|
|
126
|
+
let counter = 0;
|
|
127
|
+
const nextMarkdown = markdown.replace(MEDIA_COMMENT_PATTERN, (rawComment) => {
|
|
128
|
+
const parsed = parseDinoxMarkdownComment(rawComment);
|
|
129
|
+
if (!parsed) {
|
|
130
|
+
return rawComment;
|
|
104
131
|
}
|
|
132
|
+
const placeholder = `${MEDIA_COMMENT_PLACEHOLDER_PREFIX}${counter++}__`;
|
|
133
|
+
metadataByPlaceholder.set(placeholder, parsed);
|
|
134
|
+
return placeholder;
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
markdown: nextMarkdown,
|
|
138
|
+
metadataByPlaceholder,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function extractStandaloneMarkdownLink(content) {
|
|
142
|
+
if (!Array.isArray(content) || content.length !== 1) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const textNode = content[0];
|
|
146
|
+
if (textNode?.type !== 'text' || typeof textNode.text !== 'string') {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const marks = Array.isArray(textNode.marks) ? textNode.marks : [];
|
|
150
|
+
if (marks.length === 0 || marks.some((mark) => mark?.type !== 'link')) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const linkMark = marks.find((mark) => mark?.type === 'link');
|
|
154
|
+
const href = typeof linkMark?.attrs?.href === 'string' ? linkMark.attrs.href.trim() : '';
|
|
155
|
+
const label = textNode.text.trim();
|
|
156
|
+
return href && label ? { href, label } : null;
|
|
157
|
+
}
|
|
158
|
+
function extractMarkdownMediaCommentMetadata(node, metadataByPlaceholder) {
|
|
159
|
+
if (node?.type !== 'paragraph' || !Array.isArray(node.content) || node.content.length < 2) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const content = [...node.content];
|
|
163
|
+
const commentNode = content[content.length - 1];
|
|
164
|
+
if (commentNode?.type !== 'text' || typeof commentNode.text !== 'string') {
|
|
165
|
+
return null;
|
|
105
166
|
}
|
|
106
|
-
|
|
167
|
+
const comment = metadataByPlaceholder.get(commentNode.text.trim());
|
|
168
|
+
if (!comment) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
const meaningfulContent = content
|
|
172
|
+
.slice(0, -1)
|
|
173
|
+
.filter((child) => !(child.type === 'text' && typeof child.text === 'string' && child.text.trim() === ''));
|
|
174
|
+
return meaningfulContent.length ? { comment, content: meaningfulContent } : null;
|
|
175
|
+
}
|
|
176
|
+
function convertStandaloneMarkdownLinkParagraph(node, metadataByPlaceholder) {
|
|
177
|
+
const metadata = extractMarkdownMediaCommentMetadata(node, metadataByPlaceholder);
|
|
178
|
+
if (!metadata) {
|
|
179
|
+
return node;
|
|
180
|
+
}
|
|
181
|
+
if (metadata.content.length === 1 && metadata.content[0]?.type === 'image') {
|
|
182
|
+
return createImageNodeWithMetadata(normalizeDinoxImageAttrs((metadata.content[0].attrs || {})), metadata.comment);
|
|
183
|
+
}
|
|
184
|
+
const link = extractStandaloneMarkdownLink(metadata.content);
|
|
185
|
+
if (!link) {
|
|
186
|
+
return node;
|
|
187
|
+
}
|
|
188
|
+
switch (metadata.comment.kind) {
|
|
189
|
+
case 'video':
|
|
190
|
+
return createVideoNodeFromLink({
|
|
191
|
+
href: link.href,
|
|
192
|
+
label: link.label,
|
|
193
|
+
resourceId: metadata.comment.resourceId,
|
|
194
|
+
});
|
|
195
|
+
case 'audio':
|
|
196
|
+
return createAudioNodeFromLink({
|
|
197
|
+
href: link.href,
|
|
198
|
+
label: link.label,
|
|
199
|
+
resourceId: metadata.comment.resourceId,
|
|
200
|
+
});
|
|
201
|
+
case 'file':
|
|
202
|
+
return createFileNodeFromLink({
|
|
203
|
+
href: link.href,
|
|
204
|
+
label: link.label,
|
|
205
|
+
resourceId: metadata.comment.resourceId,
|
|
206
|
+
});
|
|
207
|
+
default:
|
|
208
|
+
return node;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function normalizeStandaloneMarkdownLinksToMediaBlocks(doc, metadataByPlaceholder) {
|
|
212
|
+
if (!doc || typeof doc !== 'object') {
|
|
213
|
+
return doc;
|
|
214
|
+
}
|
|
215
|
+
if (Array.isArray(doc.content)) {
|
|
216
|
+
doc.content = doc.content.map((child) => normalizeStandaloneMarkdownLinksToMediaBlocks(child, metadataByPlaceholder));
|
|
217
|
+
doc.content = doc.content.map((child) => convertStandaloneMarkdownLinkParagraph(child, metadataByPlaceholder));
|
|
218
|
+
}
|
|
219
|
+
return doc;
|
|
107
220
|
}
|
|
108
221
|
function normalizeContentText(text) {
|
|
109
222
|
const normalized = (text ?? '').replace(/\r\n/g, '\n');
|
|
@@ -121,29 +234,88 @@ function normalizeContentText(text) {
|
|
|
121
234
|
.replace(/\bwww\.\S+/gi, '')
|
|
122
235
|
.replace(/\s{2,}/g, ' ')
|
|
123
236
|
.trim();
|
|
124
|
-
|
|
125
|
-
|
|
237
|
+
return cleaned.length <= CONTENT_PREVIEW_MAX_LENGTH
|
|
238
|
+
? cleaned
|
|
239
|
+
: cleaned.slice(0, CONTENT_PREVIEW_MAX_LENGTH);
|
|
240
|
+
}
|
|
241
|
+
function extractPreviewTextFromNode(node) {
|
|
242
|
+
if (!node || typeof node !== 'object') {
|
|
243
|
+
return '';
|
|
244
|
+
}
|
|
245
|
+
if (node.type === 'text') {
|
|
246
|
+
return typeof node.text === 'string' ? node.text : '';
|
|
126
247
|
}
|
|
127
|
-
|
|
248
|
+
switch (node.type) {
|
|
249
|
+
case 'audio':
|
|
250
|
+
case 'video':
|
|
251
|
+
return String(node.attrs?.title || node.attrs?.src || '').trim();
|
|
252
|
+
case 'audiosegment':
|
|
253
|
+
return String(node.attrs?.text || '').trim();
|
|
254
|
+
case 'bidlink':
|
|
255
|
+
case 'mention':
|
|
256
|
+
return String(node.attrs?.label || node.attrs?.id || '').trim();
|
|
257
|
+
case 'file':
|
|
258
|
+
return String(node.attrs?.name || '').trim();
|
|
259
|
+
case 'frontmatter':
|
|
260
|
+
return '';
|
|
261
|
+
case 'hardBreak':
|
|
262
|
+
return '\n';
|
|
263
|
+
case 'hashtag':
|
|
264
|
+
return `#${String(node.attrs?.label || node.attrs?.id || '').trim()}`;
|
|
265
|
+
case 'image':
|
|
266
|
+
return String(node.attrs?.alt || '').trim();
|
|
267
|
+
case 'location':
|
|
268
|
+
return String(node.attrs?.name || '').trim();
|
|
269
|
+
case 'time':
|
|
270
|
+
return String(node.attrs?.iso || '').trim();
|
|
271
|
+
default:
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
if (!Array.isArray(node.content) || node.content.length === 0) {
|
|
275
|
+
return '';
|
|
276
|
+
}
|
|
277
|
+
const pieces = node.content
|
|
278
|
+
.map((child) => extractPreviewTextFromNode(child))
|
|
279
|
+
.filter((value) => value.length > 0);
|
|
280
|
+
const joined = pieces.join('');
|
|
281
|
+
if (node.type === 'blockquote' ||
|
|
282
|
+
node.type === 'bulletList' ||
|
|
283
|
+
node.type === 'codeBlock' ||
|
|
284
|
+
node.type === 'heading' ||
|
|
285
|
+
node.type === 'listItem' ||
|
|
286
|
+
node.type === 'orderedList' ||
|
|
287
|
+
node.type === 'paragraph' ||
|
|
288
|
+
node.type === 'table' ||
|
|
289
|
+
node.type === 'tableCell' ||
|
|
290
|
+
node.type === 'tableHeader' ||
|
|
291
|
+
node.type === 'tableRow' ||
|
|
292
|
+
node.type === 'taskItem' ||
|
|
293
|
+
node.type === 'taskList') {
|
|
294
|
+
return `${joined}\n`;
|
|
295
|
+
}
|
|
296
|
+
return joined;
|
|
297
|
+
}
|
|
298
|
+
function getPreviewTextFromDocument(contentJson) {
|
|
299
|
+
return extractPreviewTextFromNode(contentJson);
|
|
128
300
|
}
|
|
129
301
|
export function convertMarkdownToNoteContent(markdown) {
|
|
130
|
-
let editor = null;
|
|
131
302
|
try {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
const
|
|
303
|
+
const source = typeof markdown === 'string' ? markdown : String(markdown ?? '');
|
|
304
|
+
if (!source.trim()) {
|
|
305
|
+
return {
|
|
306
|
+
contentJson: createEmptyDocument(),
|
|
307
|
+
contentText: '',
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
const preprocessed = preprocessMarkdownMediaComments(source);
|
|
311
|
+
const parsed = getDinoxMarkdownManager().parse(preprocessed.markdown);
|
|
312
|
+
const normalized = normalizeStandaloneMarkdownLinksToMediaBlocks(parsed, preprocessed.metadataByPlaceholder);
|
|
313
|
+
const contentJson = validateAndCleanDocument(normalized);
|
|
314
|
+
const contentText = normalizeContentText(getPreviewTextFromDocument(contentJson));
|
|
141
315
|
return { contentJson, contentText };
|
|
142
316
|
}
|
|
143
317
|
catch (error) {
|
|
144
318
|
throw new DinoxError('Failed to convert markdown to TipTap JSON', { cause: error });
|
|
145
319
|
}
|
|
146
|
-
finally {
|
|
147
|
-
editor?.destroy();
|
|
148
|
-
}
|
|
149
320
|
}
|
|
321
|
+
export { createAudioNodeFromLink, createFileNodeFromLink, createImageNodeWithMetadata, createVideoNodeFromLink, inferMimeTypeFromHref, normalizeFileBlockAttrs, };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { MarkdownManager } from '@tiptap/markdown';
|
|
2
|
+
import { Node } from '@tiptap/core';
|
|
3
|
+
import { AudioMarkdownAttrs, DinoxImageAttrs } from './tiptapMarkdownSchemaUtils.js';
|
|
4
|
+
export declare function createDinoxMarkdownExtensions(): (Node<any, any> | Node<import("@tiptap/extension-image").ImageOptions, any> | Node<import("@tiptap/extension-paragraph").ParagraphOptions, any> | import("@tiptap/core").Mark<import("@tiptap/extension-bold").BoldOptions, any> | Node<import("@tiptap/extension-code-block").CodeBlockOptions, any> | import("@tiptap/core").Mark<import("@tiptap/extension-link").LinkOptions, any> | Node<import("@tiptap/extension-hard-break").HardBreakOptions, any> | Node<import("@tiptap/extension-heading").HeadingOptions, any> | Node<import("@tiptap/extension-list").BulletListOptions, any> | Node<import("@tiptap/extension-list").ListItemOptions, any> | Node<import("@tiptap/extension-list").TaskListOptions, any> | Node<import("@tiptap/extension-list").TaskItemOptions, any> | import("@tiptap/core").Mark<import("@tiptap/extension-highlight").HighlightOptions, any> | Node<import("@tiptap/extension-horizontal-rule").HorizontalRuleOptions, any> | import("@tiptap/core").Extension<import("@tiptap/extension-mathematics").MathematicsOptions, any> | Node<import("@tiptap/extension-table").TableOptions, any>)[];
|
|
5
|
+
export declare function getDinoxMarkdownManager(): MarkdownManager;
|
|
6
|
+
export declare function createVideoNodeFromLink(input: {
|
|
7
|
+
href: string;
|
|
8
|
+
label: string;
|
|
9
|
+
resourceId?: string | null;
|
|
10
|
+
}): {
|
|
11
|
+
type: string;
|
|
12
|
+
attrs: import("./tiptapMarkdownSchemaUtils.js").VideoMarkdownAttrs;
|
|
13
|
+
};
|
|
14
|
+
export declare function createAudioNodeFromLink(input: {
|
|
15
|
+
href: string;
|
|
16
|
+
label: string;
|
|
17
|
+
resourceId?: string | null;
|
|
18
|
+
}): {
|
|
19
|
+
type: string;
|
|
20
|
+
attrs: AudioMarkdownAttrs;
|
|
21
|
+
};
|
|
22
|
+
export declare function createFileNodeFromLink(input: {
|
|
23
|
+
href: string;
|
|
24
|
+
label: string;
|
|
25
|
+
resourceId?: string | null;
|
|
26
|
+
}): {
|
|
27
|
+
type: string;
|
|
28
|
+
attrs: import("./tiptapMarkdownSchemaUtils.js").FileBlockAttrs;
|
|
29
|
+
};
|
|
30
|
+
export declare function createImageNodeWithMetadata(attrs: DinoxImageAttrs, metadata: {
|
|
31
|
+
resourceId?: string | null;
|
|
32
|
+
widthPercent?: number | null;
|
|
33
|
+
}): {
|
|
34
|
+
type: string;
|
|
35
|
+
attrs: DinoxImageAttrs;
|
|
36
|
+
};
|
|
37
|
+
export type { AudioMarkdownAttrs };
|