Skip to content

Commit ab76241

Browse files
committed
FIX: JSDoc comments for exported function
1 parent 646e62f commit ab76241

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

src/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import { templateRoutes } from './routes/templates.js';
1111
import { qrRoutes } from './routes/qr.js';
1212
import { wellKnownRoutes } from './routes/well-known.js';
1313

14+
/**
15+
* Configuration options for creating a LinkForty server instance.
16+
*/
1417
export interface ServerOptions {
1518
database?: DatabaseOptions;
1619
redis?: {
@@ -22,6 +25,15 @@ export interface ServerOptions {
2225
logger?: boolean;
2326
}
2427

28+
/**
29+
* Create and configure a LinkForty Fastify server instance.
30+
*
31+
* Registers CORS, optional Redis, the database connection, and all built-in
32+
* route plugins. The returned instance is ready to call `listen()` on.
33+
*
34+
* @param options - Server configuration (database, Redis, CORS, logger).
35+
* @returns A configured Fastify instance with all routes registered.
36+
*/
2537
export async function createServer(options: ServerOptions = {}) {
2638
const fastify = Fastify({
2739
logger: options.logger !== undefined ? options.logger : true,

src/lib/utils.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,22 @@ import { nanoid } from 'nanoid';
22
import geoip from 'geoip-lite';
33
import UAParser from 'ua-parser-js';
44

5+
/**
6+
* Generate a URL-safe random short code using nanoid.
7+
*
8+
* @param length - Number of characters in the generated code. Defaults to 8.
9+
* @returns A random URL-safe string of the specified length.
10+
*/
511
export function generateShortCode(length: number = 8): string {
612
return nanoid(length);
713
}
814

15+
/**
16+
* Parse a User-Agent string into structured device and browser information.
17+
*
18+
* @param userAgent - Raw User-Agent header value from an HTTP request.
19+
* @returns An object containing `deviceType`, `platform`, `platformVersion`, and `browser`.
20+
*/
921
export function parseUserAgent(userAgent: string) {
1022
const parser = new UAParser(userAgent);
1123
const result = parser.getResult();
@@ -68,6 +80,14 @@ const COUNTRY_NAMES: Record<string, string> = {
6880
RO: 'Romania',
6981
};
7082

83+
/**
84+
* Look up geographic location data for an IP address using geoip-lite.
85+
*
86+
* @param ip - IPv4 or IPv6 address to look up.
87+
* @returns An object with `countryCode`, `countryName`, `region`, `city`,
88+
* `latitude`, `longitude`, and `timezone`. All fields are `null` when the
89+
* IP address is not found in the GeoIP database.
90+
*/
7191
export function getLocationFromIP(ip: string) {
7292
const geo = geoip.lookup(ip);
7393

@@ -94,6 +114,17 @@ export function getLocationFromIP(ip: string) {
94114
};
95115
}
96116

117+
/**
118+
* Append UTM tracking parameters to a URL.
119+
*
120+
* Each key in `utmParameters` is prefixed with `utm_` before being added as a
121+
* query parameter (e.g., `{ source: 'email' }` → `?utm_source=email`).
122+
* Empty values are skipped.
123+
*
124+
* @param originalUrl - The destination URL to append parameters to.
125+
* @param utmParameters - Optional map of UTM parameter names (without the `utm_` prefix) to values.
126+
* @returns The URL string with UTM parameters appended.
127+
*/
97128
export function buildRedirectUrl(
98129
originalUrl: string,
99130
utmParameters?: Record<string, string>
@@ -111,6 +142,15 @@ export function buildRedirectUrl(
111142
return url.toString();
112143
}
113144

145+
/**
146+
* Detect the device platform from a User-Agent string.
147+
*
148+
* Uses simple substring matching to identify iOS and Android devices.
149+
* Anything that does not match is classified as `'web'`.
150+
*
151+
* @param userAgent - Raw User-Agent header value from an HTTP request.
152+
* @returns `'ios'`, `'android'`, or `'web'`.
153+
*/
114154
export function detectDevice(userAgent: string): 'ios' | 'android' | 'web' {
115155
const ua = userAgent.toLowerCase();
116156

src/types/index.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
// Template types
2+
3+
/**
4+
* Default settings applied to links created from a template.
5+
*/
26
export interface LinkTemplateSettings {
37
defaultIosUrl?: string;
48
defaultAndroidUrl?: string;
@@ -9,6 +13,9 @@ export interface LinkTemplateSettings {
913
expiresAfterDays?: number;
1014
}
1115

16+
/**
17+
* A reusable link template that pre-populates settings when creating new links.
18+
*/
1219
export interface LinkTemplate {
1320
id: string;
1421
userId?: string;
@@ -30,6 +37,9 @@ export interface CreateTemplateRequest {
3037

3138
export interface UpdateTemplateRequest extends Partial<CreateTemplateRequest> {}
3239

40+
/**
41+
* A short link with routing, deep-linking, UTM, targeting, and Open Graph metadata.
42+
*/
3343
export interface Link {
3444
id: string;
3545
userId?: string;
@@ -64,6 +74,9 @@ export interface Link {
6474
click_count?: number;
6575
}
6676

77+
/**
78+
* Standard UTM tracking parameters appended to redirect URLs for campaign attribution.
79+
*/
6780
export interface UTMParameters {
6881
source?: string;
6982
medium?: string;
@@ -72,12 +85,19 @@ export interface UTMParameters {
7285
content?: string;
7386
}
7487

88+
/**
89+
* Rules that control which redirect URL a visitor receives based on their
90+
* country, device type, or browser language.
91+
*/
7592
export interface TargetingRules {
7693
countries?: string[];
7794
devices?: ('ios' | 'android' | 'web')[];
7895
languages?: string[];
7996
}
8097

98+
/**
99+
* A recorded click event on a short link, including device, location, and UTM data.
100+
*/
81101
export interface ClickEvent {
82102
id: string;
83103
linkId: string;
@@ -130,6 +150,10 @@ export interface UpdateLinkRequest extends Partial<CreateLinkRequest> {
130150
isActive?: boolean;
131151
}
132152

153+
/**
154+
* Aggregated analytics for one or more links over a time period, broken down
155+
* by date, geography, device, browser, UTM parameters, and referrer.
156+
*/
133157
export interface AnalyticsData {
134158
totalClicks: number;
135159
uniqueClicks: number;
@@ -157,8 +181,16 @@ export interface AnalyticsData {
157181
}
158182

159183
// Webhook types
184+
185+
/**
186+
* Discriminated event type sent in webhook payloads.
187+
* Consumers should filter webhooks by subscribing to specific event types.
188+
*/
160189
export type WebhookEvent = 'click_event' | 'install_event' | 'conversion_event' | 'sdk_event';
161190

191+
/**
192+
* A registered webhook endpoint that receives event notifications from LinkForty.
193+
*/
162194
export interface Webhook {
163195
id: string;
164196
user_id: string;
@@ -193,13 +225,19 @@ export interface UpdateWebhookRequest {
193225
timeoutMs?: number;
194226
}
195227

228+
/**
229+
* The JSON body delivered to a webhook endpoint for every event.
230+
*/
196231
export interface WebhookPayload {
197232
event: WebhookEvent;
198233
event_id: string;
199234
timestamp: string;
200235
data: ClickEvent | InstallEvent | ConversionEvent;
201236
}
202237

238+
/**
239+
* Outcome of a single webhook delivery attempt, including HTTP status and retry info.
240+
*/
203241
export interface WebhookDeliveryResult {
204242
success: boolean;
205243
webhookId: string;
@@ -212,6 +250,9 @@ export interface WebhookDeliveryResult {
212250
errorMessage?: string;
213251
}
214252

253+
/**
254+
* An app install event, optionally attributed to a prior click via device fingerprinting.
255+
*/
215256
export interface InstallEvent {
216257
id: string;
217258
linkId?: string;
@@ -224,6 +265,9 @@ export interface InstallEvent {
224265
platform?: string;
225266
}
226267

268+
/**
269+
* A post-install in-app conversion event (e.g., purchase, sign-up) tied to an install.
270+
*/
227271
export interface ConversionEvent {
228272
id: string;
229273
installId: string;

0 commit comments

Comments
 (0)