@tutti-os/ui-rich-text 0.0.1
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/LICENSE +202 -0
- package/README.md +168 -0
- package/dist/chunk-52PIIFZA.js +525 -0
- package/dist/chunk-52PIIFZA.js.map +1 -0
- package/dist/chunk-K5POY2YJ.js +268 -0
- package/dist/chunk-K5POY2YJ.js.map +1 -0
- package/dist/chunk-VQHCWUBH.js +63 -0
- package/dist/chunk-VQHCWUBH.js.map +1 -0
- package/dist/chunk-YLWTSNTT.js +1 -0
- package/dist/chunk-YLWTSNTT.js.map +1 -0
- package/dist/core/index.d.ts +34 -0
- package/dist/core/index.js +38 -0
- package/dist/core/index.js.map +1 -0
- package/dist/editor/index.d.ts +77 -0
- package/dist/editor/index.js +1738 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/mention-QICvf4wE.d.ts +81 -0
- package/dist/plugins/index.d.ts +20 -0
- package/dist/plugins/index.js +30 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/richTextI18n-CUeqHuEQ.d.ts +13 -0
- package/dist/types/index.d.ts +57 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
// src/extensions/names.ts
|
|
2
|
+
var workspaceReferenceNodeName = "workspaceReference";
|
|
3
|
+
var mentionReferenceNodeName = "mentionReference";
|
|
4
|
+
|
|
5
|
+
// src/core/richTextMarkdownLinks.ts
|
|
6
|
+
function* findRichTextMarkdownLinks(value) {
|
|
7
|
+
let cursor = 0;
|
|
8
|
+
while (cursor < value.length) {
|
|
9
|
+
const labelStart = value.indexOf("[", cursor);
|
|
10
|
+
if (labelStart < 0) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (labelStart > 0 && value[labelStart - 1] === "!") {
|
|
14
|
+
cursor = labelStart + 1;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const labelEnd = findMarkdownLabelEnd(value, labelStart + 1);
|
|
18
|
+
if (labelEnd < 0 || value[labelEnd + 1] !== "(") {
|
|
19
|
+
cursor = labelStart + 1;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const hrefStart = labelEnd + 2;
|
|
23
|
+
const hrefEnd = findMarkdownHrefEnd(value, hrefStart);
|
|
24
|
+
if (hrefEnd < 0) {
|
|
25
|
+
cursor = labelStart + 1;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
yield {
|
|
29
|
+
href: unescapeMarkdownLinkText(value.slice(hrefStart, hrefEnd)),
|
|
30
|
+
index: labelStart,
|
|
31
|
+
label: unescapeMarkdownLinkText(value.slice(labelStart + 1, labelEnd)),
|
|
32
|
+
source: value.slice(labelStart, hrefEnd + 1),
|
|
33
|
+
to: hrefEnd + 1
|
|
34
|
+
};
|
|
35
|
+
cursor = hrefEnd + 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function unescapeMarkdownLinkText(value) {
|
|
39
|
+
return value.replace(/\\([\\[\]()])/g, "$1");
|
|
40
|
+
}
|
|
41
|
+
function findMarkdownLabelEnd(value, cursor) {
|
|
42
|
+
let escaped = false;
|
|
43
|
+
for (let index = cursor; index < value.length; index += 1) {
|
|
44
|
+
const char = value[index];
|
|
45
|
+
if (escaped) {
|
|
46
|
+
escaped = false;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (char === "\\") {
|
|
50
|
+
escaped = true;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (char === "]") {
|
|
54
|
+
return index;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return -1;
|
|
58
|
+
}
|
|
59
|
+
function findMarkdownHrefEnd(value, cursor) {
|
|
60
|
+
let escaped = false;
|
|
61
|
+
let depth = 0;
|
|
62
|
+
for (let index = cursor; index < value.length; index += 1) {
|
|
63
|
+
const char = value[index];
|
|
64
|
+
if (escaped) {
|
|
65
|
+
escaped = false;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (char === "\\") {
|
|
69
|
+
escaped = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (char === "(") {
|
|
73
|
+
depth += 1;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (char !== ")") {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (depth === 0) {
|
|
80
|
+
return index;
|
|
81
|
+
}
|
|
82
|
+
depth -= 1;
|
|
83
|
+
}
|
|
84
|
+
return -1;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/core/richTextDocument.ts
|
|
88
|
+
var MARKDOWN_IMAGE_PATTERN = /!\[([^\]]*)\]\(([^)\s]+)\)/g;
|
|
89
|
+
var EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\/\//i;
|
|
90
|
+
var MENTION_LINK_PREFIX = /^mention:\/\//i;
|
|
91
|
+
var MENTION_META_PARAM_PREFIX = "meta.";
|
|
92
|
+
function normalizeLineEndings(value) {
|
|
93
|
+
return value.replace(/\r\n?/g, "\n");
|
|
94
|
+
}
|
|
95
|
+
function normalizeContentString(value) {
|
|
96
|
+
const trimmed = normalizeLineEndings(value ?? "").trim();
|
|
97
|
+
if (!trimmed) {
|
|
98
|
+
return "";
|
|
99
|
+
}
|
|
100
|
+
const markdown = convertLegacyDocumentString(trimmed);
|
|
101
|
+
return markdown || trimmed;
|
|
102
|
+
}
|
|
103
|
+
function normalizeRichTextContent(value) {
|
|
104
|
+
return normalizeContentString(value);
|
|
105
|
+
}
|
|
106
|
+
function convertLegacyDocumentString(value) {
|
|
107
|
+
try {
|
|
108
|
+
const parsed = JSON.parse(value);
|
|
109
|
+
if (parsed?.type !== "doc" || !Array.isArray(parsed.content)) {
|
|
110
|
+
return "";
|
|
111
|
+
}
|
|
112
|
+
return renderLegacyNodesToMarkdown(parsed.content).trim();
|
|
113
|
+
} catch {
|
|
114
|
+
return "";
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function renderLegacyNodesToMarkdown(nodes) {
|
|
118
|
+
return nodes.map((node) => renderLegacyNodeToMarkdown(node)).filter((part) => part.length > 0).join("\n\n");
|
|
119
|
+
}
|
|
120
|
+
function renderLegacyNodeToMarkdown(node) {
|
|
121
|
+
if (!node) {
|
|
122
|
+
return "";
|
|
123
|
+
}
|
|
124
|
+
if (node.type === "text") {
|
|
125
|
+
return node.text ?? "";
|
|
126
|
+
}
|
|
127
|
+
if (node.type === "workspaceFileLink") {
|
|
128
|
+
const attrs = node.attrs ?? {};
|
|
129
|
+
const kind = attrs.kind === "folder" ? "folder" : "file";
|
|
130
|
+
const hrefValue = (typeof attrs.href === "string" ? attrs.href : void 0) || (typeof attrs.path === "string" ? attrs.path : void 0) || "";
|
|
131
|
+
const href = normalizeRichTextLinkHref(hrefValue, kind);
|
|
132
|
+
const label = (typeof attrs.name === "string" ? attrs.name : void 0)?.trim() || href.split("/").filter(Boolean).at(-1) || href;
|
|
133
|
+
return href && label ? `[${label}](${href})` : label;
|
|
134
|
+
}
|
|
135
|
+
if (Array.isArray(node.content)) {
|
|
136
|
+
const inline = node.content.map((child) => renderLegacyNodeToMarkdown(child)).filter((part) => part.length > 0).join("").trim();
|
|
137
|
+
if (!inline) {
|
|
138
|
+
return "";
|
|
139
|
+
}
|
|
140
|
+
if (node.type === "paragraph") {
|
|
141
|
+
return inline;
|
|
142
|
+
}
|
|
143
|
+
return inline;
|
|
144
|
+
}
|
|
145
|
+
return "";
|
|
146
|
+
}
|
|
147
|
+
function normalizeWorkspacePath(pathOrHref, kind) {
|
|
148
|
+
const trimmed = pathOrHref.trim();
|
|
149
|
+
if (!trimmed) {
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
if (kind === "folder" && !trimmed.endsWith("/")) {
|
|
153
|
+
return `${trimmed}/`;
|
|
154
|
+
}
|
|
155
|
+
return trimmed;
|
|
156
|
+
}
|
|
157
|
+
function isWorkspaceReferenceHref(href) {
|
|
158
|
+
const trimmed = href.trim();
|
|
159
|
+
if (!trimmed || MENTION_LINK_PREFIX.test(trimmed) || EXTERNAL_LINK_PREFIX.test(trimmed)) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
function isRichTextMentionHref(href) {
|
|
165
|
+
return MENTION_LINK_PREFIX.test(href.trim());
|
|
166
|
+
}
|
|
167
|
+
function createMentionQueryParams(mention) {
|
|
168
|
+
const params = new URLSearchParams();
|
|
169
|
+
if (mention.kind?.trim()) {
|
|
170
|
+
params.set("kind", mention.kind.trim());
|
|
171
|
+
}
|
|
172
|
+
if (mention.href?.trim()) {
|
|
173
|
+
params.set("link", mention.href.trim());
|
|
174
|
+
}
|
|
175
|
+
if (mention.version?.trim()) {
|
|
176
|
+
params.set("v", mention.version.trim());
|
|
177
|
+
}
|
|
178
|
+
for (const [key, value] of Object.entries(mention.meta ?? {})) {
|
|
179
|
+
const nextKey = key.trim();
|
|
180
|
+
const nextValue = value.trim();
|
|
181
|
+
if (!nextKey || !nextValue) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
params.set(`${MENTION_META_PARAM_PREFIX}${nextKey}`, nextValue);
|
|
185
|
+
}
|
|
186
|
+
return params;
|
|
187
|
+
}
|
|
188
|
+
function createRichTextMentionHref(mention) {
|
|
189
|
+
const plugin = mention.plugin.trim();
|
|
190
|
+
const entityId = mention.entityId.trim();
|
|
191
|
+
if (!plugin || !entityId) {
|
|
192
|
+
return "";
|
|
193
|
+
}
|
|
194
|
+
const params = createMentionQueryParams(mention);
|
|
195
|
+
const queryString = params.toString();
|
|
196
|
+
const pathname = `${encodeURIComponent(plugin)}/${encodeURIComponent(entityId)}`;
|
|
197
|
+
return queryString ? `mention://${pathname}?${queryString}` : `mention://${pathname}`;
|
|
198
|
+
}
|
|
199
|
+
function createRichTextMentionMarkdown(mention) {
|
|
200
|
+
const label = mention.label.trim();
|
|
201
|
+
const href = createRichTextMentionHref(mention);
|
|
202
|
+
if (!label || !href) {
|
|
203
|
+
return "";
|
|
204
|
+
}
|
|
205
|
+
return `[${label}](${href})`;
|
|
206
|
+
}
|
|
207
|
+
function parseRichTextMentionHref(href, label) {
|
|
208
|
+
const trimmedHref = href.trim();
|
|
209
|
+
if (!isRichTextMentionHref(trimmedHref)) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
const parsed = new URL(trimmedHref);
|
|
214
|
+
const plugin = decodeURIComponent(parsed.hostname).trim();
|
|
215
|
+
const entityId = decodeURIComponent(
|
|
216
|
+
parsed.pathname.replace(/^\/+/, "")
|
|
217
|
+
).trim();
|
|
218
|
+
const nextLabel = label?.trim() ?? "";
|
|
219
|
+
if (!plugin || !entityId || !nextLabel) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
const metaEntries = [...parsed.searchParams.entries()].filter(
|
|
223
|
+
([key, value]) => key.startsWith(MENTION_META_PARAM_PREFIX) && value.trim().length > 0
|
|
224
|
+
).map(
|
|
225
|
+
([key, value]) => [key.slice(MENTION_META_PARAM_PREFIX.length), value.trim()]
|
|
226
|
+
).filter(([key, value]) => key.trim().length > 0 && value.length > 0);
|
|
227
|
+
return {
|
|
228
|
+
trigger: "@",
|
|
229
|
+
plugin,
|
|
230
|
+
entityId,
|
|
231
|
+
label: nextLabel,
|
|
232
|
+
kind: parsed.searchParams.get("kind")?.trim() || void 0,
|
|
233
|
+
href: parsed.searchParams.get("link")?.trim() || void 0,
|
|
234
|
+
version: parsed.searchParams.get("v")?.trim() || void 0,
|
|
235
|
+
meta: metaEntries.length > 0 ? Object.fromEntries(metaEntries) : void 0
|
|
236
|
+
};
|
|
237
|
+
} catch {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function normalizeRichTextLinkHref(pathOrHref, kind = "file") {
|
|
242
|
+
return normalizeWorkspacePath(pathOrHref, kind);
|
|
243
|
+
}
|
|
244
|
+
function createRichTextLinkMarkdown(input) {
|
|
245
|
+
const kind = input.kind === "folder" ? "folder" : "file";
|
|
246
|
+
const href = normalizeRichTextLinkHref(input.path, kind);
|
|
247
|
+
const displayName = input.name?.trim() || href.split("/").filter(Boolean).at(-1) || href || input.path.trim();
|
|
248
|
+
if (!href || !displayName) {
|
|
249
|
+
return "";
|
|
250
|
+
}
|
|
251
|
+
return `[${escapeMarkdownLinkLabel(displayName)}](${escapeMarkdownLinkHref(href)})`;
|
|
252
|
+
}
|
|
253
|
+
function appendRichTextLinksToContent(value, refs) {
|
|
254
|
+
const content = normalizeContentString(value);
|
|
255
|
+
const existing = new Set(
|
|
256
|
+
extractRichTextLinksFromContent(content).map((ref) => ref.path)
|
|
257
|
+
);
|
|
258
|
+
const rendered = refs.map((ref) => {
|
|
259
|
+
const kind = ref.kind === "folder" ? "folder" : "file";
|
|
260
|
+
const path = normalizeRichTextLinkHref(ref.path, kind);
|
|
261
|
+
if (!path || existing.has(path)) {
|
|
262
|
+
return "";
|
|
263
|
+
}
|
|
264
|
+
existing.add(path);
|
|
265
|
+
return createRichTextLinkMarkdown({ ...ref, path, kind });
|
|
266
|
+
}).filter(Boolean);
|
|
267
|
+
if (rendered.length === 0) {
|
|
268
|
+
return content;
|
|
269
|
+
}
|
|
270
|
+
return content ? `${content} ${rendered.join(" ")}` : rendered.join(" ");
|
|
271
|
+
}
|
|
272
|
+
function extractRichTextLinksFromContent(value) {
|
|
273
|
+
const content = normalizeContentString(value);
|
|
274
|
+
const refs = /* @__PURE__ */ new Map();
|
|
275
|
+
for (const match of findRichTextMarkdownLinks(content)) {
|
|
276
|
+
const name = match.label.trim();
|
|
277
|
+
const href = match.href.trim();
|
|
278
|
+
if (!name || !isWorkspaceReferenceHref(href)) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
const kind = href.endsWith("/") ? "folder" : "file";
|
|
282
|
+
const path = normalizeRichTextLinkHref(href, kind);
|
|
283
|
+
if (!path || refs.has(path)) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
refs.set(path, {
|
|
287
|
+
name,
|
|
288
|
+
path,
|
|
289
|
+
href: path,
|
|
290
|
+
kind
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
return [...refs.values()];
|
|
294
|
+
}
|
|
295
|
+
function extractRichTextMentionsFromContent(value) {
|
|
296
|
+
const content = normalizeContentString(value);
|
|
297
|
+
const refs = /* @__PURE__ */ new Map();
|
|
298
|
+
for (const match of findRichTextMarkdownLinks(content)) {
|
|
299
|
+
const label = match.label.trim();
|
|
300
|
+
const href = match.href.trim();
|
|
301
|
+
const mention = parseRichTextMentionHref(href, label);
|
|
302
|
+
if (!mention) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
const mentionKey = `${mention.plugin}:${mention.entityId}`;
|
|
306
|
+
if (refs.has(mentionKey)) {
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
refs.set(mentionKey, mention);
|
|
310
|
+
}
|
|
311
|
+
return [...refs.values()];
|
|
312
|
+
}
|
|
313
|
+
function removeRichTextMentionFromContent(content, mention) {
|
|
314
|
+
const plugin = mention.plugin.trim();
|
|
315
|
+
const entityId = mention.entityId.trim();
|
|
316
|
+
if (!plugin || !entityId) {
|
|
317
|
+
return normalizeContentString(content);
|
|
318
|
+
}
|
|
319
|
+
const normalized = normalizeContentString(content);
|
|
320
|
+
const next = replaceRichTextMarkdownLinks(normalized, (match) => {
|
|
321
|
+
const parsedMention = parseRichTextMentionHref(match.href, match.label);
|
|
322
|
+
if (!parsedMention) {
|
|
323
|
+
return match.source;
|
|
324
|
+
}
|
|
325
|
+
return parsedMention.plugin === plugin && parsedMention.entityId === entityId ? "" : match.source;
|
|
326
|
+
});
|
|
327
|
+
return next.replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
328
|
+
}
|
|
329
|
+
function removeRichTextLinkFromContent(content, path) {
|
|
330
|
+
const targetPath = path.trim();
|
|
331
|
+
if (!targetPath) {
|
|
332
|
+
return normalizeContentString(content);
|
|
333
|
+
}
|
|
334
|
+
const normalized = normalizeContentString(content);
|
|
335
|
+
const next = replaceRichTextMarkdownLinks(normalized, (match) => {
|
|
336
|
+
const href = match.href.trim();
|
|
337
|
+
const kind = href.endsWith("/") ? "folder" : "file";
|
|
338
|
+
const refPath = normalizeRichTextLinkHref(href, kind);
|
|
339
|
+
return refPath === targetPath ? "" : match.source;
|
|
340
|
+
});
|
|
341
|
+
return next.replace(/[ \t]+\n/g, "\n").replace(/\n[ \t]+/g, "\n").replace(/[ \t]{2,}/g, " ").replace(/\n{3,}/g, "\n\n").trim();
|
|
342
|
+
}
|
|
343
|
+
function extractPlainTextFromContent(value) {
|
|
344
|
+
const content = normalizeContentString(value);
|
|
345
|
+
if (!content) {
|
|
346
|
+
return "";
|
|
347
|
+
}
|
|
348
|
+
return replaceRichTextMarkdownLinks(
|
|
349
|
+
content.replace(MARKDOWN_IMAGE_PATTERN, " $1 "),
|
|
350
|
+
(match) => ` ${match.label} `
|
|
351
|
+
).replace(/^[\s>*#+-]+/gm, " ").replace(/`([^`]+)`/g, " $1 ").replace(/[*_~]/g, " ").replace(/\s+/g, " ").trim();
|
|
352
|
+
}
|
|
353
|
+
function extractPlainTextWithoutFilesFromContent(value) {
|
|
354
|
+
const content = normalizeContentString(value);
|
|
355
|
+
if (!content) {
|
|
356
|
+
return "";
|
|
357
|
+
}
|
|
358
|
+
return replaceRichTextMarkdownLinks(
|
|
359
|
+
content.replace(MARKDOWN_IMAGE_PATTERN, " "),
|
|
360
|
+
() => " "
|
|
361
|
+
).replace(/^[\s>*#+-]+/gm, " ").replace(/`([^`]+)`/g, " $1 ").replace(/[*_~]/g, " ").replace(/\s+/g, " ").trim();
|
|
362
|
+
}
|
|
363
|
+
function parseRichTextContentToDocument(value) {
|
|
364
|
+
const content = normalizeContentString(value);
|
|
365
|
+
if (!content) {
|
|
366
|
+
return {
|
|
367
|
+
type: "doc",
|
|
368
|
+
content: [{ type: "paragraph" }]
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
const paragraphs = content.split(/\n{2,}/).map((paragraph) => createRichTextParagraphNode(paragraph)).filter((paragraph) => Array.isArray(paragraph.content));
|
|
372
|
+
return {
|
|
373
|
+
type: "doc",
|
|
374
|
+
content: paragraphs.length > 0 ? paragraphs : [{ type: "paragraph" }]
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function serializeRichTextDocumentToContent(document) {
|
|
378
|
+
const paragraphs = (document.content ?? []).map((node) => serializeRichTextBlockNode(node)).filter((value) => value.length > 0);
|
|
379
|
+
return paragraphs.join("\n\n").trim();
|
|
380
|
+
}
|
|
381
|
+
function createRichTextParagraphNode(paragraph) {
|
|
382
|
+
return {
|
|
383
|
+
type: "paragraph",
|
|
384
|
+
content: createRichTextInlineNodes(paragraph)
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function createRichTextInlineNodes(text) {
|
|
388
|
+
const content = [];
|
|
389
|
+
let cursor = 0;
|
|
390
|
+
for (const match of findRichTextMarkdownLinks(text)) {
|
|
391
|
+
const { index, source } = match;
|
|
392
|
+
if (index > cursor) {
|
|
393
|
+
appendPlainTextNodes(content, text.slice(cursor, index));
|
|
394
|
+
}
|
|
395
|
+
const label = match.label.trim();
|
|
396
|
+
const href = match.href.trim();
|
|
397
|
+
const mention = parseRichTextMentionHref(href, label);
|
|
398
|
+
if (mention) {
|
|
399
|
+
content.push({
|
|
400
|
+
type: mentionReferenceNodeName,
|
|
401
|
+
attrs: mention
|
|
402
|
+
});
|
|
403
|
+
} else if (label && isWorkspaceReferenceHref(href)) {
|
|
404
|
+
const kind = href.endsWith("/") ? "folder" : "file";
|
|
405
|
+
content.push({
|
|
406
|
+
type: workspaceReferenceNodeName,
|
|
407
|
+
attrs: {
|
|
408
|
+
kind,
|
|
409
|
+
label,
|
|
410
|
+
path: normalizeRichTextLinkHref(href, kind)
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
} else {
|
|
414
|
+
appendPlainTextNodes(content, source);
|
|
415
|
+
}
|
|
416
|
+
cursor = match.to;
|
|
417
|
+
}
|
|
418
|
+
if (cursor < text.length) {
|
|
419
|
+
appendPlainTextNodes(content, text.slice(cursor));
|
|
420
|
+
}
|
|
421
|
+
return content;
|
|
422
|
+
}
|
|
423
|
+
function replaceRichTextMarkdownLinks(value, replace) {
|
|
424
|
+
let nextValue = "";
|
|
425
|
+
let cursor = 0;
|
|
426
|
+
for (const match of findRichTextMarkdownLinks(value)) {
|
|
427
|
+
nextValue += value.slice(cursor, match.index);
|
|
428
|
+
nextValue += replace(match);
|
|
429
|
+
cursor = match.to;
|
|
430
|
+
}
|
|
431
|
+
return `${nextValue}${value.slice(cursor)}`;
|
|
432
|
+
}
|
|
433
|
+
function escapeMarkdownLinkLabel(value) {
|
|
434
|
+
return value.replace(/[\\[\]]/g, "\\$&");
|
|
435
|
+
}
|
|
436
|
+
function escapeMarkdownLinkHref(value) {
|
|
437
|
+
return value.replace(/[\\()]/g, "\\$&");
|
|
438
|
+
}
|
|
439
|
+
function appendPlainTextNodes(content, text) {
|
|
440
|
+
if (!text) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const lines = text.split("\n");
|
|
444
|
+
lines.forEach((line, index) => {
|
|
445
|
+
if (line.length > 0) {
|
|
446
|
+
content.push({
|
|
447
|
+
type: "text",
|
|
448
|
+
text: line
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
if (index < lines.length - 1) {
|
|
452
|
+
content.push({ type: "hardBreak" });
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function serializeRichTextBlockNode(node) {
|
|
457
|
+
if (node.type === "paragraph") {
|
|
458
|
+
return serializeRichTextInlineNodes(node.content ?? []);
|
|
459
|
+
}
|
|
460
|
+
return serializeRichTextInlineNodes(node.content ?? []);
|
|
461
|
+
}
|
|
462
|
+
function serializeRichTextInlineNodes(nodes) {
|
|
463
|
+
return nodes.map((node) => {
|
|
464
|
+
if (node.type === "text") {
|
|
465
|
+
return typeof node.text === "string" ? node.text : "";
|
|
466
|
+
}
|
|
467
|
+
if (node.type === "hardBreak") {
|
|
468
|
+
return "\n";
|
|
469
|
+
}
|
|
470
|
+
if (node.type === workspaceReferenceNodeName) {
|
|
471
|
+
const attrs = node.attrs ?? {};
|
|
472
|
+
return createRichTextLinkMarkdown({
|
|
473
|
+
kind: attrs.kind === "folder" ? "folder" : "file",
|
|
474
|
+
name: typeof attrs.label === "string" ? attrs.label : "",
|
|
475
|
+
path: typeof attrs.path === "string" ? attrs.path : ""
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (node.type === mentionReferenceNodeName) {
|
|
479
|
+
const attrs = node.attrs ?? {};
|
|
480
|
+
const label = typeof attrs.label === "string" ? attrs.label.trim() : "";
|
|
481
|
+
const plugin = typeof attrs.plugin === "string" ? attrs.plugin.trim() : "";
|
|
482
|
+
const entityId = typeof attrs.entityId === "string" ? attrs.entityId.trim() : "";
|
|
483
|
+
if (!label || !plugin || !entityId) {
|
|
484
|
+
return "";
|
|
485
|
+
}
|
|
486
|
+
return createRichTextMentionMarkdown({
|
|
487
|
+
entityId,
|
|
488
|
+
href: typeof attrs.href === "string" ? attrs.href : void 0,
|
|
489
|
+
kind: typeof attrs.kind === "string" ? attrs.kind : void 0,
|
|
490
|
+
label,
|
|
491
|
+
meta: attrs.meta && typeof attrs.meta === "object" ? attrs.meta : void 0,
|
|
492
|
+
plugin,
|
|
493
|
+
trigger: "@",
|
|
494
|
+
version: typeof attrs.version === "string" ? attrs.version : void 0
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
if (Array.isArray(node.content)) {
|
|
498
|
+
return serializeRichTextInlineNodes(node.content);
|
|
499
|
+
}
|
|
500
|
+
return "";
|
|
501
|
+
}).join("");
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export {
|
|
505
|
+
workspaceReferenceNodeName,
|
|
506
|
+
mentionReferenceNodeName,
|
|
507
|
+
findRichTextMarkdownLinks,
|
|
508
|
+
normalizeRichTextContent,
|
|
509
|
+
isRichTextMentionHref,
|
|
510
|
+
createRichTextMentionHref,
|
|
511
|
+
createRichTextMentionMarkdown,
|
|
512
|
+
parseRichTextMentionHref,
|
|
513
|
+
normalizeRichTextLinkHref,
|
|
514
|
+
createRichTextLinkMarkdown,
|
|
515
|
+
appendRichTextLinksToContent,
|
|
516
|
+
extractRichTextLinksFromContent,
|
|
517
|
+
extractRichTextMentionsFromContent,
|
|
518
|
+
removeRichTextMentionFromContent,
|
|
519
|
+
removeRichTextLinkFromContent,
|
|
520
|
+
extractPlainTextFromContent,
|
|
521
|
+
extractPlainTextWithoutFilesFromContent,
|
|
522
|
+
parseRichTextContentToDocument,
|
|
523
|
+
serializeRichTextDocumentToContent
|
|
524
|
+
};
|
|
525
|
+
//# sourceMappingURL=chunk-52PIIFZA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/extensions/names.ts","../src/core/richTextMarkdownLinks.ts","../src/core/richTextDocument.ts"],"sourcesContent":["export const workspaceReferenceNodeName = \"workspaceReference\";\nexport const mentionReferenceNodeName = \"mentionReference\";\n","export interface RichTextMarkdownLinkMatch {\n href: string;\n index: number;\n label: string;\n source: string;\n to: number;\n}\n\nexport function* findRichTextMarkdownLinks(\n value: string\n): Generator<RichTextMarkdownLinkMatch> {\n let cursor = 0;\n\n while (cursor < value.length) {\n const labelStart = value.indexOf(\"[\", cursor);\n if (labelStart < 0) {\n return;\n }\n if (labelStart > 0 && value[labelStart - 1] === \"!\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const labelEnd = findMarkdownLabelEnd(value, labelStart + 1);\n if (labelEnd < 0 || value[labelEnd + 1] !== \"(\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const hrefStart = labelEnd + 2;\n const hrefEnd = findMarkdownHrefEnd(value, hrefStart);\n if (hrefEnd < 0) {\n cursor = labelStart + 1;\n continue;\n }\n\n yield {\n href: unescapeMarkdownLinkText(value.slice(hrefStart, hrefEnd)),\n index: labelStart,\n label: unescapeMarkdownLinkText(value.slice(labelStart + 1, labelEnd)),\n source: value.slice(labelStart, hrefEnd + 1),\n to: hrefEnd + 1\n };\n cursor = hrefEnd + 1;\n }\n}\n\nfunction unescapeMarkdownLinkText(value: string): string {\n return value.replace(/\\\\([\\\\[\\]()])/g, \"$1\");\n}\n\nfunction findMarkdownLabelEnd(value: string, cursor: number): number {\n let escaped = false;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"]\") {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction findMarkdownHrefEnd(value: string, cursor: number): number {\n let escaped = false;\n let depth = 0;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"(\") {\n depth += 1;\n continue;\n }\n if (char !== \")\") {\n continue;\n }\n if (depth === 0) {\n return index;\n }\n depth -= 1;\n }\n\n return -1;\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\nimport type { RichTextMentionAttrs } from \"../types/mention.ts\";\nimport {\n findRichTextMarkdownLinks,\n type RichTextMarkdownLinkMatch\n} from \"./richTextMarkdownLinks.ts\";\n\nexport type RichTextLinkRef = {\n name: string;\n path: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextLinkInput = {\n name?: string | null;\n path: string;\n kind?: \"file\" | \"folder\";\n};\n\nexport type RichTextMentionRef = RichTextMentionAttrs;\nexport type RichTextDocument = JSONContent;\n\nconst MARKDOWN_IMAGE_PATTERN = /!\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g;\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\nconst MENTION_META_PARAM_PREFIX = \"meta.\";\n\ntype LegacyJSONContentNode = {\n type?: string;\n text?: string;\n attrs?: Record<string, unknown>;\n content?: LegacyJSONContentNode[];\n};\n\nfunction normalizeLineEndings(value: string): string {\n return value.replace(/\\r\\n?/g, \"\\n\");\n}\n\nfunction normalizeContentString(value?: string | null): string {\n const trimmed = normalizeLineEndings(value ?? \"\").trim();\n if (!trimmed) {\n return \"\";\n }\n const markdown = convertLegacyDocumentString(trimmed);\n return markdown || trimmed;\n}\n\nexport function normalizeRichTextContent(value?: string | null): string {\n return normalizeContentString(value);\n}\n\nfunction convertLegacyDocumentString(value: string): string {\n try {\n const parsed = JSON.parse(value) as LegacyJSONContentNode;\n if (parsed?.type !== \"doc\" || !Array.isArray(parsed.content)) {\n return \"\";\n }\n return renderLegacyNodesToMarkdown(parsed.content).trim();\n } catch {\n return \"\";\n }\n}\n\nfunction renderLegacyNodesToMarkdown(nodes: LegacyJSONContentNode[]): string {\n return nodes\n .map((node) => renderLegacyNodeToMarkdown(node))\n .filter((part) => part.length > 0)\n .join(\"\\n\\n\");\n}\n\nfunction renderLegacyNodeToMarkdown(\n node: LegacyJSONContentNode | null | undefined\n): string {\n if (!node) {\n return \"\";\n }\n if (node.type === \"text\") {\n return node.text ?? \"\";\n }\n if (node.type === \"workspaceFileLink\") {\n const attrs = node.attrs ?? {};\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const hrefValue =\n (typeof attrs.href === \"string\" ? attrs.href : undefined) ||\n (typeof attrs.path === \"string\" ? attrs.path : undefined) ||\n \"\";\n const href = normalizeRichTextLinkHref(hrefValue, kind);\n const label =\n (typeof attrs.name === \"string\" ? attrs.name : undefined)?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href;\n return href && label ? `[${label}](${href})` : label;\n }\n if (Array.isArray(node.content)) {\n const inline = node.content\n .map((child) => renderLegacyNodeToMarkdown(child))\n .filter((part) => part.length > 0)\n .join(\"\")\n .trim();\n if (!inline) {\n return \"\";\n }\n if (node.type === \"paragraph\") {\n return inline;\n }\n return inline;\n }\n return \"\";\n}\n\nfunction normalizeWorkspacePath(\n pathOrHref: string,\n kind: \"file\" | \"folder\"\n): string {\n const trimmed = pathOrHref.trim();\n if (!trimmed) {\n return \"\";\n }\n if (kind === \"folder\" && !trimmed.endsWith(\"/\")) {\n return `${trimmed}/`;\n }\n return trimmed;\n}\n\nfunction isWorkspaceReferenceHref(href: string): boolean {\n const trimmed = href.trim();\n if (\n !trimmed ||\n MENTION_LINK_PREFIX.test(trimmed) ||\n EXTERNAL_LINK_PREFIX.test(trimmed)\n ) {\n return false;\n }\n return true;\n}\n\nexport function isRichTextMentionHref(href: string): boolean {\n return MENTION_LINK_PREFIX.test(href.trim());\n}\n\nfunction createMentionQueryParams(\n mention: RichTextMentionAttrs\n): URLSearchParams {\n const params = new URLSearchParams();\n if (mention.kind?.trim()) {\n params.set(\"kind\", mention.kind.trim());\n }\n if (mention.href?.trim()) {\n params.set(\"link\", mention.href.trim());\n }\n if (mention.version?.trim()) {\n params.set(\"v\", mention.version.trim());\n }\n for (const [key, value] of Object.entries(mention.meta ?? {})) {\n const nextKey = key.trim();\n const nextValue = value.trim();\n if (!nextKey || !nextValue) {\n continue;\n }\n params.set(`${MENTION_META_PARAM_PREFIX}${nextKey}`, nextValue);\n }\n return params;\n}\n\nexport function createRichTextMentionHref(\n mention: RichTextMentionAttrs\n): string {\n const plugin = mention.plugin.trim();\n const entityId = mention.entityId.trim();\n if (!plugin || !entityId) {\n return \"\";\n }\n\n const params = createMentionQueryParams(mention);\n const queryString = params.toString();\n const pathname = `${encodeURIComponent(plugin)}/${encodeURIComponent(entityId)}`;\n return queryString\n ? `mention://${pathname}?${queryString}`\n : `mention://${pathname}`;\n}\n\nexport function createRichTextMentionMarkdown(\n mention: RichTextMentionAttrs\n): string {\n const label = mention.label.trim();\n const href = createRichTextMentionHref(mention);\n if (!label || !href) {\n return \"\";\n }\n return `[${label}](${href})`;\n}\n\nexport function parseRichTextMentionHref(\n href: string,\n label?: string | null\n): RichTextMentionRef | null {\n const trimmedHref = href.trim();\n if (!isRichTextMentionHref(trimmedHref)) {\n return null;\n }\n\n try {\n const parsed = new URL(trimmedHref);\n const plugin = decodeURIComponent(parsed.hostname).trim();\n const entityId = decodeURIComponent(\n parsed.pathname.replace(/^\\/+/, \"\")\n ).trim();\n const nextLabel = label?.trim() ?? \"\";\n\n if (!plugin || !entityId || !nextLabel) {\n return null;\n }\n\n const metaEntries = [...parsed.searchParams.entries()]\n .filter(\n ([key, value]) =>\n key.startsWith(MENTION_META_PARAM_PREFIX) && value.trim().length > 0\n )\n .map(\n ([key, value]) =>\n [key.slice(MENTION_META_PARAM_PREFIX.length), value.trim()] as const\n )\n .filter(([key, value]) => key.trim().length > 0 && value.length > 0);\n\n return {\n trigger: \"@\",\n plugin,\n entityId,\n label: nextLabel,\n kind: parsed.searchParams.get(\"kind\")?.trim() || undefined,\n href: parsed.searchParams.get(\"link\")?.trim() || undefined,\n version: parsed.searchParams.get(\"v\")?.trim() || undefined,\n meta: metaEntries.length > 0 ? Object.fromEntries(metaEntries) : undefined\n };\n } catch {\n return null;\n }\n}\n\nexport function normalizeRichTextLinkHref(\n pathOrHref: string,\n kind: \"file\" | \"folder\" = \"file\"\n): string {\n return normalizeWorkspacePath(pathOrHref, kind);\n}\n\nexport function createRichTextLinkMarkdown(input: RichTextLinkInput): string {\n const kind = input.kind === \"folder\" ? \"folder\" : \"file\";\n const href = normalizeRichTextLinkHref(input.path, kind);\n const displayName =\n input.name?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href ||\n input.path.trim();\n if (!href || !displayName) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(displayName)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function appendRichTextLinksToContent(\n value: string | null | undefined,\n refs: readonly RichTextLinkInput[]\n): string {\n const content = normalizeContentString(value);\n const existing = new Set(\n extractRichTextLinksFromContent(content).map((ref) => ref.path)\n );\n const rendered = refs\n .map((ref) => {\n const kind = ref.kind === \"folder\" ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(ref.path, kind);\n if (!path || existing.has(path)) {\n return \"\";\n }\n existing.add(path);\n return createRichTextLinkMarkdown({ ...ref, path, kind });\n })\n .filter(Boolean);\n\n if (rendered.length === 0) {\n return content;\n }\n return content ? `${content} ${rendered.join(\" \")}` : rendered.join(\" \");\n}\n\nexport function extractRichTextLinksFromContent(\n value: string | null | undefined\n): RichTextLinkRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextLinkRef>();\n for (const match of findRichTextMarkdownLinks(content)) {\n const name = match.label.trim();\n const href = match.href.trim();\n if (!name || !isWorkspaceReferenceHref(href)) {\n continue;\n }\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(href, kind);\n if (!path || refs.has(path)) {\n continue;\n }\n refs.set(path, {\n name,\n path,\n href: path,\n kind\n });\n }\n return [...refs.values()];\n}\n\nexport function extractRichTextMentionsFromContent(\n value: string | null | undefined\n): RichTextMentionRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextMentionRef>();\n\n for (const match of findRichTextMarkdownLinks(content)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (!mention) {\n continue;\n }\n const mentionKey = `${mention.plugin}:${mention.entityId}`;\n if (refs.has(mentionKey)) {\n continue;\n }\n refs.set(mentionKey, mention);\n }\n\n return [...refs.values()];\n}\n\nexport function removeRichTextMentionFromContent(\n content: string,\n mention: Pick<RichTextMentionAttrs, \"plugin\" | \"entityId\">\n): string {\n const plugin = mention.plugin.trim();\n const entityId = mention.entityId.trim();\n if (!plugin || !entityId) {\n return normalizeContentString(content);\n }\n\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const parsedMention = parseRichTextMentionHref(match.href, match.label);\n if (!parsedMention) {\n return match.source;\n }\n return parsedMention.plugin === plugin &&\n parsedMention.entityId === entityId\n ? \"\"\n : match.source;\n });\n\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function removeRichTextLinkFromContent(\n content: string,\n path: string\n): string {\n const targetPath = path.trim();\n if (!targetPath) {\n return normalizeContentString(content);\n }\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const href = match.href.trim();\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const refPath = normalizeRichTextLinkHref(href, kind);\n return refPath === targetPath ? \"\" : match.source;\n });\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n[ \\t]+/g, \"\\n\")\n .replace(/[ \\t]{2,}/g, \" \")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function extractPlainTextFromContent(value?: string | null): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" $1 \"),\n (match) => ` ${match.label} `\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function extractPlainTextWithoutFilesFromContent(\n value?: string | null\n): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" \"),\n () => \" \"\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function parseRichTextContentToDocument(\n value?: string | null\n): RichTextDocument {\n const content = normalizeContentString(value);\n if (!content) {\n return {\n type: \"doc\",\n content: [{ type: \"paragraph\" }]\n };\n }\n\n const paragraphs = content\n .split(/\\n{2,}/)\n .map((paragraph) => createRichTextParagraphNode(paragraph))\n .filter((paragraph) => Array.isArray(paragraph.content));\n\n return {\n type: \"doc\",\n content: paragraphs.length > 0 ? paragraphs : [{ type: \"paragraph\" }]\n };\n}\n\nexport function serializeRichTextDocumentToContent(\n document: RichTextDocument\n): string {\n const paragraphs = (document.content ?? [])\n .map((node) => serializeRichTextBlockNode(node))\n .filter((value) => value.length > 0);\n\n return paragraphs.join(\"\\n\\n\").trim();\n}\n\nfunction createRichTextParagraphNode(paragraph: string): JSONContent {\n return {\n type: \"paragraph\",\n content: createRichTextInlineNodes(paragraph)\n };\n}\n\nfunction createRichTextInlineNodes(text: string): JSONContent[] {\n const content: JSONContent[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(text)) {\n const { index, source } = match;\n if (index > cursor) {\n appendPlainTextNodes(content, text.slice(cursor, index));\n }\n\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (mention) {\n content.push({\n type: mentionReferenceNodeName,\n attrs: mention\n });\n } else if (label && isWorkspaceReferenceHref(href)) {\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n content.push({\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label,\n path: normalizeRichTextLinkHref(href, kind)\n }\n });\n } else {\n appendPlainTextNodes(content, source);\n }\n\n cursor = match.to;\n }\n\n if (cursor < text.length) {\n appendPlainTextNodes(content, text.slice(cursor));\n }\n\n return content;\n}\n\nfunction replaceRichTextMarkdownLinks(\n value: string,\n replace: (match: RichTextMarkdownLinkMatch) => string\n): string {\n let nextValue = \"\";\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n nextValue += value.slice(cursor, match.index);\n nextValue += replace(match);\n cursor = match.to;\n }\n\n return `${nextValue}${value.slice(cursor)}`;\n}\n\nfunction escapeMarkdownLinkLabel(value: string): string {\n return value.replace(/[\\\\[\\]]/g, \"\\\\$&\");\n}\n\nfunction escapeMarkdownLinkHref(value: string): string {\n return value.replace(/[\\\\()]/g, \"\\\\$&\");\n}\n\nfunction appendPlainTextNodes(content: JSONContent[], text: string): void {\n if (!text) {\n return;\n }\n\n const lines = text.split(\"\\n\");\n lines.forEach((line, index) => {\n if (line.length > 0) {\n content.push({\n type: \"text\",\n text: line\n });\n }\n if (index < lines.length - 1) {\n content.push({ type: \"hardBreak\" });\n }\n });\n}\n\nfunction serializeRichTextBlockNode(node: JSONContent): string {\n if (node.type === \"paragraph\") {\n return serializeRichTextInlineNodes(node.content ?? []);\n }\n return serializeRichTextInlineNodes(node.content ?? []);\n}\n\nfunction serializeRichTextInlineNodes(nodes: readonly JSONContent[]): string {\n return nodes\n .map((node) => {\n if (node.type === \"text\") {\n return typeof node.text === \"string\" ? node.text : \"\";\n }\n if (node.type === \"hardBreak\") {\n return \"\\n\";\n }\n if (node.type === workspaceReferenceNodeName) {\n const attrs = node.attrs ?? {};\n return createRichTextLinkMarkdown({\n kind: attrs.kind === \"folder\" ? \"folder\" : \"file\",\n name: typeof attrs.label === \"string\" ? attrs.label : \"\",\n path: typeof attrs.path === \"string\" ? attrs.path : \"\"\n });\n }\n if (node.type === mentionReferenceNodeName) {\n const attrs = node.attrs ?? {};\n const label = typeof attrs.label === \"string\" ? attrs.label.trim() : \"\";\n const plugin =\n typeof attrs.plugin === \"string\" ? attrs.plugin.trim() : \"\";\n const entityId =\n typeof attrs.entityId === \"string\" ? attrs.entityId.trim() : \"\";\n if (!label || !plugin || !entityId) {\n return \"\";\n }\n return createRichTextMentionMarkdown({\n entityId,\n href: typeof attrs.href === \"string\" ? attrs.href : undefined,\n kind: typeof attrs.kind === \"string\" ? attrs.kind : undefined,\n label,\n meta:\n attrs.meta && typeof attrs.meta === \"object\"\n ? (attrs.meta as Record<string, string>)\n : undefined,\n plugin,\n trigger: \"@\",\n version: typeof attrs.version === \"string\" ? attrs.version : undefined\n });\n }\n\n if (Array.isArray(node.content)) {\n return serializeRichTextInlineNodes(node.content);\n }\n\n return \"\";\n })\n .join(\"\");\n}\n"],"mappings":"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","names":[]}
|