Files
MyIP/package.json
T
jason5ng32andClaude Fable 5 9bfbf21a60 Feat(monitoring): integrate Sentry across frontend and backend, env-gated end to end
Frontend (@sentry/vue, loaded via build-time-gated dynamic import — no
VITE_SENTRY_DSN_FRONTEND, no Sentry in the bundle; init joins the mount
gate so instrumentation precedes the first render):
- uncaught errors, route-change tracing / Web Vitals, error-only masked
  Session Replay, console.error capture fingerprinted per message prefix
  so each fallback source stays a distinct issue
- explicit ip-source:exhausted signal via the app-events bus
- hidden source maps uploaded (then deleted) by @sentry/vite-plugin,
  gated on SENTRY_AUTH_TOKEN

Backend (@sentry/node, bootstrapped by sentry-instrument.js via
node --import so ESM loader hooks land before express; never loaded
without SENTRY_DSN_BACKEND):
- Express error capture + per-route tracing
- logger hook mirrors warn+ lines to Sentry Logs and elevates error+
  to grouped, alertable Issues
- Sentry Crons check-ins for the MaxMind / CAIDA / service-status jobs
  via the no-op-without-DSN wrapper common/sentry-cron.js

Delivery & ops:
- first-party tunnel /api/monitoring relays envelopes past ad blockers;
  DSN-allowlisted (never an open relay), exempt from the shared rate
  limiter with its own generous ceiling
- rate-limit ledger file becomes opt-in now that the warn line reaches
  Sentry Logs; ecosystem.config.cjs carries the --import flag for pm2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 11:16:17 +08:00

73 lines
2.2 KiB
JSON

{
"name": "myip",
"private": true,
"version": "6.4.0",
"type": "module",
"packageManager": "pnpm@11.10.0",
"scripts": {
"dev": "concurrently \"vite\" \"nodemon --import ./sentry-instrument.js backend-server.js\"",
"build": "vite build",
"test": "node --test tests/*.test.js",
"check": "pnpm run test && pnpm run build",
"preview": "vite preview",
"start-backend": "node --import ./sentry-instrument.js backend-server.js",
"start-frontend": "node frontend-server.js",
"start": "concurrently \"node frontend-server.js\" \"node --import ./sentry-instrument.js backend-server.js\""
},
"dependencies": {
"@cloudflare/speedtest": "^1.11.0",
"@iconify-json/circle-flags": "^1.2.10",
"@iconify/vue": "^5.0.1",
"@khmyznikov/pwa-install": "^0.6.4",
"@lucide/vue": "^1.23.0",
"@sentry/node": "^10.64.0",
"@sentry/vue": "^10.64.0",
"@tanstack/vue-table": "^8.21.3",
"@thumbmarkjs/thumbmarkjs": "^1.10.0",
"@vueuse/core": "^14.3.0",
"chart.js": "^4.5.1",
"circle-progress.vue": "^3.4.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"concurrently": "^10.0.3",
"country-code-lookup": "^0.1.5",
"dagre": "^0.8.5",
"dotenv": "^17.4.2",
"express": "^5.2.1",
"express-rate-limit": "^8.5.2",
"express-slow-down": "^3.1.0",
"firebase": "^12.16.0",
"html-to-image": "^1.11.13",
"http-proxy-middleware": "^4.2.0",
"maxmind": "^5.0.6",
"pinia": "^3.0.4",
"pino": "^10.3.1",
"pino-http": "^11.0.0",
"pino-pretty": "^13.1.3",
"reka-ui": "^2.10.1",
"svgmap": "2.21.0",
"tailwind-merge": "^3.6.0",
"tar": "^7.5.19",
"tw-animate-css": "^1.4.0",
"ua-parser-js": "^2.0.10",
"unbzip2-stream": "^1.4.3",
"vaul-vue": "^0.4.1",
"vue": "^3.5.39",
"vue-i18n": "^11.4.6",
"vue-markdown-render": "^2.3.1",
"vue-router": "^5.1.0",
"vue-sonner": "^2.0.9",
"whoiser": "^1.18.0"
},
"devDependencies": {
"@sentry/vite-plugin": "^5.3.0",
"@tailwindcss/vite": "^4.3.2",
"@vitejs/plugin-vue": "^6.0.7",
"code-inspector-plugin": "^1.6.6",
"nodemon": "^3.1.14",
"tailwindcss": "^4.3.2",
"vconsole": "^3.15.1",
"vite": "^8.1.4"
}
}