Files
eSIM-Tools/netlify.toml
Abner a1222dfedc feat: 升级 Sentry 监控系统,增强错误捕获能力
- 使用 npm @sentry/browser@10.30.0 构建完整 SDK bundle(替代旧的 114KB 手动 bundle)
- 放宽错误过滤规则:移除对网络错误(Failed to fetch、Network request failed)的误过滤
- 优化 beforeSend:仅在堆栈帧明确包含扩展路径时才过滤,减少误杀
- 启用 Session Replay:10% 会话采样 + 100% 错误录制,支持用户操作回放
- 添加用户反馈组件:showReportDialog() 允许用户主动报告问题
- 添加健康检查:getSentryHealth() 输出 SDK 状态和过滤统计
- 同步更新 sentry-init.js 和 sentry-loader.js 配置
2026-05-19 13:27:00 +08:00

195 lines
6.2 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[build]
# 构建命令
command = "npm run build --silent"
# 发布目录:仅暴露构建后的 dist 输出
publish = "dist"
# Functions目录
functions = "netlify/functions"
# Edge Functions 目录
edge_functions = "netlify/edge-functions"
[build.environment]
# 固定 Node 版本,避免二进制依赖(如 sharp在 Node 22 下编译耗时
NODE_VERSION = "20.12.2"
# 安装时减少无关输出与提示
NPM_FLAGS = "--no-audit --no-fund --omit=optional"
# 重定向和重写规则
[[redirects]]
# Giffgaff eSIM页面 - 模块化版本
from = "/giffgaff"
to = "/src/giffgaff/giffgaff_modular.html"
status = 200
[[redirects]]
# Simyo eSIM页面 - 模块化版本
from = "/simyo"
to = "/src/simyo/simyo_modular.html"
status = 200
[[redirects]]
# 根路径重定向到选择页面
from = "/"
to = "/index.html"
status = 200
# API代理重定向用于解决CORS问题
# 通用 Simyo API 代理 (webapi - 新版API)
[[redirects]]
from = "/api/simyo/*"
to = "https://appapi.simyo.nl/webapi/api/v1/:splat"
status = 200
force = true
headers = {X-Forwarded-Host = "appapi.simyo.nl"}
# v2 API 代理(用于特定端点如可用验证方式查询)
[[redirects]]
from = "/api/simyo/esim.availableValidationMethods"
to = "https://appapi.simyo.nl/webapi/api/v2/esim.availableValidationMethods"
status = 200
force = true
headers = {X-Forwarded-Host = "appapi.simyo.nl"}
# 保留旧版 simyoapi 路径的兼容性(如果需要)
[[redirects]]
from = "/api/simyo/legacy/*"
to = "https://appapi.simyo.nl/simyoapi/api/v1/:splat"
status = 200
force = true
headers = {X-Forwarded-Host = "appapi.simyo.nl"}
[[headers]]
# 限制 Simyo 代理仅允许指定站点跨域访问
for = "/api/simyo/*"
[headers.values]
Access-Control-Allow-Origin = "https://esim.cosr.eu.org"
Access-Control-Allow-Headers = "Content-Type, Authorization"
Access-Control-Allow-Methods = "GET, POST, OPTIONS"
Vary = "Origin"
# 将 /bff/* 映射到 Edge Function bff-proxy
[[edge_functions]]
path = "/bff/*"
function = "bff-proxy"
# Markdown for Agents检测 Accept: text/markdown 请求
[[edge_functions]]
path = "/"
function = "markdown-negotiation"
[[redirects]]
from = "/api/giffgaff/*"
to = "https://api.giffgaff.com/:splat"
status = 200
force = true
headers = {X-Forwarded-Host = "api.giffgaff.com"}
[[headers]]
for = "/api/giffgaff/*"
[headers.values]
# giffgaff 直连不受此限制,保持通用放行
Access-Control-Allow-Origin = "*"
Access-Control-Allow-Headers = "Content-Type, Authorization"
Access-Control-Allow-Methods = "GET, POST, OPTIONS"
[[redirects]]
from = "/api/giffgaff-id/*"
to = "https://id.giffgaff.com/:splat"
status = 200
force = true
headers = {X-Forwarded-Host = "id.giffgaff.com"}
[[headers]]
for = "/api/giffgaff-id/*"
[headers.values]
Access-Control-Allow-Origin = "*"
Access-Control-Allow-Headers = "Content-Type, Authorization"
Access-Control-Allow-Methods = "GET, POST, OPTIONS"
[[redirects]]
from = "/api/giffgaff-public/*"
to = "https://publicapi.giffgaff.com/:splat"
status = 200
force = true
headers = {X-Forwarded-Host = "publicapi.giffgaff.com"}
[[headers]]
for = "/api/giffgaff-public/*"
[headers.values]
Access-Control-Allow-Origin = "*"
Access-Control-Allow-Headers = "Content-Type, Authorization"
Access-Control-Allow-Methods = "GET, POST, OPTIONS"
# favicon 根路径重定向(浏览器默认请求 /favicon.ico
[[redirects]]
from = "/favicon.ico"
to = "/src/assets/favicon.ico"
status = 200
# OG 社交分享图片重定向
[[redirects]]
from = "/og-image.png"
to = "/src/assets/og-image.png"
status = 200
# 处理SPA路由兜底 404
[[redirects]]
from = "/*"
to = "/index.html"
status = 404
# 静态资源长期缓存CSS/JS/字体/图片)
[[headers]]
for = "/src/styles/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/src/js/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/src/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/dist/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
# HTML 页面:短缓存 + stale-while-revalidate
[[headers]]
for = "/*.html"
[headers.values]
Cache-Control = "public, max-age=300, stale-while-revalidate=86400"
# 安全头部
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
# 生产 CSP移除 unsafe-inline基于 nonce/hash 的策略(页面模板需注入 nonce
# 如暂无模板注入机制,可先允许外链受信源并避免内联脚本
Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://www.googletagmanager.com https://www.google.com https://www.gstatic.com https://browser.sentry-cdn.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://fonts.googleapis.com; img-src 'self' data: https:; connect-src 'self' https://qrcode.show https://api.qrserver.com https://appapi.simyo.nl https://api.giffgaff.com https://id.giffgaff.com https://publicapi.giffgaff.com https://www.google.com https://www.gstatic.com https://*.sentry.io https://cdn.jsdelivr.net https://browser.sentry-cdn.com; font-src 'self' data: https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://fonts.gstatic.com; manifest-src 'self';"
# Agent 发现 Link 响应头 (RFC 8288)
[[headers]]
for = "/"
[headers.values]
Link = "</.well-known/api-catalog>; rel=\"api-catalog\", </.well-known/oauth-protected-resource>; rel=\"oauth-protected-resource\", </.well-known/mcp/server-card.json>; rel=\"mcp-server-card\", </.well-known/agent-skills/index.json>; rel=\"agent-skills\""
# Markdown for Agents 支持头部
[[headers]]
for = "/"
[headers.values]
Vary = "Accept"
[[headers]]
for = "/manifest.webmanifest"
[headers.values]
Content-Type = "application/manifest+json; charset=utf-8"