Files
safetynet/packages/core/diagnostics.mjs
T

13 lines
1.3 KiB
JavaScript
Raw Normal View History

2026-10-13 10:33:31 +02:00
import {z} from 'zod';
export function diagnosticsEndpointAllowed(value){
try{const u=new URL(value);if(u.username||u.password||u.search||u.hash||!['https:','http:'].includes(u.protocol))return false;
const host=u.hostname.replace(/^\[|\]$/g,'');return u.protocol==='https:'||host==='::1'||/^127\.(?:\d{1,3}\.){2}\d{1,3}$/.test(host)&&host.split('.').every(part=>Number(part)<=255);
}catch{return false;}
}
export const DiagnosticsSchema=z.object({
enabled:z.boolean().default(false),mode:z.enum(['operational','debug']).default('operational'),
endpoint:z.string().max(2048).refine(diagnosticsEndpointAllowed,'Collector requires HTTPS or numeric loopback without credentials, query or fragment').optional(),
sampleRate:z.number().min(0).max(1).default(0.1),debugSampleRate:z.number().min(0).max(1).default(1),
maxQueueSize:z.number().int().min(16).max(4096).default(512),flushIntervalMs:z.number().int().min(250).max(10000).default(2000),
maxRecordAgeMs:z.number().int().min(1000).max(300000).default(30000),exportTimeoutMs:z.number().int().min(250).max(10000).default(2000)
}).strict().superRefine((config,context)=>{if(config.enabled&&!config.endpoint)context.addIssue({code:'custom',message:'Enabled diagnostics require a centrally configured collector',path:['endpoint']});});