export interface LaunchTemplateExportRequest { server_url: string; build_id?: string; strain_card_id?: string; campaign?: string; ami_id?: string; instance_type?: string; region?: string; } export interface LaunchTemplateExportResponse { success: boolean; genesis_snapshot_hash: string; strain_card_id: string; launch_template_json: string; user_data_sh: string; asg_example_json: string; error?: string; } export const LAUNCH_TEMPLATE_FILES = [ { id: 'launch-template', label: 'launch-template.json', field: 'launch_template_json' as const }, { id: 'user-data', label: 'user-data.sh', field: 'user_data_sh' as const }, { id: 'asg-example', label: 'asg-example.json', field: 'asg_example_json' as const }, ] as const; export function launchTemplateZipName(campaign?: string): string { const slug = (campaign ?? '').trim().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, ''); return slug ? `aetherforge-launch-template-${slug}.zip` : 'aetherforge-launch-template-genesis.zip'; } export function downloadLaunchTemplateFile( resp: LaunchTemplateExportResponse, file: (typeof LAUNCH_TEMPLATE_FILES)[number]['field'], filename: string, ): void { const content = resp[file]; if (!content) return; const blob = new Blob([content], { type: file === 'user_data_sh' ? 'text/x-shellscript' : 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); }