@tutti-os/ui-rich-text 0.0.12 → 0.0.14

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.
@@ -88,7 +88,7 @@ function findMarkdownHrefEnd(value, cursor) {
88
88
  var MARKDOWN_IMAGE_PATTERN = /!\[([^\]]*)\]\(([^)\s]+)\)/g;
89
89
  var EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\/\//i;
90
90
  var MENTION_LINK_PREFIX = /^mention:\/\//i;
91
- var MENTION_META_PARAM_PREFIX = "meta.";
91
+ var MENTION_LEGACY_QUERY_KEYS = /* @__PURE__ */ new Set(["kind", "link", "v", "version"]);
92
92
  function normalizeLineEndings(value) {
93
93
  return value.replace(/\r\n?/g, "\n");
94
94
  }
@@ -164,45 +164,42 @@ function isWorkspaceReferenceHref(href) {
164
164
  function isRichTextMentionHref(href) {
165
165
  return MENTION_LINK_PREFIX.test(href.trim());
166
166
  }
167
+ function normalizeMentionLabel(value) {
168
+ return value.trim().replace(/^@+/, "").trim();
169
+ }
167
170
  function createMentionQueryParams(mention) {
168
171
  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 ?? {})) {
172
+ for (const [key, value] of Object.entries(mention.scope ?? {}).sort(
173
+ ([left], [right]) => left.localeCompare(right)
174
+ )) {
179
175
  const nextKey = key.trim();
180
176
  const nextValue = value.trim();
181
- if (!nextKey || !nextValue) {
177
+ if (!nextKey || !nextValue || MENTION_LEGACY_QUERY_KEYS.has(nextKey) || nextKey.startsWith("meta.")) {
182
178
  continue;
183
179
  }
184
- params.set(`${MENTION_META_PARAM_PREFIX}${nextKey}`, nextValue);
180
+ params.set(nextKey, nextValue);
185
181
  }
186
182
  return params;
187
183
  }
188
184
  function createRichTextMentionHref(mention) {
189
- const plugin = mention.plugin.trim();
185
+ const providerId = mention.providerId.trim();
190
186
  const entityId = mention.entityId.trim();
191
- if (!plugin || !entityId) {
187
+ const label = normalizeMentionLabel(mention.label);
188
+ if (!providerId || !entityId || !label) {
192
189
  return "";
193
190
  }
194
191
  const params = createMentionQueryParams(mention);
195
192
  const queryString = params.toString();
196
- const pathname = `${encodeURIComponent(plugin)}/${encodeURIComponent(entityId)}`;
193
+ const pathname = `${encodeURIComponent(providerId)}/${encodeURIComponent(entityId)}`;
197
194
  return queryString ? `mention://${pathname}?${queryString}` : `mention://${pathname}`;
198
195
  }
199
196
  function createRichTextMentionMarkdown(mention) {
200
- const label = mention.label.trim();
197
+ const label = normalizeMentionLabel(mention.label);
201
198
  const href = createRichTextMentionHref(mention);
202
199
  if (!label || !href) {
203
200
  return "";
204
201
  }
205
- return `[${label}](${href})`;
202
+ return `[${escapeMarkdownLinkLabel(`@${label}`)}](${escapeMarkdownLinkHref(href)})`;
206
203
  }
207
204
  function parseRichTextMentionHref(href, label) {
208
205
  const trimmedHref = href.trim();
@@ -211,29 +208,34 @@ function parseRichTextMentionHref(href, label) {
211
208
  }
212
209
  try {
213
210
  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) {
211
+ const providerId = decodeURIComponent(parsed.hostname).trim();
212
+ const encodedEntityId = parsed.pathname.replace(/^\/+/, "");
213
+ const entityId = decodeURIComponent(encodedEntityId).trim();
214
+ const nextLabel = normalizeMentionLabel(label?.trim() ?? "");
215
+ if (!providerId || !encodedEntityId || encodedEntityId.includes("/") || !entityId || !nextLabel) {
220
216
  return null;
221
217
  }
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 {
218
+ const scopeEntries = [];
219
+ for (const [key, value] of parsed.searchParams.entries()) {
220
+ const scopeKey = key.trim();
221
+ const scopeValue = value.trim();
222
+ if (!scopeKey || MENTION_LEGACY_QUERY_KEYS.has(scopeKey) || scopeKey.startsWith("meta.")) {
223
+ return null;
224
+ }
225
+ if (scopeValue) {
226
+ scopeEntries.push([scopeKey, scopeValue]);
227
+ }
228
+ }
229
+ const mention = {
228
230
  trigger: "@",
229
- plugin,
231
+ providerId,
230
232
  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
233
+ label: nextLabel
236
234
  };
235
+ if (scopeEntries.length > 0) {
236
+ mention.scope = Object.fromEntries(scopeEntries);
237
+ }
238
+ return mention;
237
239
  } catch {
238
240
  return null;
239
241
  }
@@ -302,7 +304,17 @@ function extractRichTextMentionsFromContent(value) {
302
304
  if (!mention) {
303
305
  continue;
304
306
  }
305
- const mentionKey = `${mention.plugin}:${mention.entityId}`;
307
+ const mentionKey = [
308
+ mention.providerId,
309
+ mention.entityId,
310
+ JSON.stringify(
311
+ Object.fromEntries(
312
+ Object.entries(mention.scope ?? {}).sort(
313
+ ([left], [right]) => left.localeCompare(right)
314
+ )
315
+ )
316
+ )
317
+ ].join(":");
306
318
  if (refs.has(mentionKey)) {
307
319
  continue;
308
320
  }
@@ -311,9 +323,9 @@ function extractRichTextMentionsFromContent(value) {
311
323
  return [...refs.values()];
312
324
  }
313
325
  function removeRichTextMentionFromContent(content, mention) {
314
- const plugin = mention.plugin.trim();
326
+ const providerId = mention.providerId.trim();
315
327
  const entityId = mention.entityId.trim();
316
- if (!plugin || !entityId) {
328
+ if (!providerId || !entityId) {
317
329
  return normalizeContentString(content);
318
330
  }
319
331
  const normalized = normalizeContentString(content);
@@ -322,7 +334,7 @@ function removeRichTextMentionFromContent(content, mention) {
322
334
  if (!parsedMention) {
323
335
  return match.source;
324
336
  }
325
- return parsedMention.plugin === plugin && parsedMention.entityId === entityId ? "" : match.source;
337
+ return parsedMention.providerId === providerId && parsedMention.entityId === entityId ? "" : match.source;
326
338
  });
327
339
  return next.replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
328
340
  }
@@ -478,20 +490,17 @@ function serializeRichTextInlineNodes(nodes) {
478
490
  if (node.type === mentionReferenceNodeName) {
479
491
  const attrs = node.attrs ?? {};
480
492
  const label = typeof attrs.label === "string" ? attrs.label.trim() : "";
481
- const plugin = typeof attrs.plugin === "string" ? attrs.plugin.trim() : "";
493
+ const providerId = typeof attrs.providerId === "string" ? attrs.providerId.trim() : "";
482
494
  const entityId = typeof attrs.entityId === "string" ? attrs.entityId.trim() : "";
483
- if (!label || !plugin || !entityId) {
495
+ if (!label || !providerId || !entityId) {
484
496
  return "";
485
497
  }
498
+ const scope = attrs.scope && typeof attrs.scope === "object" ? attrs.scope : void 0;
486
499
  return createRichTextMentionMarkdown({
487
500
  entityId,
488
- href: typeof attrs.href === "string" ? attrs.href : void 0,
489
- kind: typeof attrs.kind === "string" ? attrs.kind : void 0,
490
501
  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
502
+ providerId,
503
+ scope
495
504
  });
496
505
  }
497
506
  if (Array.isArray(node.content)) {
@@ -522,4 +531,4 @@ export {
522
531
  parseRichTextContentToDocument,
523
532
  serializeRichTextDocumentToContent
524
533
  };
525
- //# sourceMappingURL=chunk-52PIIFZA.js.map
534
+ //# sourceMappingURL=chunk-QOVFZUZN.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 {\n RichTextMentionAttrs,\n RichTextMentionIdentity\n} 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_LEGACY_QUERY_KEYS = new Set([\"kind\", \"link\", \"v\", \"version\"]);\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 normalizeMentionLabel(value: string): string {\n return value.trim().replace(/^@+/, \"\").trim();\n}\n\nfunction createMentionQueryParams(\n mention: RichTextMentionIdentity\n): URLSearchParams {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(mention.scope ?? {}).sort(\n ([left], [right]) => left.localeCompare(right)\n )) {\n const nextKey = key.trim();\n const nextValue = value.trim();\n if (\n !nextKey ||\n !nextValue ||\n MENTION_LEGACY_QUERY_KEYS.has(nextKey) ||\n nextKey.startsWith(\"meta.\")\n ) {\n continue;\n }\n params.set(nextKey, nextValue);\n }\n return params;\n}\n\nexport function createRichTextMentionHref(\n mention: RichTextMentionIdentity\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n const label = normalizeMentionLabel(mention.label);\n if (!providerId || !entityId || !label) {\n return \"\";\n }\n\n const params = createMentionQueryParams(mention);\n const queryString = params.toString();\n const pathname = `${encodeURIComponent(providerId)}/${encodeURIComponent(entityId)}`;\n return queryString\n ? `mention://${pathname}?${queryString}`\n : `mention://${pathname}`;\n}\n\nexport function createRichTextMentionMarkdown(\n mention: RichTextMentionIdentity\n): string {\n const label = normalizeMentionLabel(mention.label);\n const href = createRichTextMentionHref(mention);\n if (!label || !href) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(`@${label}`)}](${escapeMarkdownLinkHref(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 providerId = decodeURIComponent(parsed.hostname).trim();\n const encodedEntityId = parsed.pathname.replace(/^\\/+/, \"\");\n const entityId = decodeURIComponent(encodedEntityId).trim();\n const nextLabel = normalizeMentionLabel(label?.trim() ?? \"\");\n\n if (\n !providerId ||\n !encodedEntityId ||\n encodedEntityId.includes(\"/\") ||\n !entityId ||\n !nextLabel\n ) {\n return null;\n }\n\n const scopeEntries: Array<readonly [string, string]> = [];\n for (const [key, value] of parsed.searchParams.entries()) {\n const scopeKey = key.trim();\n const scopeValue = value.trim();\n if (\n !scopeKey ||\n MENTION_LEGACY_QUERY_KEYS.has(scopeKey) ||\n scopeKey.startsWith(\"meta.\")\n ) {\n return null;\n }\n if (scopeValue) {\n scopeEntries.push([scopeKey, scopeValue]);\n }\n }\n\n const mention: RichTextMentionRef = {\n trigger: \"@\",\n providerId,\n entityId,\n label: nextLabel\n };\n if (scopeEntries.length > 0) {\n mention.scope = Object.fromEntries(scopeEntries);\n }\n return mention;\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 = [\n mention.providerId,\n mention.entityId,\n JSON.stringify(\n Object.fromEntries(\n Object.entries(mention.scope ?? {}).sort(([left], [right]) =>\n left.localeCompare(right)\n )\n )\n )\n ].join(\":\");\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, \"providerId\" | \"entityId\">\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n if (!providerId || !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.providerId === providerId &&\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 providerId =\n typeof attrs.providerId === \"string\" ? attrs.providerId.trim() : \"\";\n const entityId =\n typeof attrs.entityId === \"string\" ? attrs.entityId.trim() : \"\";\n if (!label || !providerId || !entityId) {\n return \"\";\n }\n const scope =\n attrs.scope && typeof attrs.scope === \"object\"\n ? (attrs.scope as Record<string, string>)\n : undefined;\n return createRichTextMentionMarkdown({\n entityId,\n label,\n providerId,\n scope\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":[]}
@@ -1,5 +1,5 @@
1
1
  import { JSONContent } from '@tiptap/core';
2
- import { R as RichTextMentionAttrs } from '../mention-QICvf4wE.js';
2
+ import { a as RichTextMentionIdentity, R as RichTextMentionAttrs } from '../mention-CgUcsO8r.js';
3
3
 
4
4
  type RichTextLinkRef = {
5
5
  name: string;
@@ -16,15 +16,15 @@ type RichTextMentionRef = RichTextMentionAttrs;
16
16
  type RichTextDocument = JSONContent;
17
17
  declare function normalizeRichTextContent(value?: string | null): string;
18
18
  declare function isRichTextMentionHref(href: string): boolean;
19
- declare function createRichTextMentionHref(mention: RichTextMentionAttrs): string;
20
- declare function createRichTextMentionMarkdown(mention: RichTextMentionAttrs): string;
19
+ declare function createRichTextMentionHref(mention: RichTextMentionIdentity): string;
20
+ declare function createRichTextMentionMarkdown(mention: RichTextMentionIdentity): string;
21
21
  declare function parseRichTextMentionHref(href: string, label?: string | null): RichTextMentionRef | null;
22
22
  declare function normalizeRichTextLinkHref(pathOrHref: string, kind?: "file" | "folder"): string;
23
23
  declare function createRichTextLinkMarkdown(input: RichTextLinkInput): string;
24
24
  declare function appendRichTextLinksToContent(value: string | null | undefined, refs: readonly RichTextLinkInput[]): string;
25
25
  declare function extractRichTextLinksFromContent(value: string | null | undefined): RichTextLinkRef[];
26
26
  declare function extractRichTextMentionsFromContent(value: string | null | undefined): RichTextMentionRef[];
27
- declare function removeRichTextMentionFromContent(content: string, mention: Pick<RichTextMentionAttrs, "plugin" | "entityId">): string;
27
+ declare function removeRichTextMentionFromContent(content: string, mention: Pick<RichTextMentionAttrs, "providerId" | "entityId">): string;
28
28
  declare function removeRichTextLinkFromContent(content: string, path: string): string;
29
29
  declare function extractPlainTextFromContent(value?: string | null): string;
30
30
  declare function extractPlainTextWithoutFilesFromContent(value?: string | null): string;
@@ -16,7 +16,7 @@ import {
16
16
  removeRichTextLinkFromContent,
17
17
  removeRichTextMentionFromContent,
18
18
  serializeRichTextDocumentToContent
19
- } from "../chunk-52PIIFZA.js";
19
+ } from "../chunk-QOVFZUZN.js";
20
20
  export {
21
21
  appendRichTextLinksToContent,
22
22
  createRichTextLinkMarkdown,
@@ -1,19 +1,19 @@
1
1
  import { ReactNode, JSX } from 'react';
2
- import { RichTextAtProvider } from '../types/index.js';
2
+ import { RichTextTriggerProvider, RichTextTrigger, RichTextTriggerConfig, RichTextTriggerBoundary, RichTextTriggerRegistry, RichTextTriggerQueryInput, RichTextTriggerQueryMatch } from '../types/index.js';
3
3
  import { a as RichTextI18nRuntime } from '../richTextI18n-CUeqHuEQ.js';
4
- import { R as RichTextMentionAttrs, i as RichTextResolvedMention, j as RichTextResolvedMentionView } from '../mention-QICvf4wE.js';
4
+ import { R as RichTextMentionAttrs, l as RichTextResolvedMention, m as RichTextResolvedMentionView } from '../mention-CgUcsO8r.js';
5
5
  import '@tutti-os/ui-i18n-runtime';
6
6
 
7
- interface RichTextAtTextOverrides {
7
+ interface RichTextTriggerTextOverrides {
8
8
  loadingLabel?: string;
9
9
  noMatchesLabel?: string;
10
10
  removeReferenceActionLabel?: string;
11
11
  }
12
12
 
13
- interface RichTextAtEditorProps {
13
+ interface RichTextTriggerEditorProps {
14
14
  value: string;
15
15
  onChange: (value: string) => void;
16
- providers?: readonly RichTextAtProvider[];
16
+ triggerProviders?: readonly RichTextTriggerProvider[];
17
17
  placeholder?: string;
18
18
  disabled?: boolean;
19
19
  className?: string;
@@ -23,16 +23,22 @@ interface RichTextAtEditorProps {
23
23
  maxResults?: number;
24
24
  removeDecorationAriaLabel?: string;
25
25
  i18n?: RichTextI18nRuntime;
26
- textOverrides?: RichTextAtTextOverrides;
26
+ textOverrides?: RichTextTriggerTextOverrides;
27
27
  overlay?: ReactNode;
28
28
  focusSignal?: unknown;
29
+ menuZIndex?: string | number;
29
30
  }
30
- declare function RichTextAtEditor({ value, onChange, providers, placeholder, disabled, className, textareaClassName, placeholderClassName, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay, focusSignal }: RichTextAtEditorProps): JSX.Element;
31
+ declare global {
32
+ interface Window {
33
+ __tuttiRichTextDebugLog?: (event: string, payload: unknown) => void;
34
+ }
35
+ }
36
+ declare function RichTextTriggerEditor({ value, onChange, triggerProviders, placeholder, disabled, className, textareaClassName, placeholderClassName, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay, focusSignal, menuZIndex }: RichTextTriggerEditorProps): JSX.Element;
31
37
 
32
- interface RichTextAtTextareaProps {
38
+ interface RichTextTriggerTextareaProps {
33
39
  value: string;
34
40
  onChange: (value: string) => void;
35
- providers?: readonly RichTextAtProvider[];
41
+ triggerProviders?: readonly RichTextTriggerProvider[];
36
42
  placeholder?: string;
37
43
  disabled?: boolean;
38
44
  className?: string;
@@ -42,10 +48,10 @@ interface RichTextAtTextareaProps {
42
48
  maxResults?: number;
43
49
  removeDecorationAriaLabel?: string;
44
50
  i18n?: RichTextI18nRuntime;
45
- textOverrides?: RichTextAtTextOverrides;
51
+ textOverrides?: RichTextTriggerTextOverrides;
46
52
  overlay?: ReactNode;
47
53
  }
48
- declare function RichTextAtTextarea({ value, onChange, providers, placeholder, disabled, className, textareaClassName, rows, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay }: RichTextAtTextareaProps): JSX.Element;
54
+ declare function RichTextTriggerTextarea({ value, onChange, triggerProviders, placeholder, disabled, className, textareaClassName, rows, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay }: RichTextTriggerTextareaProps): JSX.Element;
49
55
 
50
56
  interface RichTextMentionReadonlyClickPayload<TResolved = unknown> {
51
57
  mention: RichTextMentionAttrs;
@@ -70,8 +76,19 @@ interface RichTextReadonlyContentProps {
70
76
  value: string;
71
77
  className?: string;
72
78
  paragraphClassName?: string;
79
+ onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;
73
80
  onOpenWorkspaceReference?: (reference: RichTextReadonlyWorkspaceReference) => void | Promise<void>;
74
81
  }
75
- declare function RichTextReadonlyContent({ value, className, paragraphClassName, onOpenWorkspaceReference }: RichTextReadonlyContentProps): JSX.Element | null;
82
+ declare function RichTextReadonlyContent({ value, className, paragraphClassName, onMentionAction, onOpenWorkspaceReference }: RichTextReadonlyContentProps): JSX.Element | null;
83
+
84
+ interface RichTextTriggerQueryState {
85
+ from: number;
86
+ to: number;
87
+ keyword: string;
88
+ trigger: RichTextTrigger;
89
+ }
90
+ declare function isRichTextTriggerPrefixBoundary(character: string, boundary: RichTextTriggerBoundary): boolean;
91
+ declare function findRichTextTriggerQuery(value: string, caret: number, triggerConfigs: readonly RichTextTriggerConfig[]): RichTextTriggerQueryState | null;
92
+ declare function queryRichTextTriggerMatches(registry: RichTextTriggerRegistry, input: RichTextTriggerQueryInput): Promise<readonly RichTextTriggerQueryMatch[]>;
76
93
 
77
- export { RichTextAtEditor, type RichTextAtEditorProps, type RichTextAtTextOverrides, RichTextAtTextarea, type RichTextAtTextareaProps, RichTextMentionReadonly, type RichTextMentionReadonlyClickPayload, type RichTextMentionReadonlyProps, RichTextReadonlyContent, type RichTextReadonlyContentProps, type RichTextReadonlyWorkspaceReference };
94
+ export { RichTextMentionReadonly, type RichTextMentionReadonlyClickPayload, type RichTextMentionReadonlyProps, RichTextReadonlyContent, type RichTextReadonlyContentProps, type RichTextReadonlyWorkspaceReference, RichTextTriggerEditor, type RichTextTriggerEditorProps, type RichTextTriggerQueryState, type RichTextTriggerTextOverrides, RichTextTriggerTextarea, type RichTextTriggerTextareaProps, findRichTextTriggerQuery, isRichTextTriggerPrefixBoundary, queryRichTextTriggerMatches };