diff --git a/extension/lib/platforms.js b/extension/lib/platforms.js new file mode 100644 index 0000000..9092c80 --- /dev/null +++ b/extension/lib/platforms.js @@ -0,0 +1,85 @@ +/** + * Platform definitions — mirrored from backend/app/services/platforms.py. + * Two copies of these regexes (here and in backend extension_service.py) + * is cheaper than building a shared definition file for two short + * tables in different runtimes. Keep in sync by hand; reviewers catch + * drift. + */ + +const PLATFORMS = { + patreon: { + name: 'Patreon', + domains: ['.patreon.com', 'www.patreon.com', 'patreon.com'], + authType: 'cookies', + color: '#FF424D', + urlPattern: /^https?:\/\/(www\.)?patreon\.com/, + }, + subscribestar: { + name: 'SubscribeStar', + domains: [ + '.subscribestar.com', + '.subscribestar.adult', + 'www.subscribestar.com', + 'subscribestar.com', + 'subscribestar.adult', + ], + authType: 'cookies', + color: '#FFD700', + urlPattern: /^https?:\/\/(www\.)?subscribestar\.(com|adult)/, + }, + hentaifoundry: { + name: 'Hentai Foundry', + domains: ['.hentai-foundry.com', 'www.hentai-foundry.com', 'hentai-foundry.com'], + authType: 'cookies', + color: '#9C27B0', + urlPattern: /^https?:\/\/(www\.)?hentai-foundry\.com/, + }, + discord: { + name: 'Discord', + domains: ['.discord.com', 'discord.com'], + authType: 'token', + color: '#5865F2', + urlPattern: /^https?:\/\/(www\.)?discord\.com/, + note: 'Open Discord in browser to capture token', + }, + pixiv: { + name: 'Pixiv', + domains: ['.pixiv.net', 'www.pixiv.net', 'pixiv.net'], + authType: 'token', + color: '#0096FA', + urlPattern: /^https?:\/\/(www\.)?pixiv\.net/, + note: 'Click to authenticate via OAuth', + }, + deviantart: { + name: 'DeviantArt', + domains: ['.deviantart.com', 'www.deviantart.com', 'deviantart.com'], + authType: 'cookies', + color: '#05CC47', + urlPattern: /^https?:\/\/(www\.)?deviantart\.com/, + }, +}; + +/** + * Per-platform artist-page URL patterns — these are STRICTER than + * urlPattern (which matches any URL on the domain). Used by the content + * script to decide whether to show the floating "Add as source" button. + */ +const PLATFORM_ARTIST_PATTERNS = { + patreon: /^https?:\/\/(www\.)?patreon\.com\/(?!home$|search\b|messages\b|notifications\b|library\b|settings\b|posts\b|c\/)[^/?#]+\/?$/i, + subscribestar: /^https?:\/\/(www\.)?subscribestar\.(com|adult)\/(?!feed$|messages$|library$)[^/?#]+\/?$/i, + hentaifoundry: /^https?:\/\/(www\.)?hentai-foundry\.com\/user\/[^/?#]+/i, + deviantart: /^https?:\/\/(www\.)?deviantart\.com\/(?!home$|watch\b|tag\b|browse\b)[^/?#]+\/?$/i, + pixiv: /^https?:\/\/(www\.)?pixiv\.net\/(en\/)?users\/\d+/i, +}; + +function getPlatformFromUrl(url) { + for (const [key, platform] of Object.entries(PLATFORMS)) { + if (platform.urlPattern.test(url)) return key; + } + return null; +} + +function isArtistPage(url, platformKey) { + const pattern = PLATFORM_ARTIST_PATTERNS[platformKey]; + return pattern ? pattern.test(url) : false; +}