aboutsummaryrefslogtreecommitdiff
path: root/front-end/src/store/websiteLookup.ts
blob: 560d00f3c581493bc57e17a418bd3e0d1b86f76c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

import 'pinia'
import { MaybeRef, Ref, shallowRef, watch } from 'vue';
import { WebMessage, apiCall, useAxios } from '@vnuge/vnlib.browser'
import { get, set } from '@vueuse/core';
import { PiniaPluginContext, PiniaPlugin, storeToRefs } from 'pinia'
import { defer, filter, isEmpty, noop } from 'lodash-es';

export interface WebsiteLookupResult {
    readonly title: string | undefined,
    readonly description: string | undefined,
    keywords: string[] | undefined,
}

export interface LookupApi{
    isSupported: Ref<boolean>,
    timeout: Ref<number>,
    execLookup(url:string): Promise<WebsiteLookupResult>
}

declare module 'pinia' {
    export interface PiniaCustomProperties {
       websiteLookup:{
            isSupported: boolean,
           execLookup(url: string): Promise<WebsiteLookupResult>
       }
    }
}

const urlToBase64UrlEncoded = (url: string) => {
    return btoa(url)
        .replace(/-/g, '+')
        .replace(/_/g, '/')
        .replace(/\./g, '=') //Fix padding
}

export const siteLookupPlugin = (lookupEndpoint: MaybeRef<string>, to: number): PiniaPlugin => {

    return ({ store }: PiniaPluginContext) => {

        const { loggedIn } = storeToRefs(store)
        const axios = useAxios(null)

        const isSupported = shallowRef(false)
        const timeout = shallowRef(to)
     
        const checkIsSupported = () => {
            return apiCall(async () => {
                //Execute test with the 'support' query parameter
                const { data } = await axios.get<WebMessage>(`${get(lookupEndpoint)}?support`)
                set(isSupported, data.success)
            });
        }

        const execLookup = async (url:string) => {
            const base64Url = urlToBase64UrlEncoded(url)

            //Execute test with the 'support' query parameter
            const { data } = await axios.get<WebMessage<WebsiteLookupResult>>(`${get(lookupEndpoint)}?timeout=${get(timeout)}&url=${base64Url}`)
            const lookup = data.getResultOrThrow();
            lookup.keywords = filter(lookup.keywords, (k) => !isEmpty(k))
            return lookup
        }

        //If login status changes, recheck support
        watch([loggedIn], ([li]) => li ? defer(checkIsSupported) : noop(), { immediate: true })

        return {
            websiteLookup: {
                isSupported,
                execLookup,
                timeout
            } as LookupApi
        } as any
    }
}