diff --git a/packages/core/src/handler.ts b/packages/core/src/handler.ts new file mode 100644 index 0000000..06720d3 --- /dev/null +++ b/packages/core/src/handler.ts @@ -0,0 +1,32 @@ +import { Platform } from './types'; + +export interface ParsedPayload { + [key: string]: any; +} + +export interface AppHandler { + + // The platform identifier (e.g., 'youtube', 'linkedin') + + platform: Platform; + + + // Optional priority for the handler. Higher numbers are matched first. + // Defaults to 0. + + priority?: number; + + + // Checks if the URL is supported by this handler.Should be fast and synchronous. + + match(url: string): boolean; + + + // Parses the URL into a structured payload. Returns null if parsing fails. + + parse(url: string): ParsedPayload | null; + + + // Builds a deep link or web URL for the specified OS. + buildLink(payload: ParsedPayload, os: 'ios' | 'android' | 'web'): string; +} diff --git a/packages/core/src/utils/url.ts b/packages/core/src/utils/url.ts new file mode 100644 index 0000000..79de949 --- /dev/null +++ b/packages/core/src/utils/url.ts @@ -0,0 +1,41 @@ +/** + * Normalizes a URL string to a URL object. + * Adds 'https://' if protocol is missing. + */ +export function normalizeUrl(url: string): URL | null { + try { + let urlString = url.trim(); + if (!urlString.startsWith('http://') && !urlString.startsWith('https://')) { + urlString = 'https://' + urlString; + } + return new URL(urlString); + } catch { + return null; + } +} + +/** + * Extracts path segments from a URL object, ignoring empty segments. + */ +export function extractPathSegments(url: URL): string[] { + return url.pathname.split('/').filter((segment) => segment.length > 0); +} + +/** + * Checks if the hostname matches any of the allowed domains. + * Handles 'www.' prefix automatically. + */ +export function matchHostname(url: URL, allowedDomains: string[]): boolean { + const hostname = url.hostname.toLowerCase().replace(/^www\./, ''); + return allowedDomains.some((domain) => { + const normalizedDomain = domain.toLowerCase().replace(/^www\./, ''); + return hostname === normalizedDomain || hostname.endsWith('.' + normalizedDomain); + }); +} + +/** + * Safely extracts a query parameter. + */ +export function getQueryParam(url: URL, param: string): string | null { + return url.searchParams.get(param); +}