@dinoxx/dinox-cli 1.0.17 → 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,577 @@
|
|
|
1
|
+
import Blockquote from '@tiptap/extension-blockquote';
|
|
2
|
+
import Bold from '@tiptap/extension-bold';
|
|
3
|
+
import BulletList from '@tiptap/extension-bullet-list';
|
|
4
|
+
import Code from '@tiptap/extension-code';
|
|
5
|
+
import CodeBlock from '@tiptap/extension-code-block';
|
|
6
|
+
import Document from '@tiptap/extension-document';
|
|
7
|
+
import HardBreak from '@tiptap/extension-hard-break';
|
|
8
|
+
import Heading from '@tiptap/extension-heading';
|
|
9
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
10
|
+
import Image from '@tiptap/extension-image';
|
|
11
|
+
import Italic from '@tiptap/extension-italic';
|
|
12
|
+
import Link from '@tiptap/extension-link';
|
|
13
|
+
import { ListItem, OrderedList, TaskItem, TaskList } from '@tiptap/extension-list';
|
|
14
|
+
import { Mathematics } from '@tiptap/extension-mathematics';
|
|
15
|
+
import Paragraph from '@tiptap/extension-paragraph';
|
|
16
|
+
import Strike from '@tiptap/extension-strike';
|
|
17
|
+
import { Table } from '@tiptap/extension-table';
|
|
18
|
+
import { TableCell } from '@tiptap/extension-table-cell';
|
|
19
|
+
import { TableHeader } from '@tiptap/extension-table-header';
|
|
20
|
+
import { TableRow } from '@tiptap/extension-table-row';
|
|
21
|
+
import Text from '@tiptap/extension-text';
|
|
22
|
+
import Underline from '@tiptap/extension-underline';
|
|
23
|
+
import HorizontalRule from '@tiptap/extension-horizontal-rule';
|
|
24
|
+
import { MarkdownManager } from '@tiptap/markdown';
|
|
25
|
+
import { Node, createInlineMarkdownSpec, nodeInputRule } from '@tiptap/core';
|
|
26
|
+
import { buildFrontmatterMarkdownBlock, buildImageWidthPercentStyle, extractAudioAttrsFromHtml, extractVideoAttrsFromHtml, findHashtagPathStart, IMAGE_WIDTH_PERCENT_ATTR, inferMimeTypeFromHref, normalizeAudioMarkdownAttrs, normalizeDinoxImageAttrs, normalizeFileBlockAttrs, normalizeFrontmatterRaw, normalizeStoredImageWidthPercent, normalizeVideoMarkdownAttrs, parseHashtagPath, parseMarkdownAttributes, serializeMarkdownAttributes, } from './tiptapMarkdownSchemaUtils.js';
|
|
27
|
+
const EditorDocument = Document.extend({
|
|
28
|
+
content: 'frontmatter? block+',
|
|
29
|
+
});
|
|
30
|
+
const FRONTMATTER_BLOCK_RE = /^(?:\uFEFF)?---[ \t]*\n([\s\S]*?)\n---[ \t]*(?:\n|$)/;
|
|
31
|
+
const FrontmatterNode = Node.create({
|
|
32
|
+
name: 'frontmatter',
|
|
33
|
+
group: 'frontmatter',
|
|
34
|
+
atom: true,
|
|
35
|
+
defining: true,
|
|
36
|
+
isolating: true,
|
|
37
|
+
addAttributes() {
|
|
38
|
+
return {
|
|
39
|
+
raw: {
|
|
40
|
+
default: '',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
renderText({ node }) {
|
|
45
|
+
return buildFrontmatterMarkdownBlock(node.attrs?.raw);
|
|
46
|
+
},
|
|
47
|
+
parseMarkdown(token, helpers) {
|
|
48
|
+
return helpers.createNode('frontmatter', {
|
|
49
|
+
raw: normalizeFrontmatterRaw(token.content),
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
renderMarkdown(node) {
|
|
53
|
+
return buildFrontmatterMarkdownBlock(node.attrs?.raw);
|
|
54
|
+
},
|
|
55
|
+
markdownTokenizer: {
|
|
56
|
+
name: 'frontmatter',
|
|
57
|
+
level: 'block',
|
|
58
|
+
start(src) {
|
|
59
|
+
return src.match(/^(?:\uFEFF)?---[ \t]*\n/)?.index ?? -1;
|
|
60
|
+
},
|
|
61
|
+
tokenize(src, tokens) {
|
|
62
|
+
if (tokens.length > 0) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const match = src.match(FRONTMATTER_BLOCK_RE);
|
|
66
|
+
if (!match) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
type: 'frontmatter',
|
|
71
|
+
raw: match[0],
|
|
72
|
+
content: normalizeFrontmatterRaw(match[1] ?? ''),
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
const DinoxImage = Image.extend({
|
|
78
|
+
addAttributes() {
|
|
79
|
+
return {
|
|
80
|
+
...(this.parent?.() ?? {}),
|
|
81
|
+
resourceId: {
|
|
82
|
+
default: null,
|
|
83
|
+
},
|
|
84
|
+
storageKey: {
|
|
85
|
+
default: null,
|
|
86
|
+
},
|
|
87
|
+
widthPercent: {
|
|
88
|
+
default: null,
|
|
89
|
+
renderHTML: (attributes) => {
|
|
90
|
+
const widthPercent = normalizeStoredImageWidthPercent(attributes.widthPercent);
|
|
91
|
+
const style = buildImageWidthPercentStyle(widthPercent);
|
|
92
|
+
if (widthPercent == null || !style) {
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
[IMAGE_WIDTH_PERCENT_ATTR]: String(widthPercent),
|
|
97
|
+
style,
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
parseMarkdown(token, helpers) {
|
|
104
|
+
const attrs = normalizeDinoxImageAttrs({
|
|
105
|
+
alt: token.text,
|
|
106
|
+
src: token.href,
|
|
107
|
+
title: token.title,
|
|
108
|
+
});
|
|
109
|
+
if (!attrs.src) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
return helpers.createNode('image', attrs);
|
|
113
|
+
},
|
|
114
|
+
addInputRules() {
|
|
115
|
+
return [
|
|
116
|
+
nodeInputRule({
|
|
117
|
+
find: /(?:^|\s)(!\[(.*?)\]\((\S+)(?:\s+"(.*?)")?\))$/,
|
|
118
|
+
type: this.type,
|
|
119
|
+
getAttributes: (match) => {
|
|
120
|
+
const [, , alt, src, title] = match;
|
|
121
|
+
return normalizeDinoxImageAttrs({ alt, src, title });
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
];
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
const AudioNode = Node.create({
|
|
128
|
+
name: 'audio',
|
|
129
|
+
group: 'block',
|
|
130
|
+
atom: true,
|
|
131
|
+
addAttributes() {
|
|
132
|
+
return {
|
|
133
|
+
preload: { default: null },
|
|
134
|
+
resourceId: { default: null },
|
|
135
|
+
src: { default: null },
|
|
136
|
+
storageKey: { default: null },
|
|
137
|
+
title: { default: null },
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
renderText({ node }) {
|
|
141
|
+
return String(node.attrs?.title || node.attrs?.src || '').trim();
|
|
142
|
+
},
|
|
143
|
+
parseMarkdown(token, helpers) {
|
|
144
|
+
const attrs = normalizeAudioMarkdownAttrs((token.attributes || {}));
|
|
145
|
+
return attrs.src ? helpers.createNode('audio', attrs, []) : [];
|
|
146
|
+
},
|
|
147
|
+
markdownTokenizer: {
|
|
148
|
+
name: 'audio',
|
|
149
|
+
level: 'block',
|
|
150
|
+
start(src) {
|
|
151
|
+
return src.search(/<audio\b/i);
|
|
152
|
+
},
|
|
153
|
+
tokenize(src) {
|
|
154
|
+
const htmlMatch = src.match(/^<audio\b[\s\S]*?(?:<\/audio>|\/>)(?:\n|$)?/i);
|
|
155
|
+
if (!htmlMatch) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
const attrs = extractAudioAttrsFromHtml(htmlMatch[0]);
|
|
159
|
+
return attrs?.src
|
|
160
|
+
? {
|
|
161
|
+
type: 'audio',
|
|
162
|
+
raw: htmlMatch[0],
|
|
163
|
+
attributes: attrs,
|
|
164
|
+
}
|
|
165
|
+
: undefined;
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
const VideoNode = Node.create({
|
|
170
|
+
name: 'video',
|
|
171
|
+
group: 'block',
|
|
172
|
+
atom: true,
|
|
173
|
+
addAttributes() {
|
|
174
|
+
return {
|
|
175
|
+
autoplay: { default: false },
|
|
176
|
+
loop: { default: false },
|
|
177
|
+
muted: { default: false },
|
|
178
|
+
playsInline: { default: false },
|
|
179
|
+
poster: { default: null },
|
|
180
|
+
resourceId: { default: null },
|
|
181
|
+
src: { default: null },
|
|
182
|
+
storageKey: { default: null },
|
|
183
|
+
title: { default: null },
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
renderText({ node }) {
|
|
187
|
+
return String(node.attrs?.title || node.attrs?.src || '').trim();
|
|
188
|
+
},
|
|
189
|
+
parseMarkdown(token, helpers) {
|
|
190
|
+
const attrs = normalizeVideoMarkdownAttrs((token.attributes || {}));
|
|
191
|
+
return attrs.src ? helpers.createNode('video', attrs, []) : [];
|
|
192
|
+
},
|
|
193
|
+
markdownTokenizer: {
|
|
194
|
+
name: 'video',
|
|
195
|
+
level: 'block',
|
|
196
|
+
start(src) {
|
|
197
|
+
return src.search(/<video\b/i);
|
|
198
|
+
},
|
|
199
|
+
tokenize(src) {
|
|
200
|
+
const htmlMatch = src.match(/^<video\b[\s\S]*?(?:<\/video>|\/>)(?:\n|$)?/i);
|
|
201
|
+
if (!htmlMatch) {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
const attrs = extractVideoAttrsFromHtml(htmlMatch[0]);
|
|
205
|
+
return attrs?.src
|
|
206
|
+
? {
|
|
207
|
+
type: 'video',
|
|
208
|
+
raw: htmlMatch[0],
|
|
209
|
+
attributes: attrs,
|
|
210
|
+
}
|
|
211
|
+
: undefined;
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
const FileNode = Node.create({
|
|
216
|
+
name: 'file',
|
|
217
|
+
group: 'block',
|
|
218
|
+
atom: true,
|
|
219
|
+
defining: true,
|
|
220
|
+
addAttributes() {
|
|
221
|
+
return {
|
|
222
|
+
id: { default: '' },
|
|
223
|
+
name: { default: '未命名文件' },
|
|
224
|
+
resourceId: { default: '' },
|
|
225
|
+
size: { default: 0 },
|
|
226
|
+
src: { default: '' },
|
|
227
|
+
type: { default: 'application/octet-stream' },
|
|
228
|
+
};
|
|
229
|
+
},
|
|
230
|
+
renderText({ node }) {
|
|
231
|
+
return normalizeFileBlockAttrs((node.attrs || {})).name;
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
const AudioSegmentNode = Node.create({
|
|
235
|
+
name: 'audiosegment',
|
|
236
|
+
group: 'block',
|
|
237
|
+
atom: true,
|
|
238
|
+
defining: true,
|
|
239
|
+
addAttributes() {
|
|
240
|
+
return {
|
|
241
|
+
id: { default: null },
|
|
242
|
+
speaker: { default: '' },
|
|
243
|
+
t0: { default: 0 },
|
|
244
|
+
t1: { default: 0 },
|
|
245
|
+
text: { default: '' },
|
|
246
|
+
};
|
|
247
|
+
},
|
|
248
|
+
renderText({ node }) {
|
|
249
|
+
return String(node.attrs?.text || '');
|
|
250
|
+
},
|
|
251
|
+
parseMarkdown(token, helpers) {
|
|
252
|
+
const t0 = Number(token.attributes?.t0);
|
|
253
|
+
const t1 = Number(token.attributes?.t1);
|
|
254
|
+
return helpers.createNode('audiosegment', {
|
|
255
|
+
...token.attributes,
|
|
256
|
+
t0: Number.isFinite(t0) ? t0 : 0,
|
|
257
|
+
t1: Number.isFinite(t1) ? t1 : 0,
|
|
258
|
+
text: typeof token.content === 'string' ? token.content : '',
|
|
259
|
+
}, []);
|
|
260
|
+
},
|
|
261
|
+
renderMarkdown(node) {
|
|
262
|
+
const attrs = node.attrs || {};
|
|
263
|
+
const attrString = serializeMarkdownAttributes({
|
|
264
|
+
id: attrs.id,
|
|
265
|
+
speaker: attrs.speaker,
|
|
266
|
+
t0: attrs.t0,
|
|
267
|
+
t1: attrs.t1,
|
|
268
|
+
}, ['id', 't0', 't1', 'speaker']);
|
|
269
|
+
const header = attrString ? `:::audiosegment {${attrString}}` : ':::audiosegment';
|
|
270
|
+
return `${header}\n${String(attrs.text || '')}\n:::`;
|
|
271
|
+
},
|
|
272
|
+
markdownTokenizer: {
|
|
273
|
+
name: 'audiosegment',
|
|
274
|
+
level: 'block',
|
|
275
|
+
start(src) {
|
|
276
|
+
const match = src.match(/^:::audiosegment(?:\s|$)/m);
|
|
277
|
+
return match?.index ?? -1;
|
|
278
|
+
},
|
|
279
|
+
tokenize(src) {
|
|
280
|
+
const match = src.match(/^:::audiosegment(?:\s+\{([^}]*)\})?\s*\n([\s\S]*?)\n:::(?:\n|$)?/);
|
|
281
|
+
if (!match) {
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
type: 'audiosegment',
|
|
286
|
+
raw: match[0],
|
|
287
|
+
content: match[2] || '',
|
|
288
|
+
attributes: parseMarkdownAttributes(match[1] || ''),
|
|
289
|
+
};
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
const HashtagNode = Node.create({
|
|
294
|
+
name: 'hashtag',
|
|
295
|
+
group: 'inline',
|
|
296
|
+
inline: true,
|
|
297
|
+
atom: true,
|
|
298
|
+
addAttributes() {
|
|
299
|
+
return {
|
|
300
|
+
id: { default: null },
|
|
301
|
+
label: { default: null },
|
|
302
|
+
};
|
|
303
|
+
},
|
|
304
|
+
renderText({ node }) {
|
|
305
|
+
return `#${String(node.attrs?.label || node.attrs?.id || '').trim()}`;
|
|
306
|
+
},
|
|
307
|
+
parseMarkdown(token, helpers) {
|
|
308
|
+
const label = typeof token.attributes?.label === 'string' ? token.attributes.label : '';
|
|
309
|
+
const id = typeof token.attributes?.id === 'string' && token.attributes.id ? token.attributes.id : label;
|
|
310
|
+
return label || id ? helpers.createNode('hashtag', { id, label: label || id }) : [];
|
|
311
|
+
},
|
|
312
|
+
markdownTokenizer: {
|
|
313
|
+
name: 'hashtag',
|
|
314
|
+
level: 'inline',
|
|
315
|
+
start(src) {
|
|
316
|
+
return findHashtagPathStart(src);
|
|
317
|
+
},
|
|
318
|
+
tokenize(src) {
|
|
319
|
+
const parsed = parseHashtagPath(src, 0);
|
|
320
|
+
return parsed
|
|
321
|
+
? {
|
|
322
|
+
type: 'hashtag',
|
|
323
|
+
raw: parsed.raw,
|
|
324
|
+
attributes: {
|
|
325
|
+
id: parsed.label,
|
|
326
|
+
label: parsed.label,
|
|
327
|
+
},
|
|
328
|
+
}
|
|
329
|
+
: undefined;
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
const BidLinkNode = Node.create({
|
|
334
|
+
name: 'bidlink',
|
|
335
|
+
group: 'inline',
|
|
336
|
+
inline: true,
|
|
337
|
+
atom: true,
|
|
338
|
+
addAttributes() {
|
|
339
|
+
return {
|
|
340
|
+
id: { default: null },
|
|
341
|
+
label: { default: null },
|
|
342
|
+
};
|
|
343
|
+
},
|
|
344
|
+
renderText({ node }) {
|
|
345
|
+
return String(node.attrs?.label || node.attrs?.id || '').trim();
|
|
346
|
+
},
|
|
347
|
+
parseMarkdown(token, helpers) {
|
|
348
|
+
const label = typeof token.attributes?.label === 'string' ? token.attributes.label : '';
|
|
349
|
+
const id = typeof token.attributes?.id === 'string' && token.attributes.id ? token.attributes.id : label;
|
|
350
|
+
return label || id ? helpers.createNode('bidlink', { id, label: label || id }) : [];
|
|
351
|
+
},
|
|
352
|
+
markdownTokenizer: {
|
|
353
|
+
name: 'bidlink',
|
|
354
|
+
level: 'inline',
|
|
355
|
+
start(src) {
|
|
356
|
+
const index = src.indexOf('[[');
|
|
357
|
+
return index >= 0 ? index : -1;
|
|
358
|
+
},
|
|
359
|
+
tokenize(src) {
|
|
360
|
+
const match = src.match(/^\[\[((?:\\.|[^\]\n])+?)\]\]/);
|
|
361
|
+
if (!match) {
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
const rawValue = match[1].trim();
|
|
365
|
+
if (!rawValue) {
|
|
366
|
+
return undefined;
|
|
367
|
+
}
|
|
368
|
+
let separatorIndex = -1;
|
|
369
|
+
for (let index = rawValue.length - 1; index >= 0; index -= 1) {
|
|
370
|
+
if (rawValue[index] === '|' && rawValue[index - 1] !== '\\') {
|
|
371
|
+
separatorIndex = index;
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
const unescape = (value) => value.replace(/\\([\\|\]])/g, '$1');
|
|
376
|
+
const label = unescape(separatorIndex >= 0 ? rawValue.slice(0, separatorIndex).trim() : rawValue.trim());
|
|
377
|
+
const id = unescape(separatorIndex >= 0 ? rawValue.slice(separatorIndex + 1).trim() || label : label);
|
|
378
|
+
return {
|
|
379
|
+
type: 'bidlink',
|
|
380
|
+
raw: match[0],
|
|
381
|
+
attributes: {
|
|
382
|
+
id,
|
|
383
|
+
label,
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
const MentionNode = Node.create({
|
|
390
|
+
name: 'mention',
|
|
391
|
+
group: 'inline',
|
|
392
|
+
inline: true,
|
|
393
|
+
atom: true,
|
|
394
|
+
addAttributes() {
|
|
395
|
+
return {
|
|
396
|
+
id: { default: null },
|
|
397
|
+
label: { default: null },
|
|
398
|
+
marker: { default: '#' },
|
|
399
|
+
};
|
|
400
|
+
},
|
|
401
|
+
renderText({ node }) {
|
|
402
|
+
return String(node.attrs?.label || node.attrs?.id || '').trim();
|
|
403
|
+
},
|
|
404
|
+
...createInlineMarkdownSpec({
|
|
405
|
+
nodeName: 'mention',
|
|
406
|
+
selfClosing: true,
|
|
407
|
+
allowedAttributes: ['id', 'label', 'marker'],
|
|
408
|
+
}),
|
|
409
|
+
});
|
|
410
|
+
const LocationNode = Node.create({
|
|
411
|
+
name: 'location',
|
|
412
|
+
group: 'inline',
|
|
413
|
+
inline: true,
|
|
414
|
+
atom: true,
|
|
415
|
+
addAttributes() {
|
|
416
|
+
return {
|
|
417
|
+
address: { default: '' },
|
|
418
|
+
latitude: { default: null },
|
|
419
|
+
longitude: { default: null },
|
|
420
|
+
name: { default: '' },
|
|
421
|
+
};
|
|
422
|
+
},
|
|
423
|
+
renderText({ node }) {
|
|
424
|
+
return String(node.attrs?.name || '').trim();
|
|
425
|
+
},
|
|
426
|
+
...createInlineMarkdownSpec({
|
|
427
|
+
nodeName: 'location',
|
|
428
|
+
selfClosing: true,
|
|
429
|
+
allowedAttributes: ['name', 'address', 'latitude', 'longitude'],
|
|
430
|
+
parseAttributes: (attrString) => {
|
|
431
|
+
const attrs = parseMarkdownAttributes(attrString);
|
|
432
|
+
return {
|
|
433
|
+
address: attrs.address || '',
|
|
434
|
+
latitude: attrs.latitude ? Number(attrs.latitude) : null,
|
|
435
|
+
longitude: attrs.longitude ? Number(attrs.longitude) : null,
|
|
436
|
+
name: attrs.name || '',
|
|
437
|
+
};
|
|
438
|
+
},
|
|
439
|
+
serializeAttributes: (attrs) => serializeMarkdownAttributes({
|
|
440
|
+
address: attrs.address,
|
|
441
|
+
latitude: attrs.latitude,
|
|
442
|
+
longitude: attrs.longitude,
|
|
443
|
+
name: attrs.name,
|
|
444
|
+
}, ['name', 'address', 'latitude', 'longitude']),
|
|
445
|
+
}),
|
|
446
|
+
});
|
|
447
|
+
const TimeNode = Node.create({
|
|
448
|
+
name: 'time',
|
|
449
|
+
group: 'inline',
|
|
450
|
+
inline: true,
|
|
451
|
+
atom: true,
|
|
452
|
+
addAttributes() {
|
|
453
|
+
return {
|
|
454
|
+
displayFormat: { default: 'datetime' },
|
|
455
|
+
iso: { default: '' },
|
|
456
|
+
};
|
|
457
|
+
},
|
|
458
|
+
renderText({ node }) {
|
|
459
|
+
return String(node.attrs?.iso || '').trim();
|
|
460
|
+
},
|
|
461
|
+
...createInlineMarkdownSpec({
|
|
462
|
+
nodeName: 'time',
|
|
463
|
+
selfClosing: true,
|
|
464
|
+
allowedAttributes: ['iso', 'displayFormat'],
|
|
465
|
+
parseAttributes: (attrString) => {
|
|
466
|
+
const attrs = parseMarkdownAttributes(attrString);
|
|
467
|
+
return {
|
|
468
|
+
displayFormat: attrs.displayFormat || 'datetime',
|
|
469
|
+
iso: attrs.iso || '',
|
|
470
|
+
};
|
|
471
|
+
},
|
|
472
|
+
serializeAttributes: (attrs) => serializeMarkdownAttributes({
|
|
473
|
+
displayFormat: attrs.displayFormat,
|
|
474
|
+
iso: attrs.iso,
|
|
475
|
+
}, ['iso', 'displayFormat']),
|
|
476
|
+
}),
|
|
477
|
+
});
|
|
478
|
+
export function createDinoxMarkdownExtensions() {
|
|
479
|
+
return [
|
|
480
|
+
EditorDocument,
|
|
481
|
+
FrontmatterNode,
|
|
482
|
+
Paragraph,
|
|
483
|
+
Text,
|
|
484
|
+
Bold,
|
|
485
|
+
Italic,
|
|
486
|
+
Strike,
|
|
487
|
+
Underline,
|
|
488
|
+
Code,
|
|
489
|
+
CodeBlock,
|
|
490
|
+
Link.configure({
|
|
491
|
+
openOnClick: false,
|
|
492
|
+
}),
|
|
493
|
+
HardBreak,
|
|
494
|
+
Heading,
|
|
495
|
+
Blockquote,
|
|
496
|
+
BulletList,
|
|
497
|
+
OrderedList,
|
|
498
|
+
ListItem,
|
|
499
|
+
TaskList,
|
|
500
|
+
TaskItem.configure({
|
|
501
|
+
nested: true,
|
|
502
|
+
}),
|
|
503
|
+
Highlight.configure({}),
|
|
504
|
+
HorizontalRule,
|
|
505
|
+
DinoxImage.configure({
|
|
506
|
+
allowBase64: true,
|
|
507
|
+
inline: false,
|
|
508
|
+
}),
|
|
509
|
+
Mathematics,
|
|
510
|
+
Table.configure({
|
|
511
|
+
lastColumnResizable: false,
|
|
512
|
+
resizable: true,
|
|
513
|
+
}),
|
|
514
|
+
TableHeader,
|
|
515
|
+
TableCell,
|
|
516
|
+
TableRow,
|
|
517
|
+
VideoNode,
|
|
518
|
+
HashtagNode,
|
|
519
|
+
BidLinkNode,
|
|
520
|
+
MentionNode,
|
|
521
|
+
LocationNode,
|
|
522
|
+
TimeNode,
|
|
523
|
+
AudioSegmentNode,
|
|
524
|
+
AudioNode,
|
|
525
|
+
FileNode,
|
|
526
|
+
];
|
|
527
|
+
}
|
|
528
|
+
let markdownManager = null;
|
|
529
|
+
export function getDinoxMarkdownManager() {
|
|
530
|
+
if (!markdownManager) {
|
|
531
|
+
markdownManager = new MarkdownManager({
|
|
532
|
+
extensions: createDinoxMarkdownExtensions(),
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
return markdownManager;
|
|
536
|
+
}
|
|
537
|
+
export function createVideoNodeFromLink(input) {
|
|
538
|
+
return {
|
|
539
|
+
type: 'video',
|
|
540
|
+
attrs: normalizeVideoMarkdownAttrs({
|
|
541
|
+
resourceId: input.resourceId,
|
|
542
|
+
src: input.href,
|
|
543
|
+
title: input.label,
|
|
544
|
+
}),
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
export function createAudioNodeFromLink(input) {
|
|
548
|
+
return {
|
|
549
|
+
type: 'audio',
|
|
550
|
+
attrs: normalizeAudioMarkdownAttrs({
|
|
551
|
+
resourceId: input.resourceId,
|
|
552
|
+
src: input.href,
|
|
553
|
+
title: input.label,
|
|
554
|
+
}),
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
export function createFileNodeFromLink(input) {
|
|
558
|
+
return {
|
|
559
|
+
type: 'file',
|
|
560
|
+
attrs: normalizeFileBlockAttrs({
|
|
561
|
+
name: input.label,
|
|
562
|
+
resourceId: input.resourceId ?? undefined,
|
|
563
|
+
src: input.href,
|
|
564
|
+
type: inferMimeTypeFromHref(input.href),
|
|
565
|
+
}),
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
export function createImageNodeWithMetadata(attrs, metadata) {
|
|
569
|
+
return {
|
|
570
|
+
type: 'image',
|
|
571
|
+
attrs: normalizeDinoxImageAttrs({
|
|
572
|
+
...attrs,
|
|
573
|
+
resourceId: metadata.resourceId ?? attrs.resourceId,
|
|
574
|
+
widthPercent: metadata.widthPercent ?? attrs.widthPercent,
|
|
575
|
+
}),
|
|
576
|
+
};
|
|
577
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
declare const DEFAULT_FILE_TYPE = "application/octet-stream";
|
|
2
|
+
declare const IMAGE_WIDTH_PERCENT_ATTR = "data-dinox-width-percent";
|
|
3
|
+
declare const MEDIA_RESOURCE_ID_ATTR = "data-resource-id";
|
|
4
|
+
declare const MEDIA_STORAGE_KEY_ATTR = "data-storage-key";
|
|
5
|
+
export type DinoxMarkdownMediaKind = 'image' | 'video' | 'audio' | 'file';
|
|
6
|
+
export type DinoxMarkdownComment = {
|
|
7
|
+
kind: DinoxMarkdownMediaKind | null;
|
|
8
|
+
resourceId: string | null;
|
|
9
|
+
widthPercent: number | null;
|
|
10
|
+
};
|
|
11
|
+
export type DinoxImageAttrs = {
|
|
12
|
+
alt: string | null;
|
|
13
|
+
height: number | null;
|
|
14
|
+
resourceId: string | null;
|
|
15
|
+
src: string | null;
|
|
16
|
+
storageKey: string | null;
|
|
17
|
+
title: string | null;
|
|
18
|
+
width: number | null;
|
|
19
|
+
widthPercent: number | null;
|
|
20
|
+
};
|
|
21
|
+
export type AudioMarkdownAttrs = {
|
|
22
|
+
preload?: string;
|
|
23
|
+
resourceId?: string;
|
|
24
|
+
src?: string;
|
|
25
|
+
storageKey?: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
};
|
|
28
|
+
export type VideoMarkdownAttrs = {
|
|
29
|
+
autoplay?: boolean;
|
|
30
|
+
loop?: boolean;
|
|
31
|
+
muted?: boolean;
|
|
32
|
+
playsInline?: boolean;
|
|
33
|
+
poster?: string;
|
|
34
|
+
resourceId?: string;
|
|
35
|
+
src?: string;
|
|
36
|
+
storageKey?: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
};
|
|
39
|
+
export type FileBlockAttrs = {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
resourceId?: string;
|
|
43
|
+
size: number;
|
|
44
|
+
src: string;
|
|
45
|
+
type: string;
|
|
46
|
+
};
|
|
47
|
+
export type ParsedHashtagPath = {
|
|
48
|
+
end: number;
|
|
49
|
+
label: string;
|
|
50
|
+
raw: string;
|
|
51
|
+
};
|
|
52
|
+
export declare function parseMarkdownAttributes(attrString: string): Record<string, string>;
|
|
53
|
+
export declare function serializeMarkdownAttributes(attrs: Record<string, unknown>, allowedKeys?: string[]): string;
|
|
54
|
+
export declare function normalizeMarkdownLineEndings(value: string): string;
|
|
55
|
+
export declare function normalizeFrontmatterRaw(raw: unknown): string;
|
|
56
|
+
export declare function buildFrontmatterMarkdownBlock(raw: unknown): string;
|
|
57
|
+
export declare function extractMarkdownFrontmatter(markdown: string): {
|
|
58
|
+
body: string;
|
|
59
|
+
frontmatter: string | null;
|
|
60
|
+
};
|
|
61
|
+
export declare function normalizeStoredImageWidthPercent(value: unknown): number | null;
|
|
62
|
+
export declare function parseImageWidthPercentFromStyle(styleValue: unknown): number | null;
|
|
63
|
+
export declare function buildImageWidthPercentStyle(widthPercent: unknown): string | null;
|
|
64
|
+
export declare function normalizeDinoxImageAttrs(input: Record<string, unknown>): DinoxImageAttrs;
|
|
65
|
+
export declare function normalizeAudioMarkdownAttrs(input: Record<string, unknown>): AudioMarkdownAttrs;
|
|
66
|
+
export declare function normalizeVideoMarkdownAttrs(input: Record<string, unknown>): VideoMarkdownAttrs;
|
|
67
|
+
export declare function normalizeFileBlockAttrs(input: Partial<FileBlockAttrs>): FileBlockAttrs;
|
|
68
|
+
export declare function inferMimeTypeFromHref(href: string): string | undefined;
|
|
69
|
+
export declare function parseDinoxMarkdownComment(rawComment: unknown): DinoxMarkdownComment | null;
|
|
70
|
+
export declare function extractAudioAttrsFromHtml(html: string): AudioMarkdownAttrs | null;
|
|
71
|
+
export declare function extractVideoAttrsFromHtml(html: string): VideoMarkdownAttrs | null;
|
|
72
|
+
export declare function parseHashtagPath(source: string, hashIndex: number): ParsedHashtagPath | null;
|
|
73
|
+
export declare function findHashtagPathStart(source: string): number;
|
|
74
|
+
export { DEFAULT_FILE_TYPE, IMAGE_WIDTH_PERCENT_ATTR, MEDIA_RESOURCE_ID_ATTR, MEDIA_STORAGE_KEY_ATTR, };
|