@mdguggenbichler/slugbase-core 0.0.6 → 0.0.8
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/backend/dist/index.d.ts +0 -1
- package/backend/dist/index.d.ts.map +1 -1
- package/backend/dist/index.js +0 -3
- package/backend/dist/index.js.map +1 -1
- package/backend/dist/middleware/error-handler.d.ts.map +1 -1
- package/backend/dist/middleware/error-handler.js +0 -3
- package/backend/dist/middleware/error-handler.js.map +1 -1
- package/backend/dist/middleware/security.d.ts.map +1 -1
- package/backend/dist/middleware/security.js +1 -7
- package/backend/dist/middleware/security.js.map +1 -1
- package/backend/dist/register-routes.d.ts.map +1 -1
- package/backend/dist/register-routes.js +0 -5
- package/backend/dist/register-routes.js.map +1 -1
- package/frontend/index.tsx +1 -0
- package/frontend/src/App.tsx +71 -21
- package/frontend/src/api/client.ts +1 -14
- package/frontend/src/main.tsx +0 -1
- package/package.json +1 -1
- package/frontend/src/components/SentryDebug.tsx +0 -32
- package/frontend/src/instrument.ts +0 -20
package/backend/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,eAAe,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,eAAe,CAAC"}
|
package/backend/dist/index.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
// IMPORTANT: Load environment variables FIRST, before any other imports
|
|
2
2
|
import './load-env.js';
|
|
3
|
-
import './instrument.js';
|
|
4
3
|
import express from 'express';
|
|
5
4
|
import { join } from 'path';
|
|
6
5
|
import { fileURLToPath } from 'url';
|
|
7
6
|
import { dirname } from 'path';
|
|
8
|
-
import * as Sentry from '@sentry/node';
|
|
9
7
|
import { validateEnvironmentVariables } from './utils/env-validation.js';
|
|
10
8
|
import { initDatabase, isInitialized } from './db/index.js';
|
|
11
9
|
import { loadOIDCStrategies } from './auth/oidc.js';
|
|
@@ -47,7 +45,6 @@ async function start() {
|
|
|
47
45
|
});
|
|
48
46
|
});
|
|
49
47
|
app.use(notFoundHandler);
|
|
50
|
-
Sentry.setupExpressErrorHandler(app);
|
|
51
48
|
app.use(errorHandler);
|
|
52
49
|
const initialized = await isInitialized();
|
|
53
50
|
console.log(`System initialized: ${initialized}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,sCA2BrF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,QAE1D"}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import * as Sentry from '@sentry/node';
|
|
2
1
|
/**
|
|
3
2
|
* Error handling middleware
|
|
4
3
|
* Prevents information disclosure in production
|
|
5
4
|
*/
|
|
6
5
|
export function errorHandler(err, req, res, next) {
|
|
7
|
-
// Report to Sentry when configured (no-op when SENTRY_DSN is unset)
|
|
8
|
-
Sentry.captureException(err);
|
|
9
6
|
// Log error details server-side
|
|
10
7
|
console.error('Error:', {
|
|
11
8
|
message: err.message,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAQ,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB;IACpF,gCAAgC;IAChC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE;QACtB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACrE,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM,EAAE,GAAG,CAAC,MAAM;KACnB,CAAC,CAAC;IAEH,iFAAiF;IACjF,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC;QACrC,MAAM,YAAY,GAA2B;YAC3C,GAAG,EAAE,aAAa;YAClB,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,WAAW;SACjB,CAAC;QACF,MAAM,WAAW,GAAG,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAC5F,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,iCAAiC;IACjC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QAC5C,KAAK,EAAE,GAAG,CAAC,OAAO,IAAI,mBAAmB;QACzC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;KACpE,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,GAAa;IACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/middleware/security.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,eAAe,SAFE,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAWhD,CAAC;AAEP,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,SAdD,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAuBhD,CAAC;AAEP,eAAO,MAAM,kBAAkB,SAzBD,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAgChD,CAAC;AAEP,eAAO,MAAM,iBAAiB,SAlCA,GAAG,OAAO,GAAG,QAAQ,GAAG,gEA0ChD,CAAC;AAEP,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,SA7CD,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAqDhD,CAAC;AAEP,iFAAiF;AACjF,eAAO,MAAM,mBAAmB,SAxDF,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAgEhD,CAAC;AAEP,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,SAnEL,GAAG,OAAO,GAAG,QAAQ,GAAG,gEA2EhD,CAAC;AAEP;;GAEG;AACH,wBAAgB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/middleware/security.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,eAAe,SAFE,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAWhD,CAAC;AAEP,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,SAdD,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAuBhD,CAAC;AAEP,eAAO,MAAM,kBAAkB,SAzBD,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAgChD,CAAC;AAEP,eAAO,MAAM,iBAAiB,SAlCA,GAAG,OAAO,GAAG,QAAQ,GAAG,gEA0ChD,CAAC;AAEP,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,SA7CD,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAqDhD,CAAC;AAEP,iFAAiF;AACjF,eAAO,MAAM,mBAAmB,SAxDF,GAAG,OAAO,GAAG,QAAQ,GAAG,gEAgEhD,CAAC;AAEP,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,SAnEL,GAAG,OAAO,GAAG,QAAQ,GAAG,gEA2EhD,CAAC;AAEP;;GAEG;AACH,wBAAgB,oBAAoB,wFA2E5B,CAAC,4BAvCR;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,OAmB3D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,MAAM,CAe5D"}
|
|
@@ -88,13 +88,7 @@ export function setupSecurityHeaders() {
|
|
|
88
88
|
styleSrc: ["'self'", "'unsafe-inline'"], // Swagger UI needs inline styles
|
|
89
89
|
scriptSrc: ["'self'"],
|
|
90
90
|
imgSrc: ["'self'", "data:", "https:"], // Allow data URIs and HTTPS images (for favicons)
|
|
91
|
-
connectSrc: [
|
|
92
|
-
"'self'",
|
|
93
|
-
// Sentry error tracking (ingest endpoints vary by region)
|
|
94
|
-
"https://*.ingest.sentry.io",
|
|
95
|
-
"https://*.ingest.de.sentry.io",
|
|
96
|
-
"https://*.ingest.eu.sentry.io",
|
|
97
|
-
],
|
|
91
|
+
connectSrc: ["'self'"],
|
|
98
92
|
fontSrc: ["'self'"],
|
|
99
93
|
objectSrc: ["'none'"],
|
|
100
94
|
mediaSrc: ["'self'"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/middleware/security.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/middleware/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-routes.d.ts","sourceRoot":"","sources":["../src/register-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAqB9B,MAAM,WAAW,aAAa;CAE7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"register-routes.d.ts","sourceRoot":"","sources":["../src/register-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAqB9B,MAAM,WAAW,aAAa;CAE7B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CA2BpF"}
|
|
@@ -43,11 +43,6 @@ export function registerCoreRoutes(app, _deps) {
|
|
|
43
43
|
app.use('/api/dashboard', dashboardRoutes);
|
|
44
44
|
app.use('/api', healthRoutes);
|
|
45
45
|
app.use('/api/go', goRoutes);
|
|
46
|
-
if (process.env.SENTRY_DEBUG === 'true') {
|
|
47
|
-
app.get('/api/debug-sentry', () => {
|
|
48
|
-
throw new Error('Sentry backend test error');
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
46
|
app.get('/go/:slug/remember/:bookmarkId', redirectRateLimiter, optionalAuthForGo, (req, res) => {
|
|
52
47
|
handleGoRemember(req, res).catch((err) => {
|
|
53
48
|
console.error('Go remember error:', err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-routes.js","sourceRoot":"","sources":["../src/register-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,cAAc,MAAM,uBAAuB,CAAC;AACnD,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAC/C,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,QAAQ,EAAE,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAC5D,OAAO,eAAe,MAAM,yBAAyB,CAAC;AACtD,OAAO,eAAe,MAAM,yBAAyB,CAAC;AACtD,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AACvD,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,uBAAuB,MAAM,gCAAgC,CAAC;AACrE,OAAO,eAAe,MAAM,uBAAuB,CAAC;AACpD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAM/D;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAoB,EAAE,KAAqB;IAC5E,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAAC;IACpD,GAAG,CAAC,GAAG,CAAC,yBAAyB,EAAE,uBAAuB,CAAC,CAAC;IAC5D,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;IAC1C,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACtC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAChC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAClC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAClC,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACpC,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACrC,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,CAAC;IACnD,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;IAC7C,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;IAC7C,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,CAAC;IACpD,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;IAC9C,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAC3C,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAE7B,
|
|
1
|
+
{"version":3,"file":"register-routes.js","sourceRoot":"","sources":["../src/register-routes.ts"],"names":[],"mappings":"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"}
|
package/frontend/index.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @slugbase/core/frontend – re-exports App and createApiClient for self-hosted and cloud apps.
|
|
3
3
|
* Published package includes frontend/src (copied at publish); in-repo use copy-core-dist or alias to root frontend.
|
|
4
|
+
* When embedding, the host must initialize i18n and provide a single Router; see repo docs (docs/embedding.md).
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
export { default as App } from './src/App';
|
package/frontend/src/App.tsx
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import React, { Suspense, lazy } from 'react';
|
|
1
|
+
import React, { Suspense, lazy, Component, type ReactNode } from 'react';
|
|
2
2
|
import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import * as Sentry from '@sentry/react';
|
|
5
4
|
import { AuthProvider, useAuth } from './contexts/AuthContext';
|
|
6
5
|
import { AppConfigProvider, useAppConfig } from './contexts/AppConfigContext';
|
|
7
|
-
import { SentryDebug } from './components/SentryDebug';
|
|
8
6
|
import { ToastProvider } from './components/ui/Toast';
|
|
9
7
|
import { TooltipProvider } from './components/ui/tooltip-base';
|
|
10
8
|
import Layout from './components/Layout';
|
|
@@ -133,46 +131,98 @@ function ForwardingHandler() {
|
|
|
133
131
|
);
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
interface AppErrorFallbackProps {
|
|
135
|
+
error?: Error | null;
|
|
136
|
+
onReset?: () => void;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function AppErrorFallback({ error, onReset }: AppErrorFallbackProps) {
|
|
140
|
+
// Use hardcoded strings so this fallback never throws (e.g. when i18n context is missing in embedded host).
|
|
141
|
+
const message = error?.message ?? (error != null ? String(error) : '');
|
|
138
142
|
return (
|
|
139
143
|
<div className="min-h-screen flex flex-col items-center justify-center gap-4 p-4" role="alert">
|
|
140
|
-
<p className="text-lg text-gray-700 dark:text-gray-300 text-center">
|
|
144
|
+
<p className="text-lg text-gray-700 dark:text-gray-300 text-center">
|
|
145
|
+
Something went wrong loading this page. Please try again.
|
|
146
|
+
</p>
|
|
147
|
+
{(message || error?.stack) && (
|
|
148
|
+
<details className="w-full max-w-md text-sm text-gray-600 dark:text-gray-400" open>
|
|
149
|
+
<summary className="cursor-pointer">{message || 'Error details'}</summary>
|
|
150
|
+
{error?.stack && <pre className="mt-2 overflow-auto whitespace-pre-wrap">{error.stack}</pre>}
|
|
151
|
+
</details>
|
|
152
|
+
)}
|
|
141
153
|
<button
|
|
142
154
|
type="button"
|
|
143
|
-
onClick={() => window.location.reload()}
|
|
155
|
+
onClick={() => (onReset ? onReset() : window.location.reload())}
|
|
144
156
|
className="px-4 py-2 rounded-md bg-primary text-primary-foreground hover:opacity-90"
|
|
145
157
|
>
|
|
146
|
-
|
|
158
|
+
Reload
|
|
147
159
|
</button>
|
|
148
160
|
</div>
|
|
149
161
|
);
|
|
150
162
|
}
|
|
151
163
|
|
|
164
|
+
interface AppErrorBoundaryState {
|
|
165
|
+
error: Error | null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class AppErrorBoundary extends Component<{ children: ReactNode }, AppErrorBoundaryState> {
|
|
169
|
+
state: AppErrorBoundaryState = { error: null };
|
|
170
|
+
|
|
171
|
+
static getDerivedStateFromError(error: unknown): AppErrorBoundaryState {
|
|
172
|
+
const normalized =
|
|
173
|
+
error instanceof Error ? error : new Error(error != null ? String(error) : 'Unknown error');
|
|
174
|
+
return { error: normalized };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
componentDidCatch(error: unknown, info: React.ErrorInfo) {
|
|
178
|
+
console.error('App error boundary caught:', error, info.componentStack);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
render() {
|
|
182
|
+
if (this.state.error) {
|
|
183
|
+
return (
|
|
184
|
+
<AppErrorFallback
|
|
185
|
+
error={this.state.error}
|
|
186
|
+
onReset={() => this.setState({ error: null })}
|
|
187
|
+
/>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
return this.props.children;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
152
194
|
export interface AppProps {
|
|
153
195
|
/** Base path for app routes (e.g. '/' for self-hosted, '/app' for cloud). */
|
|
154
196
|
basePath?: string;
|
|
155
197
|
/** API base URL (e.g. '' for same-origin, or full URL if frontend is on different origin). */
|
|
156
198
|
apiBaseUrl?: string;
|
|
199
|
+
/** When set (e.g. "" or null), core does not render BrowserRouter; host (e.g. cloud) provides it. */
|
|
200
|
+
routerBasename?: string | null;
|
|
157
201
|
}
|
|
158
202
|
|
|
159
|
-
function App({ basePath, apiBaseUrl }: AppProps = {}) {
|
|
203
|
+
function App({ basePath, apiBaseUrl, routerBasename }: AppProps = {}) {
|
|
160
204
|
const appRootPath = basePath === '/' || !basePath ? '/' : basePath;
|
|
205
|
+
const content = (
|
|
206
|
+
<AuthProvider>
|
|
207
|
+
<TooltipProvider>
|
|
208
|
+
<ToastProvider>
|
|
209
|
+
<AppRoutes />
|
|
210
|
+
</ToastProvider>
|
|
211
|
+
</TooltipProvider>
|
|
212
|
+
</AuthProvider>
|
|
213
|
+
);
|
|
161
214
|
return (
|
|
162
|
-
<
|
|
215
|
+
<AppErrorBoundary>
|
|
163
216
|
<AppConfigProvider appBasePath={basePath} apiBaseUrl={apiBaseUrl} appRootPath={appRootPath}>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
</TooltipProvider>
|
|
172
|
-
</AuthProvider>
|
|
173
|
-
</BrowserRouter>
|
|
217
|
+
{routerBasename !== undefined ? (
|
|
218
|
+
content
|
|
219
|
+
) : (
|
|
220
|
+
<BrowserRouter basename={basePath ?? ''}>
|
|
221
|
+
{content}
|
|
222
|
+
</BrowserRouter>
|
|
223
|
+
)}
|
|
174
224
|
</AppConfigProvider>
|
|
175
|
-
</
|
|
225
|
+
</AppErrorBoundary>
|
|
176
226
|
);
|
|
177
227
|
}
|
|
178
228
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import axios, { type AxiosInstance } from 'axios';
|
|
2
|
-
import * as Sentry from '@sentry/react';
|
|
3
2
|
import { apiBaseUrl } from '../config/api';
|
|
4
3
|
|
|
5
4
|
function baseURLFromOptions(options: { baseUrl?: string; basePath?: string } = {}): string {
|
|
@@ -31,10 +30,7 @@ export function createApiClient(options: { baseUrl?: string; basePath?: string }
|
|
|
31
30
|
});
|
|
32
31
|
client.interceptors.response.use(
|
|
33
32
|
(r) => r,
|
|
34
|
-
(error) =>
|
|
35
|
-
if (error.response?.status >= 500) Sentry.captureException(error);
|
|
36
|
-
return Promise.reject(error);
|
|
37
|
-
}
|
|
33
|
+
(error) => Promise.reject(error)
|
|
38
34
|
);
|
|
39
35
|
return client;
|
|
40
36
|
}
|
|
@@ -118,15 +114,6 @@ api.interceptors.response.use(
|
|
|
118
114
|
}
|
|
119
115
|
return api.request(error.config);
|
|
120
116
|
}
|
|
121
|
-
// Report 5xx, network errors, and unexpected 4xx to Sentry (skip 401/403/404 - auth flow)
|
|
122
|
-
const status = error.response?.status;
|
|
123
|
-
const shouldReport =
|
|
124
|
-
status === undefined ||
|
|
125
|
-
status >= 500 ||
|
|
126
|
-
(status >= 400 && status !== 401 && status !== 403 && status !== 404);
|
|
127
|
-
if (shouldReport) {
|
|
128
|
-
Sentry.captureException(error);
|
|
129
|
-
}
|
|
130
117
|
return Promise.reject(error);
|
|
131
118
|
}
|
|
132
119
|
);
|
package/frontend/src/main.tsx
CHANGED
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import * as Sentry from '@sentry/react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Floating debug buttons for Sentry testing.
|
|
5
|
-
* Only visible when VITE_SENTRY_DEBUG=true at build time.
|
|
6
|
-
*/
|
|
7
|
-
export function SentryDebug() {
|
|
8
|
-
if (import.meta.env.VITE_SENTRY_DEBUG !== 'true') return null;
|
|
9
|
-
|
|
10
|
-
return (
|
|
11
|
-
<div className="fixed bottom-4 right-4 z-50 flex gap-2">
|
|
12
|
-
<button
|
|
13
|
-
type="button"
|
|
14
|
-
onClick={() => {
|
|
15
|
-
throw new Error('Sentry frontend test error (throw)');
|
|
16
|
-
}}
|
|
17
|
-
className="px-3 py-1.5 text-sm rounded-md bg-red-100 dark:bg-red-900/80 text-red-800 dark:text-red-200 hover:opacity-90"
|
|
18
|
-
>
|
|
19
|
-
Test Sentry (throw)
|
|
20
|
-
</button>
|
|
21
|
-
<button
|
|
22
|
-
type="button"
|
|
23
|
-
onClick={() => {
|
|
24
|
-
Sentry.captureException(new Error('Sentry frontend test (capture)'));
|
|
25
|
-
}}
|
|
26
|
-
className="px-3 py-1.5 text-sm rounded-md bg-amber-100 dark:bg-amber-900/80 text-amber-800 dark:text-amber-200 hover:opacity-90"
|
|
27
|
-
>
|
|
28
|
-
Test Sentry (capture)
|
|
29
|
-
</button>
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sentry instrumentation - must run before any other imports.
|
|
3
|
-
* When VITE_SENTRY_DSN is unset, Sentry is disabled (no network calls).
|
|
4
|
-
*/
|
|
5
|
-
import * as Sentry from '@sentry/react';
|
|
6
|
-
|
|
7
|
-
const dsn = import.meta.env.VITE_SENTRY_DSN as string | undefined;
|
|
8
|
-
if (dsn) {
|
|
9
|
-
Sentry.init({
|
|
10
|
-
dsn,
|
|
11
|
-
environment: (import.meta.env.VITE_SENTRY_ENVIRONMENT as string) || import.meta.env.MODE || 'development',
|
|
12
|
-
integrations: [
|
|
13
|
-
Sentry.browserTracingIntegration(),
|
|
14
|
-
Sentry.replayIntegration({ maskAllText: true, blockAllMedia: true }),
|
|
15
|
-
],
|
|
16
|
-
tracesSampleRate: import.meta.env.PROD ? 0.1 : 1.0,
|
|
17
|
-
replaysSessionSampleRate: import.meta.env.PROD ? 0.1 : 0,
|
|
18
|
-
sendDefaultPii: false,
|
|
19
|
-
});
|
|
20
|
-
}
|