Create src folder for shlink-web-component

This commit is contained in:
Alejandro Celaya
2023-08-02 08:23:48 +02:00
parent b7d57a53f2
commit c48facc863
294 changed files with 347 additions and 347 deletions

View File

@@ -0,0 +1,62 @@
import type { ShortUrl, ShortUrlData } from '../short-urls/data';
import type {
ShlinkDomainRedirects,
ShlinkDomainsResponse,
ShlinkEditDomainRedirects,
ShlinkHealth,
ShlinkMercureInfo,
ShlinkShortUrlData,
ShlinkShortUrlsListParams,
ShlinkShortUrlsResponse,
ShlinkTags,
ShlinkVisits,
ShlinkVisitsOverview,
ShlinkVisitsParams,
} from './types';
export type ShlinkApiClient = {
readonly baseUrl: string;
readonly apiKey: string;
listShortUrls(params?: ShlinkShortUrlsListParams): Promise<ShlinkShortUrlsResponse>;
createShortUrl(options: ShortUrlData): Promise<ShortUrl>;
getShortUrlVisits(shortCode: string, query?: ShlinkVisitsParams): Promise<ShlinkVisits>;
getTagVisits(tag: string, query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits>;
getDomainVisits(domain: string, query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits>;
getOrphanVisits(query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits>;
getNonOrphanVisits(query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits>;
getVisitsOverview(): Promise<ShlinkVisitsOverview>;
getShortUrl(shortCode: string, domain?: string | null): Promise<ShortUrl>;
deleteShortUrl(shortCode: string, domain?: string | null): Promise<void>;
updateShortUrl(
shortCode: string,
domain: string | null | undefined,
body: ShlinkShortUrlData,
): Promise<ShortUrl>;
listTags(): Promise<ShlinkTags>;
tagsStats(): Promise<ShlinkTags>;
deleteTags(tags: string[]): Promise<{ tags: string[] }>;
editTag(oldName: string, newName: string): Promise<{ oldName: string; newName: string }>;
health(authority?: string): Promise<ShlinkHealth>;
mercureInfo(): Promise<ShlinkMercureInfo>;
listDomains(): Promise<ShlinkDomainsResponse>;
editDomainRedirects(domainRedirects: ShlinkEditDomainRedirects): Promise<ShlinkDomainRedirects>;
};

View File

@@ -0,0 +1,54 @@
export enum ErrorTypeV2 {
INVALID_ARGUMENT = 'INVALID_ARGUMENT',
INVALID_SHORT_URL_DELETION = 'INVALID_SHORT_URL_DELETION',
DOMAIN_NOT_FOUND = 'DOMAIN_NOT_FOUND',
FORBIDDEN_OPERATION = 'FORBIDDEN_OPERATION',
INVALID_URL = 'INVALID_URL',
INVALID_SLUG = 'INVALID_SLUG',
INVALID_SHORTCODE = 'INVALID_SHORTCODE',
TAG_CONFLICT = 'TAG_CONFLICT',
TAG_NOT_FOUND = 'TAG_NOT_FOUND',
MERCURE_NOT_CONFIGURED = 'MERCURE_NOT_CONFIGURED',
INVALID_AUTHORIZATION = 'INVALID_AUTHORIZATION',
INVALID_API_KEY = 'INVALID_API_KEY',
NOT_FOUND = 'NOT_FOUND',
}
export enum ErrorTypeV3 {
INVALID_ARGUMENT = 'https://shlink.io/api/error/invalid-data',
INVALID_SHORT_URL_DELETION = 'https://shlink.io/api/error/invalid-short-url-deletion',
DOMAIN_NOT_FOUND = 'https://shlink.io/api/error/domain-not-found',
FORBIDDEN_OPERATION = 'https://shlink.io/api/error/forbidden-tag-operation',
INVALID_URL = 'https://shlink.io/api/error/invalid-url',
INVALID_SLUG = 'https://shlink.io/api/error/non-unique-slug',
INVALID_SHORTCODE = 'https://shlink.io/api/error/short-url-not-found',
TAG_CONFLICT = 'https://shlink.io/api/error/tag-conflict',
TAG_NOT_FOUND = 'https://shlink.io/api/error/tag-not-found',
MERCURE_NOT_CONFIGURED = 'https://shlink.io/api/error/mercure-not-configured',
INVALID_AUTHORIZATION = 'https://shlink.io/api/error/missing-authentication',
INVALID_API_KEY = 'https://shlink.io/api/error/invalid-api-key',
NOT_FOUND = 'https://shlink.io/api/error/not-found',
}
export interface ProblemDetailsError {
type: string;
detail: string;
title: string;
status: number;
[extraProps: string]: any;
}
export interface InvalidArgumentError extends ProblemDetailsError {
type: ErrorTypeV2.INVALID_ARGUMENT | ErrorTypeV3.INVALID_ARGUMENT;
invalidElements: string[];
}
export interface InvalidShortUrlDeletion extends ProblemDetailsError {
type: 'INVALID_SHORTCODE_DELETION' | ErrorTypeV2.INVALID_SHORT_URL_DELETION | ErrorTypeV3.INVALID_SHORT_URL_DELETION;
threshold: number;
}
export interface RegularNotFound extends ProblemDetailsError {
type: ErrorTypeV2.NOT_FOUND | ErrorTypeV3.NOT_FOUND;
status: 404;
}

View File

@@ -0,0 +1,3 @@
export * from './errors';
export * from './ShlinkApiClient';
export * from './types';

View File

@@ -0,0 +1,132 @@
import type { Order } from '../../../shlink-frontend-kit/src';
import type { ShortUrl, ShortUrlMeta } from '../short-urls/data';
import type { Visit } from '../visits/types';
export interface ShlinkShortUrlsResponse {
data: ShortUrl[];
pagination: ShlinkPaginator;
}
export interface ShlinkMercureInfo {
token: string;
mercureHubUrl: string;
}
export interface ShlinkHealth {
status: 'pass' | 'fail';
version: string;
}
export interface ShlinkTagsStats {
tag: string;
shortUrlsCount: number;
visitsSummary?: ShlinkVisitsSummary; // Optional only before Shlink 3.5.0
/** @deprecated */
visitsCount: number;
}
export interface ShlinkTags {
tags: string[];
stats: ShlinkTagsStats[];
}
export interface ShlinkTagsResponse {
data: string[];
/** @deprecated Present only when withStats=true is provided, which is deprecated */
stats: ShlinkTagsStats[];
}
export interface ShlinkTagsStatsResponse {
data: ShlinkTagsStats[];
}
export interface ShlinkPaginator {
currentPage: number;
pagesCount: number;
totalItems: number;
}
export interface ShlinkVisitsSummary {
total: number;
nonBots: number;
bots: number;
}
export interface ShlinkVisits {
data: Visit[];
pagination: ShlinkPaginator;
}
export interface ShlinkVisitsOverview {
nonOrphanVisits?: ShlinkVisitsSummary; // Optional only before Shlink 3.5.0
orphanVisits?: ShlinkVisitsSummary; // Optional only before Shlink 3.5.0
/** @deprecated */
visitsCount: number;
/** @deprecated */
orphanVisitsCount: number;
}
export interface ShlinkVisitsParams {
domain?: string | null;
page?: number;
itemsPerPage?: number;
startDate?: string;
endDate?: string;
excludeBots?: boolean;
}
export interface ShlinkShortUrlData extends ShortUrlMeta {
longUrl?: string;
title?: string;
validateUrl?: boolean;
tags?: string[];
}
export interface ShlinkDomainRedirects {
baseUrlRedirect: string | null;
regular404Redirect: string | null;
invalidShortUrlRedirect: string | null;
}
export interface ShlinkEditDomainRedirects extends Partial<ShlinkDomainRedirects> {
domain: string;
}
export interface ShlinkDomain {
domain: string;
isDefault: boolean;
redirects: ShlinkDomainRedirects;
}
export interface ShlinkDomainsResponse {
data: ShlinkDomain[];
defaultRedirects: ShlinkDomainRedirects;
}
export type TagsFilteringMode = 'all' | 'any';
type ShlinkShortUrlsOrderableFields = 'dateCreated' | 'shortCode' | 'longUrl' | 'title' | 'visits' | 'nonBotVisits';
export type ShlinkShortUrlsOrder = Order<ShlinkShortUrlsOrderableFields>;
export interface ShlinkShortUrlsListParams {
page?: string;
itemsPerPage?: number;
searchTerm?: string;
tags?: string[];
tagsMode?: TagsFilteringMode;
orderBy?: ShlinkShortUrlsOrder;
startDate?: string;
endDate?: string;
excludeMaxVisitsReached?: boolean;
excludePastValidUntil?: boolean;
}
export interface ShlinkShortUrlsListNormalizedParams extends
Omit<ShlinkShortUrlsListParams, 'orderBy' | 'excludeMaxVisitsReached' | 'excludePastValidUntil'> {
orderBy?: string;
excludeMaxVisitsReached?: 'true';
excludePastValidUntil?: 'true';
}

View File

@@ -0,0 +1,25 @@
import type {
InvalidArgumentError,
InvalidShortUrlDeletion,
ProblemDetailsError,
RegularNotFound } from './errors';
import {
ErrorTypeV2,
ErrorTypeV3,
} from './errors';
export const isInvalidArgumentError = (error?: ProblemDetailsError): error is InvalidArgumentError =>
error?.type === ErrorTypeV2.INVALID_ARGUMENT || error?.type === ErrorTypeV3.INVALID_ARGUMENT;
export const isInvalidDeletionError = (error?: ProblemDetailsError): error is InvalidShortUrlDeletion =>
error?.type === 'INVALID_SHORTCODE_DELETION'
|| error?.type === ErrorTypeV2.INVALID_SHORT_URL_DELETION
|| error?.type === ErrorTypeV3.INVALID_SHORT_URL_DELETION;
export const isRegularNotFound = (error?: ProblemDetailsError): error is RegularNotFound =>
(error?.type === ErrorTypeV2.NOT_FOUND || error?.type === ErrorTypeV3.NOT_FOUND) && error?.status === 404;
const isProblemDetails = (e: unknown): e is ProblemDetailsError =>
!!e && typeof e === 'object' && ['type', 'detail', 'title', 'status'].every((prop) => prop in e);
export const parseApiError = (e: unknown): ProblemDetailsError | undefined => (isProblemDetails(e) ? e : undefined);