@lumiastream/ui 0.0.6 → 0.1.0-beta.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/dist/index.d.ts CHANGED
@@ -123,4 +123,109 @@ declare const codeMirrorlinterOptions: (type: "overlay" | "code", language?: "js
123
123
  };
124
124
  };
125
125
 
126
- export { LSButton, type LSButtonProps, codeMirrorlinterOptions, variableCompletionOptions };
126
+ declare const MEDIA_PREVIEW_USER_LEVEL_VALUES: readonly ["streamer", "moderators", "vips", "tier3", "tier2", "subscribers", "regular", "follower", "anyone"];
127
+ type MediaPreviewUserLevel = (typeof MEDIA_PREVIEW_USER_LEVEL_VALUES)[number];
128
+ type ChatboxMediaPreviewKind = 'image' | 'video' | 'audio' | 'youtube' | 'youtubeShort' | 'spotify';
129
+ type ChatboxMediaPreview = {
130
+ kind: ChatboxMediaPreviewKind;
131
+ src: string;
132
+ title?: string;
133
+ };
134
+ type MessageLinkPart = {
135
+ text: string;
136
+ url?: string;
137
+ };
138
+ type ChatMessageToken = {
139
+ type: 'text';
140
+ text: string;
141
+ } | {
142
+ type: 'link';
143
+ text: string;
144
+ url: string;
145
+ } | {
146
+ type: 'media';
147
+ text: string;
148
+ url: string;
149
+ media: ChatboxMediaPreview;
150
+ };
151
+ type MediaPreviewRoleSettings = {
152
+ previewMediaForViewers: boolean;
153
+ previewMediaForSubscribers: boolean;
154
+ previewMediaForVips: boolean;
155
+ previewMediaForModerators: boolean;
156
+ previewMediaForStreamer: boolean;
157
+ previewMediaForTier3: boolean;
158
+ previewMediaForTier2: boolean;
159
+ previewMediaForRegular: boolean;
160
+ previewMediaForFollower: boolean;
161
+ previewMediaForAnyone: boolean;
162
+ };
163
+ type MediaPreviewRoleSettingsInput = Partial<Record<keyof MediaPreviewRoleSettings, unknown>> & {
164
+ previewMediaUserLevels?: unknown;
165
+ };
166
+ type ChatMessageTokenizationOptions = {
167
+ hyperClickableLinks?: boolean;
168
+ previewMediaInChat?: boolean;
169
+ };
170
+ type ChatterProfileUrlInput = {
171
+ platform?: unknown;
172
+ username?: unknown;
173
+ displayname?: unknown;
174
+ userId?: unknown;
175
+ };
176
+ type ChatMessageEmoteStore = {
177
+ ffz?: Record<string, string>;
178
+ bttv?: Record<string, string>;
179
+ seventv?: Record<string, string>;
180
+ };
181
+ type ChatMessageContentItem = string | {
182
+ id: string;
183
+ urls: string[];
184
+ key: string;
185
+ } | {
186
+ id: string;
187
+ type: 'cheer';
188
+ roundedAmount: number;
189
+ cheerAmount: number;
190
+ bitColor: string;
191
+ key: string;
192
+ };
193
+ type BuildChatMessageContentOptions = {
194
+ message?: string;
195
+ replaceWord?: string;
196
+ filteredWordsRegex?: RegExp;
197
+ emotesRaw?: string;
198
+ emotesPack?: Record<string, any> | any[];
199
+ origin?: string;
200
+ emoteParserType?: string;
201
+ isCheer?: boolean;
202
+ storeEmotes?: ChatMessageEmoteStore;
203
+ youtubeEmotes?: Record<string, string>;
204
+ allowParserTypes?: string[];
205
+ };
206
+ type ChatterProfileResolverPayload = {
207
+ username?: string;
208
+ displayname?: string;
209
+ userId?: string;
210
+ platform?: string;
211
+ extraSettings?: Record<string, any>;
212
+ };
213
+ type ChatterProfileResolver = (payload: ChatterProfileResolverPayload) => Promise<unknown> | unknown;
214
+ type ResolveChatterProfileUrlWithResolversInput = ChatterProfileUrlInput & {
215
+ extraSettings?: Record<string, any>;
216
+ resolvers?: Array<ChatterProfileResolver | null | undefined>;
217
+ };
218
+ declare const parseMessageLinks: (value: string) => MessageLinkPart[];
219
+ declare const tokenizeChatMessage: (value: string, options?: ChatMessageTokenizationOptions) => ChatMessageToken[];
220
+ declare const buildChatMessageContent: ({ message, replaceWord, filteredWordsRegex, emotesRaw, emotesPack, origin, emoteParserType, isCheer, storeEmotes, youtubeEmotes, allowParserTypes, }: BuildChatMessageContentOptions) => ChatMessageContentItem[];
221
+ declare const resolveMediaPreviewSetting: (value: unknown, fallback: boolean) => boolean;
222
+ declare const normalizeMediaPreviewUserLevels: (value: unknown) => MediaPreviewUserLevel[];
223
+ declare const resolveMediaPreviewRoleSettings: (settings: MediaPreviewRoleSettingsInput) => MediaPreviewRoleSettings;
224
+ declare const getNormalizedUserLevels: (value: unknown) => Record<string, boolean>;
225
+ declare const isMediaPreviewAllowedForUser: (userLevelsRaw: unknown, roleSettings: MediaPreviewRoleSettings) => boolean;
226
+ declare const getMediaPreviewFromUrl: (url: string) => ChatboxMediaPreview | null;
227
+ declare const resolvePlatformChatterProfileUrl: ({ platform, username, displayname, userId }: ChatterProfileUrlInput) => string | null;
228
+ declare const normalizeHttpUrl: (value: unknown) => string | null;
229
+ declare const resolveChatterProfileUrlWithResolvers: ({ platform, username, displayname, userId, extraSettings, resolvers, }: ResolveChatterProfileUrlWithResolversInput) => Promise<string | null>;
230
+
231
+ export { type BuildChatMessageContentOptions, type ChatMessageContentItem, type ChatMessageEmoteStore, type ChatMessageToken, type ChatMessageTokenizationOptions, type ChatboxMediaPreview, type ChatboxMediaPreviewKind, type ChatterProfileResolver, type ChatterProfileResolverPayload, type ChatterProfileUrlInput, LSButton, type LSButtonProps, MEDIA_PREVIEW_USER_LEVEL_VALUES, type MediaPreviewRoleSettings, type MediaPreviewRoleSettingsInput, type MediaPreviewUserLevel, type MessageLinkPart, type ResolveChatterProfileUrlWithResolversInput, buildChatMessageContent, codeMirrorlinterOptions, getMediaPreviewFromUrl, getNormalizedUserLevels, isMediaPreviewAllowedForUser, normalizeHttpUrl, normalizeMediaPreviewUserLevels, parseMessageLinks, resolveChatterProfileUrlWithResolvers, resolveMediaPreviewRoleSettings, resolveMediaPreviewSetting, resolvePlatformChatterProfileUrl, tokenizeChatMessage, variableCompletionOptions };
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ function styleInject(css, { insertAt } = {}) {
21
21
  }
22
22
 
23
23
  // src/tailwind.css
24
- styleInject('/*! tailwindcss v4.1.11 | MIT License | https://tailwindcss.com */\n@layer theme, base, components, utilities;\n@layer theme {\n :root,\n :host {\n --font-sans:\n ui-sans-serif,\n system-ui,\n sans-serif,\n "Apple Color Emoji",\n "Segoe UI Emoji",\n "Segoe UI Symbol",\n "Noto Color Emoji";\n --font-mono:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n --color-blue-500: oklch(62.3% 0.214 259.815);\n --color-gray-500: oklch(55.1% 0.027 264.364);\n --spacing: 0.25rem;\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 1rem;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *,\n ::after,\n ::before,\n ::backdrop,\n ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html,\n :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b,\n strong {\n font-weight: bolder;\n }\n code,\n kbd,\n samp,\n pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub,\n sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol,\n ul,\n menu {\n list-style: none;\n }\n img,\n svg,\n video,\n canvas,\n audio,\n iframe,\n embed,\n object {\n display: block;\n vertical-align: middle;\n }\n img,\n video {\n max-width: 100%;\n height: auto;\n }\n button,\n input,\n select,\n optgroup,\n textarea,\n ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit,\n ::-webkit-datetime-edit-year-field,\n ::-webkit-datetime-edit-month-field,\n ::-webkit-datetime-edit-day-field,\n ::-webkit-datetime-edit-hour-field,\n ::-webkit-datetime-edit-minute-field,\n ::-webkit-datetime-edit-second-field,\n ::-webkit-datetime-edit-millisecond-field,\n ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button,\n input:where([type=button], [type=reset], [type=submit]),\n ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button,\n ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=until-found])) {\n display: none !important;\n }\n}\n@layer utilities {\n .static {\n position: static;\n }\n .contents {\n display: contents;\n }\n .bg-blue-500 {\n background-color: var(--color-blue-500);\n }\n .bg-gray-500 {\n background-color: var(--color-gray-500);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n .py-3 {\n padding-block: calc(var(--spacing) * 3);\n }\n .text-base {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n}\n');
24
+ styleInject('/*! tailwindcss v4.1.11 | MIT License | https://tailwindcss.com */\n@layer theme, base, components, utilities;\n@layer theme {\n :root,\n :host {\n --font-sans:\n ui-sans-serif,\n system-ui,\n sans-serif,\n "Apple Color Emoji",\n "Segoe UI Emoji",\n "Segoe UI Symbol",\n "Noto Color Emoji";\n --font-mono:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n --color-blue-500: oklch(62.3% 0.214 259.815);\n --color-gray-500: oklch(55.1% 0.027 264.364);\n --spacing: 0.25rem;\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 1rem;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *,\n ::after,\n ::before,\n ::backdrop,\n ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html,\n :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b,\n strong {\n font-weight: bolder;\n }\n code,\n kbd,\n samp,\n pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub,\n sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol,\n ul,\n menu {\n list-style: none;\n }\n img,\n svg,\n video,\n canvas,\n audio,\n iframe,\n embed,\n object {\n display: block;\n vertical-align: middle;\n }\n img,\n video {\n max-width: 100%;\n height: auto;\n }\n button,\n input,\n select,\n optgroup,\n textarea,\n ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit,\n ::-webkit-datetime-edit-year-field,\n ::-webkit-datetime-edit-month-field,\n ::-webkit-datetime-edit-day-field,\n ::-webkit-datetime-edit-hour-field,\n ::-webkit-datetime-edit-minute-field,\n ::-webkit-datetime-edit-second-field,\n ::-webkit-datetime-edit-millisecond-field,\n ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button,\n input:where([type=button], [type=reset], [type=submit]),\n ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button,\n ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=until-found])) {\n display: none !important;\n }\n}\n@layer utilities {\n .static {\n position: static;\n }\n .block {\n display: block;\n }\n .contents {\n display: contents;\n }\n .bg-blue-500 {\n background-color: var(--color-blue-500);\n }\n .bg-gray-500 {\n background-color: var(--color-gray-500);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n .py-3 {\n padding-block: calc(var(--spacing) * 3);\n }\n .text-base {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n}\n');
25
25
 
26
26
  // src/components/LSButton/LSButton.tsx
27
27
  import { jsx } from "react/jsx-runtime";
@@ -265,8 +265,618 @@ var codeMirrorlinterOptions = (type, language = "js") => {
265
265
  }
266
266
  return jsOptions;
267
267
  };
268
+
269
+ // src/utils/chatMedia.ts
270
+ var URL_TOKEN_REGEX = /(?:https?:\/\/|www\.)[^\s<]+/gi;
271
+ var TRAILING_LINK_PUNCTUATION_REGEX = /[),.!?;:'"]+$/;
272
+ var MEDIA_IMAGE_REGEX = /\.(gif|png|jpe?g|webp|bmp|avif)(?:[?#].*)?$/i;
273
+ var MEDIA_VIDEO_REGEX = /\.(mp4|webm|mov|m4v)(?:[?#].*)?$/i;
274
+ var MEDIA_AUDIO_REGEX = /\.(mp3|wav|ogg|oga|aac|m4a|flac|opus)(?:[?#].*)?$/i;
275
+ var YOUTUBE_ID_REGEX = /^[a-zA-Z0-9_-]{6,}$/;
276
+ var SPOTIFY_EMBED_TYPES = /* @__PURE__ */ new Set(["track", "album", "playlist", "episode", "show", "artist"]);
277
+ var MEDIA_PREVIEW_USER_LEVEL_VALUES = ["streamer", "moderators", "vips", "tier3", "tier2", "subscribers", "regular", "follower", "anyone"];
278
+ var parseMessageLinks = (value) => {
279
+ if (!value) {
280
+ return [{ text: "" }];
281
+ }
282
+ const parts = [];
283
+ let cursor = 0;
284
+ for (const match of value.matchAll(URL_TOKEN_REGEX)) {
285
+ const rawToken = match[0];
286
+ if (!rawToken) {
287
+ continue;
288
+ }
289
+ const start = match.index ?? 0;
290
+ const end = start + rawToken.length;
291
+ if (start > cursor) {
292
+ parts.push({ text: value.slice(cursor, start) });
293
+ }
294
+ const trailing = rawToken.match(TRAILING_LINK_PUNCTUATION_REGEX)?.[0] ?? "";
295
+ const cleaned = trailing ? rawToken.slice(0, -trailing.length) : rawToken;
296
+ if (cleaned) {
297
+ const href = cleaned.startsWith("http://") || cleaned.startsWith("https://") ? cleaned : `https://${cleaned}`;
298
+ parts.push({ text: cleaned, url: href });
299
+ } else {
300
+ parts.push({ text: rawToken });
301
+ }
302
+ if (trailing) {
303
+ parts.push({ text: trailing });
304
+ }
305
+ cursor = end;
306
+ }
307
+ if (cursor < value.length) {
308
+ parts.push({ text: value.slice(cursor) });
309
+ }
310
+ return parts.length ? parts : [{ text: value }];
311
+ };
312
+ var tokenizeChatMessage = (value, options) => {
313
+ const hyperClickableLinks = options?.hyperClickableLinks !== false;
314
+ const previewMediaInChat = options?.previewMediaInChat !== false;
315
+ if (!value) {
316
+ return [{ type: "text", text: "" }];
317
+ }
318
+ if (!hyperClickableLinks && !previewMediaInChat) {
319
+ return [{ type: "text", text: value }];
320
+ }
321
+ const parts = parseMessageLinks(value);
322
+ const tokens = [];
323
+ for (const part of parts) {
324
+ if (!part.url) {
325
+ tokens.push({ type: "text", text: part.text });
326
+ continue;
327
+ }
328
+ const media = previewMediaInChat ? getMediaPreviewFromUrl(part.url) : null;
329
+ if (media) {
330
+ tokens.push({
331
+ type: "media",
332
+ text: part.text,
333
+ url: part.url,
334
+ media
335
+ });
336
+ continue;
337
+ }
338
+ if (hyperClickableLinks) {
339
+ tokens.push({
340
+ type: "link",
341
+ text: part.text,
342
+ url: part.url
343
+ });
344
+ continue;
345
+ }
346
+ tokens.push({ type: "text", text: part.text });
347
+ }
348
+ return tokens.length ? tokens : [{ type: "text", text: value }];
349
+ };
350
+ var buildChatMessageContent = ({
351
+ message,
352
+ replaceWord,
353
+ filteredWordsRegex,
354
+ emotesRaw,
355
+ emotesPack,
356
+ origin,
357
+ emoteParserType,
358
+ isCheer,
359
+ storeEmotes,
360
+ youtubeEmotes,
361
+ allowParserTypes
362
+ }) => {
363
+ let normalizedMessage = message ?? "";
364
+ if (filteredWordsRegex && typeof replaceWord === "string") {
365
+ normalizedMessage = normalizedMessage.replaceAll(filteredWordsRegex, replaceWord);
366
+ }
367
+ const arrFromMsg = Array.from(normalizedMessage);
368
+ const parserType = emoteParserType || origin;
369
+ const allowParserType = !allowParserTypes || allowParserTypes.includes(parserType ?? "");
370
+ const emotes = [];
371
+ const parsePluginEmotesRaw = (raw) => {
372
+ const text = raw?.trim?.();
373
+ if (!text || text[0] !== "[" && text[0] !== "{") {
374
+ return [];
375
+ }
376
+ let parsed;
377
+ try {
378
+ parsed = JSON.parse(text);
379
+ } catch {
380
+ return [];
381
+ }
382
+ const items = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.emotes) ? parsed.emotes : [];
383
+ if (!items.length) {
384
+ return [];
385
+ }
386
+ return items.map((item) => {
387
+ const rawStart = Number(item?.start);
388
+ const rawEnd = Number(item?.end);
389
+ const directUrls = Array.isArray(item?.urls) ? item.urls.filter((url2) => typeof url2 === "string" && url2) : [];
390
+ const url = typeof item?.url === "string" ? item.url : "";
391
+ const urls = directUrls.length ? directUrls : url ? [url] : [];
392
+ if (!urls.length || !Number.isFinite(rawStart) || !Number.isFinite(rawEnd)) {
393
+ return null;
394
+ }
395
+ let start = Math.max(0, Math.floor(rawStart));
396
+ let end = Math.min(Math.floor(rawEnd) + 1, arrFromMsg.length);
397
+ if (start > 0 && arrFromMsg[start - 1] === ":") {
398
+ start -= 1;
399
+ }
400
+ if (end < arrFromMsg.length && arrFromMsg[end] === ":") {
401
+ end += 1;
402
+ }
403
+ if (end <= start) {
404
+ return null;
405
+ }
406
+ return {
407
+ id: item?.id || `${start}-${end}`,
408
+ urls,
409
+ start,
410
+ end
411
+ };
412
+ }).filter(Boolean);
413
+ };
414
+ const pluginRawEmotes = emotesRaw ? parsePluginEmotesRaw(emotesRaw) : [];
415
+ if (pluginRawEmotes.length) {
416
+ emotes.push(...pluginRawEmotes);
417
+ }
418
+ if (allowParserType && emotesRaw && !pluginRawEmotes.length && parserType === "twitch") {
419
+ for (const emote of emotesRaw.split("/")) {
420
+ if (!emote) continue;
421
+ const [emoteId, indicies] = emote.split(":");
422
+ if (!emoteId || !indicies) continue;
423
+ for (const indexSet of indicies.split(",")) {
424
+ const [start, end] = indexSet.split("-");
425
+ if (start === void 0 || end === void 0) continue;
426
+ emotes.push({
427
+ id: emoteId,
428
+ urls: [
429
+ `https://static-cdn.jtvnw.net/emoticons/v2/${emoteId}/default/dark/1.0`,
430
+ `https://static-cdn.jtvnw.net/emoticons/v2/${emoteId}/default/dark/2.0`,
431
+ `https://static-cdn.jtvnw.net/emoticons/v2/${emoteId}/default/dark/3.0`
432
+ ],
433
+ start: Math.max(+start, 0),
434
+ end: Math.min(+end + 1, normalizedMessage.length)
435
+ });
436
+ }
437
+ }
438
+ } else if (allowParserType && emotesPack && parserType === "kick") {
439
+ const emotesPackRecord = emotesPack;
440
+ Object.keys(emotesPackRecord).forEach((emoteId) => {
441
+ emotesPackRecord[emoteId]?.locations?.forEach((location) => {
442
+ const [start, end] = location.split("-");
443
+ if (start === void 0 || end === void 0) return;
444
+ let url;
445
+ if (emotesPackRecord[emoteId]?.type === "emote") {
446
+ url = `https://files.kick.com/emotes/${emoteId}/fullsize`;
447
+ } else {
448
+ url = `https://dbxmjjzl5pc1g.cloudfront.net/1065f255-473b-4a4d-a383-1282aa1ab9d5/images/emojis/${emoteId}.png`;
449
+ }
450
+ if (url) {
451
+ emotes.push({
452
+ id: emoteId,
453
+ urls: [url],
454
+ start: Math.max(+start, 0),
455
+ end: Math.min(+end + 1, normalizedMessage.length)
456
+ });
457
+ }
458
+ });
459
+ });
460
+ } else if (allowParserType && emotesPack && parserType === "discord") {
461
+ const emotesPackRecord = emotesPack;
462
+ Object.keys(emotesPackRecord).forEach((emoteId) => {
463
+ emotesPackRecord[emoteId]?.locations?.forEach((location) => {
464
+ const [start, end] = location.split("-");
465
+ if (start === void 0 || end === void 0) return;
466
+ const url = `https://cdn.discordapp.com/emojis/${emoteId}`;
467
+ emotes.push({
468
+ id: emoteId,
469
+ urls: [url],
470
+ start: Math.max(+start, 0),
471
+ end: Math.min(+end + 1, normalizedMessage.length)
472
+ });
473
+ });
474
+ });
475
+ }
476
+ let idx = -1;
477
+ let nextIdx = 0;
478
+ const separator = origin === "youtube" ? ":" : " ";
479
+ do {
480
+ nextIdx = arrFromMsg.indexOf(separator, idx + 1);
481
+ if (nextIdx === -1) {
482
+ nextIdx = arrFromMsg.length;
483
+ }
484
+ const emote = arrFromMsg.slice(idx + 1, nextIdx).join("");
485
+ const start = idx + 1;
486
+ const end = nextIdx;
487
+ if (emote) {
488
+ if (storeEmotes?.ffz?.[emote]) {
489
+ emotes.push({
490
+ id: emote,
491
+ urls: [storeEmotes.ffz[emote]],
492
+ start,
493
+ end
494
+ });
495
+ } else if (storeEmotes?.bttv?.[emote]) {
496
+ emotes.push({
497
+ id: emote,
498
+ urls: [storeEmotes.bttv[emote]],
499
+ start,
500
+ end
501
+ });
502
+ } else if (storeEmotes?.seventv?.[emote]) {
503
+ emotes.push({
504
+ id: emote,
505
+ urls: [storeEmotes.seventv[emote]],
506
+ start,
507
+ end
508
+ });
509
+ } else if (youtubeEmotes?.[emote]) {
510
+ emotes.push({
511
+ id: emote,
512
+ urls: [youtubeEmotes[emote]],
513
+ start,
514
+ end
515
+ });
516
+ } else if (isCheer && /[a-z]+\d+/gi.exec(emote)) {
517
+ const cheerAmount = parseInt(emote.replace(/^\D+/g, ""));
518
+ let roundedAmount = 1;
519
+ let bitColor = "#979797";
520
+ if (cheerAmount >= 1e4) {
521
+ roundedAmount = 1e4;
522
+ bitColor = "#f43021";
523
+ } else if (cheerAmount >= 5e3) {
524
+ roundedAmount = 5e3;
525
+ bitColor = "#0099fe";
526
+ } else if (cheerAmount >= 1e3) {
527
+ roundedAmount = 1e3;
528
+ bitColor = "#1db2a5";
529
+ } else if (cheerAmount >= 100) {
530
+ roundedAmount = 100;
531
+ bitColor = "#9c3ee8";
532
+ }
533
+ emotes.push({
534
+ id: emote,
535
+ type: "cheer",
536
+ roundedAmount,
537
+ cheerAmount,
538
+ bitColor,
539
+ start,
540
+ end
541
+ });
542
+ }
543
+ }
544
+ } while ((idx = arrFromMsg.indexOf(separator, nextIdx)) !== -1);
545
+ emotes.sort((x, y) => x.start - y.start);
546
+ let index = 0;
547
+ const content = [];
548
+ for (const emote of emotes) {
549
+ const slicedMsg = arrFromMsg.slice(index, emote.start).join("");
550
+ content.push(origin === "youtube" ? slicedMsg?.replaceAll(":", "") : slicedMsg);
551
+ if ("type" in emote && emote.type === "cheer") {
552
+ content.push({
553
+ id: emote.id,
554
+ type: "cheer",
555
+ roundedAmount: emote.roundedAmount,
556
+ cheerAmount: emote.cheerAmount,
557
+ bitColor: emote.bitColor,
558
+ key: `${emote.start}-${emote.end}`
559
+ });
560
+ } else if ("urls" in emote) {
561
+ content.push({
562
+ id: emote.id,
563
+ urls: emote.urls,
564
+ key: `${emote.start}-${emote.end}`
565
+ });
566
+ }
567
+ index = emote.end;
568
+ }
569
+ const subStrMsg = arrFromMsg.slice(index, arrFromMsg.length).join("");
570
+ content.push(origin === "youtube" ? subStrMsg?.replaceAll(":", "") : subStrMsg);
571
+ return content;
572
+ };
573
+ var resolveMediaPreviewSetting = (value, fallback) => {
574
+ return typeof value === "boolean" ? value : fallback;
575
+ };
576
+ var normalizeMediaPreviewUserLevels = (value) => {
577
+ if (Array.isArray(value)) {
578
+ const normalized = value.map((level) => String(level).trim().toLowerCase()).filter((level) => MEDIA_PREVIEW_USER_LEVEL_VALUES.includes(level));
579
+ return [...new Set(normalized)];
580
+ }
581
+ if (typeof value === "string") {
582
+ const normalized = value.split(",").map((level) => level.trim().toLowerCase()).filter((level) => MEDIA_PREVIEW_USER_LEVEL_VALUES.includes(level));
583
+ return [...new Set(normalized)];
584
+ }
585
+ return [];
586
+ };
587
+ var resolveMediaPreviewRoleSettings = (settings) => {
588
+ if (Array.isArray(settings.previewMediaUserLevels) || typeof settings.previewMediaUserLevels === "string") {
589
+ const selected = new Set(normalizeMediaPreviewUserLevels(settings.previewMediaUserLevels));
590
+ return {
591
+ previewMediaForViewers: selected.has("regular") || selected.has("follower") || selected.has("anyone"),
592
+ previewMediaForSubscribers: selected.has("subscribers"),
593
+ previewMediaForVips: selected.has("vips"),
594
+ previewMediaForModerators: selected.has("moderators"),
595
+ previewMediaForStreamer: selected.has("streamer"),
596
+ previewMediaForTier3: selected.has("tier3"),
597
+ previewMediaForTier2: selected.has("tier2"),
598
+ previewMediaForRegular: selected.has("regular"),
599
+ previewMediaForFollower: selected.has("follower"),
600
+ previewMediaForAnyone: selected.has("anyone")
601
+ };
602
+ }
603
+ const previewMediaForViewers = resolveMediaPreviewSetting(settings.previewMediaForViewers, true);
604
+ const previewMediaForSubscribers = resolveMediaPreviewSetting(settings.previewMediaForSubscribers, true);
605
+ return {
606
+ previewMediaForViewers,
607
+ previewMediaForSubscribers,
608
+ previewMediaForVips: resolveMediaPreviewSetting(settings.previewMediaForVips, true),
609
+ previewMediaForModerators: resolveMediaPreviewSetting(settings.previewMediaForModerators, true),
610
+ previewMediaForStreamer: resolveMediaPreviewSetting(settings.previewMediaForStreamer, true),
611
+ previewMediaForTier3: resolveMediaPreviewSetting(settings.previewMediaForTier3, previewMediaForSubscribers),
612
+ previewMediaForTier2: resolveMediaPreviewSetting(settings.previewMediaForTier2, previewMediaForSubscribers),
613
+ previewMediaForRegular: resolveMediaPreviewSetting(settings.previewMediaForRegular, previewMediaForViewers),
614
+ previewMediaForFollower: resolveMediaPreviewSetting(settings.previewMediaForFollower, previewMediaForViewers),
615
+ previewMediaForAnyone: resolveMediaPreviewSetting(settings.previewMediaForAnyone, previewMediaForViewers)
616
+ };
617
+ };
618
+ var getNormalizedUserLevels = (value) => {
619
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
620
+ return {};
621
+ }
622
+ const normalized = {};
623
+ for (const [key, levelValue] of Object.entries(value)) {
624
+ normalized[key.toLowerCase()] = Boolean(levelValue);
625
+ }
626
+ return normalized;
627
+ };
628
+ var isMediaPreviewAllowedForUser = (userLevelsRaw, roleSettings) => {
629
+ const levels = getNormalizedUserLevels(userLevelsRaw);
630
+ const isStreamer = levels.isself || levels.self || levels.streamer || levels.broadcaster || levels.owner;
631
+ const isModerator = levels.mod || levels.moderator;
632
+ const isVip = levels.vip || levels.vips;
633
+ const isTier3 = levels.tier3 || levels.tier_3;
634
+ const isTier2 = levels.tier2 || levels.tier_2;
635
+ const isSubscriber = levels.subscriber || levels.sub || levels.member || levels.members || levels.tier1 || levels.tier_1;
636
+ const isRegular = levels.regular;
637
+ const isFollower = levels.follower || levels.followers;
638
+ return isStreamer && roleSettings.previewMediaForStreamer || isModerator && roleSettings.previewMediaForModerators || isVip && roleSettings.previewMediaForVips || isTier3 && roleSettings.previewMediaForTier3 || isTier2 && roleSettings.previewMediaForTier2 || isSubscriber && roleSettings.previewMediaForSubscribers || isRegular && roleSettings.previewMediaForRegular || isFollower && roleSettings.previewMediaForFollower || roleSettings.previewMediaForAnyone;
639
+ };
640
+ var parseExternalUrl = (url) => {
641
+ try {
642
+ return new URL(url);
643
+ } catch {
644
+ return null;
645
+ }
646
+ };
647
+ var decodeURIComponentSafe = (value) => {
648
+ try {
649
+ return decodeURIComponent(value);
650
+ } catch {
651
+ return value;
652
+ }
653
+ };
654
+ var sanitizeMediaTitle = (value) => {
655
+ return decodeURIComponentSafe(value.replace(/\+/g, " ")).replace(/\.[^./?#]+$/, "").replace(/[_-]+/g, " ").replace(/\s+/g, " ").trim();
656
+ };
657
+ var tryExtractFilename = (value) => {
658
+ const trimmed = value.trim();
659
+ if (!trimmed) {
660
+ return "";
661
+ }
662
+ const normalizedUrl = /^https?:\/\//i.test(trimmed) ? trimmed : trimmed.startsWith("www.") ? `https://${trimmed}` : "";
663
+ if (normalizedUrl) {
664
+ const parsed = parseExternalUrl(normalizedUrl);
665
+ if (parsed) {
666
+ const segment2 = parsed.pathname.split("/").filter(Boolean).pop() ?? "";
667
+ const decoded = decodeURIComponentSafe(segment2).trim();
668
+ if (decoded) {
669
+ return decoded;
670
+ }
671
+ }
672
+ }
673
+ const withoutQueryAndHash = trimmed.split(/[?#]/)[0] ?? "";
674
+ const segment = withoutQueryAndHash.split("/").filter(Boolean).pop() ?? "";
675
+ return decodeURIComponentSafe(segment).trim();
676
+ };
677
+ var getAudioTitleFromUrl = (url) => {
678
+ const parsed = parseExternalUrl(url);
679
+ if (!parsed) {
680
+ return "Audio";
681
+ }
682
+ for (const queryKey of ["title", "name", "filename", "file"]) {
683
+ const rawValue = parsed.searchParams.get(queryKey);
684
+ const filename = rawValue ? tryExtractFilename(rawValue) : "";
685
+ if (filename) {
686
+ return filename;
687
+ }
688
+ }
689
+ const pathFilename = tryExtractFilename(parsed.pathname);
690
+ if (pathFilename) {
691
+ return pathFilename;
692
+ }
693
+ for (const queryKey of ["title", "name", "filename", "file"]) {
694
+ const rawValue = parsed.searchParams.get(queryKey);
695
+ const normalized = rawValue ? sanitizeMediaTitle(rawValue) : "";
696
+ if (normalized) {
697
+ return normalized;
698
+ }
699
+ }
700
+ const pathSegment = parsed.pathname.split("/").filter(Boolean).pop() ?? "";
701
+ const normalizedPathTitle = sanitizeMediaTitle(pathSegment);
702
+ return normalizedPathTitle || "Audio";
703
+ };
704
+ var extractYoutubeEmbedInfo = (url) => {
705
+ const parsed = parseExternalUrl(url);
706
+ if (!parsed) {
707
+ return null;
708
+ }
709
+ const hostname = parsed.hostname.replace(/^www\./i, "").toLowerCase();
710
+ let videoId = "";
711
+ let isShort = false;
712
+ if (hostname === "youtu.be") {
713
+ videoId = parsed.pathname.split("/").filter(Boolean)[0] ?? "";
714
+ } else if (hostname.endsWith("youtube.com") || hostname === "youtube-nocookie.com") {
715
+ const segments = parsed.pathname.split("/").filter(Boolean);
716
+ if (segments[0] === "watch") {
717
+ videoId = parsed.searchParams.get("v") ?? "";
718
+ } else if (segments[0] === "shorts") {
719
+ videoId = segments[1] ?? "";
720
+ isShort = true;
721
+ } else if (["embed", "live", "v"].includes(segments[0] ?? "")) {
722
+ videoId = segments[1] ?? "";
723
+ }
724
+ }
725
+ const cleaned = videoId.trim();
726
+ return YOUTUBE_ID_REGEX.test(cleaned) ? { id: cleaned, isShort } : null;
727
+ };
728
+ var extractSpotifyEmbedUrl = (url) => {
729
+ const parsed = parseExternalUrl(url);
730
+ if (!parsed) {
731
+ return null;
732
+ }
733
+ const hostname = parsed.hostname.replace(/^www\./i, "").toLowerCase();
734
+ if (hostname !== "open.spotify.com" && hostname !== "play.spotify.com") {
735
+ return null;
736
+ }
737
+ const segments = parsed.pathname.split("/").filter(Boolean);
738
+ let type = segments[0] ?? "";
739
+ let id = segments[1] ?? "";
740
+ if (type === "intl" && segments.length >= 4) {
741
+ type = segments[2] ?? "";
742
+ id = segments[3] ?? "";
743
+ }
744
+ if (!SPOTIFY_EMBED_TYPES.has(type) || !id) {
745
+ return null;
746
+ }
747
+ return `https://open.spotify.com/embed/${type}/${id}`;
748
+ };
749
+ var getMediaPreviewFromUrl = (url) => {
750
+ if (MEDIA_IMAGE_REGEX.test(url)) {
751
+ return { kind: "image", src: url };
752
+ }
753
+ if (MEDIA_AUDIO_REGEX.test(url)) {
754
+ return { kind: "audio", src: url, title: getAudioTitleFromUrl(url) };
755
+ }
756
+ if (MEDIA_VIDEO_REGEX.test(url)) {
757
+ return { kind: "video", src: url };
758
+ }
759
+ const youtube = extractYoutubeEmbedInfo(url);
760
+ if (youtube) {
761
+ return { kind: youtube.isShort ? "youtubeShort" : "youtube", src: `https://www.youtube.com/embed/${youtube.id}` };
762
+ }
763
+ const spotifyEmbed = extractSpotifyEmbedUrl(url);
764
+ if (spotifyEmbed) {
765
+ return { kind: "spotify", src: spotifyEmbed };
766
+ }
767
+ return null;
768
+ };
769
+ var normalizeProfilePlatform = (value) => {
770
+ if (value === null || value === void 0) {
771
+ return "";
772
+ }
773
+ return String(value).trim().toLowerCase();
774
+ };
775
+ var normalizeProfileHandle = (value) => {
776
+ const text = typeof value === "string" || typeof value === "number" ? String(value).trim() : "";
777
+ return text.replace(/^@+/, "");
778
+ };
779
+ var resolvePlatformChatterProfileUrl = ({ platform, username, displayname, userId }) => {
780
+ const normalizedPlatform = normalizeProfilePlatform(platform);
781
+ if (!normalizedPlatform) {
782
+ return null;
783
+ }
784
+ const normalizedUsername = normalizeProfileHandle(username) || normalizeProfileHandle(displayname);
785
+ const normalizedUserId = typeof userId === "string" || typeof userId === "number" ? String(userId).trim() : "";
786
+ switch (normalizedPlatform) {
787
+ case "twitch":
788
+ return normalizedUsername ? `https://www.twitch.tv/${encodeURIComponent(normalizedUsername)}` : null;
789
+ case "youtube":
790
+ case "youtubegaming":
791
+ if (/^UC[\w-]+$/i.test(normalizedUserId)) {
792
+ return `https://www.youtube.com/channel/${encodeURIComponent(normalizedUserId)}`;
793
+ }
794
+ if (normalizedUsername) {
795
+ return `https://www.youtube.com/@${encodeURIComponent(normalizedUsername)}`;
796
+ }
797
+ return normalizedUserId ? `https://www.youtube.com/channel/${encodeURIComponent(normalizedUserId)}` : null;
798
+ case "facebook":
799
+ if (normalizedUserId) {
800
+ return `https://www.facebook.com/${encodeURIComponent(normalizedUserId)}`;
801
+ }
802
+ return normalizedUsername ? `https://www.facebook.com/${encodeURIComponent(normalizedUsername)}` : null;
803
+ case "tiktok":
804
+ return normalizedUsername ? `https://www.tiktok.com/@${encodeURIComponent(normalizedUsername)}` : null;
805
+ case "kick":
806
+ return normalizedUsername ? `https://kick.com/${encodeURIComponent(normalizedUsername)}` : null;
807
+ case "discord":
808
+ return normalizedUserId ? `https://discord.com/users/${encodeURIComponent(normalizedUserId)}` : null;
809
+ case "trovo":
810
+ return normalizedUsername ? `https://trovo.live/${encodeURIComponent(normalizedUsername)}` : null;
811
+ default:
812
+ return null;
813
+ }
814
+ };
815
+ var normalizeHttpUrl = (value) => {
816
+ const candidate = typeof value === "string" ? value.trim() : "";
817
+ if (!candidate) {
818
+ return null;
819
+ }
820
+ const normalized = candidate.startsWith("http://") || candidate.startsWith("https://") ? candidate : candidate.startsWith("www.") ? `https://${candidate}` : candidate;
821
+ const parsed = parseExternalUrl(normalized);
822
+ if (!parsed || !/^https?:$/i.test(parsed.protocol)) {
823
+ return null;
824
+ }
825
+ return normalized;
826
+ };
827
+ var resolveChatterProfileUrlWithResolvers = async ({
828
+ platform,
829
+ username,
830
+ displayname,
831
+ userId,
832
+ extraSettings,
833
+ resolvers
834
+ }) => {
835
+ const normalizedPlatform = normalizeProfilePlatform(platform);
836
+ const normalizedUsername = normalizeProfileHandle(username);
837
+ const normalizedDisplayName = normalizeProfileHandle(displayname);
838
+ const normalizedUserId = typeof userId === "string" || typeof userId === "number" ? String(userId).trim() : "";
839
+ const payload = {
840
+ username: normalizedUsername || void 0,
841
+ displayname: normalizedDisplayName || void 0,
842
+ userId: normalizedUserId || void 0,
843
+ platform: normalizedPlatform || void 0,
844
+ extraSettings
845
+ };
846
+ for (const resolver of resolvers ?? []) {
847
+ if (typeof resolver !== "function") {
848
+ continue;
849
+ }
850
+ try {
851
+ const resolved = await resolver(payload);
852
+ const normalizedResolvedUrl = normalizeHttpUrl(resolved);
853
+ if (normalizedResolvedUrl) {
854
+ return normalizedResolvedUrl;
855
+ }
856
+ } catch {
857
+ }
858
+ }
859
+ return resolvePlatformChatterProfileUrl({
860
+ platform: normalizedPlatform || platform,
861
+ username: normalizedUsername || normalizedDisplayName,
862
+ userId: normalizedUserId || void 0
863
+ });
864
+ };
268
865
  export {
269
866
  LSButton,
867
+ MEDIA_PREVIEW_USER_LEVEL_VALUES,
868
+ buildChatMessageContent,
270
869
  codeMirrorlinterOptions,
870
+ getMediaPreviewFromUrl,
871
+ getNormalizedUserLevels,
872
+ isMediaPreviewAllowedForUser,
873
+ normalizeHttpUrl,
874
+ normalizeMediaPreviewUserLevels,
875
+ parseMessageLinks,
876
+ resolveChatterProfileUrlWithResolvers,
877
+ resolveMediaPreviewRoleSettings,
878
+ resolveMediaPreviewSetting,
879
+ resolvePlatformChatterProfileUrl,
880
+ tokenizeChatMessage,
271
881
  variableCompletionOptions
272
882
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumiastream/ui",
3
- "version": "0.0.6",
3
+ "version": "0.1.0-beta.1",
4
4
  "author": "Lumia Stream",
5
5
  "license": "ISC",
6
6
  "description": "Lumia UI Kit",
@@ -8,12 +8,13 @@
8
8
  "type": "module",
9
9
  "main": "dist/index.js",
10
10
  "module": "dist/index.js",
11
- "types": "dist/types/index.d.ts",
11
+ "types": "dist/index.d.ts",
12
12
  "files": [
13
13
  "dist"
14
14
  ],
15
15
  "exports": {
16
16
  ".": {
17
+ "types": "./dist/index.d.ts",
17
18
  "import": "./dist/index.js"
18
19
  }
19
20
  },