• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kiva / ui / 14911871966

08 May 2025 04:57PM UTC coverage: 49.059% (+0.09%) from 48.969%
14911871966

push

github

emuvente
fix: provide current route ref value from server entry and remove contentful cookie

1595 of 3417 branches covered (46.68%)

Branch coverage included in aggregate %.

0 of 11 new or added lines in 5 files covered. (0.0%)

3 existing lines in 2 files now uncovered.

2393 of 4712 relevant lines covered (50.79%)

286.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/client-entry.js
1
/* global UI_TAG */
2
/* eslint-disable no-underscore-dangle, vue/require-name-property */
3
import '#src/assets/scss/tailwind/tailwind.css';
4
import '#src/assets/scss/app.scss';
5

6
// Facilitate using sprite icon SVGs in KvIcon
7
// eslint-disable-next-line import/no-unresolved
8
import 'virtual:svg-store';
9

10
const config = window.__KV_CONFIG__ || {};
×
11

12
// Set webpack public asset path based on configuration
13
// __webpack_public_path__ = config.publicPath || '/'; // eslint-disable-line
14

15
async function getCookieStore() {
16
        const { default: CookieStore } = await import('#src/util/cookieStore');
×
17
        return new CookieStore();
×
18
}
19

20
async function getKvAuth0(cookieStore) {
21
        const { default: KvAuth0, MockKvAuth0 } = await import('#src/util/KvAuth0');
×
22
        if (config.auth0.enable) {
×
23
                return new KvAuth0({
×
24
                        audience: config.auth0.apiAudience,
25
                        checkFakeAuth: config.auth0.checkFakeAuth,
26
                        clientID: config.auth0.browserClientID,
27
                        cookieStore,
28
                        domain: config.auth0.domain,
29
                        mfaAudience: config.auth0.mfaAudience,
30
                        redirectUri: config.auth0.browserCallbackUri,
31
                        scope: config.auth0.scope,
32
                });
33
        }
34
        return MockKvAuth0;
×
35
}
36

37
async function getDevice() {
38
        const { userAgent } = window.navigator;
×
39
        if (!userAgent) {
×
40
                return null;
×
41
        }
42
        const { default: Bowser } = await import('bowser');
×
43
        return Bowser.getParser(userAgent).parse().parsedResult;
×
44
}
45

46
async function getLocale() {
47
        const { getUserLocale } = await import('get-user-locale');
×
48
        return getUserLocale();
×
49
}
50

51
async function getFetch() {
52
        const { fetch } = await import('whatwg-fetch');
×
53
        return fetch;
×
54
}
55

56
async function getUserId(apolloClient) {
57
        const { default: userIdQuery } = await import('#src/graphql/query/userId.graphql');
×
58
        const result = await apolloClient.query({ query: userIdQuery });
×
59
        return result?.data?.my?.userAccount?.id ?? null;
×
60
}
61

62
async function setupApolloCachePersistence(cache) {
63
        const { persistCache, SessionStorageWrapper } = await import('apollo3-cache-persist');
×
64
        await persistCache({
×
65
                cache,
66
                storage: new SessionStorageWrapper(window.sessionStorage),
67
        });
68
}
69

70
async function setupAuthErrorHandling(kvAuth0, apolloClient) {
71
        const { default: showTipMessage } = await import('#src/graphql/mutation/tipMessage/showTipMessage.graphql');
×
72
        // Show a tip message when there is an unhandled auth0 error
73
        kvAuth0.onError(({ eventId, user }) => {
×
74
                let message = 'We\'re sorry, something went wrong.';
×
75
                if (user) {
×
76
                        message = `${message} Please log out and try again.`;
×
77
                } else {
78
                        message = `${message} Please clear your cookies and try again.`;
×
79
                }
80
                if (eventId) {
×
81
                        message = `${message} (event id: ${eventId})`;
×
82
                }
83
                apolloClient.mutate({
×
84
                        mutation: showTipMessage,
85
                        variables: {
86
                                message,
87
                                type: 'error',
88
                                persist: true,
89
                        },
90
                });
91
        });
92
}
93

94
async function setupTouchDetection(apolloClient) {
95
        const { default: usingTouchMutation } = await import('#src/graphql/mutation/updateUsingTouch.graphql');
×
96
        // Setup adding touch info to the state
97
        window.addEventListener('touchstart', function onFirstTouch() {
×
98
                apolloClient.mutate({
×
99
                        mutation: usingTouchMutation,
100
                        variables: { usingTouch: true }
101
                });
102
                window.removeEventListener('touchstart', onFirstTouch);
×
103
        });
104
}
105

106
async function setupAnalytics(app, apolloClient) {
107
        const userId = await getUserId(apolloClient);
×
108
        await app.config.globalProperties.$setKvAnalyticsData(userId);
×
109
        app.config.globalProperties.$fireServerPageView();
×
110
        app.config.globalProperties.$fireQueuedEvents();
×
111
        const { default: collectWebVitals } = await import('#src/util/webVitals');
×
112
        collectWebVitals(app.config.globalProperties.$kvTrackEvent);
×
113
}
114

115
async function setupSentry(app, router) {
116
        const Sentry = await import('@sentry/vue');
×
117
        Sentry.init({
×
118
                app,
119
                dsn: config.sentryURI,
120
                integrations: [
121
                        Sentry.browserTracingIntegration({
122
                                router,
123
                        }),
124
                        Sentry.vueIntegration({
125
                                tracingOptions: {
126
                                        trackComponents: true,
127
                                },
128
                        }),
129
                ],
130
                release: UI_TAG,
131
                // Set tracesSampleRate to 1.0 to capture 100%
132
                // of transactions for performance monitoring.
133
                // We recommend adjusting this value in production
134
                tracesSampleRate: config?.sentryTraceSampleRate,
135
                tracePropagationTargets: [config.host],
136
                beforeSend(event) {
137
                        // make sentry colleted event easy to compare to
138
                        const eventAsString = JSON.stringify(event);
×
139
                        // match specific 3rd party events for exclusion
140
                        // Skip sending failed to fetch error caused by unhandled promise rejection in google ads
141
                        // Sentry Event Link: https://kiva.sentry.io/issues/4413252219/events/726c65f507684f43b748e913d4793518/
142
                        // This url is unreachable: https://pagead2.googlesyndication.com/pagead/buyside_topics/set/
143
                        if (eventAsString.indexOf('Failed to fetch') !== -1
×
144
                                && eventAsString.indexOf('pagead') !== -1) {
145
                                return false;
×
146
                        }
147
                        // Skip Load failed caused by failed fetch calls in 3rd party libraries
148
                        // NOTE: we do see failed loads for our own async modules, this doesn't filter those out
149
                        // Sentry Event Link: https://kiva.sentry.io/issues/3808313433/events/427b92cf47ed4aaeb321caf20783eba0/
150
                        if ((eventAsString.indexOf('Load failed') !== -1
×
151
                                || eventAsString.indexOf('Failed to fetch') !== -1
152
                                || eventAsString.indexOf('TypeError') !== -1)
153
                                && (
154
                                        (eventAsString.indexOf('ct.pinterest') !== -1)
155
                                        || (eventAsString.indexOf('rum.management') !== -1)
156
                                )
157
                        ) {
158
                                return false;
×
159
                        }
160
                        // Skip sending errors from CefSharp
161
                        // https://forum.sentry.io/t/unhandledrejection-non-error-promise-rejection-captured-with-value/14062/20
162
                        if (eventAsString.indexOf('Object Not Found Matching Id') !== -1) {
×
163
                                return false;
×
164
                        }
165
                        // return event otherwise
166
                        return event;
×
167
                },
168
        });
169
}
170

171
function setupClientRouting({
172
        app, apolloClient, cookieStore, kvAuth0, router
173
}) {
174
        // Add router hook for handling asyncData.
175
        // Doing it after initial route is resolved so that we don't double-fetch
176
        // the data that we already have. Using router.beforeResolve() so that all
177
        // async components are resolved.
178
        router.beforeResolve(async (to, from, next) => {
×
NEW
179
                const [{ authenticationGuard }, { preFetchAll }] = await Promise.all([
×
180
                        import('#src/util/authenticationGuard'),
181
                        import('#src/util/apolloPreFetch'),
182
                ]);
183

184
                const { matched } = to;
×
185
                const prevMatched = from.matched;
×
186
                const activated = matched.filter((c, i) => prevMatched[i] !== c);
×
187

188
                try {
×
189
                        await authenticationGuard({ route: to, apolloClient, kvAuth0 });
×
190
                        // Pre-fetch graphql queries from activated components
191
                        await preFetchAll(activated, apolloClient, {
×
192
                                cookieStore,
193
                                kvAuth0,
194
                                route: to,
195
                        });
196
                        next();
×
197
                } catch (error) {
198
                        // pass error through next to ensure redirect to login
199
                        next(error);
×
200
                }
201
        });
202

203
        router.beforeEach((to, from, next) => {
×
204
                app.config.globalProperties.$Progress.start(6500);
×
205
                next();
×
206
        });
207

208
        router.afterEach((to, from) => {
×
209
                // finish loading
210
                app.config.globalProperties.$Progress.finish();
×
211

212
                if (to?.query?.noAnalytics?.toLowerCase() !== 'true') {
×
213
                        // fire pageview
214
                        app.config.globalProperties.$fireAsyncPageView(to, from);
×
215
                }
216
        });
217

218
        router.onError(() => app.config.globalProperties.$Progress.fail());
×
219
}
220

221
async function initApp() {
222
        const [{ default: createApp }, cookieStore, device, locale, fetch] = await Promise.all([
×
223
                import('#src/main'),
224
                getCookieStore(),
225
                getDevice(),
226
                getLocale(),
227
                getFetch(),
228
        ]);
229
        const kvAuth0 = await getKvAuth0(cookieStore);
×
230

231
        // Create the App instance
232
        const {
233
                app,
234
                router,
235
                apolloClient,
236
        } = createApp({
×
237
                appConfig: config,
238
                apollo: {
239
                        uri: config.graphqlUri,
240
                        types: config.graphqlPossibleTypes,
241
                },
242
                cookieStore,
243
                device,
244
                kvAuth0,
245
                locale,
246
                fetch,
247
        });
248

249
        // Apply Server state to Client Store
250
        if (window.__APOLLO_STATE__) {
×
251
                apolloClient.cache.restore(window.__APOLLO_STATE__);
×
252
        }
253
        // Apply persisted state from session storage to Client Store
254
        if (config.apolloPersistCache) {
×
255
                setupApolloCachePersistence(apolloClient.cache);
×
256
        }
257

258
        setupAuthErrorHandling(kvAuth0, apolloClient);
×
259
        setupTouchDetection(apolloClient);
×
260

261
        if (config.enableSentry) {
×
262
                setupSentry(app, router);
×
263
        }
264

265
        if (config.enableAnalytics) {
×
266
                setupAnalytics(app, apolloClient);
×
267
        }
268

269
        // Wait until router has resolved all async before hooks and async components
270
        await router.isReady();
×
271
        setupClientRouting({
×
272
                app, apolloClient, cookieStore, kvAuth0, router
273
        });
274

275
        // Mount app in DOM
276
        app.mount('#app');
×
277
}
278

279
// Start application once browser is idle
280
if ('requestIdleCallback' in window) {
×
281
        requestIdleCallback(initApp, { timeout: 2000 });
×
282
} else {
283
        setTimeout(initApp, 500);
×
284
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc