From c980afd78649d1e0e988511241ffad0e54a52736 Mon Sep 17 00:00:00 2001 From: goenning Date: Fri, 29 Dec 2023 09:22:45 -0300 Subject: [PATCH] Support for custom API path --- packages/react/CHANGELOG.md | 4 ++++ packages/react/package.json | 2 +- packages/react/src/index.tsx | 7 ++++++- packages/shared.ts | 25 ++++++++++++------------- packages/web/CHANGELOG.md | 4 ++++ packages/web/package.json | 2 +- packages/web/src/index.ts | 7 ++++++- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index d880e0b..ca00764 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.1 + +- Support for custom API path + ## 0.3.0 - Internal refactor diff --git a/packages/react/package.json b/packages/react/package.json index 2edf266..20c12db 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@aptabase/react", - "version": "0.3.0", + "version": "0.3.1", "type": "module", "description": "React SDK for Aptabase: Open Source, Privacy-First and Simple Analytics for Mobile, Desktop and Web Apps", "main": "./dist/index.cjs", diff --git a/packages/react/src/index.tsx b/packages/react/src/index.tsx index 8bc9e4b..9e89aa2 100644 --- a/packages/react/src/index.tsx +++ b/packages/react/src/index.tsx @@ -1,13 +1,14 @@ 'use client'; import { createContext, useContext, useEffect } from 'react'; -import { inMemorySessionId, sendEvent, validateAppKey, type AptabaseOptions } from '../../shared'; +import { getApiUrl, inMemorySessionId, sendEvent, validateAppKey, type AptabaseOptions } from '../../shared'; // Session expires after 1 hour of inactivity const SESSION_TIMEOUT = 1 * 60 * 60; const sdkVersion = `aptabase-react@${process.env.PKG_VERSION}`; let _appKey = ''; +let _apiUrl: string | undefined; let _options: AptabaseOptions | undefined; type ContextProps = { @@ -18,14 +19,18 @@ type ContextProps = { function init(appKey: string, options?: AptabaseOptions) { if (!validateAppKey(appKey)) return; + _apiUrl = getApiUrl(appKey, options); _appKey = appKey; _options = options; } async function trackEvent(eventName: string, props?: Record): Promise { + if (!_apiUrl) return; + const sessionId = inMemorySessionId(SESSION_TIMEOUT); await sendEvent({ + apiUrl: _apiUrl, sessionId, appKey: _appKey, isDebug: _options?.isDebug, diff --git a/packages/shared.ts b/packages/shared.ts index 983ca58..3255b6c 100644 --- a/packages/shared.ts +++ b/packages/shared.ts @@ -6,8 +6,6 @@ const isInBrowserExtension = typeof chrome !== 'undefined' && !!chrome.runtime.i let _sessionId = newSessionId(); let _lastTouched = new Date(); -const apiUrl: Record = {}; - const _hosts: { [region: string]: string } = { US: 'https://us.aptabase.com', EU: 'https://eu.aptabase.com', @@ -16,8 +14,13 @@ const _hosts: { [region: string]: string } = { }; export type AptabaseOptions = { + // Custom host for self-hosted Aptabase. host?: string; + // Custom path for API endpoint. Useful when using reverse proxy. + apiPath?: string; + // Defines the app version. appVersion?: string; + // Defines whether the app is running on debug mode. isDebug?: boolean; }; @@ -51,26 +54,25 @@ export function validateAppKey(appKey: string): boolean { return true; } -function getApiUrl(appKey: string, options?: AptabaseOptions): string | undefined { - const url = apiUrl[appKey]; - if (url) url; +export function getApiUrl(appKey: string, options?: AptabaseOptions): string | undefined { + const apiPath = options?.apiPath ?? '/api/v0/event'; const region = appKey.split('-')[1]; - let host = _hosts[region]; if (region === 'SH') { if (!options?.host) { console.warn(`Host parameter must be defined when using Self-Hosted App Key. Tracking will be disabled.`); return; } - host = options.host; + return `${options.host}${apiPath}`; } - apiUrl[appKey] = `${host}/api/v0/event`; - return apiUrl[appKey]; + const host = options?.host ?? _hosts[region]; + return `${host}${apiPath}`; } export async function sendEvent(opts: { + apiUrl: string; appKey?: string; sessionId: string; locale?: string; @@ -90,11 +92,8 @@ export async function sendEvent(opts: { return; } - const apiUrl = getApiUrl(opts.appKey); - if (!apiUrl) return; - try { - const response = await fetch(apiUrl, { + const response = await fetch(opts.apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index 1996172..f1736be 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +- Support for custom API path + ## 0.4.0 - Internal refactor diff --git a/packages/web/package.json b/packages/web/package.json index 81033d3..f71695e 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@aptabase/web", - "version": "0.4.0", + "version": "0.4.1", "type": "module", "description": "JavaScript SDK for Aptabase: Open Source, Privacy-First and Simple Analytics for Mobile, Desktop and Web Apps", "main": "./dist/index.cjs", diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts index fc6424b..bf672a2 100644 --- a/packages/web/src/index.ts +++ b/packages/web/src/index.ts @@ -1,10 +1,11 @@ -import { inMemorySessionId, sendEvent, validateAppKey, type AptabaseOptions } from '../../shared'; +import { getApiUrl, inMemorySessionId, sendEvent, validateAppKey, type AptabaseOptions } from '../../shared'; // Session expires after 1 hour of inactivity const SESSION_TIMEOUT = 1 * 60 * 60; const sdkVersion = `aptabase-web@${process.env.PKG_VERSION}`; let _appKey = ''; +let _apiUrl: string | undefined; let _options: AptabaseOptions | undefined; export { type AptabaseOptions }; @@ -12,14 +13,18 @@ export { type AptabaseOptions }; export function init(appKey: string, options?: AptabaseOptions) { if (!validateAppKey(appKey)) return; + _apiUrl = getApiUrl(appKey, options); _appKey = appKey; _options = options; } export async function trackEvent(eventName: string, props?: Record): Promise { + if (!_apiUrl) return; + const sessionId = inMemorySessionId(SESSION_TIMEOUT); await sendEvent({ + apiUrl: _apiUrl, sessionId, appKey: _appKey, isDebug: _options?.isDebug,