/** * RFC 6266 / RFC 5987 disposition. Branch, tag and upload names may contain `"`, `;` and non-ASCII, * so the quoted `filename` only carries a sanitized ASCII fallback and the real name goes in `filename*`. */ export function contentDisposition(type: "inline" | "attachment", filename: string): string { const ascii = filename.replace(/[^\x20-\x7e]/g, "_").replace(/["\\;]/g, "_"); const encoded = encodeURIComponent(filename).replace( /[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`, ); return `${type}; filename="${ascii}"; filename*=UTF-8''${encoded}`; } export function attachmentDisposition(filename: string): string { return contentDisposition("attachment", filename); }