@basedash/embed 0.1.0

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/react.js ADDED
@@ -0,0 +1,477 @@
1
+ import { createContext, forwardRef, useContext, useState, useEffect, useRef, useCallback, useMemo } from 'react';
2
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
+
4
+ // src/react/index.tsx
5
+
6
+ // src/embed.ts
7
+ var DEFAULT_BASEDASH_URL = "https://charts.basedash.com";
8
+ var EMBED_QUERY_PARAMS = {
9
+ theme: "theme",
10
+ hideOrgName: "hide_org_name",
11
+ hideChat: "hide_chat",
12
+ hideDashboards: "hide_dashboards",
13
+ hideInsights: "hide_insights",
14
+ hideAutomations: "hide_automations",
15
+ hideSuggestedPrompts: "hide_suggested_prompts"
16
+ };
17
+ var DEFAULT_EMBED_OPTIONS = {
18
+ theme: "auto",
19
+ hideOrgName: false,
20
+ hideChat: false,
21
+ hideDashboards: false,
22
+ hideInsights: false,
23
+ hideAutomations: false,
24
+ hideSuggestedPrompts: false
25
+ };
26
+ var CHAT_EMBED_OPTIONS = {
27
+ ...DEFAULT_EMBED_OPTIONS,
28
+ hideOrgName: true,
29
+ hideDashboards: true,
30
+ hideInsights: true,
31
+ hideAutomations: true
32
+ };
33
+ var DASHBOARDS_EMBED_OPTIONS = {
34
+ ...DEFAULT_EMBED_OPTIONS,
35
+ hideOrgName: true,
36
+ hideChat: true,
37
+ hideInsights: true,
38
+ hideAutomations: true
39
+ };
40
+ var INSIGHTS_EMBED_OPTIONS = {
41
+ ...DEFAULT_EMBED_OPTIONS,
42
+ hideOrgName: true,
43
+ hideChat: true,
44
+ hideDashboards: true,
45
+ hideAutomations: true
46
+ };
47
+ var AUTOMATIONS_EMBED_OPTIONS = {
48
+ ...DEFAULT_EMBED_OPTIONS,
49
+ hideOrgName: true,
50
+ hideChat: true,
51
+ hideDashboards: true,
52
+ hideInsights: true
53
+ };
54
+ function buildEmbedUrl({
55
+ token,
56
+ options,
57
+ instanceUrl = DEFAULT_BASEDASH_URL
58
+ }) {
59
+ assertNonEmpty(token, "token");
60
+ const url = createInstanceUrl(instanceUrl, "api/sso/jwt");
61
+ const resolvedOptions = {
62
+ theme: options?.theme ?? DEFAULT_EMBED_OPTIONS.theme,
63
+ hideOrgName: options?.hideOrgName ?? DEFAULT_EMBED_OPTIONS.hideOrgName,
64
+ hideChat: options?.hideChat ?? DEFAULT_EMBED_OPTIONS.hideChat,
65
+ hideDashboards: options?.hideDashboards ?? DEFAULT_EMBED_OPTIONS.hideDashboards,
66
+ hideInsights: options?.hideInsights ?? DEFAULT_EMBED_OPTIONS.hideInsights,
67
+ hideAutomations: options?.hideAutomations ?? DEFAULT_EMBED_OPTIONS.hideAutomations,
68
+ hideSuggestedPrompts: options?.hideSuggestedPrompts ?? DEFAULT_EMBED_OPTIONS.hideSuggestedPrompts
69
+ };
70
+ url.searchParams.set("jwt", token);
71
+ url.searchParams.set(EMBED_QUERY_PARAMS.theme, resolvedOptions.theme);
72
+ url.searchParams.set(
73
+ EMBED_QUERY_PARAMS.hideOrgName,
74
+ String(resolvedOptions.hideOrgName)
75
+ );
76
+ url.searchParams.set(
77
+ EMBED_QUERY_PARAMS.hideChat,
78
+ String(resolvedOptions.hideChat)
79
+ );
80
+ url.searchParams.set(
81
+ EMBED_QUERY_PARAMS.hideDashboards,
82
+ String(resolvedOptions.hideDashboards)
83
+ );
84
+ url.searchParams.set(
85
+ EMBED_QUERY_PARAMS.hideInsights,
86
+ String(resolvedOptions.hideInsights)
87
+ );
88
+ url.searchParams.set(
89
+ EMBED_QUERY_PARAMS.hideAutomations,
90
+ String(resolvedOptions.hideAutomations)
91
+ );
92
+ url.searchParams.set(
93
+ EMBED_QUERY_PARAMS.hideSuggestedPrompts,
94
+ String(resolvedOptions.hideSuggestedPrompts)
95
+ );
96
+ return url.toString();
97
+ }
98
+ function buildSharedDashboardUrl({
99
+ publicSharingLinkId,
100
+ filterToken,
101
+ instanceUrl = DEFAULT_BASEDASH_URL
102
+ }) {
103
+ assertNonEmpty(publicSharingLinkId, "publicSharingLinkId");
104
+ const path = filterToken ? `shared/${encodeURIComponent(publicSharingLinkId)}/${encodeURIComponent(
105
+ filterToken
106
+ )}` : `shared/${encodeURIComponent(publicSharingLinkId)}`;
107
+ return createInstanceUrl(instanceUrl, path).toString();
108
+ }
109
+ function createInstanceUrl(instanceUrl, path) {
110
+ let baseUrl;
111
+ try {
112
+ baseUrl = new URL(instanceUrl);
113
+ } catch {
114
+ throw new TypeError(`instanceUrl must be a valid URL: ${instanceUrl}`);
115
+ }
116
+ if (baseUrl.protocol !== "https:" && baseUrl.protocol !== "http:") {
117
+ throw new TypeError("instanceUrl must use http or https");
118
+ }
119
+ baseUrl.search = "";
120
+ baseUrl.hash = "";
121
+ if (!baseUrl.pathname.endsWith("/")) {
122
+ baseUrl.pathname += "/";
123
+ }
124
+ return new URL(path, baseUrl);
125
+ }
126
+ function assertNonEmpty(value, name) {
127
+ if (value.trim().length === 0) {
128
+ throw new TypeError(`${name} must not be empty`);
129
+ }
130
+ }
131
+ var BasedashContext = createContext(null);
132
+ function BasedashProvider({
133
+ children,
134
+ token: tokenProp,
135
+ fetchToken,
136
+ instanceUrl = DEFAULT_BASEDASH_URL,
137
+ theme = "auto"
138
+ }) {
139
+ const fetchTokenRef = useRef(fetchToken);
140
+ const hasFetchedRef = useRef(false);
141
+ const requestIdRef = useRef(0);
142
+ const [state, setState] = useState(
143
+ () => tokenProp === void 0 ? { token: void 0, status: "loading", error: void 0 } : {
144
+ token: validateToken(tokenProp),
145
+ status: "ready",
146
+ error: void 0
147
+ }
148
+ );
149
+ useEffect(() => {
150
+ fetchTokenRef.current = fetchToken;
151
+ }, [fetchToken]);
152
+ const refreshToken = useCallback(async () => {
153
+ if (tokenProp !== void 0) {
154
+ const token = validateToken(tokenProp);
155
+ setState({ token, status: "ready", error: void 0 });
156
+ return token;
157
+ }
158
+ const tokenLoader = fetchTokenRef.current;
159
+ if (tokenLoader === void 0) {
160
+ throw new Error(
161
+ "BasedashProvider requires either token or fetchToken to be set"
162
+ );
163
+ }
164
+ const requestId = ++requestIdRef.current;
165
+ setState((current) => ({
166
+ token: current.token,
167
+ status: "loading",
168
+ error: void 0
169
+ }));
170
+ try {
171
+ const token = validateToken(await tokenLoader());
172
+ if (requestId === requestIdRef.current) {
173
+ setState({ token, status: "ready", error: void 0 });
174
+ }
175
+ return token;
176
+ } catch (error) {
177
+ const resolvedError = toError(error);
178
+ if (requestId === requestIdRef.current) {
179
+ setState({
180
+ token: void 0,
181
+ status: "error",
182
+ error: resolvedError
183
+ });
184
+ }
185
+ throw resolvedError;
186
+ }
187
+ }, [tokenProp]);
188
+ useEffect(() => {
189
+ if (tokenProp !== void 0) {
190
+ setState({
191
+ token: validateToken(tokenProp),
192
+ status: "ready",
193
+ error: void 0
194
+ });
195
+ hasFetchedRef.current = false;
196
+ return;
197
+ }
198
+ if (!hasFetchedRef.current) {
199
+ hasFetchedRef.current = true;
200
+ void refreshToken().catch(() => {
201
+ });
202
+ }
203
+ }, [refreshToken, tokenProp]);
204
+ const value = useMemo(
205
+ () => ({
206
+ ...state,
207
+ instanceUrl,
208
+ theme,
209
+ refreshToken
210
+ }),
211
+ [instanceUrl, refreshToken, state, theme]
212
+ );
213
+ return /* @__PURE__ */ jsx(BasedashContext.Provider, { value, children });
214
+ }
215
+ function useBasedash() {
216
+ const context = useContext(BasedashContext);
217
+ if (context === null) {
218
+ throw new Error("useBasedash must be used inside a BasedashProvider");
219
+ }
220
+ return context;
221
+ }
222
+ var BasedashApp = forwardRef(
223
+ function BasedashApp2({
224
+ token,
225
+ instanceUrl,
226
+ theme,
227
+ hideOrgName,
228
+ hideChat,
229
+ hideDashboards,
230
+ hideInsights,
231
+ hideAutomations,
232
+ hideSuggestedPrompts,
233
+ title = "Basedash",
234
+ ...frameProps
235
+ }, ref) {
236
+ return /* @__PURE__ */ jsx(
237
+ AuthenticatedBasedashFrame,
238
+ {
239
+ ref,
240
+ token,
241
+ instanceUrl,
242
+ options: {
243
+ theme,
244
+ hideOrgName,
245
+ hideChat,
246
+ hideDashboards,
247
+ hideInsights,
248
+ hideAutomations,
249
+ hideSuggestedPrompts
250
+ },
251
+ title,
252
+ ...frameProps
253
+ }
254
+ );
255
+ }
256
+ );
257
+ var BasedashChat = forwardRef(
258
+ function BasedashChat2({
259
+ token,
260
+ instanceUrl,
261
+ theme,
262
+ hideOrgName,
263
+ hideSuggestedPrompts,
264
+ title = "Basedash chat",
265
+ ...frameProps
266
+ }, ref) {
267
+ return /* @__PURE__ */ jsx(
268
+ AuthenticatedBasedashFrame,
269
+ {
270
+ ref,
271
+ token,
272
+ instanceUrl,
273
+ options: {
274
+ ...CHAT_EMBED_OPTIONS,
275
+ theme: theme ?? CHAT_EMBED_OPTIONS.theme,
276
+ hideOrgName: hideOrgName ?? CHAT_EMBED_OPTIONS.hideOrgName,
277
+ hideSuggestedPrompts: hideSuggestedPrompts ?? CHAT_EMBED_OPTIONS.hideSuggestedPrompts
278
+ },
279
+ title,
280
+ ...frameProps
281
+ }
282
+ );
283
+ }
284
+ );
285
+ var BasedashDashboards = forwardRef(function BasedashDashboards2({
286
+ token,
287
+ instanceUrl,
288
+ theme,
289
+ hideOrgName,
290
+ title = "Basedash dashboards",
291
+ ...frameProps
292
+ }, ref) {
293
+ return /* @__PURE__ */ jsx(
294
+ AuthenticatedBasedashFrame,
295
+ {
296
+ ref,
297
+ token,
298
+ instanceUrl,
299
+ options: {
300
+ ...DASHBOARDS_EMBED_OPTIONS,
301
+ theme: theme ?? DASHBOARDS_EMBED_OPTIONS.theme,
302
+ hideOrgName: hideOrgName ?? DASHBOARDS_EMBED_OPTIONS.hideOrgName
303
+ },
304
+ title,
305
+ ...frameProps
306
+ }
307
+ );
308
+ });
309
+ var BasedashInsights = forwardRef(function BasedashInsights2({
310
+ token,
311
+ instanceUrl,
312
+ theme,
313
+ hideOrgName,
314
+ title = "Basedash insights",
315
+ ...frameProps
316
+ }, ref) {
317
+ return /* @__PURE__ */ jsx(
318
+ AuthenticatedBasedashFrame,
319
+ {
320
+ ref,
321
+ token,
322
+ instanceUrl,
323
+ options: {
324
+ ...INSIGHTS_EMBED_OPTIONS,
325
+ theme: theme ?? INSIGHTS_EMBED_OPTIONS.theme,
326
+ hideOrgName: hideOrgName ?? INSIGHTS_EMBED_OPTIONS.hideOrgName
327
+ },
328
+ title,
329
+ ...frameProps
330
+ }
331
+ );
332
+ });
333
+ var BasedashAutomations = forwardRef(function BasedashAutomations2({
334
+ token,
335
+ instanceUrl,
336
+ theme,
337
+ hideOrgName,
338
+ title = "Basedash automations",
339
+ ...frameProps
340
+ }, ref) {
341
+ return /* @__PURE__ */ jsx(
342
+ AuthenticatedBasedashFrame,
343
+ {
344
+ ref,
345
+ token,
346
+ instanceUrl,
347
+ options: {
348
+ ...AUTOMATIONS_EMBED_OPTIONS,
349
+ theme: theme ?? AUTOMATIONS_EMBED_OPTIONS.theme,
350
+ hideOrgName: hideOrgName ?? AUTOMATIONS_EMBED_OPTIONS.hideOrgName
351
+ },
352
+ title,
353
+ ...frameProps
354
+ }
355
+ );
356
+ });
357
+ var BasedashSharedDashboard = forwardRef(function BasedashSharedDashboard2({
358
+ publicSharingLinkId,
359
+ filterToken,
360
+ instanceUrl,
361
+ title = "Basedash dashboard",
362
+ ...frameProps
363
+ }, ref) {
364
+ const src = buildSharedDashboardUrl({
365
+ publicSharingLinkId,
366
+ filterToken,
367
+ instanceUrl
368
+ });
369
+ return /* @__PURE__ */ jsx(BasedashFrame, { ref, src, title, ...frameProps });
370
+ });
371
+ var AuthenticatedBasedashFrame = forwardRef(function AuthenticatedBasedashFrame2({
372
+ token: tokenProp,
373
+ instanceUrl: instanceUrlProp,
374
+ options,
375
+ errorFallback,
376
+ ...frameProps
377
+ }, ref) {
378
+ const context = useContext(BasedashContext);
379
+ const token = tokenProp ?? context?.token;
380
+ const instanceUrl = instanceUrlProp ?? context?.instanceUrl ?? DEFAULT_BASEDASH_URL;
381
+ const theme = options.theme ?? context?.theme ?? "auto";
382
+ if (token === void 0) {
383
+ if (context === null) {
384
+ throw new Error(
385
+ "Authenticated Basedash embeds require a token prop or BasedashProvider"
386
+ );
387
+ }
388
+ if (context.status === "error" && context.error !== void 0) {
389
+ if (errorFallback === void 0) {
390
+ throw context.error;
391
+ }
392
+ return /* @__PURE__ */ jsx(Fragment, { children: typeof errorFallback === "function" ? errorFallback(context.error) : errorFallback });
393
+ }
394
+ return /* @__PURE__ */ jsx(Fragment, { children: frameProps.loadingFallback ?? null });
395
+ }
396
+ const src = buildEmbedUrl({
397
+ token,
398
+ instanceUrl,
399
+ options: {
400
+ ...options,
401
+ theme
402
+ }
403
+ });
404
+ return /* @__PURE__ */ jsx(BasedashFrame, { ref, src, ...frameProps });
405
+ });
406
+ var BasedashFrame = forwardRef(function BasedashFrame2({
407
+ src,
408
+ className,
409
+ style,
410
+ iframeProps,
411
+ loadingFallback,
412
+ title = "Basedash"
413
+ }, ref) {
414
+ const [loaded, setLoaded] = useState(false);
415
+ useEffect(() => {
416
+ setLoaded(false);
417
+ }, [src]);
418
+ return /* @__PURE__ */ jsxs(
419
+ "div",
420
+ {
421
+ className,
422
+ style: {
423
+ position: "relative",
424
+ width: "100%",
425
+ height: "100%",
426
+ ...style
427
+ },
428
+ children: [
429
+ !loaded && loadingFallback !== void 0 ? /* @__PURE__ */ jsx(
430
+ "div",
431
+ {
432
+ "aria-hidden": "true",
433
+ style: {
434
+ position: "absolute",
435
+ inset: 0
436
+ },
437
+ children: loadingFallback
438
+ }
439
+ ) : null,
440
+ /* @__PURE__ */ jsx(
441
+ "iframe",
442
+ {
443
+ ...iframeProps,
444
+ ref,
445
+ src,
446
+ title,
447
+ allow: iframeProps?.allow ?? "clipboard-write",
448
+ loading: iframeProps?.loading ?? "eager",
449
+ onLoad: (event) => {
450
+ setLoaded(true);
451
+ iframeProps?.onLoad?.(event);
452
+ },
453
+ style: {
454
+ width: "100%",
455
+ height: "100%",
456
+ border: 0,
457
+ ...iframeProps?.style
458
+ }
459
+ }
460
+ )
461
+ ]
462
+ }
463
+ );
464
+ });
465
+ function validateToken(token) {
466
+ if (token.trim().length === 0) {
467
+ throw new TypeError("Basedash token must not be empty");
468
+ }
469
+ return token;
470
+ }
471
+ function toError(error) {
472
+ return error instanceof Error ? error : new Error(String(error));
473
+ }
474
+
475
+ export { BasedashApp, BasedashAutomations, BasedashChat, BasedashDashboards, BasedashInsights, BasedashProvider, BasedashSharedDashboard, useBasedash };
476
+ //# sourceMappingURL=react.js.map
477
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/embed.ts","../src/react/index.tsx"],"names":["BasedashApp","BasedashChat","BasedashDashboards","BasedashInsights","BasedashAutomations","BasedashSharedDashboard","AuthenticatedBasedashFrame","BasedashFrame"],"mappings":";;;;;;AAAO,IAAM,oBAAA,GAAuB,6BAAA;AAE7B,IAAM,kBAAA,GAAqB;AAAA,EAChC,KAAA,EAAO,OAAA;AAAA,EACP,WAAA,EAAa,eAAA;AAAA,EACb,QAAA,EAAU,WAAA;AAAA,EACV,cAAA,EAAgB,iBAAA;AAAA,EAChB,YAAA,EAAc,eAAA;AAAA,EACd,eAAA,EAAiB,kBAAA;AAAA,EACjB,oBAAA,EAAsB;AACxB,CAAA;AAqDO,IAAM,qBAAA,GAAwB;AAAA,EACnC,KAAA,EAAO,MAAA;AAAA,EACP,WAAA,EAAa,KAAA;AAAA,EACb,QAAA,EAAU,KAAA;AAAA,EACV,cAAA,EAAgB,KAAA;AAAA,EAChB,YAAA,EAAc,KAAA;AAAA,EACd,eAAA,EAAiB,KAAA;AAAA,EACjB,oBAAA,EAAsB;AACxB,CAAA;AAEO,IAAM,kBAAA,GAAqB;AAAA,EAChC,GAAG,qBAAA;AAAA,EACH,WAAA,EAAa,IAAA;AAAA,EACb,cAAA,EAAgB,IAAA;AAAA,EAChB,YAAA,EAAc,IAAA;AAAA,EACd,eAAA,EAAiB;AACnB,CAAA;AAEO,IAAM,wBAAA,GAA2B;AAAA,EACtC,GAAG,qBAAA;AAAA,EACH,WAAA,EAAa,IAAA;AAAA,EACb,QAAA,EAAU,IAAA;AAAA,EACV,YAAA,EAAc,IAAA;AAAA,EACd,eAAA,EAAiB;AACnB,CAAA;AAEO,IAAM,sBAAA,GAAyB;AAAA,EACpC,GAAG,qBAAA;AAAA,EACH,WAAA,EAAa,IAAA;AAAA,EACb,QAAA,EAAU,IAAA;AAAA,EACV,cAAA,EAAgB,IAAA;AAAA,EAChB,eAAA,EAAiB;AACnB,CAAA;AAEO,IAAM,yBAAA,GAA4B;AAAA,EACvC,GAAG,qBAAA;AAAA,EACH,WAAA,EAAa,IAAA;AAAA,EACb,QAAA,EAAU,IAAA;AAAA,EACV,cAAA,EAAgB,IAAA;AAAA,EAChB,YAAA,EAAc;AAChB,CAAA;AAEO,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA,GAAc;AAChB,CAAA,EAAiC;AAC/B,EAAA,cAAA,CAAe,OAAO,OAAO,CAAA;AAE7B,EAAA,MAAM,GAAA,GAAM,iBAAA,CAAkB,WAAA,EAAa,aAAa,CAAA;AACxD,EAAA,MAAM,eAAA,GAA0C;AAAA,IAC9C,KAAA,EAAO,OAAA,EAAS,KAAA,IAAS,qBAAA,CAAsB,KAAA;AAAA,IAC/C,WAAA,EACE,OAAA,EAAS,WAAA,IAAe,qBAAA,CAAsB,WAAA;AAAA,IAChD,QAAA,EAAU,OAAA,EAAS,QAAA,IAAY,qBAAA,CAAsB,QAAA;AAAA,IACrD,cAAA,EACE,OAAA,EAAS,cAAA,IAAkB,qBAAA,CAAsB,cAAA;AAAA,IACnD,YAAA,EACE,OAAA,EAAS,YAAA,IAAgB,qBAAA,CAAsB,YAAA;AAAA,IACjD,eAAA,EACE,OAAA,EAAS,eAAA,IAAmB,qBAAA,CAAsB,eAAA;AAAA,IACpD,oBAAA,EACE,OAAA,EAAS,oBAAA,IACT,qBAAA,CAAsB;AAAA,GAC1B;AAEA,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAA,EAAO,KAAK,CAAA;AACjC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,kBAAA,CAAmB,KAAA,EAAO,gBAAgB,KAAK,CAAA;AACpE,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,IACf,kBAAA,CAAmB,WAAA;AAAA,IACnB,MAAA,CAAO,gBAAgB,WAAW;AAAA,GACpC;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,IACf,kBAAA,CAAmB,QAAA;AAAA,IACnB,MAAA,CAAO,gBAAgB,QAAQ;AAAA,GACjC;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,IACf,kBAAA,CAAmB,cAAA;AAAA,IACnB,MAAA,CAAO,gBAAgB,cAAc;AAAA,GACvC;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,IACf,kBAAA,CAAmB,YAAA;AAAA,IACnB,MAAA,CAAO,gBAAgB,YAAY;AAAA,GACrC;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,IACf,kBAAA,CAAmB,eAAA;AAAA,IACnB,MAAA,CAAO,gBAAgB,eAAe;AAAA,GACxC;AACA,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,IACf,kBAAA,CAAmB,oBAAA;AAAA,IACnB,MAAA,CAAO,gBAAgB,oBAAoB;AAAA,GAC7C;AAEA,EAAA,OAAO,IAAI,QAAA,EAAS;AACtB;AAEO,SAAS,uBAAA,CAAwB;AAAA,EACtC,mBAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA,GAAc;AAChB,CAAA,EAA2C;AACzC,EAAA,cAAA,CAAe,qBAAqB,qBAAqB,CAAA;AAEzD,EAAA,MAAM,OAAO,WAAA,GACT,CAAA,OAAA,EAAU,kBAAA,CAAmB,mBAAmB,CAAC,CAAA,CAAA,EAAI,kBAAA;AAAA,IACnD;AAAA,GACD,CAAA,CAAA,GACD,CAAA,OAAA,EAAU,kBAAA,CAAmB,mBAAmB,CAAC,CAAA,CAAA;AAErD,EAAA,OAAO,iBAAA,CAAkB,WAAA,EAAa,IAAI,CAAA,CAAE,QAAA,EAAS;AACvD;AAEA,SAAS,iBAAA,CAAkB,aAAqB,IAAA,EAAmB;AACjE,EAAA,IAAI,OAAA;AAEJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,IAAI,IAAI,WAAW,CAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,iCAAA,EAAoC,WAAW,CAAA,CAAE,CAAA;AAAA,EACvE;AAEA,EAAA,IAAI,OAAA,CAAQ,QAAA,KAAa,QAAA,IAAY,OAAA,CAAQ,aAAa,OAAA,EAAS;AACjE,IAAA,MAAM,IAAI,UAAU,oCAAoC,CAAA;AAAA,EAC1D;AAEA,EAAA,OAAA,CAAQ,MAAA,GAAS,EAAA;AACjB,EAAA,OAAA,CAAQ,IAAA,GAAO,EAAA;AACf,EAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG;AACnC,IAAA,OAAA,CAAQ,QAAA,IAAY,GAAA;AAAA,EACtB;AAEA,EAAA,OAAO,IAAI,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AAC9B;AAEA,SAAS,cAAA,CAAe,OAAe,IAAA,EAAoB;AACzD,EAAA,IAAI,KAAA,CAAM,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,EAAG,IAAI,CAAA,kBAAA,CAAoB,CAAA;AAAA,EACjD;AACF;ACvHA,IAAM,eAAA,GAAkB,cAA2C,IAAI,CAAA;AAEhE,SAAS,gBAAA,CAAiB;AAAA,EAC/B,QAAA;AAAA,EACA,KAAA,EAAO,SAAA;AAAA,EACP,UAAA;AAAA,EACA,WAAA,GAAc,oBAAA;AAAA,EACd,KAAA,GAAQ;AACV,CAAA,EAA0B;AACxB,EAAA,MAAM,aAAA,GAAgB,OAAO,UAAU,CAAA;AACvC,EAAA,MAAM,aAAA,GAAgB,OAAO,KAAK,CAAA;AAClC,EAAA,MAAM,YAAA,GAAe,OAAO,CAAC,CAAA;AAC7B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA;AAAA,IAAqB,MAC7C,SAAA,KAAc,MAAA,GACV,EAAE,KAAA,EAAO,QAAW,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,MAAA,EAAU,GACxD;AAAA,MACE,KAAA,EAAO,cAAc,SAAS,CAAA;AAAA,MAC9B,MAAA,EAAQ,OAAA;AAAA,MACR,KAAA,EAAO;AAAA;AACT,GACN;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,aAAA,CAAc,OAAA,GAAU,UAAA;AAAA,EAC1B,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,YAAA,GAAe,YAAY,YAAY;AAC3C,IAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,MAAA,MAAM,KAAA,GAAQ,cAAc,SAAS,CAAA;AACrC,MAAA,QAAA,CAAS,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,QAAW,CAAA;AACrD,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,cAAc,aAAA,CAAc,OAAA;AAClC,IAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAAY,EAAE,YAAA,CAAa,OAAA;AACjC,IAAA,QAAA,CAAS,CAAC,OAAA,MAAa;AAAA,MACrB,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,MAAA,EAAQ,SAAA;AAAA,MACR,KAAA,EAAO;AAAA,KACT,CAAE,CAAA;AAEF,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,MAAM,WAAA,EAAa,CAAA;AAC/C,MAAA,IAAI,SAAA,KAAc,aAAa,OAAA,EAAS;AACtC,QAAA,QAAA,CAAS,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,QAAW,CAAA;AAAA,MACvD;AACA,MAAA,OAAO,KAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,aAAA,GAAgB,QAAQ,KAAK,CAAA;AACnC,MAAA,IAAI,SAAA,KAAc,aAAa,OAAA,EAAS;AACtC,QAAA,QAAA,CAAS;AAAA,UACP,KAAA,EAAO,MAAA;AAAA,UACP,MAAA,EAAQ,OAAA;AAAA,UACR,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AACA,MAAA,MAAM,aAAA;AAAA,IACR;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,MAAA,QAAA,CAAS;AAAA,QACP,KAAA,EAAO,cAAc,SAAS,CAAA;AAAA,QAC9B,MAAA,EAAQ,OAAA;AAAA,QACR,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,aAAA,CAAc,OAAA,GAAU,KAAA;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,cAAc,OAAA,EAAS;AAC1B,MAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AACxB,MAAA,KAAK,YAAA,EAAa,CAAE,KAAA,CAAM,MAAM;AAAA,MAEhC,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAA,EAAG,CAAC,YAAA,EAAc,SAAS,CAAC,CAAA;AAE5B,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACZ,OAAO;AAAA,MACL,GAAG,KAAA;AAAA,MACH,WAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,WAAA,EAAa,YAAA,EAAc,KAAA,EAAO,KAAK;AAAA,GAC1C;AAEA,EAAA,uBACE,GAAA,CAAC,eAAA,CAAgB,QAAA,EAAhB,EAAyB,OACvB,QAAA,EACH,CAAA;AAEJ;AAEO,SAAS,WAAA,GAAoC;AAClD,EAAA,MAAM,OAAA,GAAU,WAAW,eAAe,CAAA;AAC1C,EAAA,IAAI,YAAY,IAAA,EAAM;AACpB,IAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,OAAA;AACT;AA+FO,IAAM,WAAA,GAAc,UAAA;AAAA,EACzB,SAASA,YAAAA,CACP;AAAA,IACE,KAAA;AAAA,IACA,WAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,cAAA;AAAA,IACA,YAAA;AAAA,IACA,eAAA;AAAA,IACA,oBAAA;AAAA,IACA,KAAA,GAAQ,UAAA;AAAA,IACR,GAAG;AAAA,KAEL,GAAA,EACA;AACA,IAAA,uBACE,GAAA;AAAA,MAAC,0BAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,KAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA,EAAS;AAAA,UACP,KAAA;AAAA,UACA,WAAA;AAAA,UACA,QAAA;AAAA,UACA,cAAA;AAAA,UACA,YAAA;AAAA,UACA,eAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,KAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AAEO,IAAM,YAAA,GAAe,UAAA;AAAA,EAC1B,SAASC,aAAAA,CACP;AAAA,IACE,KAAA;AAAA,IACA,WAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,oBAAA;AAAA,IACA,KAAA,GAAQ,eAAA;AAAA,IACR,GAAG;AAAA,KAEL,GAAA,EACA;AACA,IAAA,uBACE,GAAA;AAAA,MAAC,0BAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,KAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA,EAAS;AAAA,UACP,GAAG,kBAAA;AAAA,UACH,KAAA,EAAO,SAAS,kBAAA,CAAmB,KAAA;AAAA,UACnC,WAAA,EAAa,eAAe,kBAAA,CAAmB,WAAA;AAAA,UAC/C,oBAAA,EACE,wBACA,kBAAA,CAAmB;AAAA,SACvB;AAAA,QACA,KAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AAEO,IAAM,kBAAA,GAAqB,UAAA,CAGhC,SAASC,mBAAAA,CACT;AAAA,EACE,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA,GAAQ,qBAAA;AAAA,EACR,GAAG;AACL,CAAA,EACA,GAAA,EACA;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,0BAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,GAAG,wBAAA;AAAA,QACH,KAAA,EAAO,SAAS,wBAAA,CAAyB,KAAA;AAAA,QACzC,WAAA,EAAa,eAAe,wBAAA,CAAyB;AAAA,OACvD;AAAA,MACA,KAAA;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AAEM,IAAM,gBAAA,GAAmB,UAAA,CAG9B,SAASC,iBAAAA,CACT;AAAA,EACE,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA,GAAQ,mBAAA;AAAA,EACR,GAAG;AACL,CAAA,EACA,GAAA,EACA;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,0BAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,GAAG,sBAAA;AAAA,QACH,KAAA,EAAO,SAAS,sBAAA,CAAuB,KAAA;AAAA,QACvC,WAAA,EAAa,eAAe,sBAAA,CAAuB;AAAA,OACrD;AAAA,MACA,KAAA;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AAEM,IAAM,mBAAA,GAAsB,UAAA,CAGjC,SAASC,oBAAAA,CACT;AAAA,EACE,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA,GAAQ,sBAAA;AAAA,EACR,GAAG;AACL,CAAA,EACA,GAAA,EACA;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,0BAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,GAAG,yBAAA;AAAA,QACH,KAAA,EAAO,SAAS,yBAAA,CAA0B,KAAA;AAAA,QAC1C,WAAA,EACE,eAAe,yBAAA,CAA0B;AAAA,OAC7C;AAAA,MACA,KAAA;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AAEM,IAAM,uBAAA,GAA0B,UAAA,CAGrC,SAASC,wBAAAA,CACT;AAAA,EACE,mBAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA,GAAQ,oBAAA;AAAA,EACR,GAAG;AACL,CAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,MAAM,uBAAA,CAAwB;AAAA,IAClC,mBAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,2BAAQ,aAAA,EAAA,EAAc,GAAA,EAAU,GAAA,EAAU,KAAA,EAAe,GAAG,UAAA,EAAY,CAAA;AAC1E,CAAC;AAQD,IAAM,0BAAA,GAA6B,UAAA,CAGjC,SAASC,2BAAAA,CACT;AAAA,EACE,KAAA,EAAO,SAAA;AAAA,EACP,WAAA,EAAa,eAAA;AAAA,EACb,OAAA;AAAA,EACA,aAAA;AAAA,EACA,GAAG;AACL,CAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,OAAA,GAAU,WAAW,eAAe,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,aAAa,OAAA,EAAS,KAAA;AACpC,EAAA,MAAM,WAAA,GACJ,eAAA,IAAmB,OAAA,EAAS,WAAA,IAAe,oBAAA;AAC7C,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,OAAA,EAAS,KAAA,IAAS,MAAA;AAEjD,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,IAAI,YAAY,IAAA,EAAM;AACpB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,OAAA,IAAW,OAAA,CAAQ,UAAU,MAAA,EAAW;AAC7D,MAAA,IAAI,kBAAkB,MAAA,EAAW;AAC/B,QAAA,MAAM,OAAA,CAAQ,KAAA;AAAA,MAChB;AAEA,MAAA,uBACE,GAAA,CAAA,QAAA,EAAA,EACG,iBAAO,aAAA,KAAkB,UAAA,GACtB,cAAc,OAAA,CAAQ,KAAK,IAC3B,aAAA,EACN,CAAA;AAAA,IAEJ;AAEA,IAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,UAAA,CAAW,eAAA,IAAmB,IAAA,EAAK,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,MAAM,aAAA,CAAc;AAAA,IACxB,KAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA,EAAS;AAAA,MACP,GAAG,OAAA;AAAA,MACH;AAAA;AACF,GACD,CAAA;AAED,EAAA,uBAAO,GAAA,CAAC,aAAA,EAAA,EAAc,GAAA,EAAU,GAAA,EAAW,GAAG,UAAA,EAAY,CAAA;AAC5D,CAAC,CAAA;AAMD,IAAM,aAAA,GAAgB,UAAA,CAGpB,SAASC,cAAAA,CACT;AAAA,EACE,GAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA;AAAA,EACA,KAAA,GAAQ;AACV,CAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAE1C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAA,CAAU,KAAK,CAAA;AAAA,EACjB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,KAAA,EAAO,MAAA;AAAA,QACP,MAAA,EAAQ,MAAA;AAAA,QACR,GAAG;AAAA,OACL;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,CAAC,MAAA,IAAU,oBAAoB,MAAA,mBAC9B,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAY,MAAA;AAAA,YACZ,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,KAAA,EAAO;AAAA,aACT;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH,GACE,IAAA;AAAA,wBACJ,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACE,GAAG,WAAA;AAAA,YACJ,GAAA;AAAA,YACA,GAAA;AAAA,YACA,KAAA;AAAA,YACA,KAAA,EAAO,aAAa,KAAA,IAAS,iBAAA;AAAA,YAC7B,OAAA,EAAS,aAAa,OAAA,IAAW,OAAA;AAAA,YACjC,MAAA,EAAQ,CAAC,KAAA,KAAU;AACjB,cAAA,SAAA,CAAU,IAAI,CAAA;AACd,cAAA,WAAA,EAAa,SAAS,KAAK,CAAA;AAAA,YAC7B,CAAA;AAAA,YACA,KAAA,EAAO;AAAA,cACL,KAAA,EAAO,MAAA;AAAA,cACP,MAAA,EAAQ,MAAA;AAAA,cACR,MAAA,EAAQ,CAAA;AAAA,cACR,GAAG,WAAA,EAAa;AAAA;AAClB;AAAA;AACF;AAAA;AAAA,GACF;AAEJ,CAAC,CAAA;AAED,SAAS,cAAc,KAAA,EAAuB;AAC5C,EAAA,IAAI,KAAA,CAAM,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,UAAU,kCAAkC,CAAA;AAAA,EACxD;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,QAAQ,KAAA,EAAuB;AACtC,EAAA,OAAO,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACjE","file":"react.js","sourcesContent":["export const DEFAULT_BASEDASH_URL = \"https://charts.basedash.com\";\n\nexport const EMBED_QUERY_PARAMS = {\n theme: \"theme\",\n hideOrgName: \"hide_org_name\",\n hideChat: \"hide_chat\",\n hideDashboards: \"hide_dashboards\",\n hideInsights: \"hide_insights\",\n hideAutomations: \"hide_automations\",\n hideSuggestedPrompts: \"hide_suggested_prompts\",\n} as const;\n\nexport type BasedashTheme = \"light\" | \"dark\" | \"auto\";\n\nexport type BasedashRole = \"ADMIN\" | \"MEMBER\";\n\nexport interface EmbedUser {\n email: string;\n firstName?: string;\n lastName?: string;\n role?: BasedashRole;\n /**\n * Reserved for future group synchronization support in Basedash.\n */\n groups?: string[];\n}\n\nexport interface EmbedOptions {\n theme?: BasedashTheme;\n hideOrgName?: boolean;\n hideChat?: boolean;\n hideDashboards?: boolean;\n hideInsights?: boolean;\n hideAutomations?: boolean;\n hideSuggestedPrompts?: boolean;\n}\n\nexport interface BuildEmbedUrlOptions {\n token: string;\n options?: EmbedOptions;\n /**\n * Override this when embedding a self-hosted Basedash instance.\n *\n * @default \"https://charts.basedash.com\"\n */\n instanceUrl?: string;\n}\n\nexport interface BuildSharedDashboardUrlOptions {\n publicSharingLinkId: string;\n /**\n * A token created with `createDashboardFilterToken` from\n * `@basedash/embed/server`.\n */\n filterToken?: string;\n /**\n * Override this when embedding a self-hosted Basedash instance.\n *\n * @default \"https://charts.basedash.com\"\n */\n instanceUrl?: string;\n}\n\nexport const DEFAULT_EMBED_OPTIONS = {\n theme: \"auto\",\n hideOrgName: false,\n hideChat: false,\n hideDashboards: false,\n hideInsights: false,\n hideAutomations: false,\n hideSuggestedPrompts: false,\n} as const satisfies Required<EmbedOptions>;\n\nexport const CHAT_EMBED_OPTIONS = {\n ...DEFAULT_EMBED_OPTIONS,\n hideOrgName: true,\n hideDashboards: true,\n hideInsights: true,\n hideAutomations: true,\n} as const satisfies Required<EmbedOptions>;\n\nexport const DASHBOARDS_EMBED_OPTIONS = {\n ...DEFAULT_EMBED_OPTIONS,\n hideOrgName: true,\n hideChat: true,\n hideInsights: true,\n hideAutomations: true,\n} as const satisfies Required<EmbedOptions>;\n\nexport const INSIGHTS_EMBED_OPTIONS = {\n ...DEFAULT_EMBED_OPTIONS,\n hideOrgName: true,\n hideChat: true,\n hideDashboards: true,\n hideAutomations: true,\n} as const satisfies Required<EmbedOptions>;\n\nexport const AUTOMATIONS_EMBED_OPTIONS = {\n ...DEFAULT_EMBED_OPTIONS,\n hideOrgName: true,\n hideChat: true,\n hideDashboards: true,\n hideInsights: true,\n} as const satisfies Required<EmbedOptions>;\n\nexport function buildEmbedUrl({\n token,\n options,\n instanceUrl = DEFAULT_BASEDASH_URL,\n}: BuildEmbedUrlOptions): string {\n assertNonEmpty(token, \"token\");\n\n const url = createInstanceUrl(instanceUrl, \"api/sso/jwt\");\n const resolvedOptions: Required<EmbedOptions> = {\n theme: options?.theme ?? DEFAULT_EMBED_OPTIONS.theme,\n hideOrgName:\n options?.hideOrgName ?? DEFAULT_EMBED_OPTIONS.hideOrgName,\n hideChat: options?.hideChat ?? DEFAULT_EMBED_OPTIONS.hideChat,\n hideDashboards:\n options?.hideDashboards ?? DEFAULT_EMBED_OPTIONS.hideDashboards,\n hideInsights:\n options?.hideInsights ?? DEFAULT_EMBED_OPTIONS.hideInsights,\n hideAutomations:\n options?.hideAutomations ?? DEFAULT_EMBED_OPTIONS.hideAutomations,\n hideSuggestedPrompts:\n options?.hideSuggestedPrompts ??\n DEFAULT_EMBED_OPTIONS.hideSuggestedPrompts,\n };\n\n url.searchParams.set(\"jwt\", token);\n url.searchParams.set(EMBED_QUERY_PARAMS.theme, resolvedOptions.theme);\n url.searchParams.set(\n EMBED_QUERY_PARAMS.hideOrgName,\n String(resolvedOptions.hideOrgName),\n );\n url.searchParams.set(\n EMBED_QUERY_PARAMS.hideChat,\n String(resolvedOptions.hideChat),\n );\n url.searchParams.set(\n EMBED_QUERY_PARAMS.hideDashboards,\n String(resolvedOptions.hideDashboards),\n );\n url.searchParams.set(\n EMBED_QUERY_PARAMS.hideInsights,\n String(resolvedOptions.hideInsights),\n );\n url.searchParams.set(\n EMBED_QUERY_PARAMS.hideAutomations,\n String(resolvedOptions.hideAutomations),\n );\n url.searchParams.set(\n EMBED_QUERY_PARAMS.hideSuggestedPrompts,\n String(resolvedOptions.hideSuggestedPrompts),\n );\n\n return url.toString();\n}\n\nexport function buildSharedDashboardUrl({\n publicSharingLinkId,\n filterToken,\n instanceUrl = DEFAULT_BASEDASH_URL,\n}: BuildSharedDashboardUrlOptions): string {\n assertNonEmpty(publicSharingLinkId, \"publicSharingLinkId\");\n\n const path = filterToken\n ? `shared/${encodeURIComponent(publicSharingLinkId)}/${encodeURIComponent(\n filterToken,\n )}`\n : `shared/${encodeURIComponent(publicSharingLinkId)}`;\n\n return createInstanceUrl(instanceUrl, path).toString();\n}\n\nfunction createInstanceUrl(instanceUrl: string, path: string): URL {\n let baseUrl: URL;\n\n try {\n baseUrl = new URL(instanceUrl);\n } catch {\n throw new TypeError(`instanceUrl must be a valid URL: ${instanceUrl}`);\n }\n\n if (baseUrl.protocol !== \"https:\" && baseUrl.protocol !== \"http:\") {\n throw new TypeError(\"instanceUrl must use http or https\");\n }\n\n baseUrl.search = \"\";\n baseUrl.hash = \"\";\n if (!baseUrl.pathname.endsWith(\"/\")) {\n baseUrl.pathname += \"/\";\n }\n\n return new URL(path, baseUrl);\n}\n\nfunction assertNonEmpty(value: string, name: string): void {\n if (value.trim().length === 0) {\n throw new TypeError(`${name} must not be empty`);\n }\n}\n","import {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport {\n AUTOMATIONS_EMBED_OPTIONS,\n CHAT_EMBED_OPTIONS,\n DASHBOARDS_EMBED_OPTIONS,\n DEFAULT_BASEDASH_URL,\n INSIGHTS_EMBED_OPTIONS,\n buildEmbedUrl,\n buildSharedDashboardUrl,\n} from \"../embed\";\n\nimport type {\n CSSProperties,\n IframeHTMLAttributes,\n ReactNode,\n} from \"react\";\nimport type { BasedashTheme, EmbedOptions } from \"../embed\";\n\nexport type FetchBasedashToken = () => Promise<string>;\n\nexport type BasedashTokenStatus = \"loading\" | \"ready\" | \"error\";\n\ninterface BasedashProviderCommonProps {\n children: ReactNode;\n /**\n * Override this when embedding a self-hosted Basedash instance.\n *\n * @default \"https://charts.basedash.com\"\n */\n instanceUrl?: string;\n /**\n * Default theme for authenticated embeds under this provider.\n *\n * @default \"auto\"\n */\n theme?: BasedashTheme;\n}\n\nexport type BasedashProviderProps = BasedashProviderCommonProps &\n (\n | {\n /**\n * A short-lived token generated on your server.\n */\n token: string;\n fetchToken?: never;\n }\n | {\n token?: never;\n /**\n * Fetch a short-lived token from your backend. The embed secret must\n * never be sent to the browser.\n */\n fetchToken: FetchBasedashToken;\n }\n );\n\nexport interface BasedashContextValue {\n token: string | undefined;\n status: BasedashTokenStatus;\n error: Error | undefined;\n instanceUrl: string;\n theme: BasedashTheme;\n refreshToken: () => Promise<string>;\n}\n\ninterface TokenState {\n token: string | undefined;\n status: BasedashTokenStatus;\n error: Error | undefined;\n}\n\nconst BasedashContext = createContext<BasedashContextValue | null>(null);\n\nexport function BasedashProvider({\n children,\n token: tokenProp,\n fetchToken,\n instanceUrl = DEFAULT_BASEDASH_URL,\n theme = \"auto\",\n}: BasedashProviderProps) {\n const fetchTokenRef = useRef(fetchToken);\n const hasFetchedRef = useRef(false);\n const requestIdRef = useRef(0);\n const [state, setState] = useState<TokenState>(() =>\n tokenProp === undefined\n ? { token: undefined, status: \"loading\", error: undefined }\n : {\n token: validateToken(tokenProp),\n status: \"ready\",\n error: undefined,\n },\n );\n\n useEffect(() => {\n fetchTokenRef.current = fetchToken;\n }, [fetchToken]);\n\n const refreshToken = useCallback(async () => {\n if (tokenProp !== undefined) {\n const token = validateToken(tokenProp);\n setState({ token, status: \"ready\", error: undefined });\n return token;\n }\n\n const tokenLoader = fetchTokenRef.current;\n if (tokenLoader === undefined) {\n throw new Error(\n \"BasedashProvider requires either token or fetchToken to be set\",\n );\n }\n\n const requestId = ++requestIdRef.current;\n setState((current) => ({\n token: current.token,\n status: \"loading\",\n error: undefined,\n }));\n\n try {\n const token = validateToken(await tokenLoader());\n if (requestId === requestIdRef.current) {\n setState({ token, status: \"ready\", error: undefined });\n }\n return token;\n } catch (error) {\n const resolvedError = toError(error);\n if (requestId === requestIdRef.current) {\n setState({\n token: undefined,\n status: \"error\",\n error: resolvedError,\n });\n }\n throw resolvedError;\n }\n }, [tokenProp]);\n\n useEffect(() => {\n if (tokenProp !== undefined) {\n setState({\n token: validateToken(tokenProp),\n status: \"ready\",\n error: undefined,\n });\n hasFetchedRef.current = false;\n return;\n }\n\n if (!hasFetchedRef.current) {\n hasFetchedRef.current = true;\n void refreshToken().catch(() => {\n // The error is exposed through context and rendered by embed components.\n });\n }\n }, [refreshToken, tokenProp]);\n\n const value = useMemo<BasedashContextValue>(\n () => ({\n ...state,\n instanceUrl,\n theme,\n refreshToken,\n }),\n [instanceUrl, refreshToken, state, theme],\n );\n\n return (\n <BasedashContext.Provider value={value}>\n {children}\n </BasedashContext.Provider>\n );\n}\n\nexport function useBasedash(): BasedashContextValue {\n const context = useContext(BasedashContext);\n if (context === null) {\n throw new Error(\"useBasedash must be used inside a BasedashProvider\");\n }\n return context;\n}\n\ntype IframeProps = Omit<\n IframeHTMLAttributes<HTMLIFrameElement>,\n \"children\" | \"src\" | \"title\"\n>;\n\nexport interface BasedashFrameProps {\n /**\n * A class applied to the frame's outer container.\n */\n className?: string;\n /**\n * Styles applied to the frame's outer container.\n */\n style?: CSSProperties;\n /**\n * Props forwarded to the underlying iframe.\n */\n iframeProps?: IframeProps;\n /**\n * Content displayed over the iframe until its load event fires.\n */\n loadingFallback?: ReactNode;\n /**\n * Content displayed if fetching the token fails. A function receives the\n * original error.\n */\n errorFallback?: ReactNode | ((error: Error) => ReactNode);\n title?: string;\n}\n\ninterface AuthenticatedEmbedProps extends BasedashFrameProps {\n /**\n * A token generated on your server. When omitted, the nearest\n * BasedashProvider supplies the token.\n */\n token?: string;\n /**\n * Overrides the provider's instance URL.\n */\n instanceUrl?: string;\n /**\n * Overrides the provider's theme.\n */\n theme?: BasedashTheme;\n}\n\nexport interface BasedashAppProps extends AuthenticatedEmbedProps {\n hideOrgName?: boolean;\n hideChat?: boolean;\n hideDashboards?: boolean;\n hideInsights?: boolean;\n hideAutomations?: boolean;\n hideSuggestedPrompts?: boolean;\n}\n\nexport interface BasedashChatProps extends AuthenticatedEmbedProps {\n /**\n * @default true\n */\n hideOrgName?: boolean;\n hideSuggestedPrompts?: boolean;\n}\n\nexport interface BasedashDashboardsProps extends AuthenticatedEmbedProps {\n /**\n * @default true\n */\n hideOrgName?: boolean;\n}\n\nexport interface BasedashInsightsProps extends AuthenticatedEmbedProps {\n /**\n * @default true\n */\n hideOrgName?: boolean;\n}\n\nexport interface BasedashAutomationsProps extends AuthenticatedEmbedProps {\n /**\n * @default true\n */\n hideOrgName?: boolean;\n}\n\nexport interface BasedashSharedDashboardProps extends BasedashFrameProps {\n publicSharingLinkId: string;\n /**\n * A token created with `createDashboardFilterToken`.\n */\n filterToken?: string;\n instanceUrl?: string;\n}\n\nexport const BasedashApp = forwardRef<HTMLIFrameElement, BasedashAppProps>(\n function BasedashApp(\n {\n token,\n instanceUrl,\n theme,\n hideOrgName,\n hideChat,\n hideDashboards,\n hideInsights,\n hideAutomations,\n hideSuggestedPrompts,\n title = \"Basedash\",\n ...frameProps\n },\n ref,\n ) {\n return (\n <AuthenticatedBasedashFrame\n ref={ref}\n token={token}\n instanceUrl={instanceUrl}\n options={{\n theme,\n hideOrgName,\n hideChat,\n hideDashboards,\n hideInsights,\n hideAutomations,\n hideSuggestedPrompts,\n }}\n title={title}\n {...frameProps}\n />\n );\n },\n);\n\nexport const BasedashChat = forwardRef<HTMLIFrameElement, BasedashChatProps>(\n function BasedashChat(\n {\n token,\n instanceUrl,\n theme,\n hideOrgName,\n hideSuggestedPrompts,\n title = \"Basedash chat\",\n ...frameProps\n },\n ref,\n ) {\n return (\n <AuthenticatedBasedashFrame\n ref={ref}\n token={token}\n instanceUrl={instanceUrl}\n options={{\n ...CHAT_EMBED_OPTIONS,\n theme: theme ?? CHAT_EMBED_OPTIONS.theme,\n hideOrgName: hideOrgName ?? CHAT_EMBED_OPTIONS.hideOrgName,\n hideSuggestedPrompts:\n hideSuggestedPrompts ??\n CHAT_EMBED_OPTIONS.hideSuggestedPrompts,\n }}\n title={title}\n {...frameProps}\n />\n );\n },\n);\n\nexport const BasedashDashboards = forwardRef<\n HTMLIFrameElement,\n BasedashDashboardsProps\n>(function BasedashDashboards(\n {\n token,\n instanceUrl,\n theme,\n hideOrgName,\n title = \"Basedash dashboards\",\n ...frameProps\n },\n ref,\n) {\n return (\n <AuthenticatedBasedashFrame\n ref={ref}\n token={token}\n instanceUrl={instanceUrl}\n options={{\n ...DASHBOARDS_EMBED_OPTIONS,\n theme: theme ?? DASHBOARDS_EMBED_OPTIONS.theme,\n hideOrgName: hideOrgName ?? DASHBOARDS_EMBED_OPTIONS.hideOrgName,\n }}\n title={title}\n {...frameProps}\n />\n );\n});\n\nexport const BasedashInsights = forwardRef<\n HTMLIFrameElement,\n BasedashInsightsProps\n>(function BasedashInsights(\n {\n token,\n instanceUrl,\n theme,\n hideOrgName,\n title = \"Basedash insights\",\n ...frameProps\n },\n ref,\n) {\n return (\n <AuthenticatedBasedashFrame\n ref={ref}\n token={token}\n instanceUrl={instanceUrl}\n options={{\n ...INSIGHTS_EMBED_OPTIONS,\n theme: theme ?? INSIGHTS_EMBED_OPTIONS.theme,\n hideOrgName: hideOrgName ?? INSIGHTS_EMBED_OPTIONS.hideOrgName,\n }}\n title={title}\n {...frameProps}\n />\n );\n});\n\nexport const BasedashAutomations = forwardRef<\n HTMLIFrameElement,\n BasedashAutomationsProps\n>(function BasedashAutomations(\n {\n token,\n instanceUrl,\n theme,\n hideOrgName,\n title = \"Basedash automations\",\n ...frameProps\n },\n ref,\n) {\n return (\n <AuthenticatedBasedashFrame\n ref={ref}\n token={token}\n instanceUrl={instanceUrl}\n options={{\n ...AUTOMATIONS_EMBED_OPTIONS,\n theme: theme ?? AUTOMATIONS_EMBED_OPTIONS.theme,\n hideOrgName:\n hideOrgName ?? AUTOMATIONS_EMBED_OPTIONS.hideOrgName,\n }}\n title={title}\n {...frameProps}\n />\n );\n});\n\nexport const BasedashSharedDashboard = forwardRef<\n HTMLIFrameElement,\n BasedashSharedDashboardProps\n>(function BasedashSharedDashboard(\n {\n publicSharingLinkId,\n filterToken,\n instanceUrl,\n title = \"Basedash dashboard\",\n ...frameProps\n },\n ref,\n) {\n const src = buildSharedDashboardUrl({\n publicSharingLinkId,\n filterToken,\n instanceUrl,\n });\n\n return <BasedashFrame ref={ref} src={src} title={title} {...frameProps} />;\n});\n\ninterface AuthenticatedBasedashFrameProps extends BasedashFrameProps {\n token: string | undefined;\n instanceUrl: string | undefined;\n options: EmbedOptions;\n}\n\nconst AuthenticatedBasedashFrame = forwardRef<\n HTMLIFrameElement,\n AuthenticatedBasedashFrameProps\n>(function AuthenticatedBasedashFrame(\n {\n token: tokenProp,\n instanceUrl: instanceUrlProp,\n options,\n errorFallback,\n ...frameProps\n },\n ref,\n) {\n const context = useContext(BasedashContext);\n const token = tokenProp ?? context?.token;\n const instanceUrl =\n instanceUrlProp ?? context?.instanceUrl ?? DEFAULT_BASEDASH_URL;\n const theme = options.theme ?? context?.theme ?? \"auto\";\n\n if (token === undefined) {\n if (context === null) {\n throw new Error(\n \"Authenticated Basedash embeds require a token prop or BasedashProvider\",\n );\n }\n\n if (context.status === \"error\" && context.error !== undefined) {\n if (errorFallback === undefined) {\n throw context.error;\n }\n\n return (\n <>\n {typeof errorFallback === \"function\"\n ? errorFallback(context.error)\n : errorFallback}\n </>\n );\n }\n\n return <>{frameProps.loadingFallback ?? null}</>;\n }\n\n const src = buildEmbedUrl({\n token,\n instanceUrl,\n options: {\n ...options,\n theme,\n },\n });\n\n return <BasedashFrame ref={ref} src={src} {...frameProps} />;\n});\n\ninterface InternalBasedashFrameProps extends BasedashFrameProps {\n src: string;\n}\n\nconst BasedashFrame = forwardRef<\n HTMLIFrameElement,\n InternalBasedashFrameProps\n>(function BasedashFrame(\n {\n src,\n className,\n style,\n iframeProps,\n loadingFallback,\n title = \"Basedash\",\n },\n ref,\n) {\n const [loaded, setLoaded] = useState(false);\n\n useEffect(() => {\n setLoaded(false);\n }, [src]);\n\n return (\n <div\n className={className}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n ...style,\n }}\n >\n {!loaded && loadingFallback !== undefined ? (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n inset: 0,\n }}\n >\n {loadingFallback}\n </div>\n ) : null}\n <iframe\n {...iframeProps}\n ref={ref}\n src={src}\n title={title}\n allow={iframeProps?.allow ?? \"clipboard-write\"}\n loading={iframeProps?.loading ?? \"eager\"}\n onLoad={(event) => {\n setLoaded(true);\n iframeProps?.onLoad?.(event);\n }}\n style={{\n width: \"100%\",\n height: \"100%\",\n border: 0,\n ...iframeProps?.style,\n }}\n />\n </div>\n );\n});\n\nfunction validateToken(token: string): string {\n if (token.trim().length === 0) {\n throw new TypeError(\"Basedash token must not be empty\");\n }\n return token;\n}\n\nfunction toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n"]}
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ var jose = require('jose');
4
+
5
+ // src/server/index.ts
6
+ var ALGORITHM = "HS256";
7
+ var DEFAULT_EMBED_TOKEN_EXPIRATION = "10m";
8
+ var DEFAULT_DASHBOARD_TOKEN_EXPIRATION = "1h";
9
+ async function createEmbedToken({
10
+ secret,
11
+ orgId,
12
+ user,
13
+ expiresIn = DEFAULT_EMBED_TOKEN_EXPIRATION
14
+ }) {
15
+ assertSecret(secret);
16
+ assertNonEmpty(orgId, "orgId");
17
+ assertNonEmpty(user.email, "user.email");
18
+ assertExpiration(expiresIn);
19
+ const payload = {
20
+ email: user.email,
21
+ orgId,
22
+ ...user.firstName === void 0 ? {} : { firstName: user.firstName },
23
+ ...user.lastName === void 0 ? {} : { lastName: user.lastName },
24
+ ...user.role === void 0 ? {} : { role: user.role },
25
+ ...user.groups === void 0 ? {} : { groups: user.groups }
26
+ };
27
+ return signToken(payload, secret, expiresIn);
28
+ }
29
+ async function createDashboardFilterToken({
30
+ secret,
31
+ dashboardLinkId,
32
+ params,
33
+ expiresIn = DEFAULT_DASHBOARD_TOKEN_EXPIRATION
34
+ }) {
35
+ assertSecret(secret);
36
+ assertNonEmpty(dashboardLinkId, "dashboardLinkId");
37
+ assertExpiration(expiresIn);
38
+ assertDashboardParams(params);
39
+ return signToken(
40
+ {
41
+ dashboardLinkId,
42
+ params
43
+ },
44
+ secret,
45
+ expiresIn
46
+ );
47
+ }
48
+ async function signToken(payload, secret, expiresIn) {
49
+ const issuedAt = Math.floor(Date.now() / 1e3);
50
+ const expiration = typeof expiresIn === "number" ? issuedAt + expiresIn : expiresIn;
51
+ return new jose.SignJWT(payload).setProtectedHeader({ alg: ALGORITHM, typ: "JWT" }).setIssuedAt(issuedAt).setExpirationTime(expiration).sign(toSecretKey(secret));
52
+ }
53
+ function toSecretKey(secret) {
54
+ return typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
55
+ }
56
+ function assertSecret(secret) {
57
+ if (typeof secret === "string" && secret.length === 0 || secret instanceof Uint8Array && secret.byteLength === 0) {
58
+ throw new TypeError("secret must not be empty");
59
+ }
60
+ }
61
+ function assertExpiration(expiresIn) {
62
+ if (typeof expiresIn === "string" && expiresIn.trim().length === 0 || typeof expiresIn === "number" && (!Number.isFinite(expiresIn) || expiresIn <= 0)) {
63
+ throw new TypeError("expiresIn must be a positive duration");
64
+ }
65
+ }
66
+ function assertDashboardParams(params) {
67
+ for (const [key, value] of Object.entries(params)) {
68
+ assertNonEmpty(key, "params key");
69
+ const validValue = typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) || Array.isArray(value) && value.every((item) => typeof item === "string");
70
+ if (!validValue) {
71
+ throw new TypeError(
72
+ `params.${key} must be a string, string array, finite number, or boolean`
73
+ );
74
+ }
75
+ }
76
+ }
77
+ function assertNonEmpty(value, name) {
78
+ if (value.trim().length === 0) {
79
+ throw new TypeError(`${name} must not be empty`);
80
+ }
81
+ }
82
+
83
+ exports.createDashboardFilterToken = createDashboardFilterToken;
84
+ exports.createEmbedToken = createEmbedToken;
85
+ //# sourceMappingURL=server.cjs.map
86
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/index.ts"],"names":["SignJWT"],"mappings":"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","file":"server.cjs","sourcesContent":["import { SignJWT } from \"jose\";\n\nimport type { BasedashRole, EmbedUser } from \"../embed\";\n\nconst ALGORITHM = \"HS256\";\nconst DEFAULT_EMBED_TOKEN_EXPIRATION = \"10m\";\nconst DEFAULT_DASHBOARD_TOKEN_EXPIRATION = \"1h\";\n\nexport type EmbedSecret = string | Uint8Array;\n\n/**\n * A duration understood by `jose` (for example, `\"10m\"` or `\"1h\"`) or a\n * duration in seconds.\n */\nexport type TokenExpiration = string | number;\n\nexport type DashboardFilterValue = string | string[] | number | boolean;\n\nexport interface CreateEmbedTokenOptions {\n secret: EmbedSecret;\n orgId: string;\n user: EmbedUser;\n /**\n * @default \"10m\"\n */\n expiresIn?: TokenExpiration;\n}\n\nexport interface CreateDashboardFilterTokenOptions {\n secret: EmbedSecret;\n dashboardLinkId: string;\n params: Record<string, DashboardFilterValue>;\n /**\n * @default \"1h\"\n */\n expiresIn?: TokenExpiration;\n}\n\nexport interface EmbedTokenClaims {\n email: string;\n orgId: string;\n firstName?: string;\n lastName?: string;\n role?: BasedashRole;\n groups?: string[];\n iat: number;\n exp: number;\n}\n\nexport interface DashboardFilterTokenClaims {\n dashboardLinkId: string;\n params: Record<string, DashboardFilterValue>;\n iat: number;\n exp: number;\n}\n\n/**\n * Creates the short-lived JWT used by full-app Basedash embeds.\n *\n * This function must only run on a trusted server. Never send the embed secret\n * to a browser.\n */\nexport async function createEmbedToken({\n secret,\n orgId,\n user,\n expiresIn = DEFAULT_EMBED_TOKEN_EXPIRATION,\n}: CreateEmbedTokenOptions): Promise<string> {\n assertSecret(secret);\n assertNonEmpty(orgId, \"orgId\");\n assertNonEmpty(user.email, \"user.email\");\n assertExpiration(expiresIn);\n\n const payload = {\n email: user.email,\n orgId,\n ...(user.firstName === undefined ? {} : { firstName: user.firstName }),\n ...(user.lastName === undefined ? {} : { lastName: user.lastName }),\n ...(user.role === undefined ? {} : { role: user.role }),\n ...(user.groups === undefined ? {} : { groups: user.groups }),\n };\n\n return signToken(payload, secret, expiresIn);\n}\n\n/**\n * Creates a JWT that locks filter values on a shared dashboard.\n *\n * This function must only run on a trusted server. Never send the embed secret\n * to a browser.\n */\nexport async function createDashboardFilterToken({\n secret,\n dashboardLinkId,\n params,\n expiresIn = DEFAULT_DASHBOARD_TOKEN_EXPIRATION,\n}: CreateDashboardFilterTokenOptions): Promise<string> {\n assertSecret(secret);\n assertNonEmpty(dashboardLinkId, \"dashboardLinkId\");\n assertExpiration(expiresIn);\n assertDashboardParams(params);\n\n return signToken(\n {\n dashboardLinkId,\n params,\n },\n secret,\n expiresIn,\n );\n}\n\nasync function signToken(\n payload: Record<string, unknown>,\n secret: EmbedSecret,\n expiresIn: TokenExpiration,\n): Promise<string> {\n const issuedAt = Math.floor(Date.now() / 1000);\n const expiration =\n typeof expiresIn === \"number\" ? issuedAt + expiresIn : expiresIn;\n\n return new SignJWT(payload)\n .setProtectedHeader({ alg: ALGORITHM, typ: \"JWT\" })\n .setIssuedAt(issuedAt)\n .setExpirationTime(expiration)\n .sign(toSecretKey(secret));\n}\n\nfunction toSecretKey(secret: EmbedSecret): Uint8Array {\n return typeof secret === \"string\" ? new TextEncoder().encode(secret) : secret;\n}\n\nfunction assertSecret(secret: EmbedSecret): void {\n if (\n (typeof secret === \"string\" && secret.length === 0) ||\n (secret instanceof Uint8Array && secret.byteLength === 0)\n ) {\n throw new TypeError(\"secret must not be empty\");\n }\n}\n\nfunction assertExpiration(expiresIn: TokenExpiration): void {\n if (\n (typeof expiresIn === \"string\" && expiresIn.trim().length === 0) ||\n (typeof expiresIn === \"number\" &&\n (!Number.isFinite(expiresIn) || expiresIn <= 0))\n ) {\n throw new TypeError(\"expiresIn must be a positive duration\");\n }\n}\n\nfunction assertDashboardParams(\n params: Record<string, DashboardFilterValue>,\n): void {\n for (const [key, value] of Object.entries(params)) {\n assertNonEmpty(key, \"params key\");\n\n const validValue =\n typeof value === \"string\" ||\n typeof value === \"boolean\" ||\n (typeof value === \"number\" && Number.isFinite(value)) ||\n (Array.isArray(value) &&\n value.every((item): item is string => typeof item === \"string\"));\n\n if (!validValue) {\n throw new TypeError(\n `params.${key} must be a string, string array, finite number, or boolean`,\n );\n }\n }\n}\n\nfunction assertNonEmpty(value: string, name: string): void {\n if (value.trim().length === 0) {\n throw new TypeError(`${name} must not be empty`);\n }\n}\n"]}