EduLink

EduLink - Хелпер для работы с ссылками для дальнейшей их передачи. Упрощает создание ссылок и централизованное их использование

import { EduLink } from '#sf/services/link';

export class JournalLinks {
  root = () =>
    new EduLink('/journal');

  create = () => this.root().appendPath('/new');

  topic = (idOrSlug: TopicIdOrSlug) => this.root().appendPath(`/${idOrSlug}`);

  topicComments = (idOrSlug: TopicIdOrSlug) =>
    this.topic(idOrSlug).setHash('comments');
}

class DialogsLinks {
  mail = () =>
    new EduLink('/mail');

  mailChat = (userId: number, predefinedText?: string) =>
    this.mail()
      .appendPath(`/${userId}`)
      .addQuery(PREDEFINED_TEXT_QUERY, predefinedText);
}

Создание ссылки

По умолчанию если не указан origin, используется EduLink.defaultOrign который равен process.env.EDU_BASE_URL

import { EduLink } from '#sf/services/link';

new EduLink('/some-path');
new EduLink({
  path: '/some-path',
  query: {
    foo: 'bar',
    baz: [123, 321],
  },
  hash: 'foo',
});
new EduLink({
  protocol: 'http:',
  hostname: 'example.com',
  port: 321,
  path: '/some-path',
});
new EduLink({
  origin: 'http://example.com:321',
  path: '/some-path',
});

Переиспользование

const root = () => new EduLink('/foo');
const anotherLink () => root()
  .appendPath('/bar')
  .setPath('/full-replaced-path')
  .setOrigin('http://another-origin.com')
  .setQuery({
    foo: 'foo',
    bar: 'bar',
  })
  .addQuery('baz', 'baz')
  .removeQuery('baz')
  .setHash('some-hash')

Использование

Обычная ссылка

Часть компонентов поддерживают передачу EduLink, например

<template>
  <SfLink :href="href">
    SomeLink
  </SfLink>
</template>

<script setup>
import { EduLink } from '#sf/services/link';

const href = new EduLink('/some-href');
</script>

HTTP Редирект/Canonical

Если ссылка точно является инстансом EduLink достаточно использовать link.toString(true). Если тип ссылки неизвестен (string | EduLink) то универсальным будет использование toAbsoluteUrl

import { EduLink } from '#sf/services/link';
import { toAbsoluteUrl } from '#sf/utils/url';

const href: string | EduLink;
const redirectUrl = toAbsoluteUrl(href, process.env.EDU_BASE_URL);
const anotherHostHref = toAbsoluteUrl(anotherHostHref, process.env.EDU_BASE_URL);

const anotherHref: EduLink;
const fullUrl = anotherHref.toString();

Так же в nuxt3 navigateTo для абсолютных редиректов необходимо указать external: true. Один из способов реализации для кейса где тип redirectUrl: string | EduLink

import { useDomain } from '#sf/modules/domain';
import { isAnotherDomain } from '#sf/utils/url';


export default defineNuxtRouteMiddleware((to) => {
  const redirectUrl: string | EduLink;

  const domain = useDomain();
  const external = isAnotherDomain(redirectUrl, domain?.origin);

  return navigateTo(redirectUrl.toString(external), {
    external,
  });
});

Router.push

Для смены маршрута в SPA режиме хватит относительного урла

import { EduLink } from '#sf/services/link';

const href = new EduLink('/some-href');

router.push(href.toString());

Если неизвестно какого типа ссылка string | EduLink, то будет удобен хелпер getFullPath. Он так же проверяет если ссылка абсолютно и отсекает origin

import { EduLink } from '#sf/services/link';
import { getFullPath } from '#sf/utils/url';

const href: string | EduLink;

router.push(getFullPath(href));