import { createRouter, createWebHistory, createMemoryHistory, NavigationGuardNext, RouteLocationNormalized, RouteRecordRaw } from 'vue-router' import { accountsDBPromise } from '../db/index' import { logger } from '../utils/logger' /** * * @param to :RouteLocationNormalized * @param from :RouteLocationNormalized * @param next :NavigationGuardNext */ const enterOrStart = async ( to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext ) => { // one of the few times we use accountsDBPromise directly; try to avoid more usage const accountsDB = await accountsDBPromise const num_accounts = await accountsDB.accounts.count() if (num_accounts > 0) { next() } else { next({ name: 'start' }) } } const routes: Array = [ { path: '/account', name: 'account', component: () => import('../views/AccountViewView.vue') }, { path: '/claim/:id?', name: 'claim', component: () => import('../views/ClaimView.vue') }, { path: '/claim-add-raw/:id?', name: 'claim-add-raw', component: () => import('../views/ClaimAddRawView.vue') }, { path: '/claim-cert/:id', name: 'claim-cert', component: () => import('../views/ClaimCertificateView.vue') }, { path: '/confirm-contact', name: 'confirm-contact', component: () => import('../views/ConfirmContactView.vue') }, { path: '/confirm-gift/:id?', name: 'confirm-gift', component: () => import('../views/ConfirmGiftView.vue') }, { path: '/contact-amounts', name: 'contact-amounts', component: () => import('../views/ContactAmountsView.vue') }, { path: '/contact-edit/:did', name: 'contact-edit', component: () => import('../views/ContactEditView.vue') }, { path: '/contact-gift', name: 'contact-gift', component: () => import('../views/ContactGiftingView.vue') }, { path: '/contact-import/:jwt?', name: 'contact-import', component: () => import('../views/ContactImportView.vue') }, { path: '/contact-qr', name: 'contact-qr', component: () => import('../views/ContactQRScanShowView.vue') }, { path: '/contacts', name: 'contacts', component: () => import('../views/ContactsView.vue') }, { path: '/did/:did?', name: 'did', component: () => import('../views/DIDView.vue') }, { path: '/discover', name: 'discover', component: () => import('../views/DiscoverView.vue') }, { path: '/gifted-details', name: 'gifted-details', component: () => import('../views/GiftedDetailsView.vue') }, { path: '/help', name: 'help', component: () => import('../views/HelpView.vue') }, { path: '/help-notifications', name: 'help-notifications', component: () => import('../views/HelpNotificationsView.vue') }, { path: '/help-notification-types', name: 'help-notification-types', component: () => import('../views/HelpNotificationTypesView.vue') }, { path: '/help-onboarding', name: 'help-onboarding', component: () => import('../views/HelpOnboardingView.vue') }, { path: '/', name: 'home', component: () => import('../views/HomeView.vue') }, { path: '/identity-switcher', name: 'identity-switcher', component: () => import('../views/IdentitySwitcherView.vue') }, { path: '/import-account', name: 'import-account', component: () => import('../views/ImportAccountView.vue') }, { path: '/import-derive', name: 'import-derive', component: () => import('../views/ImportDerivedAccountView.vue') }, { path: '/invite-one', name: 'invite-one', component: () => import('../views/InviteOneView.vue') }, { path: '/invite-one-accept/:jwt?', name: 'InviteOneAcceptView', component: () => import('../views/InviteOneAcceptView.vue') }, { path: '/logs', name: 'logs', component: () => import('../views/LogView.vue') }, { path: '/new-activity', name: 'new-activity', component: () => import('../views/NewActivityView.vue') }, { path: '/new-edit-account', name: 'new-edit-account', component: () => import('../views/NewEditAccountView.vue') }, { path: '/new-edit-project', name: 'new-edit-project', component: () => import('../views/NewEditProjectView.vue') }, { path: '/new-identifier', name: 'new-identifier', component: () => import('../views/NewIdentifierView.vue') }, { path: '/offer-details/:id?', name: 'offer-details', component: () => import('../views/OfferDetailsView.vue') }, { path: '/onboard-meeting-list', name: 'onboard-meeting-list', component: () => import('../views/OnboardMeetingListView.vue') }, { path: '/onboard-meeting-members/:groupId', name: 'onboard-meeting-members', component: () => import('../views/OnboardMeetingMembersView.vue') }, { path: '/onboard-meeting-setup', name: 'onboard-meeting-setup', component: () => import('../views/OnboardMeetingSetupView.vue') }, { path: '/project/:id?', name: 'project', component: () => import('../views/ProjectViewView.vue') }, { path: '/projects', name: 'projects', component: () => import('../views/ProjectsView.vue'), beforeEnter: enterOrStart }, { path: '/quick-action-bvc', name: 'quick-action-bvc', component: () => import('../views/QuickActionBvcView.vue') }, { path: '/quick-action-bvc-begin', name: 'quick-action-bvc-begin', component: () => import('../views/QuickActionBvcBeginView.vue') }, { path: '/quick-action-bvc-end', name: 'quick-action-bvc-end', component: () => import('../views/QuickActionBvcEndView.vue') }, { path: '/recent-offers-to-user', name: 'recent-offers-to-user', component: () => import('../views/RecentOffersToUserView.vue') }, { path: '/recent-offers-to-user-projects', name: 'recent-offers-to-user-projects', component: () => import('../views/RecentOffersToUserProjectsView.vue') }, { path: '/scan-contact', name: 'scan-contact', component: () => import('../views/ContactScanView.vue') }, { path: '/search-area', name: 'search-area', component: () => import('../views/SearchAreaView.vue') }, { path: '/seed-backup', name: 'seed-backup', component: () => import('../views/SeedBackupView.vue') }, { path: '/share-my-contact-info', name: 'share-my-contact-info', component: () => import('../views/ShareMyContactInfoView.vue') }, { path: '/shared-photo', name: 'shared-photo', component: () => import('../views/SharedPhotoView.vue') }, // /share-target is also an endpoint in the service worker { path: '/start', name: 'start', component: () => import('../views/StartView.vue') }, { path: '/statistics', name: 'statistics', component: () => import('../views/StatisticsView.vue') }, { path: '/test', name: 'test', component: () => import('../views/TestView.vue') }, { path: '/user-profile/:id?', name: 'user-profile', component: () => import('../views/UserProfileView.vue') }, { path: '/deep-link-error', name: 'deep-link-error', component: () => import('../views/DeepLinkErrorView.vue'), meta: { title: 'Invalid Deep Link', requiresAuth: false } } ] const isElectron = window.location.protocol === 'file:' const initialPath = isElectron ? window.location.pathname.split('/dist-electron/www/')[1] || '/' : window.location.pathname const history = isElectron ? createMemoryHistory() // Memory history for Electron : createWebHistory('/') // Add base path for web apps /** @type {*} */ const router = createRouter({ history, routes }) // Replace initial URL to start at `/` if necessary router.replace(initialPath || '/') const errorHandler = ( // eslint-disable-next-line @typescript-eslint/no-explicit-any error: any, to: RouteLocationNormalized, from: RouteLocationNormalized ) => { // Handle the error here logger.error('Caught in top level error handler:', error, to, from) alert('Something is very wrong. Try reloading or restarting the app.') // You can also perform additional actions, such as displaying an error message or redirecting the user to a specific page } router.onError(errorHandler) // Assign the error handler to the router instance // router.beforeEach((to, from, next) => { // console.log("Navigating to view:", to.name); // console.log("From view:", from.name); // next(); // }); export default router