@smart-cloud/ai-kit-ui 1.1.17 → 1.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smart-cloud/ai-kit-ui",
3
- "version": "1.1.17",
3
+ "version": "1.1.19",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "@emotion/cache": "^11.14.0",
21
21
  "@emotion/react": "^11.14.0",
22
22
  "@mantine/colors-generator": "^8.3.13",
23
- "@smart-cloud/ai-kit-core": "^1.1.7",
23
+ "@smart-cloud/ai-kit-core": "^1.1.8",
24
24
  "@smart-cloud/wpsuite-core": "^2.0.5",
25
25
  "@tabler/icons-react": "^3.36.1",
26
26
  "chroma-js": "^3.2.0",
@@ -53,8 +53,9 @@ const TWENTY_FOUR_HOURS_MS = 24 * 60 * 60 * 1000;
53
53
 
54
54
  // New: history storage support
55
55
  const DEFAULT_HISTORY_STORAGE: HistoryStorageMode = "localstorage";
56
- const HISTORY_STORAGE_KEY = `ai-kit-chatbot-history-v1:${typeof window !== "undefined" ? window.location.hostname : "unknown"
57
- }`;
56
+ const HISTORY_STORAGE_KEY = `ai-kit-chatbot-history-v1:${
57
+ typeof window !== "undefined" ? window.location.hostname : "unknown"
58
+ }`;
58
59
 
59
60
  export const DEFAULT_CHATBOT_LABELS: Required<AiChatbotLabels> = {
60
61
  modalTitle: "AI Assistant",
@@ -295,7 +296,6 @@ const AiChatbotBase: FC<AiChatbotProps & AiKitShellInjectedProps> = (props) => {
295
296
 
296
297
  useEffect(() => {
297
298
  if (language) {
298
- console.log(`AiChatbot: setting language to ${language}`);
299
299
  I18n.setLanguage(language || "en");
300
300
  }
301
301
  }, [language]);
@@ -595,7 +595,7 @@ const AiChatbotBase: FC<AiChatbotProps & AiKitShellInjectedProps> = (props) => {
595
595
  try {
596
596
  const activeSessionId =
597
597
  sessionRef.current &&
598
- Date.now() - sessionRef.current.storedAt < TWENTY_FOUR_HOURS_MS
598
+ Date.now() - sessionRef.current.storedAt < TWENTY_FOUR_HOURS_MS
599
599
  ? sessionRef.current.id
600
600
  : undefined;
601
601
  if (!activeSessionId) return;
@@ -680,7 +680,7 @@ const AiChatbotBase: FC<AiChatbotProps & AiKitShellInjectedProps> = (props) => {
680
680
  try {
681
681
  const activeSessionId =
682
682
  sessionRef.current &&
683
- Date.now() - sessionRef.current.storedAt < TWENTY_FOUR_HOURS_MS
683
+ Date.now() - sessionRef.current.storedAt < TWENTY_FOUR_HOURS_MS
684
684
  ? sessionRef.current.id
685
685
  : undefined;
686
686
 
@@ -22,14 +22,21 @@ export type AiKitShellInjectedProps = {
22
22
  rootElement: HTMLElement;
23
23
  };
24
24
 
25
- function hashStringDjb2(str: string): string {
25
+ const hashStringDjb2 = (str: string): string => {
26
26
  let hash = 5381;
27
27
  for (let i = 0; i < str.length; i++) {
28
28
  hash = ((hash << 5) + hash) ^ str.charCodeAt(i);
29
29
  }
30
30
  // unsigned + base36
31
31
  return (hash >>> 0).toString(36);
32
- }
32
+ };
33
+
34
+ const sanitizeThemeOverrides = (input: string): string =>
35
+ input
36
+ .replace(/<\/?(?:style|script)\b[^>]*>/gi, "")
37
+ .replace(/@import\s+['"]?javascript:[^;]+;?/gi, "")
38
+ .replace(/url\(\s*(['"]?)javascript:[^)]+\)/gi, "")
39
+ .replace(/\bexpression\s*\([^)]*\)/gi, "");
33
40
 
34
41
  const STYLE_TEXT_ID = "ai-kit-style-text";
35
42
 
@@ -126,19 +133,19 @@ export function withAiKitShell<P extends object>(
126
133
  ].includes(primaryColor) && { primaryColor }),
127
134
  ...(primaryShade &&
128
135
  Object.keys(primaryShade).length > 0 && {
129
- primaryShade: {
130
- light:
131
- primaryShade.light ??
132
- (typeof DEFAULT_THEME.primaryShade === "object"
133
- ? DEFAULT_THEME.primaryShade.light
134
- : (DEFAULT_THEME.primaryShade ?? 6)),
135
- dark:
136
- primaryShade.dark ??
137
- (typeof DEFAULT_THEME.primaryShade === "object"
138
- ? DEFAULT_THEME.primaryShade.dark
139
- : (DEFAULT_THEME.primaryShade ?? 6)),
140
- },
141
- }),
136
+ primaryShade: {
137
+ light:
138
+ primaryShade.light ??
139
+ (typeof DEFAULT_THEME.primaryShade === "object"
140
+ ? DEFAULT_THEME.primaryShade.light
141
+ : (DEFAULT_THEME.primaryShade ?? 6)),
142
+ dark:
143
+ primaryShade.dark ??
144
+ (typeof DEFAULT_THEME.primaryShade === "object"
145
+ ? DEFAULT_THEME.primaryShade.dark
146
+ : (DEFAULT_THEME.primaryShade ?? 6)),
147
+ },
148
+ }),
142
149
  components: {
143
150
  Button: {
144
151
  styles: { root: { borderRadius: "inherit" } },
@@ -179,41 +186,32 @@ export function withAiKitShell<P extends object>(
179
186
  return themeOverrides ? hashStringDjb2(themeOverrides) : "";
180
187
  }, [themeOverrides]);
181
188
 
182
- useEffect(
183
- () => {
184
-
185
- if (!host) {
186
- return;
187
- }
188
-
189
- const existingStyle = host.shadowRoot!.getElementById(
190
- STYLE_TEXT_ID,
191
- ) as HTMLStyleElement | null;
189
+ useEffect(() => {
190
+ if (!host) {
191
+ return;
192
+ }
192
193
 
193
- console.log('injectStyle called', host, host.shadowRoot, existingStyle);
194
+ const existingStyle = host.shadowRoot!.getElementById(
195
+ STYLE_TEXT_ID,
196
+ ) as HTMLStyleElement | null;
194
197
 
195
- if (themeOverrides) {
196
- if (!existingStyle) {
197
- console.log('Creating new style element');
198
- const s = host.shadowRoot!.ownerDocument.createElement("style");
199
- s.id = STYLE_TEXT_ID;
200
- s.setAttribute("data-hash", themeOverridesHash);
201
- s.textContent = themeOverrides;
202
- host.shadowRoot!.appendChild(s);
203
- } else {
204
- const prevHash = existingStyle.getAttribute("data-hash") || "";
205
- if (prevHash !== themeOverridesHash) {
206
- console.log('Updating existing style element');
207
- existingStyle.textContent = themeOverrides;
208
- }
198
+ if (themeOverrides) {
199
+ if (!existingStyle) {
200
+ const s = host.shadowRoot!.ownerDocument.createElement("style");
201
+ s.id = STYLE_TEXT_ID;
202
+ s.setAttribute("data-hash", themeOverridesHash);
203
+ s.textContent = sanitizeThemeOverrides(themeOverrides);
204
+ host.shadowRoot!.appendChild(s);
205
+ } else {
206
+ const prevHash = existingStyle.getAttribute("data-hash") || "";
207
+ if (prevHash !== themeOverridesHash) {
208
+ existingStyle.textContent = sanitizeThemeOverrides(themeOverrides);
209
209
  }
210
- } else if (existingStyle) {
211
- console.log('Removing existing style element');
212
- existingStyle.remove();
213
210
  }
214
- },
215
- [host, themeOverrides, themeOverridesHash],
216
- );
211
+ } else if (existingStyle) {
212
+ existingStyle.remove();
213
+ }
214
+ }, [host, themeOverrides, themeOverridesHash]);
217
215
 
218
216
  return (
219
217
  <ShadowBoundary
@@ -266,7 +264,8 @@ export function withAiKitShell<P extends object>(
266
264
  );
267
265
  };
268
266
 
269
- Wrapped.displayName = `withAiKitShell(${RootComponent.displayName ?? RootComponent.name ?? "Component"
270
- })`;
267
+ Wrapped.displayName = `withAiKitShell(${
268
+ RootComponent.displayName ?? RootComponent.name ?? "Component"
269
+ })`;
271
270
  return Wrapped;
272
271
  }