@sentry/junior-dashboard 0.76.1 → 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/nitro.d.ts DELETED
@@ -1,22 +0,0 @@
1
- export interface JuniorDashboardNitroOptions {
2
- basePath?: string;
3
- authPath?: string;
4
- authRequired?: boolean;
5
- allowedGoogleDomains?: string[];
6
- allowedEmails?: string[];
7
- trustedOrigins?: string[];
8
- sessionMaxAgeSeconds?: number;
9
- mockConversations?: boolean;
10
- disabled?: boolean;
11
- }
12
- /**
13
- * Mount the authenticated Junior dashboard into a Nitro deployment.
14
- *
15
- * @deprecated Register `juniorDashboardPlugin()` in `createApp({ plugins })`;
16
- * this helper remains for existing Nitro apps.
17
- */
18
- export declare function juniorDashboardNitro(options: JuniorDashboardNitroOptions): {
19
- nitro: {
20
- setup(nitro: unknown): void;
21
- };
22
- };
package/dist/nitro.js DELETED
@@ -1,116 +0,0 @@
1
- // src/nitro.ts
2
- import { cpSync, existsSync, mkdirSync } from "fs";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
- var dashboardAssetNames = ["client.js", "tailwind.css"];
6
- function normalizePath(path2, fallback) {
7
- const value = path2?.trim() || fallback;
8
- const withSlash = value.startsWith("/") ? value : `/${value}`;
9
- return stripTrailingSlashes(withSlash);
10
- }
11
- function stripTrailingSlashes(value) {
12
- let end = value.length;
13
- while (end > 1 && value.charCodeAt(end - 1) === 47) {
14
- end -= 1;
15
- }
16
- return end === value.length ? value : value.slice(0, end);
17
- }
18
- function routeEntry(handler) {
19
- return { handler };
20
- }
21
- function dashboardAssetPath(fileName) {
22
- const candidates = [
23
- fileURLToPath(new URL(`./${fileName}`, import.meta.url)),
24
- fileURLToPath(new URL(`../dist/${fileName}`, import.meta.url))
25
- ];
26
- for (const candidate of candidates) {
27
- if (existsSync(candidate)) {
28
- return candidate;
29
- }
30
- }
31
- throw new Error(
32
- `Junior dashboard asset ${fileName} was not built; run pnpm --filter @sentry/junior-dashboard build before building Nitro`
33
- );
34
- }
35
- function copyDashboardAssets(serverDir) {
36
- const targetDir = path.join(
37
- serverDir,
38
- "node_modules",
39
- "@sentry",
40
- "junior-dashboard",
41
- "dist"
42
- );
43
- mkdirSync(targetDir, { recursive: true });
44
- for (const fileName of dashboardAssetNames) {
45
- cpSync(dashboardAssetPath(fileName), path.join(targetDir, fileName));
46
- }
47
- }
48
- function virtualHandler(config) {
49
- return `import { defineHandler } from "nitro";
50
- import { createDashboardApp } from "@sentry/junior-dashboard";
51
-
52
- let app;
53
-
54
- export default defineHandler(async (event) => {
55
- app ??= createDashboardApp(${JSON.stringify(config)});
56
- return app.fetch(event.req);
57
- });
58
- `;
59
- }
60
- function dashboardPageRoutes(basePath, handler) {
61
- const pluginsPath = basePath === "/" ? "/plugins" : `${basePath}/plugins`;
62
- const sessionsPath = basePath === "/" ? "/sessions" : `${basePath}/sessions`;
63
- const conversationsPath = basePath === "/" ? "/conversations" : `${basePath}/conversations`;
64
- if (basePath === "/") {
65
- return {
66
- "/": routeEntry(handler),
67
- [conversationsPath]: routeEntry(handler),
68
- [`${conversationsPath}/**`]: routeEntry(handler),
69
- [pluginsPath]: routeEntry(handler),
70
- [sessionsPath]: routeEntry(handler),
71
- [`${sessionsPath}/**`]: routeEntry(handler)
72
- };
73
- }
74
- return {
75
- [basePath]: routeEntry(handler),
76
- [`${basePath}/**`]: routeEntry(handler)
77
- };
78
- }
79
- function juniorDashboardNitro(options) {
80
- return {
81
- nitro: {
82
- setup(nitro) {
83
- if (options.disabled) {
84
- return;
85
- }
86
- const basePath = normalizePath(options.basePath, "/");
87
- const authPath = normalizePath(options.authPath, "/api/auth");
88
- const handler = "#junior-dashboard/handler";
89
- const dashboardConfig = {
90
- ...options,
91
- basePath,
92
- authPath,
93
- disabled: void 0
94
- };
95
- nitro.options.virtual[handler] = virtualHandler(dashboardConfig);
96
- nitro.options.virtual["#junior-dashboard/config"] = `export const dashboard = ${JSON.stringify(dashboardConfig)};`;
97
- nitro.hooks.hook("compiled", () => {
98
- copyDashboardAssets(nitro.options.output.serverDir);
99
- });
100
- const dashboardRoutes = {
101
- ...dashboardPageRoutes(basePath, handler),
102
- "/api/dashboard/**": routeEntry(handler),
103
- [authPath]: routeEntry(handler),
104
- [`${authPath}/**`]: routeEntry(handler)
105
- };
106
- nitro.options.routes = {
107
- ...dashboardRoutes,
108
- ...nitro.options.routes ?? {}
109
- };
110
- }
111
- }
112
- };
113
- }
114
- export {
115
- juniorDashboardNitro
116
- };
package/src/config.ts DELETED
@@ -1,76 +0,0 @@
1
- import type { JuniorDashboardOptions } from "./app";
2
-
3
- export type JuniorDashboardRuntimeConfig = Omit<
4
- JuniorDashboardOptions,
5
- "auth" | "reporting"
6
- >;
7
-
8
- /** Read dashboard runtime config injected by the Nitro module. */
9
- export async function resolveDashboardConfig(): Promise<JuniorDashboardRuntimeConfig> {
10
- try {
11
- const mod: { dashboard?: JuniorDashboardRuntimeConfig } =
12
- await import("#junior-dashboard/config");
13
- return mod.dashboard ?? readEnvConfig();
14
- } catch (error) {
15
- if (!isMissingVirtualConfig(error)) {
16
- throw error;
17
- }
18
- return readEnvConfig();
19
- }
20
- }
21
-
22
- function readEnvConfig(): JuniorDashboardRuntimeConfig {
23
- const mockConversations =
24
- process.env.JUNIOR_DASHBOARD_MOCK_CONVERSATIONS === "true";
25
-
26
- return {
27
- authRequired: process.env.JUNIOR_DASHBOARD_AUTH_REQUIRED !== "false",
28
- allowedGoogleDomains: readListEnv("JUNIOR_DASHBOARD_GOOGLE_DOMAINS"),
29
- allowedEmails: readListEnv("JUNIOR_DASHBOARD_ALLOWED_EMAILS"),
30
- trustedOrigins: readListEnv("JUNIOR_DASHBOARD_TRUSTED_ORIGINS"),
31
- ...(mockConversations ? { mockConversations } : {}),
32
- };
33
- }
34
-
35
- function readListEnv(name: string): string[] {
36
- const value = process.env[name];
37
- if (!value?.trim()) {
38
- return [];
39
- }
40
-
41
- if (value.trim().startsWith("[")) {
42
- let parsed: unknown;
43
- try {
44
- parsed = JSON.parse(value);
45
- } catch (error) {
46
- throw new Error(`${name} must be a JSON string array`, {
47
- cause: error,
48
- });
49
- }
50
- if (
51
- !Array.isArray(parsed) ||
52
- parsed.some((item) => typeof item !== "string")
53
- ) {
54
- throw new Error(`${name} must be a JSON string array`);
55
- }
56
- return parsed;
57
- }
58
-
59
- return value
60
- .split(",")
61
- .map((item) => item.trim())
62
- .filter(Boolean);
63
- }
64
-
65
- function isMissingVirtualConfig(error: unknown): boolean {
66
- if (!(error instanceof Error)) {
67
- return false;
68
- }
69
- const code = (error as { code?: string }).code;
70
- return (
71
- (code === "ERR_PACKAGE_IMPORT_NOT_DEFINED" ||
72
- code === "ERR_MODULE_NOT_FOUND" ||
73
- code === "MODULE_NOT_FOUND") &&
74
- error.message.includes("#junior-dashboard/config")
75
- );
76
- }
package/src/handler.ts DELETED
@@ -1,26 +0,0 @@
1
- import { defineHandler } from "nitro";
2
- import { createDashboardApp } from "./app";
3
- import { resolveDashboardConfig } from "./config";
4
-
5
- let app: ReturnType<typeof createDashboardApp> | undefined;
6
- let appPromise: Promise<ReturnType<typeof createDashboardApp>> | undefined;
7
-
8
- async function resolveApp(): Promise<ReturnType<typeof createDashboardApp>> {
9
- appPromise ??= resolveDashboardConfig()
10
- .then((config) => {
11
- app = createDashboardApp(config);
12
- return app;
13
- })
14
- .catch((error: unknown) => {
15
- appPromise = undefined;
16
- throw error;
17
- });
18
- return app ?? appPromise;
19
- }
20
-
21
- const handler: unknown = defineHandler(async (event) => {
22
- const dashboardApp = await resolveApp();
23
- return dashboardApp.fetch(event.req);
24
- });
25
-
26
- export default handler;
package/src/nitro.ts DELETED
@@ -1,157 +0,0 @@
1
- import { cpSync, existsSync, mkdirSync } from "node:fs";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import type { Nitro } from "nitro/types";
5
-
6
- export interface JuniorDashboardNitroOptions {
7
- basePath?: string;
8
- authPath?: string;
9
- authRequired?: boolean;
10
- allowedGoogleDomains?: string[];
11
- allowedEmails?: string[];
12
- trustedOrigins?: string[];
13
- sessionMaxAgeSeconds?: number;
14
- mockConversations?: boolean;
15
- disabled?: boolean;
16
- }
17
-
18
- type NitroRouteConfig = NonNullable<Nitro["options"]["routes"]>;
19
- const dashboardAssetNames = ["client.js", "tailwind.css"] as const;
20
-
21
- function normalizePath(path: string | undefined, fallback: string): string {
22
- const value = path?.trim() || fallback;
23
- const withSlash = value.startsWith("/") ? value : `/${value}`;
24
- return stripTrailingSlashes(withSlash);
25
- }
26
-
27
- function stripTrailingSlashes(value: string): string {
28
- let end = value.length;
29
- while (end > 1 && value.charCodeAt(end - 1) === 47) {
30
- end -= 1;
31
- }
32
- return end === value.length ? value : value.slice(0, end);
33
- }
34
-
35
- function routeEntry(handler: string): { handler: string } {
36
- return { handler };
37
- }
38
-
39
- function dashboardAssetPath(fileName: string): string {
40
- const candidates = [
41
- fileURLToPath(new URL(`./${fileName}`, import.meta.url)),
42
- fileURLToPath(new URL(`../dist/${fileName}`, import.meta.url)),
43
- ];
44
-
45
- for (const candidate of candidates) {
46
- if (existsSync(candidate)) {
47
- return candidate;
48
- }
49
- }
50
-
51
- throw new Error(
52
- `Junior dashboard asset ${fileName} was not built; run pnpm --filter @sentry/junior-dashboard build before building Nitro`,
53
- );
54
- }
55
-
56
- function copyDashboardAssets(serverDir: string): void {
57
- const targetDir = path.join(
58
- serverDir,
59
- "node_modules",
60
- "@sentry",
61
- "junior-dashboard",
62
- "dist",
63
- );
64
- mkdirSync(targetDir, { recursive: true });
65
-
66
- for (const fileName of dashboardAssetNames) {
67
- cpSync(dashboardAssetPath(fileName), path.join(targetDir, fileName));
68
- }
69
- }
70
-
71
- function virtualHandler(config: Record<string, unknown>): string {
72
- return `import { defineHandler } from "nitro";
73
- import { createDashboardApp } from "@sentry/junior-dashboard";
74
-
75
- let app;
76
-
77
- export default defineHandler(async (event) => {
78
- app ??= createDashboardApp(${JSON.stringify(config)});
79
- return app.fetch(event.req);
80
- });
81
- `;
82
- }
83
-
84
- function dashboardPageRoutes(
85
- basePath: string,
86
- handler: string,
87
- ): NitroRouteConfig {
88
- const pluginsPath = basePath === "/" ? "/plugins" : `${basePath}/plugins`;
89
- const sessionsPath = basePath === "/" ? "/sessions" : `${basePath}/sessions`;
90
- const conversationsPath =
91
- basePath === "/" ? "/conversations" : `${basePath}/conversations`;
92
-
93
- if (basePath === "/") {
94
- return {
95
- "/": routeEntry(handler),
96
- [conversationsPath]: routeEntry(handler),
97
- [`${conversationsPath}/**`]: routeEntry(handler),
98
- [pluginsPath]: routeEntry(handler),
99
- [sessionsPath]: routeEntry(handler),
100
- [`${sessionsPath}/**`]: routeEntry(handler),
101
- };
102
- }
103
-
104
- return {
105
- [basePath]: routeEntry(handler),
106
- [`${basePath}/**`]: routeEntry(handler),
107
- };
108
- }
109
-
110
- /**
111
- * Mount the authenticated Junior dashboard into a Nitro deployment.
112
- *
113
- * @deprecated Register `juniorDashboardPlugin()` in `createApp({ plugins })`;
114
- * this helper remains for existing Nitro apps.
115
- */
116
- export function juniorDashboardNitro(options: JuniorDashboardNitroOptions): {
117
- nitro: { setup(nitro: unknown): void };
118
- } {
119
- return {
120
- nitro: {
121
- setup(nitro: Nitro) {
122
- if (options.disabled) {
123
- return;
124
- }
125
-
126
- const basePath = normalizePath(options.basePath, "/");
127
- const authPath = normalizePath(options.authPath, "/api/auth");
128
- const handler = "#junior-dashboard/handler";
129
- const dashboardConfig = {
130
- ...options,
131
- basePath,
132
- authPath,
133
- disabled: undefined,
134
- };
135
-
136
- nitro.options.virtual[handler] = virtualHandler(dashboardConfig);
137
- nitro.options.virtual["#junior-dashboard/config"] =
138
- `export const dashboard = ${JSON.stringify(dashboardConfig)};`;
139
- nitro.hooks.hook("compiled", () => {
140
- copyDashboardAssets(nitro.options.output.serverDir);
141
- });
142
-
143
- const dashboardRoutes: NitroRouteConfig = {
144
- ...dashboardPageRoutes(basePath, handler),
145
- "/api/dashboard/**": routeEntry(handler),
146
- [authPath]: routeEntry(handler),
147
- [`${authPath}/**`]: routeEntry(handler),
148
- };
149
-
150
- nitro.options.routes = {
151
- ...dashboardRoutes,
152
- ...(nitro.options.routes ?? {}),
153
- };
154
- },
155
- },
156
- };
157
- }
@@ -1,5 +0,0 @@
1
- declare module "#junior-dashboard/config" {
2
- import type { JuniorDashboardRuntimeConfig } from "./config";
3
-
4
- export const dashboard: JuniorDashboardRuntimeConfig;
5
- }