refactor(tts): derive save filename from URL path only

This commit is contained in:
2026-08-10 09:12:34 +08:00
parent 82caa9bb9c
commit 45bf362fbc
5 changed files with 16 additions and 35 deletions
+3 -17
View File
@@ -43,26 +43,12 @@ describe('fetchModFileFromUrl', () => {
});
describe('getFileName', () => {
it('parses a quoted content-disposition filename', () => {
expect(
getFileName('https://example.com/save', 'attachment; filename="mod.json"'),
).toBe('mod.json');
});
it('parses an unquoted filename', () => {
expect(
getFileName('https://example.com/save', 'attachment; filename=mod.json'),
).toBe('mod.json');
});
it('falls back to the URL path when there is no disposition', () => {
expect(getFileName('https://example.com/files/mod.json', null)).toBe(
'mod.json',
);
it('derives the filename from the URL path', () => {
expect(getFileName('https://example.com/files/mod.json')).toBe('mod.json');
});
it('falls back to a default when the URL has no path', () => {
expect(getFileName('https://example.com', null)).toBe('save.json');
expect(getFileName('https://example.com')).toBe('save.json');
});
});
+6 -11
View File
@@ -47,17 +47,12 @@ export async function fetchModFromUrl(fileUrl: string): Promise<TTSMod> {
}
/**
* Derive a filename from a `content-disposition` header.
* Parses `filename="..."`; falls back to the URL path, then a default.
* Derive a filename for a downloaded save from its URL path, falling back to
* a default when the URL has no path segment. The upstream `content-disposition`
* header is intentionally ignored: Steam save URLs are extension-less and
* rarely carry a useful filename, so the URL path is the reliable source.
*/
export function getFileName(url: string, disposition: string | null): string {
if (disposition) {
const match = disposition.match(/filename\*?=(?:"([^"]*)"|([^;\s]*))/i);
const name = match?.[1] ?? match?.[2];
if (name) {
return name;
}
}
export function getFileName(url: string): string {
return new URL(url).pathname.split('/').pop() || 'save.json';
}
@@ -81,7 +76,7 @@ export async function fetchModFileFromUrl(
fileUrl: string,
): Promise<{ data: ArrayBuffer; filename: string }> {
const data = await downloadSave(fileUrl);
const filename = getFileName(fileUrl, null);
const filename = getFileName(fileUrl);
return { data, filename };
}