diff --git a/src/extractor/VixSrc.test.ts b/src/extractor/VixSrc.test.ts index f170da1..ccfc32f 100644 --- a/src/extractor/VixSrc.test.ts +++ b/src/extractor/VixSrc.test.ts @@ -8,7 +8,7 @@ import { createTestContext } from '../test'; const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] }); const extractorRegistry = new ExtractorRegistry(logger, [new VixSrc(new FetcherMock(`${__dirname}/__fixtures__/VixSrc`))]); -const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow-proxy.test', mediaFlowProxyPassword: 'asdfg' }); +const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow-proxy.test', mediaFlowProxyPassword: 'asdfg', de: 'on', en: 'on', it: 'on' }); describe('VixSrc', () => { test('Full Metal Jacket', async () => { diff --git a/src/extractor/VixSrc.ts b/src/extractor/VixSrc.ts index 027e749..696d85e 100644 --- a/src/extractor/VixSrc.ts +++ b/src/extractor/VixSrc.ts @@ -1,6 +1,12 @@ import bytes from 'bytes'; import { Extractor } from './Extractor'; -import { Fetcher, buildMediaFlowProxyExtractorStreamUrl, supportsMediaFlowProxy } from '../utils'; +import { + buildMediaFlowProxyExtractorStreamUrl, + Fetcher, + getCountryCodes, + iso639FromCountryCode, + supportsMediaFlowProxy, +} from '../utils'; import { Context, CountryCode, Format, UrlResult } from '../types'; export class VixSrc extends Extractor { @@ -29,15 +35,18 @@ export class VixSrc extends Extractor { const sizeMatch = html.match(/"size":(\d+)/); const qualityMatch = html.match(/"quality":(\d+)/); + const playlistUrl = await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'VixCloud', url); + const countryCodes = await this.determineCountryCodesFromPlaylist(ctx, playlistUrl); + return [ { - url: await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'VixCloud', url), + url: playlistUrl, format: Format.hls, label: this.label, sourceId: `${this.id}_${countryCode}`, ttl: this.ttl, meta: { - countryCodes: [countryCode], + countryCodes, ...(filenameMatch && { title: filenameMatch[1] }), ...(sizeMatch && { bytes: bytes.parse(`${sizeMatch[1]} kb`) as number }), ...(qualityMatch && { height: parseInt(qualityMatch[1] as string) }), @@ -45,4 +54,20 @@ export class VixSrc extends Extractor { }, ]; }; + + private async determineCountryCodesFromPlaylist(ctx: Context, playlistUrl: URL): Promise { + const playlist = await this.fetcher.text(ctx, playlistUrl); + + const countryCodes: CountryCode[] = [CountryCode.it]; + + getCountryCodes(ctx.config).forEach((countryCode) => { + const iso639 = iso639FromCountryCode(countryCode); + + if (!countryCodes.includes(countryCode) && (new RegExp(`#EXT-X-MEDIA:TYPE=AUDIO.*LANGUAGE="${iso639}"`)).test(playlist)) { + countryCodes.push(countryCode); + } + }); + + return countryCodes; + } } diff --git a/src/extractor/__fixtures__/VixSrc/https:mediaflow-proxy.test-cb6d823acd1376f3e6f8fea1ce447e7e b/src/extractor/__fixtures__/VixSrc/https:mediaflow-proxy.test-cb6d823acd1376f3e6f8fea1ce447e7e new file mode 100644 index 0000000..7de051a --- /dev/null +++ b/src/extractor/__fixtures__/VixSrc/https:mediaflow-proxy.test-cb6d823acd1376f3e6f8fea1ce447e7e @@ -0,0 +1,11 @@ +#EXTM3U +#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="Italian",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="ita",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Fmovie%2F600&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F219736%3Ftype%3Daudio%26rendition%3Dita%26token%3Dgi4-3epkYBCfogktY8L9Tw%26expires%3D1756061649%26edge%3Dsc-u13-01" +#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="English",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="eng",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Fmovie%2F600&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F219736%3Ftype%3Daudio%26rendition%3Deng%26token%3Dgi4-3epkYBCfogktY8L9Tw%26expires%3D1756061649%26edge%3Dsc-u13-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Italian",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="ita",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Fmovie%2F600&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F219736%3Ftype%3Dsubtitle%26rendition%3D3-ita%26token%3Dgi4-3epkYBCfogktY8L9Tw%26expires%3D1756061649%26edge%3Dsc-u13-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="eng",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Fmovie%2F600&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F219736%3Ftype%3Dsubtitle%26rendition%3D4-eng%26token%3Dgi4-3epkYBCfogktY8L9Tw%26expires%3D1756061649%26edge%3Dsc-u13-01" +#EXT-X-STREAM-INF:BANDWIDTH=1200000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=854x480,AUDIO="audio",SUBTITLES="subs" +https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Fmovie%2F600&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F219736%3Ftype%3Dvideo%26rendition%3D480p%26token%3D7v6ck17PxObPaqCCgb3UfQ%26expires%3D1756061649%26edge%3Dsc-u13-01 +#EXT-X-STREAM-INF:BANDWIDTH=2150000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1280x720,AUDIO="audio",SUBTITLES="subs" +https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Fmovie%2F600&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F219736%3Ftype%3Dvideo%26rendition%3D720p%26token%3Da9W71KeqCbV67VX1xceReQ%26expires%3D1756061649%26edge%3Dsc-u13-01 +#EXT-X-STREAM-INF:BANDWIDTH=4500000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="audio",SUBTITLES="subs" +https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Fmovie%2F600&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F219736%3Ftype%3Dvideo%26rendition%3D1080p%26token%3DOOVfUQ_3veZMjPBb3FPkxg%26expires%3D1756061649%26edge%3Dsc-u13-01 diff --git a/src/extractor/__fixtures__/VixSrc/https:mediaflow-proxy.test-da9e1c658d0c7c544a31018ec7cdcb02 b/src/extractor/__fixtures__/VixSrc/https:mediaflow-proxy.test-da9e1c658d0c7c544a31018ec7cdcb02 new file mode 100644 index 0000000..96d6d7a --- /dev/null +++ b/src/extractor/__fixtures__/VixSrc/https:mediaflow-proxy.test-da9e1c658d0c7c544a31018ec7cdcb02 @@ -0,0 +1,17 @@ +#EXTM3U +#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="Italian",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="ita",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Daudio%26rendition%3Dita%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="English",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="eng",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Daudio%26rendition%3Deng%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English [CC]",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="eng",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D3-eng%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="German",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="ger",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D4-ger%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="French [CC]",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="fre",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D5-fre%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="French",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="fre",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D6-fre%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Italian [Forced]",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="forced-ita",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D7-forced-ita%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Italian",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="ita",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D8-ita%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Japanese",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="jpn",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D9-jpn%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Ukrainian",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE="ukr",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dsubtitle%26rendition%3D10-ukr%26token%3D9Xuf0k_DgmDiASPFeByoWg%26expires%3D1756061649%26edge%3Dsc-u2-01" +#EXT-X-STREAM-INF:BANDWIDTH=1200000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=854x480,AUDIO="audio",SUBTITLES="subs" +https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dvideo%26rendition%3D480p%26token%3DgsQVLhHScXTJAxmwkTD2tQ%26expires%3D1756061649%26edge%3Dsc-u2-01 +#EXT-X-STREAM-INF:BANDWIDTH=2150000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1280x720,AUDIO="audio",SUBTITLES="subs" +https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dvideo%26rendition%3D720p%26token%3Dxqxvb6W5pFM0RE_zkKgMAA%26expires%3D1756061649%26edge%3Dsc-u2-01 +#EXT-X-STREAM-INF:BANDWIDTH=4500000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="audio",SUBTITLES="subs" +https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fvixsrc.to%2Ftv%2F42009%2F4%2F2&d=https%3A%2F%2Fvixsrc.to%2Fplaylist%2F307316%3Ftype%3Dvideo%26rendition%3D1080p%26token%3Dg7Q1oAxS7C07i_q_8_chaA%26expires%3D1756061649%26edge%3Dsc-u2-01 diff --git a/src/extractor/__snapshots__/VixSrc.test.ts.snap b/src/extractor/__snapshots__/VixSrc.test.ts.snap index e9f1b37..b86c314 100644 --- a/src/extractor/__snapshots__/VixSrc.test.ts.snap +++ b/src/extractor/__snapshots__/VixSrc.test.ts.snap @@ -9,6 +9,7 @@ exports[`VixSrc Black Mirror 1`] = ` "bytes": 2389338112, "countryCodes": [ "it", + "en", ], "height": 1080, "title": "Black.Mirror.S04E02.Arkangel.1080p.NF.WEB-DL.ITA.ENG.DDP5.1.H.264.mkv", @@ -29,6 +30,7 @@ exports[`VixSrc Full Metal Jacket 1`] = ` "bytes": 8544718848, "countryCodes": [ "it", + "en", ], "height": 1080, "title": "Full.metal.jacket.1987.1080p.x264.AC3.ITA.AAC.ENG.Subs.mkv", diff --git a/src/types.ts b/src/types.ts index 8f31347..09a392f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,11 +27,9 @@ export enum BlockedReason { unknown = 'unknown', } -type NonEmptyArray = [T, ...T[]]; - export interface Meta { bytes?: number; - countryCodes: NonEmptyArray; + countryCodes: CountryCode[]; height?: number; title?: string; } diff --git a/src/utils/config.test.ts b/src/utils/config.test.ts index e894e9a..c15cb41 100644 --- a/src/utils/config.test.ts +++ b/src/utils/config.test.ts @@ -1,7 +1,13 @@ -import { getDefaultConfig } from './config'; +import { getCountryCodes, getDefaultConfig } from './config'; describe('getDefaultConfig', () => { test('has English enabled', () => { expect(getDefaultConfig().en).toBe('on'); }); }); + +describe('getCountryCodes', () => { + test('returns only all country codes', () => { + expect(getCountryCodes({ de: 'on', en: 'on', includeExternalUrls: 'on' })).toStrictEqual(['de', 'en']); + }); +}); diff --git a/src/utils/config.ts b/src/utils/config.ts index 0181cbe..55c6688 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -1,7 +1,23 @@ -import { Config } from '../types'; +import { Config, CountryCode } from '../types'; export const getDefaultConfig = (): Config => { return { en: 'on' }; }; +const isCountryCode = (key: string): key is CountryCode => { + return Object.values(CountryCode).includes(key as CountryCode); +}; + +export const getCountryCodes = (config: Config): CountryCode[] => { + const countryCodes: CountryCode[] = []; + + for (const key in config) { + if (isCountryCode(key)) { + countryCodes.push(key); + } + } + + return countryCodes; +}; + export const showExternalUrls = (config: Config): boolean => 'includeExternalUrls' in config; diff --git a/src/utils/language.ts b/src/utils/language.ts index 528ea90..b46610c 100644 --- a/src/utils/language.ts +++ b/src/utils/language.ts @@ -1,12 +1,12 @@ import { CountryCode } from '../types'; -const countryCodeMap: Record = { - de: { language: 'German', flag: '🇩🇪' }, - en: { language: 'English', flag: '🇺🇸' }, - es: { language: 'Castilian Spanish', flag: '🇪🇸' }, - fr: { language: 'French', flag: '🇫🇷' }, - it: { language: 'Italian', flag: '🇮🇹' }, - mx: { language: 'Latin American Spanish', flag: '🇲🇽' }, +const countryCodeMap: Record = { + de: { language: 'German', flag: '🇩🇪', iso639: 'ger' }, + en: { language: 'English', flag: '🇺🇸', iso639: 'eng' }, + es: { language: 'Castilian Spanish', flag: '🇪🇸', iso639: 'spa' }, + fr: { language: 'French', flag: '🇫🇷', iso639: 'fra' }, + it: { language: 'Italian', flag: '🇮🇹', iso639: 'ita' }, + mx: { language: 'Latin American Spanish', flag: '🇲🇽', iso639: 'spa' }, }; export const languageFromCountryCode = (countryCode: CountryCode) => { @@ -16,3 +16,7 @@ export const languageFromCountryCode = (countryCode: CountryCode) => { export const flagFromCountryCode = (countryCode: CountryCode) => { return countryCodeMap[countryCode].flag; }; + +export const iso639FromCountryCode = (countryCode: CountryCode) => { + return countryCodeMap[countryCode].iso639; +};