import type { AnalysisArtifactTarget } from '../types/analysisArtifactTypes' const EXPERIMENT_ID = 'experiment_id' const ARTIFACT_PLUGIN_ID = 'artifact_plugin_id' const ARTIFACT_KEY = 'artifact_key' const ARTIFACT_ID = 'artifact_id' function parsePositiveInteger(value: string | null): number | undefined { if (value === null || !/^\d+$/.test(value)) return undefined const parsed = Number(value) return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined } /** Build the canonical query used to open one analysis artifact in a plugin. */ export function buildAnalysisArtifactTargetQuery( target: AnalysisArtifactTarget, ): URLSearchParams { const query = new URLSearchParams() query.set(EXPERIMENT_ID, String(target.experimentId)) query.set(ARTIFACT_PLUGIN_ID, target.artifactPluginId) query.set(ARTIFACT_KEY, target.artifactKey) if (target.artifactId !== undefined) { query.set(ARTIFACT_ID, String(target.artifactId)) } return query } /** Parse a complete canonical target. Incomplete or invalid input is not guessed. */ export function parseAnalysisArtifactTarget( query: URLSearchParams, ): AnalysisArtifactTarget | null { const experimentId = parsePositiveInteger(query.get(EXPERIMENT_ID)) const artifactPluginId = query.get(ARTIFACT_PLUGIN_ID)?.trim() const artifactKey = query.get(ARTIFACT_KEY)?.trim() const rawArtifactId = query.get(ARTIFACT_ID) const artifactId = parsePositiveInteger(rawArtifactId) if ( experimentId === undefined || !artifactPluginId || !artifactKey || (rawArtifactId !== null && artifactId === undefined) ) { return null } return { experimentId, artifactPluginId, artifactKey, ...(artifactId === undefined ? {} : { artifactId }), } }