Merge branch 'acct-parse-url' into lookup-api

This commit is contained in:
tamaina 2025-08-29 16:18:01 +09:00
commit c6499a95d1
2 changed files with 24 additions and 2 deletions

View File

@ -29,8 +29,13 @@ export function parse(acct: string): Acct {
export function parseUrl(str: string): Acct {
const url = new URL(str);
const path = url.pathname.split('/').find((p) => p.startsWith('@') && p.length >= 2);
const splited = url.pathname.split('/');
let path = splited.pop();
if (path === '') path = splited.pop(); // If the last segment is empty due to a trailing '/', use the previous segment
if (!path) throw new Error('This url is not acct like.');
if (!path.startsWith('@')) throw new Error('This url is not acct like.');
if (path.length <= 1) throw new Error('This url is not acct like.');
const split = path.split('@', 3); // ['', 'username', 'other.example.com']

View File

@ -39,9 +39,26 @@ function testParseUrl(fn: (acct: string) => acct.Acct) {
expect(res).toEqual({ username: 'alice', host: 'other.example.com' });
});
it('throws on non-acct-like url path', () => {
it('throws on non-acct-like url path (root)', () => {
expect(() => fn('https://example.com')).toThrowError();
});
it('throws on non-acct-like url path (users/alice)', () => {
expect(() => fn('https://example.com/users/alice')).toThrowError();
});
it('throws ended with @', () => {
expect(() => fn('https://example.com/@')).toThrowError();
});
it('parses url ended with /', () => {
const res = fn('https://example.com/@alice/');
expect(res).toEqual({ username: 'alice', host: 'example.com' });
});
it('throws url have @username path but ended with sub directory', () => {
expect(() => fn('https://example.com/@alice/subdir')).toThrowError();
});
}
describe('acct.parse', () => {