@sentry/junior-dashboard 0.77.0 → 0.78.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/app.d.ts CHANGED
@@ -14,11 +14,20 @@ export interface JuniorDashboardOptions {
14
14
  reporting?: JuniorReporting;
15
15
  mockConversations?: boolean;
16
16
  }
17
+ interface DashboardRuntimeOptions extends JuniorDashboardOptions {
18
+ pluginRoutes?: DashboardPluginRoute[];
19
+ }
20
+ interface DashboardPluginRoute {
21
+ app: {
22
+ fetch(request: Request): Promise<Response> | Response;
23
+ };
24
+ pluginName: string;
25
+ }
17
26
  type Variables = {
18
27
  dashboardSession: DashboardSession;
19
28
  };
20
29
  /** Create the authenticated dashboard Hono app mounted by Nitro. */
21
- export declare function createDashboardApp(options: JuniorDashboardOptions): Hono<{
30
+ export declare function createDashboardApp(rawOptions: DashboardRuntimeOptions): Hono<{
22
31
  Variables: Variables;
23
32
  }>;
24
33
  export {};
package/dist/app.js CHANGED
@@ -1633,6 +1633,44 @@ function normalizeValues(values) {
1633
1633
  )
1634
1634
  ];
1635
1635
  }
1636
+ function readEnvList(name) {
1637
+ const value = process.env[name];
1638
+ if (!value?.trim()) {
1639
+ return void 0;
1640
+ }
1641
+ if (value.trim().startsWith("[")) {
1642
+ let parsed;
1643
+ try {
1644
+ parsed = JSON.parse(value);
1645
+ } catch (error) {
1646
+ throw new Error(`${name} must be a JSON string array`, {
1647
+ cause: error
1648
+ });
1649
+ }
1650
+ if (!Array.isArray(parsed) || parsed.some((item) => typeof item !== "string")) {
1651
+ throw new Error(`${name} must be a JSON string array`);
1652
+ }
1653
+ return parsed;
1654
+ }
1655
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
1656
+ }
1657
+ function readEnvFlag(name) {
1658
+ const value = process.env[name]?.trim();
1659
+ if (!value) {
1660
+ return void 0;
1661
+ }
1662
+ return value === "true" ? true : value === "false" ? false : void 0;
1663
+ }
1664
+ function resolveDashboardOptions(options) {
1665
+ return {
1666
+ ...options,
1667
+ authRequired: options.authRequired ?? readEnvFlag("JUNIOR_DASHBOARD_AUTH_REQUIRED"),
1668
+ allowedGoogleDomains: options.allowedGoogleDomains ?? readEnvList("JUNIOR_DASHBOARD_GOOGLE_DOMAINS"),
1669
+ allowedEmails: options.allowedEmails ?? readEnvList("JUNIOR_DASHBOARD_ALLOWED_EMAILS"),
1670
+ trustedOrigins: options.trustedOrigins ?? readEnvList("JUNIOR_DASHBOARD_TRUSTED_ORIGINS"),
1671
+ mockConversations: options.mockConversations ?? readEnvFlag("JUNIOR_DASHBOARD_MOCK_CONVERSATIONS")
1672
+ };
1673
+ }
1636
1674
  function isJsonRoute(pathname) {
1637
1675
  return pathname.startsWith("/api/");
1638
1676
  }
@@ -1909,7 +1947,18 @@ function renderFavicon() {
1909
1947
  { headers: { "content-type": "image/svg+xml" } }
1910
1948
  );
1911
1949
  }
1912
- function createDashboardApp(options) {
1950
+ function pluginRoutePrefix(pluginName) {
1951
+ return `/api/dashboard/plugins/${pluginName}`;
1952
+ }
1953
+ function pluginRouteRequest(request, prefix) {
1954
+ const url = new URL(request.url);
1955
+ const pathname = url.pathname;
1956
+ const nextPath = pathname === prefix ? "/" : pathname.slice(prefix.length) || "/";
1957
+ url.pathname = nextPath.startsWith("/") ? nextPath : `/${nextPath}`;
1958
+ return new Request(url, request);
1959
+ }
1960
+ function createDashboardApp(rawOptions) {
1961
+ const options = resolveDashboardOptions(rawOptions);
1913
1962
  if (process.env.SENTRY_DSN?.trim()) {
1914
1963
  initSentry();
1915
1964
  }
@@ -2001,6 +2050,12 @@ function createDashboardApp(options) {
2001
2050
  app.get("/api/dashboard/sessions", async () => {
2002
2051
  return Response.json(await reporting.getSessions());
2003
2052
  });
2053
+ for (const route of options.pluginRoutes ?? []) {
2054
+ const prefix = pluginRoutePrefix(route.pluginName);
2055
+ const handler = (c) => route.app.fetch(pluginRouteRequest(c.req.raw, prefix));
2056
+ app.all(prefix, handler);
2057
+ app.all(`${prefix}/*`, handler);
2058
+ }
2004
2059
  app.get("/api/dashboard/conversation-stats", async () => {
2005
2060
  try {
2006
2061
  return Response.json(await readConversationStats(reporting));
@@ -13,10 +13,10 @@ export declare function useDashboardData(): {
13
13
  pluginReports: import("@sentry/junior/reporting").PluginOperationalReportFeed;
14
14
  pluginReportsLoading: boolean;
15
15
  plugins: Plugin[];
16
- runtime: Runtime;
17
16
  config: DashboardConfig;
18
17
  health: Health;
19
18
  me: Identity;
19
+ runtime: Runtime;
20
20
  sessions: SessionFeed;
21
21
  skills: Skill[];
22
22
  } | undefined;
@@ -54,10 +54,10 @@ export declare function useDashboardData(): {
54
54
  pluginReports: import("@sentry/junior/reporting").PluginOperationalReportFeed;
55
55
  pluginReportsLoading: boolean;
56
56
  plugins: Plugin[];
57
- runtime: Runtime;
58
57
  config: DashboardConfig;
59
58
  health: Health;
60
59
  me: Identity;
60
+ runtime: Runtime;
61
61
  sessions: SessionFeed;
62
62
  skills: Skill[];
63
63
  } | undefined;
@@ -95,10 +95,10 @@ export declare function useDashboardData(): {
95
95
  pluginReports: import("@sentry/junior/reporting").PluginOperationalReportFeed;
96
96
  pluginReportsLoading: boolean;
97
97
  plugins: Plugin[];
98
- runtime: Runtime;
99
98
  config: DashboardConfig;
100
99
  health: Health;
101
100
  me: Identity;
101
+ runtime: Runtime;
102
102
  sessions: SessionFeed;
103
103
  skills: Skill[];
104
104
  } | undefined;
@@ -136,10 +136,10 @@ export declare function useDashboardData(): {
136
136
  pluginReports: import("@sentry/junior/reporting").PluginOperationalReportFeed;
137
137
  pluginReportsLoading: boolean;
138
138
  plugins: Plugin[];
139
- runtime: Runtime;
140
139
  config: DashboardConfig;
141
140
  health: Health;
142
141
  me: Identity;
142
+ runtime: Runtime;
143
143
  sessions: SessionFeed;
144
144
  skills: Skill[];
145
145
  } | undefined;
@@ -177,10 +177,10 @@ export declare function useDashboardData(): {
177
177
  pluginReports: import("@sentry/junior/reporting").PluginOperationalReportFeed;
178
178
  pluginReportsLoading: boolean;
179
179
  plugins: Plugin[];
180
- runtime: Runtime;
181
180
  config: DashboardConfig;
182
181
  health: Health;
183
182
  me: Identity;
183
+ runtime: Runtime;
184
184
  sessions: SessionFeed;
185
185
  skills: Skill[];
186
186
  } | undefined;
@@ -218,10 +218,10 @@ export declare function useDashboardData(): {
218
218
  pluginReports: import("@sentry/junior/reporting").PluginOperationalReportFeed;
219
219
  pluginReportsLoading: boolean;
220
220
  plugins: Plugin[];
221
- runtime: Runtime;
222
221
  config: DashboardConfig;
223
222
  health: Health;
224
223
  me: Identity;
224
+ runtime: Runtime;
225
225
  sessions: SessionFeed;
226
226
  skills: Skill[];
227
227
  } | undefined;
package/dist/index.d.ts CHANGED
@@ -1,8 +1 @@
1
- import { type PluginRegistration } from "@sentry/junior-plugin-api";
2
- import { type JuniorDashboardOptions } from "./app";
3
1
  export { createDashboardApp, type JuniorDashboardOptions } from "./app";
4
- export interface JuniorDashboardPluginOptions extends JuniorDashboardOptions {
5
- disabled?: boolean;
6
- }
7
- /** Register dashboard routes and Slack footer links through plugin hooks. */
8
- export declare function juniorDashboardPlugin(options?: JuniorDashboardPluginOptions): PluginRegistration;