Skip to content

Commit 9fe956a

Browse files
Added support for more mastodon handles (#511)
ref https://linear.app/ghost/issue/PLG-414/mastodon-validation-bug - Enhanced mastodon function in social-urls/lib/index.js to support: - `@username@instance` format - `instance/@username` format - `hostInstance/@username@userInstance` format - Simple `instance/username` format - Removed leading @ symbols from usernames - Added test cases in urls.test.js to verify new Mastodon handle formats
1 parent 19592ba commit 9fe956a

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

packages/social-urls/lib/index.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,33 @@ module.exports.bluesky = function bluesky(username) {
4040
* @returns {string}
4141
*/
4242
module.exports.mastodon = function mastodon(username) {
43-
// Mastodon stores full URL without https://, just prepend protocol
44-
return 'https://' + username;
43+
// Remove any leading @ symbols from the username
44+
username = username.replace(/^@+/, '');
45+
46+
// Check if the input is in @username@instance format
47+
if (username.includes('@') && !username.includes('/')) {
48+
const [user, instance] = username.split('@');
49+
return `https://${instance}/@${user}`;
50+
}
51+
52+
// Check if the input is in instance/@username format
53+
if (username.includes('/@')) {
54+
return `https://${username}`;
55+
}
56+
57+
// Check if the input is in hostInstance/@username@userInstance format
58+
if (username.includes('/@') && username.includes('@', username.indexOf('/@') + 1)) {
59+
return `https://${username}`;
60+
}
61+
62+
// If we have a simple instance/username format
63+
if (username.includes('/')) {
64+
const [instance, user] = username.split('/');
65+
return `https://${instance}/@${user}`;
66+
}
67+
68+
// Default case: assume it's a local handle on the instance
69+
return `https://${username}`;
4570
};
4671

4772
/**

packages/social-urls/test/urls.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,31 @@ describe('lib/social: urls', function () {
9999
it('should handle subdomains in instance URLs', function () {
100100
social.mastodon('eu.mastodon.green/@eco').should.eql('https://eu.mastodon.green/@eco');
101101
});
102+
103+
// New test cases for different URL formats
104+
it('should handle @username@instance format', function () {
105+
social.mastodon('@[email protected]').should.eql('https://indieweb.social/@example');
106+
});
107+
108+
it('should handle instance/@username format', function () {
109+
social.mastodon('mastodon.social/@example').should.eql('https://mastodon.social/@example');
110+
});
111+
112+
it('should handle hostInstance/@username@userInstance format', function () {
113+
social.mastodon('mastodon.xyz/@[email protected]').should.eql('https://mastodon.xyz/@[email protected]');
114+
});
115+
116+
it('should handle same instance format with @username@instance', function () {
117+
social.mastodon('@[email protected]').should.eql('https://mastodon.social/@user');
118+
});
119+
120+
it('should handle same instance format with instance/@username', function () {
121+
social.mastodon('mastodon.social/@user').should.eql('https://mastodon.social/@user');
122+
});
123+
124+
it('should handle different instances format', function () {
125+
social.mastodon('mastodon.social/@[email protected]').should.eql('https://mastodon.social/@[email protected]');
126+
});
102127
});
103128

104129
describe('tiktok', function () {

0 commit comments

Comments
 (0)