@urateam/dashboard 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.
Files changed (69) hide show
  1. package/dist/__tests__/layout.test.d.ts +2 -0
  2. package/dist/__tests__/layout.test.d.ts.map +1 -0
  3. package/dist/__tests__/layout.test.js +138 -0
  4. package/dist/__tests__/layout.test.js.map +1 -0
  5. package/dist/__tests__/security.repro.test.d.ts +16 -0
  6. package/dist/__tests__/security.repro.test.d.ts.map +1 -0
  7. package/dist/__tests__/security.repro.test.js +249 -0
  8. package/dist/__tests__/security.repro.test.js.map +1 -0
  9. package/dist/__tests__/server.test.d.ts +2 -0
  10. package/dist/__tests__/server.test.d.ts.map +1 -0
  11. package/dist/__tests__/server.test.js +268 -0
  12. package/dist/__tests__/server.test.js.map +1 -0
  13. package/dist/__tests__/ui-refresh.test.d.ts +2 -0
  14. package/dist/__tests__/ui-refresh.test.d.ts.map +1 -0
  15. package/dist/__tests__/ui-refresh.test.js +860 -0
  16. package/dist/__tests__/ui-refresh.test.js.map +1 -0
  17. package/dist/routes/config.d.ts +4 -0
  18. package/dist/routes/config.d.ts.map +1 -0
  19. package/dist/routes/config.js +12 -0
  20. package/dist/routes/config.js.map +1 -0
  21. package/dist/routes/coordination.d.ts +4 -0
  22. package/dist/routes/coordination.d.ts.map +1 -0
  23. package/dist/routes/coordination.js +22 -0
  24. package/dist/routes/coordination.js.map +1 -0
  25. package/dist/routes/errors.d.ts +4 -0
  26. package/dist/routes/errors.d.ts.map +1 -0
  27. package/dist/routes/errors.js +36 -0
  28. package/dist/routes/errors.js.map +1 -0
  29. package/dist/routes/runs.d.ts +4 -0
  30. package/dist/routes/runs.d.ts.map +1 -0
  31. package/dist/routes/runs.js +72 -0
  32. package/dist/routes/runs.js.map +1 -0
  33. package/dist/routes/tokens.d.ts +4 -0
  34. package/dist/routes/tokens.d.ts.map +1 -0
  35. package/dist/routes/tokens.js +47 -0
  36. package/dist/routes/tokens.js.map +1 -0
  37. package/dist/server.d.ts +19 -0
  38. package/dist/server.d.ts.map +1 -0
  39. package/dist/server.js +107 -0
  40. package/dist/server.js.map +1 -0
  41. package/dist/views/config.d.ts +3 -0
  42. package/dist/views/config.d.ts.map +1 -0
  43. package/dist/views/config.js +47 -0
  44. package/dist/views/config.js.map +1 -0
  45. package/dist/views/coordination.d.ts +3 -0
  46. package/dist/views/coordination.d.ts.map +1 -0
  47. package/dist/views/coordination.js +63 -0
  48. package/dist/views/coordination.js.map +1 -0
  49. package/dist/views/errors.d.ts +14 -0
  50. package/dist/views/errors.d.ts.map +1 -0
  51. package/dist/views/errors.js +52 -0
  52. package/dist/views/errors.js.map +1 -0
  53. package/dist/views/layout.d.ts +21 -0
  54. package/dist/views/layout.d.ts.map +1 -0
  55. package/dist/views/layout.js +82 -0
  56. package/dist/views/layout.js.map +1 -0
  57. package/dist/views/run-detail.d.ts +35 -0
  58. package/dist/views/run-detail.d.ts.map +1 -0
  59. package/dist/views/run-detail.js +129 -0
  60. package/dist/views/run-detail.js.map +1 -0
  61. package/dist/views/run-feed.d.ts +14 -0
  62. package/dist/views/run-feed.d.ts.map +1 -0
  63. package/dist/views/run-feed.js +80 -0
  64. package/dist/views/run-feed.js.map +1 -0
  65. package/dist/views/tokens.d.ts +13 -0
  66. package/dist/views/tokens.d.ts.map +1 -0
  67. package/dist/views/tokens.js +66 -0
  68. package/dist/views/tokens.js.map +1 -0
  69. package/package.json +28 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=layout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/layout.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,138 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { layout, escapeHtml, getBasePath } from "../views/layout.js";
3
+ describe("layout", () => {
4
+ const originalEnv = process.env.DASHBOARD_BASE_PATH;
5
+ afterEach(() => {
6
+ delete process.env.DASHBOARD_BASE_PATH;
7
+ if (originalEnv) {
8
+ process.env.DASHBOARD_BASE_PATH = originalEnv;
9
+ }
10
+ });
11
+ describe("basePath computation", () => {
12
+ it("should use DASHBOARD_BASE_PATH environment variable", () => {
13
+ process.env.DASHBOARD_BASE_PATH = "/ateam";
14
+ expect(getBasePath()).toBe("/ateam");
15
+ });
16
+ it("should strip trailing slashes from DASHBOARD_BASE_PATH", () => {
17
+ process.env.DASHBOARD_BASE_PATH = "/ateam/";
18
+ expect(getBasePath()).toBe("/ateam");
19
+ });
20
+ it("should strip multiple trailing slashes", () => {
21
+ process.env.DASHBOARD_BASE_PATH = "/ateam///";
22
+ expect(getBasePath()).toBe("/ateam");
23
+ });
24
+ it("should be empty string when DASHBOARD_BASE_PATH is not set", () => {
25
+ delete process.env.DASHBOARD_BASE_PATH;
26
+ expect(getBasePath()).toBe("");
27
+ });
28
+ it("should be empty string when DASHBOARD_BASE_PATH is only slashes", () => {
29
+ process.env.DASHBOARD_BASE_PATH = "///";
30
+ expect(getBasePath()).toBe("");
31
+ });
32
+ });
33
+ describe("HTML generation", () => {
34
+ beforeEach(() => {
35
+ // Mock a simple basePath for consistent tests
36
+ process.env.DASHBOARD_BASE_PATH = "/ateam";
37
+ });
38
+ it("should generate valid HTML structure", () => {
39
+ const html = layout("Test Page", "<p>Content</p>");
40
+ expect(html).toContain("<!DOCTYPE html>");
41
+ expect(html).toContain("<html lang=\"en\">");
42
+ expect(html).toContain("</html>");
43
+ });
44
+ it("should include page title with escaped content", () => {
45
+ const html = layout("Test & Title", "content");
46
+ expect(html).toContain("<title>Test &amp; Title - urateam</title>");
47
+ });
48
+ it("should include static CSS link with basePath", () => {
49
+ process.env.DASHBOARD_BASE_PATH = "/ateam";
50
+ const html = layout("Test", "");
51
+ expect(html).toContain("<link rel=\"stylesheet\" href=\"/ateam/static/style.css\">");
52
+ });
53
+ it("should include HTMX script", () => {
54
+ const html = layout("Test", "");
55
+ expect(html).toContain('<script src="https://unpkg.com/htmx.org@2.0.0"></script>');
56
+ });
57
+ it("should include navigation links with basePath", () => {
58
+ process.env.DASHBOARD_BASE_PATH = "/ateam";
59
+ const html = layout("Test", "");
60
+ expect(html).toContain('<a href="/ateam/">Runs</a>');
61
+ expect(html).toContain('<a href="/ateam/tokens">Tokens</a>');
62
+ expect(html).toContain('<a href="/ateam/errors">Errors</a>');
63
+ expect(html).toContain('<a href="/ateam/config">Config</a>');
64
+ expect(html).toContain('<a href="/ateam/coordination">Coordination</a>');
65
+ });
66
+ it("should include navigation links without basePath when not set", () => {
67
+ delete process.env.DASHBOARD_BASE_PATH;
68
+ const html = layout("Test", "");
69
+ expect(html).toContain('<a href="/">Runs</a>');
70
+ expect(html).toContain('<a href="/tokens">Tokens</a>');
71
+ expect(html).toContain('<a href="/errors">Errors</a>');
72
+ expect(html).toContain('<a href="/config">Config</a>');
73
+ expect(html).toContain('<a href="/coordination">Coordination</a>');
74
+ });
75
+ it("should include page content", () => {
76
+ const content = "<p>Test content here</p>";
77
+ const html = layout("Test", content);
78
+ expect(html).toContain(content);
79
+ });
80
+ it("should include viewport meta tag for responsive design", () => {
81
+ const html = layout("Test", "");
82
+ expect(html).toContain('<meta name="viewport" content="width=device-width, initial-scale=1">');
83
+ });
84
+ it("should escape special characters in page title", () => {
85
+ const html = layout("<script>alert('xss')</script>", "");
86
+ expect(html).toContain("&lt;script&gt;");
87
+ expect(html).not.toContain("<script>alert");
88
+ });
89
+ });
90
+ describe("escapeHtml function", () => {
91
+ it("should escape ampersands", () => {
92
+ expect(escapeHtml("A & B")).toBe("A &amp; B");
93
+ });
94
+ it("should escape less-than signs", () => {
95
+ expect(escapeHtml("A < B")).toBe("A &lt; B");
96
+ });
97
+ it("should escape greater-than signs", () => {
98
+ expect(escapeHtml("A > B")).toBe("A &gt; B");
99
+ });
100
+ it("should escape double quotes", () => {
101
+ expect(escapeHtml('Say "Hello"')).toBe("Say &quot;Hello&quot;");
102
+ });
103
+ it("should escape single quotes", () => {
104
+ expect(escapeHtml("It's fine")).toBe("It&#039;s fine");
105
+ });
106
+ it("should escape multiple special characters", () => {
107
+ expect(escapeHtml('<script>alert("xss")</script>')).toBe('&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;');
108
+ });
109
+ it("should handle empty string", () => {
110
+ expect(escapeHtml("")).toBe("");
111
+ });
112
+ it("should handle string without special characters", () => {
113
+ expect(escapeHtml("Hello World")).toBe("Hello World");
114
+ });
115
+ it("should escape in the correct order (ampersand first)", () => {
116
+ // If we don't escape ampersand first, we might double-escape
117
+ expect(escapeHtml("&lt;")).toBe("&amp;lt;");
118
+ });
119
+ });
120
+ describe("CSS and asset loading", () => {
121
+ it("should use relative path for CSS when basePath is empty", () => {
122
+ delete process.env.DASHBOARD_BASE_PATH;
123
+ const html = layout("Test", "");
124
+ expect(html).toContain('href="/static/style.css"');
125
+ });
126
+ it("should use correct path for CSS with basePath /ateam", () => {
127
+ process.env.DASHBOARD_BASE_PATH = "/ateam";
128
+ const html = layout("Test", "");
129
+ expect(html).toContain('href="/ateam/static/style.css"');
130
+ });
131
+ it("should use correct path for CSS with custom basePath", () => {
132
+ process.env.DASHBOARD_BASE_PATH = "/myapp";
133
+ const html = layout("Test", "");
134
+ expect(html).toContain('href="/myapp/static/style.css"');
135
+ });
136
+ });
137
+ });
138
+ //# sourceMappingURL=layout.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.test.js","sourceRoot":"","sources":["../../src/__tests__/layout.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * BEC-103 Security Tests — Dashboard Security Hardening
3
+ *
4
+ * Tests verify the hardened security behaviour introduced in BEC-103:
5
+ * - Security headers on all responses (including auth-blocked responses)
6
+ * - Basic auth required (503 when not configured)
7
+ * - CSRF protection on state-changing requests (POST/PUT/DELETE/PATCH only)
8
+ * - Rate limiting to prevent brute-force attacks
9
+ * - Credential redaction in config view
10
+ * - CSP meta tag in layout HTML
11
+ *
12
+ * Run with:
13
+ * cd packages/dashboard && npx vitest run src/__tests__/security.repro.test.ts
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=security.repro.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.repro.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/security.repro.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,249 @@
1
+ /**
2
+ * BEC-103 Security Tests — Dashboard Security Hardening
3
+ *
4
+ * Tests verify the hardened security behaviour introduced in BEC-103:
5
+ * - Security headers on all responses (including auth-blocked responses)
6
+ * - Basic auth required (503 when not configured)
7
+ * - CSRF protection on state-changing requests (POST/PUT/DELETE/PATCH only)
8
+ * - Rate limiting to prevent brute-force attacks
9
+ * - Credential redaction in config view
10
+ * - CSP meta tag in layout HTML
11
+ *
12
+ * Run with:
13
+ * cd packages/dashboard && npx vitest run src/__tests__/security.repro.test.ts
14
+ */
15
+ import { describe, it, expect, beforeEach } from "vitest";
16
+ import { createDashboard } from "../server.js";
17
+ // ---------------------------------------------------------------------------
18
+ // Minimal mock DB — every chainable call resolves to []
19
+ // ---------------------------------------------------------------------------
20
+ function createMockDb() {
21
+ const handler = {
22
+ get(_target, prop) {
23
+ if (prop === "then") {
24
+ return (resolve) => resolve([]);
25
+ }
26
+ return (..._args) => new Proxy(() => { }, handler);
27
+ },
28
+ apply() {
29
+ return new Proxy(() => { }, handler);
30
+ },
31
+ };
32
+ return new Proxy(() => { }, handler);
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ // Helpers
36
+ // ---------------------------------------------------------------------------
37
+ const ROUTES = ["/", "/tokens", "/errors", "/config", "/coordination"];
38
+ /** Build a Basic auth header value. */
39
+ function basicAuthHeader(username, password) {
40
+ return "Basic " + Buffer.from(`${username}:${password}`).toString("base64");
41
+ }
42
+ const VALID_AUTH = { username: "admin", password: "s3cr3t" };
43
+ const VALID_AUTH_HEADER = basicAuthHeader(VALID_AUTH.username, VALID_AUTH.password);
44
+ function makeApp(authEnabled = false) {
45
+ const cfg = {
46
+ db: createMockDb(),
47
+ pipelineConfigs: {},
48
+ repoConfigs: {},
49
+ };
50
+ if (authEnabled) {
51
+ cfg.auth = VALID_AUTH;
52
+ }
53
+ return createDashboard(cfg);
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // 1. Security Headers
57
+ // ---------------------------------------------------------------------------
58
+ describe("BEC-103: security headers present on all responses", () => {
59
+ let app;
60
+ beforeEach(() => {
61
+ // Use app without auth — headers must be present even on 503 auth-error responses
62
+ app = makeApp();
63
+ });
64
+ it.each(ROUTES)("GET %s — X-Content-Type-Options: nosniff header is present", async (route) => {
65
+ const res = await app.request(route);
66
+ expect(res.headers.get("x-content-type-options")).toBe("nosniff");
67
+ });
68
+ it.each(ROUTES)("GET %s — X-Frame-Options: DENY header is present", async (route) => {
69
+ const res = await app.request(route);
70
+ expect(res.headers.get("x-frame-options")).toBe("DENY");
71
+ });
72
+ it.each(ROUTES)("GET %s — Content-Security-Policy header is present", async (route) => {
73
+ const res = await app.request(route);
74
+ const csp = res.headers.get("content-security-policy");
75
+ expect(csp).not.toBeNull();
76
+ // Must restrict scripts to 'self' and https://unpkg.com only
77
+ expect(csp).toContain("default-src 'self'");
78
+ expect(csp).toContain("script-src 'self' https://unpkg.com");
79
+ });
80
+ it.each(ROUTES)("GET %s — X-XSS-Protection: 0 header is present", async (route) => {
81
+ const res = await app.request(route);
82
+ expect(res.headers.get("x-xss-protection")).toBe("0");
83
+ });
84
+ it.each(ROUTES)("GET %s — Referrer-Policy header is present", async (route) => {
85
+ const res = await app.request(route);
86
+ expect(res.headers.get("referrer-policy")).toBe("strict-origin-when-cross-origin");
87
+ });
88
+ it.each(ROUTES)("GET %s — Permissions-Policy header is present", async (route) => {
89
+ const res = await app.request(route);
90
+ const pp = res.headers.get("permissions-policy");
91
+ expect(pp).not.toBeNull();
92
+ expect(pp).toContain("camera=()");
93
+ expect(pp).toContain("microphone=()");
94
+ expect(pp).toContain("geolocation=()");
95
+ });
96
+ it.each(ROUTES)("GET %s — Strict-Transport-Security header is present", async (route) => {
97
+ const res = await app.request(route);
98
+ const hsts = res.headers.get("strict-transport-security");
99
+ expect(hsts).not.toBeNull();
100
+ expect(hsts).toContain("max-age=");
101
+ });
102
+ });
103
+ // ---------------------------------------------------------------------------
104
+ // 2. Authentication is required, not optional
105
+ // ---------------------------------------------------------------------------
106
+ describe("BEC-103 fix: basic auth is required, not optional", () => {
107
+ it("dashboard returns 503 when no credentials are configured", async () => {
108
+ const app = makeApp(false); // no auth configured
109
+ const res = await app.request("/");
110
+ // Fixed: server blocks all access and prompts to configure auth
111
+ expect(res.status).toBe(503);
112
+ const body = await res.text();
113
+ expect(body).toContain("DASHBOARD_USER");
114
+ });
115
+ it("unauthenticated request to config route returns 503 (not config data)", async () => {
116
+ const appWithConfig = createDashboard({
117
+ db: createMockDb(),
118
+ pipelineConfigs: {
119
+ "auto-implement": {
120
+ name: "Auto Implement",
121
+ stages: ["triage", "implement"],
122
+ model: "claude-opus-4-6",
123
+ maxTokens: 100000,
124
+ },
125
+ },
126
+ repoConfigs: {
127
+ "my-repo": {
128
+ url: "https://github-token:ghp_SECRET@github.com/org/repo.git",
129
+ },
130
+ },
131
+ // no auth configured — should block all access
132
+ });
133
+ const res = await appWithConfig.request("/config");
134
+ // Fixed: auth required — no config data exposed to unauthenticated requests
135
+ expect(res.status).toBe(503);
136
+ });
137
+ });
138
+ // ---------------------------------------------------------------------------
139
+ // 3. CSRF protection for state-changing requests
140
+ // ---------------------------------------------------------------------------
141
+ describe("BEC-103: CSRF / HX-Request validation on state-changing requests", () => {
142
+ it("GET /runs/feed is accessible without HX-Request header (GET is safe by design)", async () => {
143
+ const app = makeApp(true);
144
+ // GET requests don't need CSRF protection — only POST/PUT/DELETE/PATCH do
145
+ const res = await app.request("/runs/feed", {
146
+ headers: { Authorization: VALID_AUTH_HEADER },
147
+ });
148
+ expect(res.status).toBe(200);
149
+ });
150
+ it("GET /coordination/feed accessible from any origin (GET requests are safe)", async () => {
151
+ const app = makeApp(true);
152
+ // Origin check only applies to state-changing requests (POST/PUT/DELETE/PATCH)
153
+ const res = await app.request("/coordination/feed", {
154
+ headers: {
155
+ Authorization: VALID_AUTH_HEADER,
156
+ Origin: "https://evil.example.com",
157
+ },
158
+ });
159
+ // GET requests are safe — no origin block on read-only endpoints
160
+ expect(res.status).toBe(200);
161
+ });
162
+ });
163
+ // ---------------------------------------------------------------------------
164
+ // 4. Rate limiting prevents brute-force
165
+ // ---------------------------------------------------------------------------
166
+ describe("BEC-103: rate limiting prevents brute-force attacks", () => {
167
+ it("rapid unauthenticated requests eventually trigger 429", async () => {
168
+ const app = makeApp(true); // auth enabled — brute-force surface
169
+ let tooManyRequests = false;
170
+ for (let i = 0; i < 20; i++) {
171
+ const res = await app.request("/", {
172
+ headers: { Authorization: "Basic " + btoa("admin:wrong") },
173
+ });
174
+ if (res.status === 429) {
175
+ tooManyRequests = true;
176
+ break;
177
+ }
178
+ }
179
+ // Rate limiting kicks in after RATE_LIMIT_MAX requests per window
180
+ expect(tooManyRequests).toBe(true);
181
+ });
182
+ });
183
+ // ---------------------------------------------------------------------------
184
+ // 5. Config view credentials are redacted (fixed: was a vulnerability)
185
+ // ---------------------------------------------------------------------------
186
+ describe("BEC-103 fix: config view redacts sensitive credentials", () => {
187
+ it("repo URL containing embedded credentials is redacted in config view", async () => {
188
+ // Credentials embedded in repo URLs must be stripped before display.
189
+ const sensitiveUrl = "https://x-access-token:ghp_SUPERSECRET123@github.com/org/repo.git";
190
+ const appWithSecret = createDashboard({
191
+ db: createMockDb(),
192
+ pipelineConfigs: {},
193
+ repoConfigs: {
194
+ "secret-repo": { url: sensitiveUrl },
195
+ },
196
+ auth: VALID_AUTH, // auth required to reach config route
197
+ });
198
+ const res = await appWithSecret.request("/config", {
199
+ headers: { Authorization: VALID_AUTH_HEADER },
200
+ });
201
+ expect(res.status).toBe(200);
202
+ const html = await res.text();
203
+ // After fix: embedded token must NOT appear in the rendered HTML
204
+ expect(html).not.toContain("ghp_SUPERSECRET123");
205
+ // Redaction marker should be visible instead
206
+ expect(html).toContain("[redacted]");
207
+ });
208
+ });
209
+ // ---------------------------------------------------------------------------
210
+ // 6. Error information leakage
211
+ // ---------------------------------------------------------------------------
212
+ describe("BEC-103: error responses do not expose internal paths", () => {
213
+ it("404 for unknown run does not expose internal stack trace", async () => {
214
+ const app = makeApp(true);
215
+ const res = await app.request("/runs/nonexistent-run-id-12345", {
216
+ headers: { Authorization: VALID_AUTH_HEADER },
217
+ });
218
+ // Check that internal file paths are not exposed in error responses
219
+ const body = await res.text();
220
+ const internalPathPatterns = [
221
+ /\/var\/agent-runs/,
222
+ /node_modules/,
223
+ /\.ts:\d+:\d+/, // TypeScript stack trace lines
224
+ /at Object\.\<anonymous\>/, // JS stack frames
225
+ ];
226
+ for (const pattern of internalPathPatterns) {
227
+ expect(pattern.test(body)).toBe(false);
228
+ }
229
+ expect(res.status).toBe(404);
230
+ });
231
+ });
232
+ // ---------------------------------------------------------------------------
233
+ // 7. CSP meta tag in layout HTML
234
+ // ---------------------------------------------------------------------------
235
+ describe("BEC-103 fix: layout HTML includes CSP meta tag", () => {
236
+ it("layout HTML includes a Content-Security-Policy meta tag", async () => {
237
+ const app = makeApp(true);
238
+ const res = await app.request("/", {
239
+ headers: { Authorization: VALID_AUTH_HEADER },
240
+ });
241
+ expect(res.status).toBe(200);
242
+ const html = await res.text();
243
+ // CSP meta tag is present in the rendered HTML
244
+ expect(html.includes('http-equiv="Content-Security-Policy"')).toBe(true);
245
+ expect(html).toContain("default-src 'self'");
246
+ expect(html).toContain("script-src 'self' https://unpkg.com");
247
+ });
248
+ });
249
+ //# sourceMappingURL=security.repro.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.repro.test.js","sourceRoot":"","sources":["../../src/__tests__/security.repro.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":""}