@bytexbyte/nxtlinq-ai-agent-sdk 1.4.3 → 1.4.5
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/dist/components/context/ChatBotContext.d.ts.map +1 -1
- package/dist/components/context/ChatBotContext.js +1 -13
- package/dist/components/ui/ChatBotUI.d.ts.map +1 -1
- package/dist/components/ui/ChatBotUI.js +7 -1
- package/dist/components/ui/MessageList.d.ts.map +1 -1
- package/dist/components/ui/MessageList.js +2 -1
- package/dist/components/ui/PermissionForm.d.ts.map +1 -1
- package/dist/components/ui/PermissionForm.js +35 -8
- package/dist/core/utils/__tests__/urlUtils.test.d.ts +5 -0
- package/dist/core/utils/__tests__/urlUtils.test.d.ts.map +1 -0
- package/dist/core/utils/__tests__/urlUtils.test.js +57 -0
- package/dist/core/utils/urlUtils.d.ts +23 -0
- package/dist/core/utils/urlUtils.d.ts.map +1 -0
- package/dist/core/utils/urlUtils.js +72 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/setupTests.js +16 -0
- package/package.json +1 -1
- package/umd/nxtlinq-ai-agent.umd.js +19 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../../src/components/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,EACL,kBAAkB,EAClB,YAAY,EAGb,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../../src/components/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,EACL,kBAAkB,EAClB,YAAY,EAGb,MAAM,uBAAuB,CAAC;AAI/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAyqDlD,CAAC"}
|
|
@@ -935,21 +935,9 @@ availableModels = DEFAULT_AI_MODELS, defaultModelIndex = 0, showModelSelector =
|
|
|
935
935
|
permissionDenied = true;
|
|
936
936
|
}
|
|
937
937
|
if (!isToolAllowed) {
|
|
938
|
-
// If permission denied due to missing AIT permission
|
|
938
|
+
// If permission denied due to missing AIT permission return
|
|
939
939
|
if (permissionDenied) {
|
|
940
940
|
setIsLoading(false);
|
|
941
|
-
setMessages(prev => [...prev, {
|
|
942
|
-
id: Date.now().toString(),
|
|
943
|
-
content: `You don't have the required AIT permission: ${toolUse.name}. Would you like to enable AIT permission?`,
|
|
944
|
-
role: 'assistant',
|
|
945
|
-
timestamp: new Date().toISOString(),
|
|
946
|
-
button: 'enableAIT',
|
|
947
|
-
metadata: {
|
|
948
|
-
requiresPermissionUpdate: true,
|
|
949
|
-
toolName: toolUse.name,
|
|
950
|
-
requiredPermission: toolUse.name
|
|
951
|
-
}
|
|
952
|
-
}]);
|
|
953
941
|
return;
|
|
954
942
|
}
|
|
955
943
|
// Only retry for auto-connect/auto-sign-in scenarios
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatBotUI.d.ts","sourceRoot":"","sources":["../../../src/components/ui/ChatBotUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqG/B,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"ChatBotUI.d.ts","sourceRoot":"","sources":["../../../src/components/ui/ChatBotUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqG/B,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EA4P7B,CAAC"}
|
|
@@ -207,6 +207,12 @@ export const ChatBotUI = () => {
|
|
|
207
207
|
display: 'flex',
|
|
208
208
|
alignItems: 'center',
|
|
209
209
|
justifyContent: 'center',
|
|
210
|
-
zIndex: 1002
|
|
210
|
+
zIndex: 1002,
|
|
211
|
+
padding: '20px'
|
|
212
|
+
}, onClick: (e) => {
|
|
213
|
+
// Close modal when clicking on background
|
|
214
|
+
if (e.target === e.currentTarget) {
|
|
215
|
+
setShowPermissionForm(false);
|
|
216
|
+
}
|
|
211
217
|
}, children: _jsx(PermissionForm, { onClose: () => setShowPermissionForm(false), onOpen: () => setShowPermissionForm(true) }) })), notification.show && (_jsx(ToastNotification, { type: notification.type, message: notification.message, onClose: handleCloseNotification, isChatOpen: isOpen }))] }));
|
|
212
218
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/ui/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/ui/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAmL/B,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { useChatBot } from '../context/ChatBotContext';
|
|
4
4
|
import { AI_MODEL_MAP } from '../types/ChatBotTypes';
|
|
5
|
+
import { convertUrlsToLinks } from '../../core/utils/urlUtils';
|
|
5
6
|
export const MessageList = () => {
|
|
6
7
|
const { messages, isLoading, connectWallet, signInWallet, hitAddress, ait, setShowPermissionForm, isWalletLoading, isAutoConnecting, isNeedSignInWithWallet, autoEnableAIT, isAITLoading, isAITEnabling, sendMessage } = useChatBot();
|
|
7
8
|
const messagesEndRef = React.useRef(null);
|
|
@@ -59,7 +60,7 @@ export const MessageList = () => {
|
|
|
59
60
|
wordWrap: 'break-word',
|
|
60
61
|
position: 'relative',
|
|
61
62
|
border: message.metadata?.isRetry ? '1px solid #ffeaa7' : 'none'
|
|
62
|
-
}, children: [message.metadata?.isRetry && (_jsx("span", { style: { marginRight: '8px', fontSize: '14px' }, children: "\uD83D\uDD04" })), message.content, message.button && (_jsx("div", { style: { marginTop: '10px' }, children: _jsx("button", { onClick: () => handleButtonClick(message.button, message), disabled: isAutoConnecting ||
|
|
63
|
+
}, children: [message.metadata?.isRetry && (_jsx("span", { style: { marginRight: '8px', fontSize: '14px' }, children: "\uD83D\uDD04" })), convertUrlsToLinks(message.content), message.button && (_jsx("div", { style: { marginTop: '10px' }, children: _jsx("button", { onClick: () => handleButtonClick(message.button, message), disabled: isAutoConnecting ||
|
|
63
64
|
(message.button === 'connectWallet' && Boolean(hitAddress)) ||
|
|
64
65
|
(message.button === 'signIn' && !isNeedSignInWithWallet) ||
|
|
65
66
|
(message.button === 'enableAIT' && (isAITLoading || isAITEnabling)), style: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionForm.d.ts","sourceRoot":"","sources":["../../../src/components/ui/PermissionForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"PermissionForm.d.ts","sourceRoot":"","sources":["../../../src/components/ui/PermissionForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAgiBxD,CAAC"}
|
|
@@ -133,7 +133,11 @@ export const PermissionForm = ({ onClose, onOpen }) => {
|
|
|
133
133
|
borderRadius: '12px',
|
|
134
134
|
width: '480px',
|
|
135
135
|
maxWidth: '90%',
|
|
136
|
-
|
|
136
|
+
maxHeight: '90vh',
|
|
137
|
+
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)',
|
|
138
|
+
display: 'flex',
|
|
139
|
+
flexDirection: 'column',
|
|
140
|
+
overflow: 'hidden'
|
|
137
141
|
}, children: [_jsxs("div", { style: {
|
|
138
142
|
display: 'flex',
|
|
139
143
|
justifyContent: 'space-between',
|
|
@@ -150,11 +154,21 @@ export const PermissionForm = ({ onClose, onOpen }) => {
|
|
|
150
154
|
fontSize: '24px',
|
|
151
155
|
cursor: 'pointer',
|
|
152
156
|
color: '#666',
|
|
153
|
-
padding: '
|
|
157
|
+
padding: '8px',
|
|
154
158
|
display: 'flex',
|
|
155
159
|
alignItems: 'center',
|
|
156
|
-
justifyContent: 'center'
|
|
157
|
-
|
|
160
|
+
justifyContent: 'center',
|
|
161
|
+
borderRadius: '4px',
|
|
162
|
+
transition: 'background-color 0.2s',
|
|
163
|
+
minWidth: '32px',
|
|
164
|
+
minHeight: '32px'
|
|
165
|
+
}, onMouseOver: (e) => {
|
|
166
|
+
e.currentTarget.style.backgroundColor = '#f0f0f0';
|
|
167
|
+
e.currentTarget.style.color = '#333';
|
|
168
|
+
}, onMouseOut: (e) => {
|
|
169
|
+
e.currentTarget.style.backgroundColor = 'transparent';
|
|
170
|
+
e.currentTarget.style.color = '#666';
|
|
171
|
+
}, title: "Close", children: "\u00D7" })] }), !hitAddress ? (_jsxs("div", { style: { textAlign: 'center', padding: '32px 0' }, children: [_jsx("div", { style: {
|
|
158
172
|
width: '64px',
|
|
159
173
|
height: '64px',
|
|
160
174
|
margin: '0 auto 16px',
|
|
@@ -259,10 +273,17 @@ export const PermissionForm = ({ onClose, onOpen }) => {
|
|
|
259
273
|
fontSize: '14px',
|
|
260
274
|
color: '#333',
|
|
261
275
|
border: '1px solid #e9ecef'
|
|
262
|
-
}, children: hitAddress })] }), _jsxs("div", { style: {
|
|
276
|
+
}, children: hitAddress })] }), _jsxs("div", { style: {
|
|
277
|
+
marginBottom: '24px',
|
|
278
|
+
flex: 1,
|
|
279
|
+
display: 'flex',
|
|
280
|
+
flexDirection: 'column',
|
|
281
|
+
minHeight: 0
|
|
282
|
+
}, children: [_jsx("h4", { style: {
|
|
263
283
|
marginBottom: '12px',
|
|
264
284
|
fontSize: '16px',
|
|
265
|
-
color: '#666'
|
|
285
|
+
color: '#666',
|
|
286
|
+
flexShrink: 0
|
|
266
287
|
}, children: "Permissions" }), isAITLoading ? (_jsx("div", { style: {
|
|
267
288
|
backgroundColor: '#f8f9fa',
|
|
268
289
|
padding: '16px',
|
|
@@ -274,7 +295,11 @@ export const PermissionForm = ({ onClose, onOpen }) => {
|
|
|
274
295
|
backgroundColor: '#f8f9fa',
|
|
275
296
|
padding: '16px',
|
|
276
297
|
borderRadius: '8px',
|
|
277
|
-
border: '1px solid #e9ecef'
|
|
298
|
+
border: '1px solid #e9ecef',
|
|
299
|
+
flex: 1,
|
|
300
|
+
overflowY: 'auto',
|
|
301
|
+
overflowX: 'hidden',
|
|
302
|
+
minHeight: 0
|
|
278
303
|
}, children: availablePermissions.map((permission) => (_jsx("div", { style: { marginBottom: '12px' }, children: _jsxs("label", { style: {
|
|
279
304
|
display: 'flex',
|
|
280
305
|
alignItems: 'center',
|
|
@@ -313,7 +338,9 @@ export const PermissionForm = ({ onClose, onOpen }) => {
|
|
|
313
338
|
justifyContent: 'flex-end',
|
|
314
339
|
gap: '12px',
|
|
315
340
|
borderTop: '1px solid #e9ecef',
|
|
316
|
-
paddingTop: '24px'
|
|
341
|
+
paddingTop: '24px',
|
|
342
|
+
flexShrink: 0,
|
|
343
|
+
marginTop: 'auto'
|
|
317
344
|
}, children: [_jsx("button", { onClick: handleCancel, style: {
|
|
318
345
|
padding: '10px 20px',
|
|
319
346
|
backgroundColor: '#f8f9fa',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlUtils.test.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/__tests__/urlUtils.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for URL utility functions
|
|
3
|
+
*/
|
|
4
|
+
import { containsUrls, convertUrlsToLinks, convertUrlsToHtml } from '../urlUtils';
|
|
5
|
+
describe('URL Utils', () => {
|
|
6
|
+
describe('containsUrls', () => {
|
|
7
|
+
it('should detect URLs with http protocol', () => {
|
|
8
|
+
expect(containsUrls('Visit https://example.com for more info')).toBe(true);
|
|
9
|
+
expect(containsUrls('Check out http://test.org')).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
it('should detect URLs with www', () => {
|
|
12
|
+
expect(containsUrls('Go to www.google.com')).toBe(true);
|
|
13
|
+
expect(containsUrls('Visit www.example.org')).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
it('should detect domain names', () => {
|
|
16
|
+
expect(containsUrls('Contact us at support@company.com')).toBe(false);
|
|
17
|
+
expect(containsUrls('Visit company.com for details')).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it('should return false for text without URLs', () => {
|
|
20
|
+
expect(containsUrls('This is just plain text')).toBe(false);
|
|
21
|
+
expect(containsUrls('No URLs here')).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('convertUrlsToHtml', () => {
|
|
25
|
+
it('should convert URLs to HTML anchor tags', () => {
|
|
26
|
+
const text = 'Visit https://example.com for more info';
|
|
27
|
+
const result = convertUrlsToHtml(text);
|
|
28
|
+
expect(result).toContain('<a href="https://example.com"');
|
|
29
|
+
expect(result).toContain('target="_blank"');
|
|
30
|
+
expect(result).toContain('rel="noopener noreferrer"');
|
|
31
|
+
});
|
|
32
|
+
it('should handle www URLs', () => {
|
|
33
|
+
const text = 'Go to www.google.com';
|
|
34
|
+
const result = convertUrlsToHtml(text);
|
|
35
|
+
expect(result).toContain('<a href="https://www.google.com"');
|
|
36
|
+
});
|
|
37
|
+
it('should handle multiple URLs', () => {
|
|
38
|
+
const text = 'Visit https://example.com and www.google.com';
|
|
39
|
+
const result = convertUrlsToHtml(text);
|
|
40
|
+
expect(result).toContain('https://example.com');
|
|
41
|
+
expect(result).toContain('https://www.google.com');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('convertUrlsToLinks', () => {
|
|
45
|
+
it('should return array with mixed content', () => {
|
|
46
|
+
const text = 'Visit https://example.com for more info';
|
|
47
|
+
const result = convertUrlsToLinks(text);
|
|
48
|
+
expect(Array.isArray(result)).toBe(true);
|
|
49
|
+
expect(result.length).toBeGreaterThan(0);
|
|
50
|
+
});
|
|
51
|
+
it('should handle text without URLs', () => {
|
|
52
|
+
const text = 'This is just plain text';
|
|
53
|
+
const result = convertUrlsToLinks(text);
|
|
54
|
+
expect(result).toEqual([text]);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL utility functions for detecting and converting URLs to clickable links
|
|
3
|
+
*/
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
/**
|
|
6
|
+
* Check if a string contains URLs
|
|
7
|
+
* @param text - The text to check
|
|
8
|
+
* @returns boolean indicating if URLs are found
|
|
9
|
+
*/
|
|
10
|
+
export declare const containsUrls: (text: string) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Convert text with URLs to JSX elements with clickable links
|
|
13
|
+
* @param text - The text containing URLs
|
|
14
|
+
* @returns Array of JSX elements and strings
|
|
15
|
+
*/
|
|
16
|
+
export declare const convertUrlsToLinks: (text: string) => (string | React.ReactElement)[];
|
|
17
|
+
/**
|
|
18
|
+
* Simple function to wrap URLs in anchor tags for basic HTML rendering
|
|
19
|
+
* @param text - The text containing URLs
|
|
20
|
+
* @returns HTML string with clickable links
|
|
21
|
+
*/
|
|
22
|
+
export declare const convertUrlsToHtml: (text: string) => string;
|
|
23
|
+
//# sourceMappingURL=urlUtils.d.ts.map
|
|
@@ -0,0 +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;AAQ/B;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,OAE3C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,CAAC,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,EA+C9E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,MAKhD,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL utility functions for detecting and converting URLs to clickable links
|
|
3
|
+
*/
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
/**
|
|
6
|
+
* Regular expression to match URLs
|
|
7
|
+
* Supports http, https, ftp, and www protocols
|
|
8
|
+
*/
|
|
9
|
+
const URL_REGEX = /(https?:\/\/[^\s]+|www\.[^\s]+|[a-zA-Z0-9-]+\.[a-zA-Z]{2,}(?:\/[^\s]*)?)/g;
|
|
10
|
+
/**
|
|
11
|
+
* Check if a string contains URLs
|
|
12
|
+
* @param text - The text to check
|
|
13
|
+
* @returns boolean indicating if URLs are found
|
|
14
|
+
*/
|
|
15
|
+
export const containsUrls = (text) => {
|
|
16
|
+
return URL_REGEX.test(text);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Convert text with URLs to JSX elements with clickable links
|
|
20
|
+
* @param text - The text containing URLs
|
|
21
|
+
* @returns Array of JSX elements and strings
|
|
22
|
+
*/
|
|
23
|
+
export const convertUrlsToLinks = (text) => {
|
|
24
|
+
const parts = [];
|
|
25
|
+
let lastIndex = 0;
|
|
26
|
+
let match;
|
|
27
|
+
// Reset regex lastIndex
|
|
28
|
+
URL_REGEX.lastIndex = 0;
|
|
29
|
+
while ((match = URL_REGEX.exec(text)) !== null) {
|
|
30
|
+
const url = match[0];
|
|
31
|
+
const startIndex = match.index;
|
|
32
|
+
// Add text before the URL
|
|
33
|
+
if (startIndex > lastIndex) {
|
|
34
|
+
parts.push(text.slice(lastIndex, startIndex));
|
|
35
|
+
}
|
|
36
|
+
// Create clickable link
|
|
37
|
+
const href = url.startsWith('http') ? url : `https://${url}`;
|
|
38
|
+
parts.push(React.createElement('a', {
|
|
39
|
+
key: startIndex,
|
|
40
|
+
href: href,
|
|
41
|
+
target: '_blank',
|
|
42
|
+
rel: 'noopener noreferrer',
|
|
43
|
+
style: {
|
|
44
|
+
color: '#007bff',
|
|
45
|
+
textDecoration: 'underline',
|
|
46
|
+
cursor: 'pointer'
|
|
47
|
+
},
|
|
48
|
+
onClick: (e) => {
|
|
49
|
+
e.preventDefault(); // Prevent default browser behavior
|
|
50
|
+
e.stopPropagation();
|
|
51
|
+
window.open(href, '_blank', 'noopener,noreferrer');
|
|
52
|
+
}
|
|
53
|
+
}, url));
|
|
54
|
+
lastIndex = startIndex + url.length;
|
|
55
|
+
}
|
|
56
|
+
// Add remaining text after the last URL
|
|
57
|
+
if (lastIndex < text.length) {
|
|
58
|
+
parts.push(text.slice(lastIndex));
|
|
59
|
+
}
|
|
60
|
+
return parts.length > 0 ? parts : [text];
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Simple function to wrap URLs in anchor tags for basic HTML rendering
|
|
64
|
+
* @param text - The text containing URLs
|
|
65
|
+
* @returns HTML string with clickable links
|
|
66
|
+
*/
|
|
67
|
+
export const convertUrlsToHtml = (text) => {
|
|
68
|
+
return text.replace(URL_REGEX, (url) => {
|
|
69
|
+
const href = url.startsWith('http') ? url : `https://${url}`;
|
|
70
|
+
return `<a href="${href}" target="_blank" rel="noopener noreferrer" style="color: #007bff; text-decoration: underline; cursor: pointer;">${url}</a>`;
|
|
71
|
+
});
|
|
72
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { AI_MODEL_MAP, ALL_AVAILABLE_MODELS, DEFAULT_AI_MODELS } from './compone
|
|
|
12
12
|
export { connectWallet, disconnectWallet, validateToken } from './core/utils/walletUtils';
|
|
13
13
|
export { createAITMetadata, generateAITId, prepareAITCreation } from './core/utils/aitUtils';
|
|
14
14
|
export { createNotification, getNotificationIcon } from './core/utils/notificationUtils';
|
|
15
|
+
export { containsUrls, convertUrlsToLinks, convertUrlsToHtml } from './core/utils/urlUtils';
|
|
15
16
|
export { createNxtlinqApi } from './api/nxtlinq-api';
|
|
16
17
|
export type { AIT, AITApi, Message, ServicePermission } from './types/ait-api';
|
|
17
18
|
export { default as useLocalStorage } from './core/lib/useLocalStorage';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAGlF,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,YAAY,EAEV,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,OAAO,EACR,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACd,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAGlF,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,YAAY,EAEV,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,OAAO,EACR,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACd,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,YAAY,EACV,GAAG,EACH,MAAM,EACN,OAAO,EACP,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export { AI_MODEL_MAP, ALL_AVAILABLE_MODELS, DEFAULT_AI_MODELS } from './compone
|
|
|
16
16
|
export { connectWallet, disconnectWallet, validateToken } from './core/utils/walletUtils';
|
|
17
17
|
export { createAITMetadata, generateAITId, prepareAITCreation } from './core/utils/aitUtils';
|
|
18
18
|
export { createNotification, getNotificationIcon } from './core/utils/notificationUtils';
|
|
19
|
+
export { containsUrls, convertUrlsToLinks, convertUrlsToHtml } from './core/utils/urlUtils';
|
|
19
20
|
// API client
|
|
20
21
|
export { createNxtlinqApi } from './api/nxtlinq-api';
|
|
21
22
|
export { default as useLocalStorage } from './core/lib/useLocalStorage';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupTests.d.ts","sourceRoot":"","sources":["../src/setupTests.ts"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Test setup file for Jest
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
// Mock window.open for URL tests
|
|
4
|
+
Object.defineProperty(window, 'open', {
|
|
5
|
+
writable: true,
|
|
6
|
+
value: jest.fn(),
|
|
7
|
+
});
|
|
8
|
+
// Mock console methods to avoid noise in tests
|
|
9
|
+
global.console = {
|
|
10
|
+
...console,
|
|
11
|
+
log: jest.fn(),
|
|
12
|
+
debug: jest.fn(),
|
|
13
|
+
info: jest.fn(),
|
|
14
|
+
warn: jest.fn(),
|
|
15
|
+
error: jest.fn(),
|
|
16
|
+
};
|
package/package.json
CHANGED