@bytexbyte/nxtlinq-ai-agent-sdk 1.6.14 → 1.6.15
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.
|
@@ -10,6 +10,8 @@ import * as React from 'react';
|
|
|
10
10
|
export declare const containsUrls: (text: string) => boolean;
|
|
11
11
|
/**
|
|
12
12
|
* Convert text with URLs to JSX elements with clickable links
|
|
13
|
+
* Supports both Markdown format [text](url) and plain URLs
|
|
14
|
+
* Also handles line breaks (\n)
|
|
13
15
|
* @param text - The text containing URLs
|
|
14
16
|
* @returns Array of JSX elements and strings
|
|
15
17
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urlUtils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/urlUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"urlUtils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/urlUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAc/B;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,OAE3C,CAAC;AAwBF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,CAAC,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,EA2F9E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,MAKhD,CAAC"}
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
* URL utility functions for detecting and converting URLs to clickable links
|
|
3
3
|
*/
|
|
4
4
|
import * as React from 'react';
|
|
5
|
+
/**
|
|
6
|
+
* Regular expression to match Markdown-style links
|
|
7
|
+
* Matches [text](url) format
|
|
8
|
+
*/
|
|
9
|
+
const MARKDOWN_LINK_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
5
10
|
/**
|
|
6
11
|
* Regular expression to match URLs
|
|
7
12
|
* Supports http, https, ftp, and www protocols
|
|
@@ -15,28 +20,83 @@ const URL_REGEX = /(https?:\/\/[^\s]+|www\.[^\s]+|[a-zA-Z0-9-]+\.[a-zA-Z]{2,}(?:
|
|
|
15
20
|
export const containsUrls = (text) => {
|
|
16
21
|
return URL_REGEX.test(text);
|
|
17
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Convert text with line breaks to JSX elements with <br/> tags
|
|
25
|
+
* @param text - The text containing line breaks
|
|
26
|
+
* @param keyPrefix - Prefix for React keys
|
|
27
|
+
* @returns Array of JSX elements and strings
|
|
28
|
+
*/
|
|
29
|
+
const convertLineBreaks = (text, keyPrefix = '') => {
|
|
30
|
+
const parts = [];
|
|
31
|
+
const lines = text.split('\n');
|
|
32
|
+
lines.forEach((line, index) => {
|
|
33
|
+
if (index > 0) {
|
|
34
|
+
parts.push(React.createElement('br', { key: `${keyPrefix}-br-${index}` }));
|
|
35
|
+
}
|
|
36
|
+
if (line) {
|
|
37
|
+
parts.push(line);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return parts;
|
|
41
|
+
};
|
|
18
42
|
/**
|
|
19
43
|
* Convert text with URLs to JSX elements with clickable links
|
|
44
|
+
* Supports both Markdown format [text](url) and plain URLs
|
|
45
|
+
* Also handles line breaks (\n)
|
|
20
46
|
* @param text - The text containing URLs
|
|
21
47
|
* @returns Array of JSX elements and strings
|
|
22
48
|
*/
|
|
23
49
|
export const convertUrlsToLinks = (text) => {
|
|
24
50
|
const parts = [];
|
|
25
51
|
let lastIndex = 0;
|
|
26
|
-
let
|
|
27
|
-
//
|
|
52
|
+
let keyCounter = 0;
|
|
53
|
+
// First, find all markdown links and plain URLs
|
|
54
|
+
const items = [];
|
|
55
|
+
// Find markdown links
|
|
56
|
+
let markdownMatch;
|
|
57
|
+
MARKDOWN_LINK_REGEX.lastIndex = 0;
|
|
58
|
+
while ((markdownMatch = MARKDOWN_LINK_REGEX.exec(text)) !== null) {
|
|
59
|
+
items.push({
|
|
60
|
+
type: 'markdown',
|
|
61
|
+
start: markdownMatch.index,
|
|
62
|
+
end: markdownMatch.index + markdownMatch[0].length,
|
|
63
|
+
text: markdownMatch[1],
|
|
64
|
+
url: markdownMatch[2]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Find plain URLs (but exclude those already matched as markdown links)
|
|
68
|
+
let urlMatch;
|
|
28
69
|
URL_REGEX.lastIndex = 0;
|
|
29
|
-
while ((
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
70
|
+
while ((urlMatch = URL_REGEX.exec(text)) !== null) {
|
|
71
|
+
const start = urlMatch.index;
|
|
72
|
+
const end = start + urlMatch[0].length;
|
|
73
|
+
// Check if this URL is already part of a markdown link
|
|
74
|
+
const isPartOfMarkdown = items.some(item => item.type === 'markdown' && start >= item.start && end <= item.end);
|
|
75
|
+
if (!isPartOfMarkdown) {
|
|
76
|
+
items.push({
|
|
77
|
+
type: 'url',
|
|
78
|
+
start,
|
|
79
|
+
end,
|
|
80
|
+
url: urlMatch[0]
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Sort items by start position
|
|
85
|
+
items.sort((a, b) => a.start - b.start);
|
|
86
|
+
// Build the result
|
|
87
|
+
items.forEach(item => {
|
|
88
|
+
// Add text before this item (with line breaks)
|
|
89
|
+
if (item.start > lastIndex) {
|
|
90
|
+
const textBefore = text.slice(lastIndex, item.start);
|
|
91
|
+
const textBeforeParts = convertLineBreaks(textBefore, `text-${keyCounter}`);
|
|
92
|
+
parts.push(...textBeforeParts);
|
|
93
|
+
keyCounter++;
|
|
35
94
|
}
|
|
36
95
|
// Create clickable link
|
|
37
|
-
const href = url.startsWith('http') ? url : `https://${url}`;
|
|
96
|
+
const href = item.url.startsWith('http') ? item.url : `https://${item.url}`;
|
|
97
|
+
const displayText = item.type === 'markdown' ? item.text : item.url;
|
|
38
98
|
parts.push(React.createElement('a', {
|
|
39
|
-
key:
|
|
99
|
+
key: `link-${keyCounter++}`,
|
|
40
100
|
href: href,
|
|
41
101
|
target: '_blank',
|
|
42
102
|
rel: 'noopener noreferrer',
|
|
@@ -51,14 +111,16 @@ export const convertUrlsToLinks = (text) => {
|
|
|
51
111
|
e.stopPropagation();
|
|
52
112
|
window.open(href, '_blank', 'noopener,noreferrer');
|
|
53
113
|
}
|
|
54
|
-
},
|
|
55
|
-
lastIndex =
|
|
56
|
-
}
|
|
57
|
-
// Add remaining text after the last
|
|
114
|
+
}, displayText));
|
|
115
|
+
lastIndex = item.end;
|
|
116
|
+
});
|
|
117
|
+
// Add remaining text after the last link (with line breaks)
|
|
58
118
|
if (lastIndex < text.length) {
|
|
59
|
-
|
|
119
|
+
const textAfter = text.slice(lastIndex);
|
|
120
|
+
const textAfterParts = convertLineBreaks(textAfter, `text-${keyCounter}`);
|
|
121
|
+
parts.push(...textAfterParts);
|
|
60
122
|
}
|
|
61
|
-
return parts.length > 0 ? parts :
|
|
123
|
+
return parts.length > 0 ? parts : convertLineBreaks(text, 'default');
|
|
62
124
|
};
|
|
63
125
|
/**
|
|
64
126
|
* Simple function to wrap URLs in anchor tags for basic HTML rendering
|
package/package.json
CHANGED