import { useContext } from 'react' ; import { defaultLanguage } from '@island.is/shared/constants' ; import { Locale } from '@island.is/shared/types' ; import { I18nContext } from '../../i18n/I18n' ; export interface LinkResolverResponse { href : string ; } interface LinkResolverInput { linkType : LinkType ; variables ? : string [ ] ; locale ? : Locale ; } interface TypeResolverResponse { locale : Locale ; type ? : LinkType ; slug ? : string [ ] ; } export type LinkType = keyof typeof routesTemplate | 'linkurl' | 'link' ; export const routesTemplate = { aboutsubpage : { is : '/s/stafraent-island/[slug]' , en : '' , } , page : { is : '/stafraent-island' , en : '' , } , search : { is : '/leit' , en : '/en/search' , } , articlecategory : { is : '/flokkur/[slug]' , en : '/en/category/[slug]' , } , news : { is : '/frett/[slug]' , en : '/en/news/[slug]' , } , newsoverview : { is : '/frett' , en : '/en/news' , } , organizationservices : { is : '/s/[slug]/thjonusta' , en : '/en/o/[slug]/services' , } , auctions : { is : '/s/syslumenn/uppbod' , en : '' , } , apicataloguedetailpage : { is : '/s/stafraent-island/vefthjonustur/[slug]' , en : '' , } , apicataloguepage : { is : '/s/stafraent-island/vefthjonustur' , en : '' , } , organizationsubpage : { is : '/s/[slug]/[subSlug]' , en : '/en/o/[slug]/[subSlug]' , } , organizationpage : { is : '/s/[slug]' , en : '/en/o/[slug]' , } , organizations : { is : '/s' , en : '/en/o' , } , opendatapage : { is : '/gagnatorg' , en : '/en/gagnatorg' , } , opendatasubpage : { is : '/gagnatorg/[slug]' , en : '/en/gagnatorg/[slug]' , } , projectsubpage : { is : '/v/[slug]/[subSlug]' , en : '/en/p/[slug]/[subSlug]' , } , projectpage : { is : '/v/[slug]' , en : '/en/p/[slug]' , } , lifeevents : { is : '/lifsvidburdir' , en : '/en/life-events' , } , lifeeventpage : { is : '/lifsvidburdir/[slug]' , en : '/en/life-events/[slug]' , } , organizationnews : { is : '/s/[organization]/frett/[slug]' , en : '/en/o/[organization]/news/[slug]' , } , organizationnewsoverview : { is : '/s/[organization]/frett' , en : '/en/o/[organization]/news' , } , adgerdirpage : { is : '/covid-adgerdir/[slug]' , en : '/en/covid-operations/[slug]' , } , adgerdirfrontpage : { is : '/covid-adgerdir' , en : '/en/covid-operations' , } , regulation : { is : '/reglugerdir/nr/[number]' , en : '' , } , regulationshome : { is : '/reglugerdir' , en : '' , } , login : { is : '/innskraning' , en : '/en/login' , } , webservicedetailpage : { is : '/throun/vefthjonustur/[slug]' , en : '/en/developers/webservices/[slug]' , } , webservicespage : { is : '/throun/vefthjonustur' , en : '/en/developers/webservices' , } , handbookpage : { is : '/throun/handbok' , en : '/en/developers/handbook' , } , developerspage : { is : '/throun' , en : '/en/developers' , } , subarticle : { is : '/[slug]/[subSlug]' , en : '/en/[slug]/[subSlug]' , } , article : { is : '/[slug]' , en : '/en/[slug]' , } , helpdesk : { is : '/thjonustuvefur' , en : '/en/helpdesk' , } , helpdeskcategory : { is : '/thjonustuvefur/[organizationSlug]/[categorySlug]' , en : '/en/helpdesk/[organizationSlug]/[categorySlug]' , } , helpdesksearch : { is : '/thjonustuvefur/leit' , en : '/en/helpdesk/search' , } , homepage : { is : '/' , en : '/en' , } , } ; export const replaceVariableInPath = ( path , replacement ) : string => { return path . replace ( /\[\w+\]/ , replacement ) ; } ; export const convertToRegex = ( routeTemplate ) => { const query = routeTemplate . replace ( /\//g , '\\/' ) . replace ( /\[\w+\]/g , '[-\\w]+' ) ; return `^${ query }$` ; } ; export const extractSlugsByRouteTemplate = ( path , template ) : string [ ] => { const pathParts = path . split ( '/' ) ; const templateParts = template . split ( '/' ) ; return pathParts . filter ( ( _ , index ) => { return templateParts [ index ] ?. startsWith ( '[' ) ?? false ; } ) ; } ; export const linkResolver = ( linkType , variables = [ ] , locale = defaultLanguage ) : LinkResolverResponse => { const type = linkType ?. toLowerCase ( ) as LinkResolverInput [ 'linkType' ] | undefined | null ; if ( type === 'linkurl' ) { return { href : variables [ 0 ] , } ; } if ( type === 'link' ) { return { href : variables . join ( '/' ) , } ; } if ( type && routesTemplate [ type ] && routesTemplate [ type ] [ locale ] ) { const typePath = routesTemplate [ type ] [ locale ] ; if ( variables . length ) { return { href : variables . reduce ( ( path , slug ) => replaceVariableInPath ( path , slug ) , typePath ) , } ; } else { return { href : typePath , } ; } } else { return { href : '/404' , } ; } } ; export const typeResolver = ( path , skipDynamic = false ) : TypeResolverResponse | null => { for ( const [ type , locales ] of Object . entries ( routesTemplate ) ) { for ( const [ locale , routeTemplate ] of Object . entries ( locales ) ) { if ( ( skipDynamic && routeTemplate . includes ( '[' ) ) || ! routeTemplate ) { continue ; } if ( path === '/en' ) { return { type : 'homepage' , locale : 'en' , slug : [ ] } ; } const regex = convertToRegex ( routeTemplate ) ; if ( ( ! skipDynamic && path ?. match ( regex ) ) || ( skipDynamic && path ?. startsWith ( routeTemplate ) ) ) { return { slug : extractSlugsByRouteTemplate ( path , routeTemplate ) , type , locale , } as TypeResolverResponse ; } } } return null ; } ; export const useLinkResolver = ( ) => { const context = useContext ( I18nContext ) ; const wrappedLinkResolver = ( linkType , variables = [ ] , locale = context ?. activeLocale ) => linkResolver ( linkType , variables , locale ) ; return { typeResolver , linkResolver : wrappedLinkResolver , } ; } ;