@mdguggenbichler/slugbase-core 0.0.6 → 0.0.7
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 +66 -18
- 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,14 +131,26 @@ function ForwardingHandler() {
|
|
|
133
131
|
);
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
|
|
134
|
+
interface AppErrorFallbackProps {
|
|
135
|
+
error?: Error | null;
|
|
136
|
+
onReset?: () => void;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function AppErrorFallback({ error, onReset }: AppErrorFallbackProps) {
|
|
137
140
|
const { t } = useTranslation();
|
|
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
144
|
<p className="text-lg text-gray-700 dark:text-gray-300 text-center">{t('common.error')}</p>
|
|
145
|
+
{message && (
|
|
146
|
+
<details className="w-full max-w-md text-sm text-gray-600 dark:text-gray-400" open={import.meta.env?.DEV}>
|
|
147
|
+
<summary className="cursor-pointer">{message}</summary>
|
|
148
|
+
{error?.stack && <pre className="mt-2 overflow-auto whitespace-pre-wrap">{error.stack}</pre>}
|
|
149
|
+
</details>
|
|
150
|
+
)}
|
|
141
151
|
<button
|
|
142
152
|
type="button"
|
|
143
|
-
onClick={() => window.location.reload()}
|
|
153
|
+
onClick={() => (onReset ? onReset() : window.location.reload())}
|
|
144
154
|
className="px-4 py-2 rounded-md bg-primary text-primary-foreground hover:opacity-90"
|
|
145
155
|
>
|
|
146
156
|
{t('common.reload')}
|
|
@@ -149,30 +159,68 @@ function AppErrorFallback() {
|
|
|
149
159
|
);
|
|
150
160
|
}
|
|
151
161
|
|
|
162
|
+
interface AppErrorBoundaryState {
|
|
163
|
+
error: Error | null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
class AppErrorBoundary extends Component<{ children: ReactNode }, AppErrorBoundaryState> {
|
|
167
|
+
state: AppErrorBoundaryState = { error: null };
|
|
168
|
+
|
|
169
|
+
static getDerivedStateFromError(error: unknown): AppErrorBoundaryState {
|
|
170
|
+
const normalized =
|
|
171
|
+
error instanceof Error ? error : new Error(error != null ? String(error) : 'Unknown error');
|
|
172
|
+
return { error: normalized };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
componentDidCatch(error: unknown, info: React.ErrorInfo) {
|
|
176
|
+
console.error('App error boundary caught:', error, info.componentStack);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
render() {
|
|
180
|
+
if (this.state.error) {
|
|
181
|
+
return (
|
|
182
|
+
<AppErrorFallback
|
|
183
|
+
error={this.state.error}
|
|
184
|
+
onReset={() => this.setState({ error: null })}
|
|
185
|
+
/>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
return this.props.children;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
152
192
|
export interface AppProps {
|
|
153
193
|
/** Base path for app routes (e.g. '/' for self-hosted, '/app' for cloud). */
|
|
154
194
|
basePath?: string;
|
|
155
195
|
/** API base URL (e.g. '' for same-origin, or full URL if frontend is on different origin). */
|
|
156
196
|
apiBaseUrl?: string;
|
|
197
|
+
/** When set (e.g. "" or null), core does not render BrowserRouter; host (e.g. cloud) provides it. */
|
|
198
|
+
routerBasename?: string | null;
|
|
157
199
|
}
|
|
158
200
|
|
|
159
|
-
function App({ basePath, apiBaseUrl }: AppProps = {}) {
|
|
201
|
+
function App({ basePath, apiBaseUrl, routerBasename }: AppProps = {}) {
|
|
160
202
|
const appRootPath = basePath === '/' || !basePath ? '/' : basePath;
|
|
203
|
+
const content = (
|
|
204
|
+
<AuthProvider>
|
|
205
|
+
<TooltipProvider>
|
|
206
|
+
<ToastProvider>
|
|
207
|
+
<AppRoutes />
|
|
208
|
+
</ToastProvider>
|
|
209
|
+
</TooltipProvider>
|
|
210
|
+
</AuthProvider>
|
|
211
|
+
);
|
|
161
212
|
return (
|
|
162
|
-
<
|
|
213
|
+
<AppErrorBoundary>
|
|
163
214
|
<AppConfigProvider appBasePath={basePath} apiBaseUrl={apiBaseUrl} appRootPath={appRootPath}>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
</TooltipProvider>
|
|
172
|
-
</AuthProvider>
|
|
173
|
-
</BrowserRouter>
|
|
215
|
+
{routerBasename !== undefined ? (
|
|
216
|
+
content
|
|
217
|
+
) : (
|
|
218
|
+
<BrowserRouter basename={basePath ?? ''}>
|
|
219
|
+
{content}
|
|
220
|
+
</BrowserRouter>
|
|
221
|
+
)}
|
|
174
222
|
</AppConfigProvider>
|
|
175
|
-
</
|
|
223
|
+
</AppErrorBoundary>
|
|
176
224
|
);
|
|
177
225
|
}
|
|
178
226
|
|
|
@@ -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
|
-
}
|