@churnsignal/churnsignal-sdk-web 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -14
- package/dist/churnsignal-sdk-web.cjs.development.js +2 -2
- package/dist/churnsignal-sdk-web.cjs.development.js.map +1 -1
- package/dist/churnsignal-sdk-web.cjs.production.min.js +1 -1
- package/dist/churnsignal-sdk-web.cjs.production.min.js.map +1 -1
- package/dist/churnsignal-sdk-web.esm.js +2 -2
- package/dist/churnsignal-sdk-web.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/api-client.ts +1 -1
- package/src/utils/api-key-parser.ts +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install @churnsignal/churnsignal-sdk-web
|
|
|
14
14
|
The SDK only requires your API key. All configuration (workspaceId, tenantId, baseUrl) is automatically extracted from the API key.
|
|
15
15
|
|
|
16
16
|
```typescript
|
|
17
|
-
import { initialise,
|
|
17
|
+
import { initialise, track } from '@churnsignal/churnsignal-sdk-web';
|
|
18
18
|
|
|
19
19
|
// Initialize with your API key
|
|
20
20
|
const success = initialise(API_KEY);
|
|
@@ -43,19 +43,6 @@ track('purchase_completed', {
|
|
|
43
43
|
}, 'user@example.com');
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
**Note:** You can also use `identify()` to set the user email once, then call `track()` without the email parameter:
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
import { initialise, identify, track } from '@churnsignal/churnsignal-sdk-web';
|
|
50
|
-
|
|
51
|
-
initialise('your-api-key-here');
|
|
52
|
-
identify({ email: 'user@example.com' });
|
|
53
|
-
|
|
54
|
-
// Now you can track without passing email each time
|
|
55
|
-
track('page_viewed', { page: '/home' });
|
|
56
|
-
track('product_viewed', { productId: 'abc123' });
|
|
57
|
-
```
|
|
58
|
-
|
|
59
46
|
### Complete Example
|
|
60
47
|
|
|
61
48
|
```typescript
|
|
@@ -29,7 +29,7 @@ var sanitiseUrl = function sanitiseUrl(url) {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
var DEFAULT_BASE_URLS = {
|
|
32
|
-
live: 'https://
|
|
32
|
+
live: 'https://b3tac2zudh.execute-api.eu-central-1.amazonaws.com/'
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
35
|
* Parses an API key to extract workspaceId, tenantId, and baseUrl
|
|
@@ -117,7 +117,7 @@ var sdkConfig = {
|
|
|
117
117
|
'Content-Type': 'application/json'
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
|
-
var API_PREFIX = '
|
|
120
|
+
var API_PREFIX = 'prod';
|
|
121
121
|
var TRACK_ENDPOINT = API_PREFIX + "/track";
|
|
122
122
|
// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;
|
|
123
123
|
var ApiClient = /*#__PURE__*/function () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"churnsignal-sdk-web.cjs.development.js","sources":["../src/utils/url-validator.ts","../src/utils/api-key-parser.ts","../src/utils/request-transformations.ts","../src/api-client.ts","../src/managers/sdk-instance-manager.ts","../src/core/initialise.ts","../src/core/identify.ts","../src/core/track.ts"],"sourcesContent":["const urlRegex = /^https?:\\/\\//;\n\nexport const isValidUrl = (url: string) => urlRegex.test(url);\n\nexport const sanitiseUrl = (url: string) => {\n // Trim whitespace\n const sanitisedUrl = url.trim();\n\n // Validate scheme\n if (!isValidUrl(url)) {\n throw new Error(\"URL must start with 'http://' or 'https://'\");\n }\n\n try {\n let urlObject = new URL(sanitisedUrl);\n\n urlObject.hostname = urlObject.hostname.toLowerCase();\n\n // Remove trailing slash\n if (urlObject.pathname !== '/') {\n urlObject.pathname = urlObject.pathname.replace(/\\/+$/, '') || '';\n }\n\n // Reconstruct the URL from its components\n // Note: The URL interface automatically handles encoding of the pathname\n return urlObject.toString().replace(/\\/+$/, '');\n } catch (e) {\n throw new Error('Invalid URL provided');\n }\n};\n","type ParsedApiKey = {\n environment: string;\n workspaceId: string;\n tenantId: string;\n baseUrl: string;\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n live: 'https://rjwzrk7gs1.execute-api.eu-central-1.amazonaws.com/'\n};\n\n/**\n * Parses an API key to extract workspaceId, tenantId, and baseUrl\n * Expected format: cs_{environment}_tenantId_workspaceId_secret\n * Matches backend parsing logic\n * \n * @param apiKey - The API key to parse\n * @returns ParsedApiKey object with extracted data\n * @throws Error if the API key format is invalid\n */\nexport const parseApiKey = (apiKey: string): ParsedApiKey => {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a non-empty string');\n }\n\n // Check if it starts with cs_ prefix\n if (!apiKey.startsWith('cs_')) {\n throw new Error('Invalid API key format. Must start with \"cs_\"');\n }\n\n // Find the environment (cs_live_, cs_test_, cs_dev_, etc.)\n const parts = apiKey.split('_');\n if (parts.length < 2) {\n throw new Error('Invalid API key format. Must include environment (e.g., cs_live_)');\n }\n\n const environment = parts[1];\n const prefix = `cs_${environment}_`;\n \n if (!apiKey.startsWith(prefix)) {\n throw new Error(`Invalid API key format. Must start with \"${prefix}\"`);\n }\n\n // Remove prefix (e.g., 'cs_live_')\n const withoutPrefix = apiKey.substring(prefix.length);\n\n // Split by underscore - format: tenantId_workspaceId_secret\n const keyParts = withoutPrefix.split('_');\n\n if (keyParts.length < 3) {\n throw new Error('Invalid API key format. Expected format: cs_{environment}_tenantId_workspaceId_secret');\n }\n\n const tenantId = keyParts[0];\n const workspaceId = keyParts[1];\n // The rest (keyParts[2] onwards) is the secret, but we don't need it for parsing\n\n if (!tenantId) {\n throw new Error('Tenant ID not found in API key');\n }\n\n if (!workspaceId) {\n throw new Error('Workspace ID not found in API key');\n }\n\n // Determine baseUrl from environment\n const baseUrl = DEFAULT_BASE_URLS[environment] || DEFAULT_BASE_URLS.live;\n\n return {\n environment,\n workspaceId,\n tenantId,\n baseUrl,\n };\n};\n\n","import { EventProperties } from '../api-client';\n\ntype TrackRequest = {\n eventName: string;\n eventProperties?: EventProperties;\n userProperties?: {\n email: string;\n }\n};\n\nexport const transformTrackRequestData = ({\n eventName,\n eventProperties,\n userProperties,\n}: TrackRequest) => {\n const transformedEvent = {\n type: eventName,\n data: eventProperties || {},\n timestamp: Date.now(),\n userEmail: userProperties?.email,\n };\n return JSON.stringify(transformedEvent);\n};\n\ntype IdentifyRequest = {\n email: string\n}\n\nexport const transformIdentifyRequestData = ({\n email\n}: IdentifyRequest) => {\n const transformedIdentify = {\n userEmail: email\n }\n return JSON.stringify(transformedIdentify);\n}","import {\n transformTrackRequestData,\n // transformIdentifyRequestData,\n} from './utils/request-transformations';\n\ntype ApiClientProps = {\n apiKey: string;\n baseUrl?: string;\n config: {\n workspaceId: string;\n tenantId?: string;\n };\n};\n\nexport type EventProperties = Record<string, any>;\n\ntype User = {\n email: string;\n};\n\nconst sdkConfig = {\n defaultHeaders: {\n 'Content-Type': 'application/json',\n },\n};\n\nconst API_PREFIX = 'sdk-prod';\n\nconst TRACK_ENDPOINT = `${API_PREFIX}/track`;\n// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;\n\nclass ApiClient {\n private apiKey: string;\n private baseUrl?: string;\n private workspaceId: string = '';\n private user?: User;\n\n constructor({ apiKey, baseUrl, config }: ApiClientProps) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.workspaceId = config.workspaceId;\n }\n\n // Wrapper function for fetch\n fetchWithConfig = (\n endpoint: string,\n options: RequestInit = { method: 'GET' }\n ) => {\n // Construct the full URL\n const url = `${this.getBaseUrl()}/${endpoint}`;\n\n // Merge the default headers with any headers provided in the options\n const headers = {\n ...sdkConfig.defaultHeaders,\n 'x-api-key': this.getApiKey(),\n ...(options.headers || {}),\n };\n\n // Merge the rest of the options with the headers\n const config = {\n ...options,\n headers,\n };\n\n // Execute the fetch call with the merged configuration\n return fetch(url, config);\n };\n\n getApiKey() {\n return this.apiKey;\n }\n\n getBaseUrl() {\n return this.baseUrl;\n }\n\n getWorkspaceId() {\n return this.workspaceId;\n }\n\n getUser() {\n return this.user;\n }\n\n identify(user: User) {\n this.user = user;\n // this.fetchWithConfig(IDENTIFY_USER_ENDPOINT, {\n // method: 'POST',\n // body: transformIdentifyRequestData({\n // ...user,\n // }),\n // });\n }\n\n track(eventName: string, eventProperties?: EventProperties, userEmail?: string) {\n // Use provided email, or fall back to identified user's email\n const email = userEmail || this.user?.email;\n \n if (!email) {\n throw new Error('User email must be provided either via identify() or as a parameter to track()');\n }\n \n this.fetchWithConfig(TRACK_ENDPOINT, {\n method: 'POST',\n body: transformTrackRequestData({\n eventName,\n eventProperties,\n userProperties: {\n email,\n },\n }),\n });\n }\n}\n\nexport default ApiClient;\n","import { sanitiseUrl } from '../utils/url-validator';\nimport { parseApiKey } from '../utils/api-key-parser';\nimport ApiClient from './../api-client';\n\ntype Config = {\n workspaceId: string;\n tenantId?: string;\n};\n\nclass SDKInstanceManager {\n private static instance: SDKInstanceManager;\n private isInitialised: boolean = false;\n private config: Config = { workspaceId: '' };\n private apiClient?: ApiClient;\n\n constructor() {\n if (!SDKInstanceManager.instance) {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n SDKInstanceManager.instance = this;\n }\n\n return SDKInstanceManager.instance;\n }\n\n /**\n * @throws Error in case validation of parameters fails\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns void\n */\n initialise(apiKey: string) {\n if (this.getIsInitialised()) {\n console.info('SDK is already initialised with API key');\n return;\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('SDK needs a valid API key to be initialised');\n }\n\n // Parse the API key to extract workspaceId, tenantId, and baseUrl for SDK configuration\n // The original unparsed API key will be sent to the API\n const parsed = parseApiKey(apiKey);\n \n this.config = {\n workspaceId: parsed.workspaceId,\n tenantId: parsed.tenantId,\n };\n \n const sanitisedUrl = sanitiseUrl(parsed.baseUrl);\n // Pass the original unparsed API key to ApiClient - it will be sent as-is to the API\n this.apiClient = new ApiClient({ apiKey, baseUrl: sanitisedUrl, config: this.config });\n this.isInitialised = true;\n }\n\n destroy() {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n }\n\n getIsInitialised() {\n return this.isInitialised;\n }\n\n getApiClient() {\n return this.apiClient;\n }\n\n getConfig() {\n return this.config;\n }\n}\n\nconst instance = new SDKInstanceManager();\nexport { instance as default };\n","import sdkInstanceManager from './../managers/sdk-instance-manager';\n\n/**\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns boolean indicating whether the initialisation of the sdk was successful or not\n */\nexport const initialise = (apiKey: string) => {\n try {\n sdkInstanceManager.initialise(apiKey);\n return true;\n } catch (e) {\n console.info((e as any)?.message);\n return false;\n }\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\nexport const identify = (user: { email: string }) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!user?.email) {\n console.error('User email must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.identify(user);\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\ntype Properties = Record<string, any>;\n\nexport const track = (eventName: string, eventProperties?: Properties, userEmail?: string) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!eventName || typeof eventName !== 'string') {\n console.error('Event name must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.track(eventName, eventProperties, userEmail);\n};\n"],"names":["urlRegex","isValidUrl","url","test","sanitiseUrl","sanitisedUrl","trim","Error","urlObject","URL","hostname","toLowerCase","pathname","replace","toString","e","DEFAULT_BASE_URLS","live","parseApiKey","apiKey","startsWith","parts","split","length","environment","prefix","withoutPrefix","substring","keyParts","tenantId","workspaceId","baseUrl","transformTrackRequestData","_ref","eventName","eventProperties","userProperties","transformedEvent","type","data","timestamp","Date","now","userEmail","email","JSON","stringify","sdkConfig","defaultHeaders","API_PREFIX","TRACK_ENDPOINT","ApiClient","config","endpoint","options","method","_this","getBaseUrl","headers","_extends","getApiKey","fetch","_proto","prototype","getWorkspaceId","getUser","user","identify","track","_this$user","fetchWithConfig","body","SDKInstanceManager","instance","isInitialised","initialise","getIsInitialised","console","info","parsed","apiClient","destroy","getApiClient","getConfig","sdkInstanceManager","message","error","_sdkInstanceManager$g"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"churnsignal-sdk-web.cjs.development.js","sources":["../src/utils/url-validator.ts","../src/utils/api-key-parser.ts","../src/utils/request-transformations.ts","../src/api-client.ts","../src/managers/sdk-instance-manager.ts","../src/core/initialise.ts","../src/core/identify.ts","../src/core/track.ts"],"sourcesContent":["const urlRegex = /^https?:\\/\\//;\n\nexport const isValidUrl = (url: string) => urlRegex.test(url);\n\nexport const sanitiseUrl = (url: string) => {\n // Trim whitespace\n const sanitisedUrl = url.trim();\n\n // Validate scheme\n if (!isValidUrl(url)) {\n throw new Error(\"URL must start with 'http://' or 'https://'\");\n }\n\n try {\n let urlObject = new URL(sanitisedUrl);\n\n urlObject.hostname = urlObject.hostname.toLowerCase();\n\n // Remove trailing slash\n if (urlObject.pathname !== '/') {\n urlObject.pathname = urlObject.pathname.replace(/\\/+$/, '') || '';\n }\n\n // Reconstruct the URL from its components\n // Note: The URL interface automatically handles encoding of the pathname\n return urlObject.toString().replace(/\\/+$/, '');\n } catch (e) {\n throw new Error('Invalid URL provided');\n }\n};\n","type ParsedApiKey = {\n environment: string;\n workspaceId: string;\n tenantId: string;\n baseUrl: string;\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n live: 'https://b3tac2zudh.execute-api.eu-central-1.amazonaws.com/'\n};\n\n/**\n * Parses an API key to extract workspaceId, tenantId, and baseUrl\n * Expected format: cs_{environment}_tenantId_workspaceId_secret\n * Matches backend parsing logic\n * \n * @param apiKey - The API key to parse\n * @returns ParsedApiKey object with extracted data\n * @throws Error if the API key format is invalid\n */\nexport const parseApiKey = (apiKey: string): ParsedApiKey => {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a non-empty string');\n }\n\n // Check if it starts with cs_ prefix\n if (!apiKey.startsWith('cs_')) {\n throw new Error('Invalid API key format. Must start with \"cs_\"');\n }\n\n // Find the environment (cs_live_, cs_test_, cs_dev_, etc.)\n const parts = apiKey.split('_');\n if (parts.length < 2) {\n throw new Error('Invalid API key format. Must include environment (e.g., cs_live_)');\n }\n\n const environment = parts[1];\n const prefix = `cs_${environment}_`;\n \n if (!apiKey.startsWith(prefix)) {\n throw new Error(`Invalid API key format. Must start with \"${prefix}\"`);\n }\n\n // Remove prefix (e.g., 'cs_live_')\n const withoutPrefix = apiKey.substring(prefix.length);\n\n // Split by underscore - format: tenantId_workspaceId_secret\n const keyParts = withoutPrefix.split('_');\n\n if (keyParts.length < 3) {\n throw new Error('Invalid API key format. Expected format: cs_{environment}_tenantId_workspaceId_secret');\n }\n\n const tenantId = keyParts[0];\n const workspaceId = keyParts[1];\n // The rest (keyParts[2] onwards) is the secret, but we don't need it for parsing\n\n if (!tenantId) {\n throw new Error('Tenant ID not found in API key');\n }\n\n if (!workspaceId) {\n throw new Error('Workspace ID not found in API key');\n }\n\n // Determine baseUrl from environment\n const baseUrl = DEFAULT_BASE_URLS[environment] || DEFAULT_BASE_URLS.live;\n\n return {\n environment,\n workspaceId,\n tenantId,\n baseUrl,\n };\n};\n\n","import { EventProperties } from '../api-client';\n\ntype TrackRequest = {\n eventName: string;\n eventProperties?: EventProperties;\n userProperties?: {\n email: string;\n }\n};\n\nexport const transformTrackRequestData = ({\n eventName,\n eventProperties,\n userProperties,\n}: TrackRequest) => {\n const transformedEvent = {\n type: eventName,\n data: eventProperties || {},\n timestamp: Date.now(),\n userEmail: userProperties?.email,\n };\n return JSON.stringify(transformedEvent);\n};\n\ntype IdentifyRequest = {\n email: string\n}\n\nexport const transformIdentifyRequestData = ({\n email\n}: IdentifyRequest) => {\n const transformedIdentify = {\n userEmail: email\n }\n return JSON.stringify(transformedIdentify);\n}","import {\n transformTrackRequestData,\n // transformIdentifyRequestData,\n} from './utils/request-transformations';\n\ntype ApiClientProps = {\n apiKey: string;\n baseUrl?: string;\n config: {\n workspaceId: string;\n tenantId?: string;\n };\n};\n\nexport type EventProperties = Record<string, any>;\n\ntype User = {\n email: string;\n};\n\nconst sdkConfig = {\n defaultHeaders: {\n 'Content-Type': 'application/json',\n },\n};\n\nconst API_PREFIX = 'prod';\n\nconst TRACK_ENDPOINT = `${API_PREFIX}/track`;\n// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;\n\nclass ApiClient {\n private apiKey: string;\n private baseUrl?: string;\n private workspaceId: string = '';\n private user?: User;\n\n constructor({ apiKey, baseUrl, config }: ApiClientProps) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.workspaceId = config.workspaceId;\n }\n\n // Wrapper function for fetch\n fetchWithConfig = (\n endpoint: string,\n options: RequestInit = { method: 'GET' }\n ) => {\n // Construct the full URL\n const url = `${this.getBaseUrl()}/${endpoint}`;\n\n // Merge the default headers with any headers provided in the options\n const headers = {\n ...sdkConfig.defaultHeaders,\n 'x-api-key': this.getApiKey(),\n ...(options.headers || {}),\n };\n\n // Merge the rest of the options with the headers\n const config = {\n ...options,\n headers,\n };\n\n // Execute the fetch call with the merged configuration\n return fetch(url, config);\n };\n\n getApiKey() {\n return this.apiKey;\n }\n\n getBaseUrl() {\n return this.baseUrl;\n }\n\n getWorkspaceId() {\n return this.workspaceId;\n }\n\n getUser() {\n return this.user;\n }\n\n identify(user: User) {\n this.user = user;\n // this.fetchWithConfig(IDENTIFY_USER_ENDPOINT, {\n // method: 'POST',\n // body: transformIdentifyRequestData({\n // ...user,\n // }),\n // });\n }\n\n track(eventName: string, eventProperties?: EventProperties, userEmail?: string) {\n // Use provided email, or fall back to identified user's email\n const email = userEmail || this.user?.email;\n \n if (!email) {\n throw new Error('User email must be provided either via identify() or as a parameter to track()');\n }\n \n this.fetchWithConfig(TRACK_ENDPOINT, {\n method: 'POST',\n body: transformTrackRequestData({\n eventName,\n eventProperties,\n userProperties: {\n email,\n },\n }),\n });\n }\n}\n\nexport default ApiClient;\n","import { sanitiseUrl } from '../utils/url-validator';\nimport { parseApiKey } from '../utils/api-key-parser';\nimport ApiClient from './../api-client';\n\ntype Config = {\n workspaceId: string;\n tenantId?: string;\n};\n\nclass SDKInstanceManager {\n private static instance: SDKInstanceManager;\n private isInitialised: boolean = false;\n private config: Config = { workspaceId: '' };\n private apiClient?: ApiClient;\n\n constructor() {\n if (!SDKInstanceManager.instance) {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n SDKInstanceManager.instance = this;\n }\n\n return SDKInstanceManager.instance;\n }\n\n /**\n * @throws Error in case validation of parameters fails\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns void\n */\n initialise(apiKey: string) {\n if (this.getIsInitialised()) {\n console.info('SDK is already initialised with API key');\n return;\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('SDK needs a valid API key to be initialised');\n }\n\n // Parse the API key to extract workspaceId, tenantId, and baseUrl for SDK configuration\n // The original unparsed API key will be sent to the API\n const parsed = parseApiKey(apiKey);\n \n this.config = {\n workspaceId: parsed.workspaceId,\n tenantId: parsed.tenantId,\n };\n \n const sanitisedUrl = sanitiseUrl(parsed.baseUrl);\n // Pass the original unparsed API key to ApiClient - it will be sent as-is to the API\n this.apiClient = new ApiClient({ apiKey, baseUrl: sanitisedUrl, config: this.config });\n this.isInitialised = true;\n }\n\n destroy() {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n }\n\n getIsInitialised() {\n return this.isInitialised;\n }\n\n getApiClient() {\n return this.apiClient;\n }\n\n getConfig() {\n return this.config;\n }\n}\n\nconst instance = new SDKInstanceManager();\nexport { instance as default };\n","import sdkInstanceManager from './../managers/sdk-instance-manager';\n\n/**\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns boolean indicating whether the initialisation of the sdk was successful or not\n */\nexport const initialise = (apiKey: string) => {\n try {\n sdkInstanceManager.initialise(apiKey);\n return true;\n } catch (e) {\n console.info((e as any)?.message);\n return false;\n }\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\nexport const identify = (user: { email: string }) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!user?.email) {\n console.error('User email must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.identify(user);\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\ntype Properties = Record<string, any>;\n\nexport const track = (eventName: string, eventProperties?: Properties, userEmail?: string) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!eventName || typeof eventName !== 'string') {\n console.error('Event name must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.track(eventName, eventProperties, userEmail);\n};\n"],"names":["urlRegex","isValidUrl","url","test","sanitiseUrl","sanitisedUrl","trim","Error","urlObject","URL","hostname","toLowerCase","pathname","replace","toString","e","DEFAULT_BASE_URLS","live","parseApiKey","apiKey","startsWith","parts","split","length","environment","prefix","withoutPrefix","substring","keyParts","tenantId","workspaceId","baseUrl","transformTrackRequestData","_ref","eventName","eventProperties","userProperties","transformedEvent","type","data","timestamp","Date","now","userEmail","email","JSON","stringify","sdkConfig","defaultHeaders","API_PREFIX","TRACK_ENDPOINT","ApiClient","config","endpoint","options","method","_this","getBaseUrl","headers","_extends","getApiKey","fetch","_proto","prototype","getWorkspaceId","getUser","user","identify","track","_this$user","fetchWithConfig","body","SDKInstanceManager","instance","isInitialised","initialise","getIsInitialised","console","info","parsed","apiClient","destroy","getApiClient","getConfig","sdkInstanceManager","message","error","_sdkInstanceManager$g"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=/^https?:\/\//,e={live:"https://
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=/^https?:\/\//,e={live:"https://b3tac2zudh.execute-api.eu-central-1.amazonaws.com/"};function i(){return(i=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var r in i)Object.prototype.hasOwnProperty.call(i,r)&&(t[r]=i[r])}return t}).apply(this,arguments)}var r={"Content-Type":"application/json"},n=function(){function t(t){var e=this,n=t.apiKey,s=t.baseUrl,o=t.config;this.workspaceId="",this.fetchWithConfig=function(t,n){void 0===n&&(n={method:"GET"});var s=e.getBaseUrl()+"/"+t,o=i({},r,{"x-api-key":e.getApiKey()},n.headers||{}),a=i({},n,{headers:o});return fetch(s,a)},this.apiKey=n,this.baseUrl=s,this.workspaceId=o.workspaceId}var e=t.prototype;return e.getApiKey=function(){return this.apiKey},e.getBaseUrl=function(){return this.baseUrl},e.getWorkspaceId=function(){return this.workspaceId},e.getUser=function(){return this.user},e.identify=function(t){this.user=t},e.track=function(t,e,i){var r,n,s,o,a=i||(null==(r=this.user)?void 0:r.email);if(!a)throw new Error("User email must be provided either via identify() or as a parameter to track()");this.fetchWithConfig("prod/track",{method:"POST",body:(n={eventName:t,eventProperties:e,userProperties:{email:a}},s=n.userProperties,o={type:n.eventName,data:n.eventProperties||{},timestamp:Date.now(),userEmail:null==s?void 0:s.email},JSON.stringify(o))})},t}(),s=new(function(){function i(){return this.isInitialised=!1,this.config={workspaceId:""},i.instance||(this.config={workspaceId:""},this.isInitialised=!1,i.instance=this),i.instance}var r=i.prototype;return r.initialise=function(i){if(this.getIsInitialised())console.info("SDK is already initialised with API key");else{if(!i||"string"!=typeof i)throw new Error("SDK needs a valid API key to be initialised");var r=function(t){if(!t||"string"!=typeof t)throw new Error("API key must be a non-empty string");if(!t.startsWith("cs_"))throw new Error('Invalid API key format. Must start with "cs_"');var i=t.split("_");if(i.length<2)throw new Error("Invalid API key format. Must include environment (e.g., cs_live_)");var r=i[1],n="cs_"+r+"_";if(!t.startsWith(n))throw new Error('Invalid API key format. Must start with "'+n+'"');var s=t.substring(n.length).split("_");if(s.length<3)throw new Error("Invalid API key format. Expected format: cs_{environment}_tenantId_workspaceId_secret");var o=s[0],a=s[1];if(!o)throw new Error("Tenant ID not found in API key");if(!a)throw new Error("Workspace ID not found in API key");return{environment:r,workspaceId:a,tenantId:o,baseUrl:e[r]||e.live}}(i);this.config={workspaceId:r.workspaceId,tenantId:r.tenantId};var s=function(e){var i=e.trim();if(!function(e){return t.test(e)}(e))throw new Error("URL must start with 'http://' or 'https://'");try{var r=new URL(i);return r.hostname=r.hostname.toLowerCase(),"/"!==r.pathname&&(r.pathname=r.pathname.replace(/\/+$/,"")||""),r.toString().replace(/\/+$/,"")}catch(t){throw new Error("Invalid URL provided")}}(r.baseUrl);this.apiClient=new n({apiKey:i,baseUrl:s,config:this.config}),this.isInitialised=!0}},r.destroy=function(){this.config={workspaceId:""},this.isInitialised=!1},r.getIsInitialised=function(){return this.isInitialised},r.getApiClient=function(){return this.apiClient},r.getConfig=function(){return this.config},i}());exports.identify=function(t){var e;s.getIsInitialised()?null!=t&&t.email?null==(e=s.getApiClient())||e.identify(t):console.error("User email must be provided"):console.error("SDK must be initialised first")},exports.initialise=function(t){try{return s.initialise(t),!0}catch(t){return console.info(null==t?void 0:t.message),!1}},exports.track=function(t,e,i){var r;s.getIsInitialised()?t&&"string"==typeof t?null==(r=s.getApiClient())||r.track(t,e,i):console.error("Event name must be provided"):console.error("SDK must be initialised first")};
|
|
2
2
|
//# sourceMappingURL=churnsignal-sdk-web.cjs.production.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"churnsignal-sdk-web.cjs.production.min.js","sources":["../src/utils/url-validator.ts","../src/utils/api-key-parser.ts","../src/utils/request-transformations.ts","../src/api-client.ts","../src/managers/sdk-instance-manager.ts","../src/core/identify.ts","../src/core/initialise.ts","../src/core/track.ts"],"sourcesContent":["const urlRegex = /^https?:\\/\\//;\n\nexport const isValidUrl = (url: string) => urlRegex.test(url);\n\nexport const sanitiseUrl = (url: string) => {\n // Trim whitespace\n const sanitisedUrl = url.trim();\n\n // Validate scheme\n if (!isValidUrl(url)) {\n throw new Error(\"URL must start with 'http://' or 'https://'\");\n }\n\n try {\n let urlObject = new URL(sanitisedUrl);\n\n urlObject.hostname = urlObject.hostname.toLowerCase();\n\n // Remove trailing slash\n if (urlObject.pathname !== '/') {\n urlObject.pathname = urlObject.pathname.replace(/\\/+$/, '') || '';\n }\n\n // Reconstruct the URL from its components\n // Note: The URL interface automatically handles encoding of the pathname\n return urlObject.toString().replace(/\\/+$/, '');\n } catch (e) {\n throw new Error('Invalid URL provided');\n }\n};\n","type ParsedApiKey = {\n environment: string;\n workspaceId: string;\n tenantId: string;\n baseUrl: string;\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n live: 'https://rjwzrk7gs1.execute-api.eu-central-1.amazonaws.com/'\n};\n\n/**\n * Parses an API key to extract workspaceId, tenantId, and baseUrl\n * Expected format: cs_{environment}_tenantId_workspaceId_secret\n * Matches backend parsing logic\n * \n * @param apiKey - The API key to parse\n * @returns ParsedApiKey object with extracted data\n * @throws Error if the API key format is invalid\n */\nexport const parseApiKey = (apiKey: string): ParsedApiKey => {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a non-empty string');\n }\n\n // Check if it starts with cs_ prefix\n if (!apiKey.startsWith('cs_')) {\n throw new Error('Invalid API key format. Must start with \"cs_\"');\n }\n\n // Find the environment (cs_live_, cs_test_, cs_dev_, etc.)\n const parts = apiKey.split('_');\n if (parts.length < 2) {\n throw new Error('Invalid API key format. Must include environment (e.g., cs_live_)');\n }\n\n const environment = parts[1];\n const prefix = `cs_${environment}_`;\n \n if (!apiKey.startsWith(prefix)) {\n throw new Error(`Invalid API key format. Must start with \"${prefix}\"`);\n }\n\n // Remove prefix (e.g., 'cs_live_')\n const withoutPrefix = apiKey.substring(prefix.length);\n\n // Split by underscore - format: tenantId_workspaceId_secret\n const keyParts = withoutPrefix.split('_');\n\n if (keyParts.length < 3) {\n throw new Error('Invalid API key format. Expected format: cs_{environment}_tenantId_workspaceId_secret');\n }\n\n const tenantId = keyParts[0];\n const workspaceId = keyParts[1];\n // The rest (keyParts[2] onwards) is the secret, but we don't need it for parsing\n\n if (!tenantId) {\n throw new Error('Tenant ID not found in API key');\n }\n\n if (!workspaceId) {\n throw new Error('Workspace ID not found in API key');\n }\n\n // Determine baseUrl from environment\n const baseUrl = DEFAULT_BASE_URLS[environment] || DEFAULT_BASE_URLS.live;\n\n return {\n environment,\n workspaceId,\n tenantId,\n baseUrl,\n };\n};\n\n","import { EventProperties } from '../api-client';\n\ntype TrackRequest = {\n eventName: string;\n eventProperties?: EventProperties;\n userProperties?: {\n email: string;\n }\n};\n\nexport const transformTrackRequestData = ({\n eventName,\n eventProperties,\n userProperties,\n}: TrackRequest) => {\n const transformedEvent = {\n type: eventName,\n data: eventProperties || {},\n timestamp: Date.now(),\n userEmail: userProperties?.email,\n };\n return JSON.stringify(transformedEvent);\n};\n\ntype IdentifyRequest = {\n email: string\n}\n\nexport const transformIdentifyRequestData = ({\n email\n}: IdentifyRequest) => {\n const transformedIdentify = {\n userEmail: email\n }\n return JSON.stringify(transformedIdentify);\n}","import {\n transformTrackRequestData,\n // transformIdentifyRequestData,\n} from './utils/request-transformations';\n\ntype ApiClientProps = {\n apiKey: string;\n baseUrl?: string;\n config: {\n workspaceId: string;\n tenantId?: string;\n };\n};\n\nexport type EventProperties = Record<string, any>;\n\ntype User = {\n email: string;\n};\n\nconst sdkConfig = {\n defaultHeaders: {\n 'Content-Type': 'application/json',\n },\n};\n\nconst API_PREFIX = 'sdk-prod';\n\nconst TRACK_ENDPOINT = `${API_PREFIX}/track`;\n// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;\n\nclass ApiClient {\n private apiKey: string;\n private baseUrl?: string;\n private workspaceId: string = '';\n private user?: User;\n\n constructor({ apiKey, baseUrl, config }: ApiClientProps) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.workspaceId = config.workspaceId;\n }\n\n // Wrapper function for fetch\n fetchWithConfig = (\n endpoint: string,\n options: RequestInit = { method: 'GET' }\n ) => {\n // Construct the full URL\n const url = `${this.getBaseUrl()}/${endpoint}`;\n\n // Merge the default headers with any headers provided in the options\n const headers = {\n ...sdkConfig.defaultHeaders,\n 'x-api-key': this.getApiKey(),\n ...(options.headers || {}),\n };\n\n // Merge the rest of the options with the headers\n const config = {\n ...options,\n headers,\n };\n\n // Execute the fetch call with the merged configuration\n return fetch(url, config);\n };\n\n getApiKey() {\n return this.apiKey;\n }\n\n getBaseUrl() {\n return this.baseUrl;\n }\n\n getWorkspaceId() {\n return this.workspaceId;\n }\n\n getUser() {\n return this.user;\n }\n\n identify(user: User) {\n this.user = user;\n // this.fetchWithConfig(IDENTIFY_USER_ENDPOINT, {\n // method: 'POST',\n // body: transformIdentifyRequestData({\n // ...user,\n // }),\n // });\n }\n\n track(eventName: string, eventProperties?: EventProperties, userEmail?: string) {\n // Use provided email, or fall back to identified user's email\n const email = userEmail || this.user?.email;\n \n if (!email) {\n throw new Error('User email must be provided either via identify() or as a parameter to track()');\n }\n \n this.fetchWithConfig(TRACK_ENDPOINT, {\n method: 'POST',\n body: transformTrackRequestData({\n eventName,\n eventProperties,\n userProperties: {\n email,\n },\n }),\n });\n }\n}\n\nexport default ApiClient;\n","import { sanitiseUrl } from '../utils/url-validator';\nimport { parseApiKey } from '../utils/api-key-parser';\nimport ApiClient from './../api-client';\n\ntype Config = {\n workspaceId: string;\n tenantId?: string;\n};\n\nclass SDKInstanceManager {\n private static instance: SDKInstanceManager;\n private isInitialised: boolean = false;\n private config: Config = { workspaceId: '' };\n private apiClient?: ApiClient;\n\n constructor() {\n if (!SDKInstanceManager.instance) {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n SDKInstanceManager.instance = this;\n }\n\n return SDKInstanceManager.instance;\n }\n\n /**\n * @throws Error in case validation of parameters fails\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns void\n */\n initialise(apiKey: string) {\n if (this.getIsInitialised()) {\n console.info('SDK is already initialised with API key');\n return;\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('SDK needs a valid API key to be initialised');\n }\n\n // Parse the API key to extract workspaceId, tenantId, and baseUrl for SDK configuration\n // The original unparsed API key will be sent to the API\n const parsed = parseApiKey(apiKey);\n \n this.config = {\n workspaceId: parsed.workspaceId,\n tenantId: parsed.tenantId,\n };\n \n const sanitisedUrl = sanitiseUrl(parsed.baseUrl);\n // Pass the original unparsed API key to ApiClient - it will be sent as-is to the API\n this.apiClient = new ApiClient({ apiKey, baseUrl: sanitisedUrl, config: this.config });\n this.isInitialised = true;\n }\n\n destroy() {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n }\n\n getIsInitialised() {\n return this.isInitialised;\n }\n\n getApiClient() {\n return this.apiClient;\n }\n\n getConfig() {\n return this.config;\n }\n}\n\nconst instance = new SDKInstanceManager();\nexport { instance as default };\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\nexport const identify = (user: { email: string }) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!user?.email) {\n console.error('User email must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.identify(user);\n};\n","import sdkInstanceManager from './../managers/sdk-instance-manager';\n\n/**\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns boolean indicating whether the initialisation of the sdk was successful or not\n */\nexport const initialise = (apiKey: string) => {\n try {\n sdkInstanceManager.initialise(apiKey);\n return true;\n } catch (e) {\n console.info((e as any)?.message);\n return false;\n }\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\ntype Properties = Record<string, any>;\n\nexport const track = (eventName: string, eventProperties?: Properties, userEmail?: string) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!eventName || typeof eventName !== 'string') {\n console.error('Event name must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.track(eventName, eventProperties, userEmail);\n};\n"],"names":["urlRegex","DEFAULT_BASE_URLS","live","sdkConfig","Content-Type","ApiClient","_ref","apiKey","baseUrl","config","this","endpoint","options","method","url","_this","getBaseUrl","headers","_extends","x-api-key","getApiKey","fetch","workspaceId","_proto","prototype","getWorkspaceId","getUser","user","identify","track","eventName","eventProperties","userEmail","userProperties","transformedEvent","email","_this$user","Error","fetchWithConfig","API_PREFIX","body","type","data","timestamp","Date","now","JSON","stringify","instance","SDKInstanceManager","isInitialised","initialise","getIsInitialised","console","info","parsed","startsWith","parts","split","length","environment","prefix","keyParts","substring","tenantId","parseApiKey","sanitisedUrl","trim","test","isValidUrl","urlObject","URL","hostname","toLowerCase","pathname","replace","toString","e","sanitiseUrl","apiClient","destroy","getApiClient","getConfig","sdkInstanceManager","_sdkInstanceManager$g","error","message"],"mappings":"oEAAA,IAAMA,EAAW,eCOXC,EAA4C,CAChDC,KAAM,iSCED,ICUDC,EACY,CACdC,eAAgB,oBASdC,aAMJ,SAAAA,EAAAC,cAAcC,EAAMD,EAANC,OAAQC,EAAOF,EAAPE,QAASC,EAAMH,EAANG,OAHvBC,iBAAsB,GAU9BA,qBAAkB,SAChBC,EACAC,YAAAA,IAAAA,EAAuB,CAAEC,OAAQ,QAGjC,IAAMC,EAASC,EAAKC,iBAAgBL,EAG9BM,EAAOC,KACRf,GACHgB,YAAaJ,EAAKK,aACdR,EAAQK,SAAW,IAInBR,EAAMS,KACPN,GACHK,QAAAA,IAIF,OAAOI,MAAMP,EAAKL,IA3BlBC,KAAKH,OAASA,EACdG,KAAKF,QAAUA,EACfE,KAAKY,YAAcb,EAAOa,YAC3B,IAAAC,EAAAlB,EAAAmB,UAuEA,OAvEAD,EA2BDH,UAAA,WACE,OAAOV,KAAKH,QACbgB,EAEDP,WAAA,WACE,OAAON,KAAKF,SACbe,EAEDE,eAAA,WACE,OAAOf,KAAKY,aACbC,EAEDG,QAAA,WACE,OAAOhB,KAAKiB,MACbJ,EAEDK,SAAA,SAASD,GACPjB,KAAKiB,KAAOA,GAObJ,EAEDM,MAAA,SAAMC,EAAmBC,EAAmCC,SDpFxB1B,EAGpC2B,EAEMC,ECiFEC,EAAQH,WAASI,EAAI1B,KAAKiB,aAALS,EAAWD,OAEtC,IAAKA,EACH,MAAM,IAAIE,MAAM,kFAGlB3B,KAAK4B,gBA1EiBC,iBA0Ee,CACnC1B,OAAQ,OACR2B,MD9FgClC,EC8FA,CAC9BwB,UAAAA,EACAC,gBAAAA,EACAE,eAAgB,CACdE,MAAAA,ID/FRF,EAAc3B,EAAd2B,eAEMC,EAAmB,CACvBO,KALOnC,EAATwB,UAMEY,KALapC,EAAfyB,iBAK2B,GACzBY,UAAWC,KAAKC,MAChBb,gBAAWC,SAAAA,EAAgBE,OAEtBW,KAAKC,UAAUb,OC2FrB7B,KCrCG2C,EAAW,eA5Df,SAAAC,IAOE,OAXMvC,oBAAyB,EACzBA,YAAiB,CAAEY,YAAa,IAIjC2B,EAAmBD,WACtBtC,KAAKD,OAAS,CAAEa,YAAa,IAC7BZ,KAAKwC,eAAgB,EACrBD,EAAmBD,SAAWtC,MAGzBuC,EAAmBD,SAG5B,IAAAzB,EAAA0B,EAAAzB,UA+CC,OA/CDD,EAQA4B,WAAA,SAAW5C,GACT,GAAIG,KAAK0C,mBACPC,QAAQC,KAAK,+CADf,CAIA,IAAK/C,GAA4B,iBAAXA,EACpB,MAAM,IAAI8B,MAAM,+CAKlB,IAAMkB,EHxBiB,SAAChD,GAC1B,IAAKA,GAA4B,iBAAXA,EACpB,MAAM,IAAI8B,MAAM,sCAIlB,IAAK9B,EAAOiD,WAAW,OACrB,MAAM,IAAInB,MAAM,iDAIlB,IAAMoB,EAAQlD,EAAOmD,MAAM,KAC3B,GAAID,EAAME,OAAS,EACjB,MAAM,IAAItB,MAAM,qEAGlB,IAAMuB,EAAcH,EAAM,GACpBI,QAAeD,MAErB,IAAKrD,EAAOiD,WAAWK,GACrB,MAAM,IAAIxB,kDAAkDwB,OAI9D,IAGMC,EAHgBvD,EAAOwD,UAAUF,EAAOF,QAGfD,MAAM,KAErC,GAAII,EAASH,OAAS,EACpB,MAAM,IAAItB,MAAM,yFAGlB,IAAM2B,EAAWF,EAAS,GACpBxC,EAAcwC,EAAS,GAG7B,IAAKE,EACH,MAAM,IAAI3B,MAAM,kCAGlB,IAAKf,EACH,MAAM,IAAIe,MAAM,qCAMlB,MAAO,CACLuB,YAAAA,EACAtC,YAAAA,EACA0C,SAAAA,EACAxD,QANcP,EAAkB2D,IAAgB3D,EAAkBC,MGtBnD+D,CAAY1D,GAE3BG,KAAKD,OAAS,CACZa,YAAaiC,EAAOjC,YACpB0C,SAAUT,EAAOS,UAGnB,IAAME,EJ/CiB,SAACpD,GAE1B,IAAMoD,EAAepD,EAAIqD,OAGzB,IAPwB,SAACrD,GAAW,OAAKd,EAASoE,KAAKtD,GAOlDuD,CAAWvD,GACd,MAAM,IAAIuB,MAAM,+CAGlB,IACE,IAAIiC,EAAY,IAAIC,IAAIL,GAWxB,OATAI,EAAUE,SAAWF,EAAUE,SAASC,cAGb,MAAvBH,EAAUI,WACZJ,EAAUI,SAAWJ,EAAUI,SAASC,QAAQ,OAAQ,KAAO,IAK1DL,EAAUM,WAAWD,QAAQ,OAAQ,IAC5C,MAAOE,GACP,MAAM,IAAIxC,MAAM,yBIwBKyC,CAAYvB,EAAO/C,SAExCE,KAAKqE,UAAY,IAAI1E,EAAU,CAAEE,OAAAA,EAAQC,QAAS0D,EAAczD,OAAQC,KAAKD,SAC7EC,KAAKwC,eAAgB,IACtB3B,EAEDyD,QAAA,WACEtE,KAAKD,OAAS,CAAEa,YAAa,IAC7BZ,KAAKwC,eAAgB,GACtB3B,EAED6B,iBAAA,WACE,OAAO1C,KAAKwC,eACb3B,EAED0D,aAAA,WACE,OAAOvE,KAAKqE,WACbxD,EAED2D,UAAA,WACE,OAAOxE,KAAKD,QACbwC,uBCtEqB,SAACtB,SAClBwD,EAAmB/B,yBAInBzB,GAAAA,EAAMQ,aAIXiD,EAAAD,EAAmBF,iBAAnBG,EAAmCxD,SAASD,GAH1C0B,QAAQgC,MAAM,+BAJdhC,QAAQgC,MAAM,qDCKQ,SAAC9E,GACzB,IAEE,OADA4E,EAAmBhC,WAAW5C,IACvB,EACP,MAAOsE,GAEP,OADAxB,QAAQC,WAAMuB,SAAAA,EAAWS,UAClB,kBCXU,SAACxD,EAAmBC,EAA8BC,SAChEmD,EAAmB/B,mBAInBtB,GAAkC,iBAAdA,SAIzBsD,EAAAD,EAAmBF,iBAAnBG,EAAmCvD,MAAMC,EAAWC,EAAiBC,GAHnEqB,QAAQgC,MAAM,+BAJdhC,QAAQgC,MAAM"}
|
|
1
|
+
{"version":3,"file":"churnsignal-sdk-web.cjs.production.min.js","sources":["../src/utils/url-validator.ts","../src/utils/api-key-parser.ts","../src/utils/request-transformations.ts","../src/api-client.ts","../src/managers/sdk-instance-manager.ts","../src/core/identify.ts","../src/core/initialise.ts","../src/core/track.ts"],"sourcesContent":["const urlRegex = /^https?:\\/\\//;\n\nexport const isValidUrl = (url: string) => urlRegex.test(url);\n\nexport const sanitiseUrl = (url: string) => {\n // Trim whitespace\n const sanitisedUrl = url.trim();\n\n // Validate scheme\n if (!isValidUrl(url)) {\n throw new Error(\"URL must start with 'http://' or 'https://'\");\n }\n\n try {\n let urlObject = new URL(sanitisedUrl);\n\n urlObject.hostname = urlObject.hostname.toLowerCase();\n\n // Remove trailing slash\n if (urlObject.pathname !== '/') {\n urlObject.pathname = urlObject.pathname.replace(/\\/+$/, '') || '';\n }\n\n // Reconstruct the URL from its components\n // Note: The URL interface automatically handles encoding of the pathname\n return urlObject.toString().replace(/\\/+$/, '');\n } catch (e) {\n throw new Error('Invalid URL provided');\n }\n};\n","type ParsedApiKey = {\n environment: string;\n workspaceId: string;\n tenantId: string;\n baseUrl: string;\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n live: 'https://b3tac2zudh.execute-api.eu-central-1.amazonaws.com/'\n};\n\n/**\n * Parses an API key to extract workspaceId, tenantId, and baseUrl\n * Expected format: cs_{environment}_tenantId_workspaceId_secret\n * Matches backend parsing logic\n * \n * @param apiKey - The API key to parse\n * @returns ParsedApiKey object with extracted data\n * @throws Error if the API key format is invalid\n */\nexport const parseApiKey = (apiKey: string): ParsedApiKey => {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a non-empty string');\n }\n\n // Check if it starts with cs_ prefix\n if (!apiKey.startsWith('cs_')) {\n throw new Error('Invalid API key format. Must start with \"cs_\"');\n }\n\n // Find the environment (cs_live_, cs_test_, cs_dev_, etc.)\n const parts = apiKey.split('_');\n if (parts.length < 2) {\n throw new Error('Invalid API key format. Must include environment (e.g., cs_live_)');\n }\n\n const environment = parts[1];\n const prefix = `cs_${environment}_`;\n \n if (!apiKey.startsWith(prefix)) {\n throw new Error(`Invalid API key format. Must start with \"${prefix}\"`);\n }\n\n // Remove prefix (e.g., 'cs_live_')\n const withoutPrefix = apiKey.substring(prefix.length);\n\n // Split by underscore - format: tenantId_workspaceId_secret\n const keyParts = withoutPrefix.split('_');\n\n if (keyParts.length < 3) {\n throw new Error('Invalid API key format. Expected format: cs_{environment}_tenantId_workspaceId_secret');\n }\n\n const tenantId = keyParts[0];\n const workspaceId = keyParts[1];\n // The rest (keyParts[2] onwards) is the secret, but we don't need it for parsing\n\n if (!tenantId) {\n throw new Error('Tenant ID not found in API key');\n }\n\n if (!workspaceId) {\n throw new Error('Workspace ID not found in API key');\n }\n\n // Determine baseUrl from environment\n const baseUrl = DEFAULT_BASE_URLS[environment] || DEFAULT_BASE_URLS.live;\n\n return {\n environment,\n workspaceId,\n tenantId,\n baseUrl,\n };\n};\n\n","import { EventProperties } from '../api-client';\n\ntype TrackRequest = {\n eventName: string;\n eventProperties?: EventProperties;\n userProperties?: {\n email: string;\n }\n};\n\nexport const transformTrackRequestData = ({\n eventName,\n eventProperties,\n userProperties,\n}: TrackRequest) => {\n const transformedEvent = {\n type: eventName,\n data: eventProperties || {},\n timestamp: Date.now(),\n userEmail: userProperties?.email,\n };\n return JSON.stringify(transformedEvent);\n};\n\ntype IdentifyRequest = {\n email: string\n}\n\nexport const transformIdentifyRequestData = ({\n email\n}: IdentifyRequest) => {\n const transformedIdentify = {\n userEmail: email\n }\n return JSON.stringify(transformedIdentify);\n}","import {\n transformTrackRequestData,\n // transformIdentifyRequestData,\n} from './utils/request-transformations';\n\ntype ApiClientProps = {\n apiKey: string;\n baseUrl?: string;\n config: {\n workspaceId: string;\n tenantId?: string;\n };\n};\n\nexport type EventProperties = Record<string, any>;\n\ntype User = {\n email: string;\n};\n\nconst sdkConfig = {\n defaultHeaders: {\n 'Content-Type': 'application/json',\n },\n};\n\nconst API_PREFIX = 'prod';\n\nconst TRACK_ENDPOINT = `${API_PREFIX}/track`;\n// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;\n\nclass ApiClient {\n private apiKey: string;\n private baseUrl?: string;\n private workspaceId: string = '';\n private user?: User;\n\n constructor({ apiKey, baseUrl, config }: ApiClientProps) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.workspaceId = config.workspaceId;\n }\n\n // Wrapper function for fetch\n fetchWithConfig = (\n endpoint: string,\n options: RequestInit = { method: 'GET' }\n ) => {\n // Construct the full URL\n const url = `${this.getBaseUrl()}/${endpoint}`;\n\n // Merge the default headers with any headers provided in the options\n const headers = {\n ...sdkConfig.defaultHeaders,\n 'x-api-key': this.getApiKey(),\n ...(options.headers || {}),\n };\n\n // Merge the rest of the options with the headers\n const config = {\n ...options,\n headers,\n };\n\n // Execute the fetch call with the merged configuration\n return fetch(url, config);\n };\n\n getApiKey() {\n return this.apiKey;\n }\n\n getBaseUrl() {\n return this.baseUrl;\n }\n\n getWorkspaceId() {\n return this.workspaceId;\n }\n\n getUser() {\n return this.user;\n }\n\n identify(user: User) {\n this.user = user;\n // this.fetchWithConfig(IDENTIFY_USER_ENDPOINT, {\n // method: 'POST',\n // body: transformIdentifyRequestData({\n // ...user,\n // }),\n // });\n }\n\n track(eventName: string, eventProperties?: EventProperties, userEmail?: string) {\n // Use provided email, or fall back to identified user's email\n const email = userEmail || this.user?.email;\n \n if (!email) {\n throw new Error('User email must be provided either via identify() or as a parameter to track()');\n }\n \n this.fetchWithConfig(TRACK_ENDPOINT, {\n method: 'POST',\n body: transformTrackRequestData({\n eventName,\n eventProperties,\n userProperties: {\n email,\n },\n }),\n });\n }\n}\n\nexport default ApiClient;\n","import { sanitiseUrl } from '../utils/url-validator';\nimport { parseApiKey } from '../utils/api-key-parser';\nimport ApiClient from './../api-client';\n\ntype Config = {\n workspaceId: string;\n tenantId?: string;\n};\n\nclass SDKInstanceManager {\n private static instance: SDKInstanceManager;\n private isInitialised: boolean = false;\n private config: Config = { workspaceId: '' };\n private apiClient?: ApiClient;\n\n constructor() {\n if (!SDKInstanceManager.instance) {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n SDKInstanceManager.instance = this;\n }\n\n return SDKInstanceManager.instance;\n }\n\n /**\n * @throws Error in case validation of parameters fails\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns void\n */\n initialise(apiKey: string) {\n if (this.getIsInitialised()) {\n console.info('SDK is already initialised with API key');\n return;\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('SDK needs a valid API key to be initialised');\n }\n\n // Parse the API key to extract workspaceId, tenantId, and baseUrl for SDK configuration\n // The original unparsed API key will be sent to the API\n const parsed = parseApiKey(apiKey);\n \n this.config = {\n workspaceId: parsed.workspaceId,\n tenantId: parsed.tenantId,\n };\n \n const sanitisedUrl = sanitiseUrl(parsed.baseUrl);\n // Pass the original unparsed API key to ApiClient - it will be sent as-is to the API\n this.apiClient = new ApiClient({ apiKey, baseUrl: sanitisedUrl, config: this.config });\n this.isInitialised = true;\n }\n\n destroy() {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n }\n\n getIsInitialised() {\n return this.isInitialised;\n }\n\n getApiClient() {\n return this.apiClient;\n }\n\n getConfig() {\n return this.config;\n }\n}\n\nconst instance = new SDKInstanceManager();\nexport { instance as default };\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\nexport const identify = (user: { email: string }) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!user?.email) {\n console.error('User email must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.identify(user);\n};\n","import sdkInstanceManager from './../managers/sdk-instance-manager';\n\n/**\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns boolean indicating whether the initialisation of the sdk was successful or not\n */\nexport const initialise = (apiKey: string) => {\n try {\n sdkInstanceManager.initialise(apiKey);\n return true;\n } catch (e) {\n console.info((e as any)?.message);\n return false;\n }\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\ntype Properties = Record<string, any>;\n\nexport const track = (eventName: string, eventProperties?: Properties, userEmail?: string) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!eventName || typeof eventName !== 'string') {\n console.error('Event name must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.track(eventName, eventProperties, userEmail);\n};\n"],"names":["urlRegex","DEFAULT_BASE_URLS","live","sdkConfig","Content-Type","ApiClient","_ref","apiKey","baseUrl","config","this","endpoint","options","method","url","_this","getBaseUrl","headers","_extends","x-api-key","getApiKey","fetch","workspaceId","_proto","prototype","getWorkspaceId","getUser","user","identify","track","eventName","eventProperties","userEmail","userProperties","transformedEvent","email","_this$user","Error","fetchWithConfig","API_PREFIX","body","type","data","timestamp","Date","now","JSON","stringify","instance","SDKInstanceManager","isInitialised","initialise","getIsInitialised","console","info","parsed","startsWith","parts","split","length","environment","prefix","keyParts","substring","tenantId","parseApiKey","sanitisedUrl","trim","test","isValidUrl","urlObject","URL","hostname","toLowerCase","pathname","replace","toString","e","sanitiseUrl","apiClient","destroy","getApiClient","getConfig","sdkInstanceManager","_sdkInstanceManager$g","error","message"],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ var sanitiseUrl = function sanitiseUrl(url) {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
var DEFAULT_BASE_URLS = {
|
|
28
|
-
live: 'https://
|
|
28
|
+
live: 'https://b3tac2zudh.execute-api.eu-central-1.amazonaws.com/'
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
31
31
|
* Parses an API key to extract workspaceId, tenantId, and baseUrl
|
|
@@ -113,7 +113,7 @@ var sdkConfig = {
|
|
|
113
113
|
'Content-Type': 'application/json'
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
|
-
var API_PREFIX = '
|
|
116
|
+
var API_PREFIX = 'prod';
|
|
117
117
|
var TRACK_ENDPOINT = API_PREFIX + "/track";
|
|
118
118
|
// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;
|
|
119
119
|
var ApiClient = /*#__PURE__*/function () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"churnsignal-sdk-web.esm.js","sources":["../src/utils/url-validator.ts","../src/utils/api-key-parser.ts","../src/utils/request-transformations.ts","../src/api-client.ts","../src/managers/sdk-instance-manager.ts","../src/core/initialise.ts","../src/core/identify.ts","../src/core/track.ts"],"sourcesContent":["const urlRegex = /^https?:\\/\\//;\n\nexport const isValidUrl = (url: string) => urlRegex.test(url);\n\nexport const sanitiseUrl = (url: string) => {\n // Trim whitespace\n const sanitisedUrl = url.trim();\n\n // Validate scheme\n if (!isValidUrl(url)) {\n throw new Error(\"URL must start with 'http://' or 'https://'\");\n }\n\n try {\n let urlObject = new URL(sanitisedUrl);\n\n urlObject.hostname = urlObject.hostname.toLowerCase();\n\n // Remove trailing slash\n if (urlObject.pathname !== '/') {\n urlObject.pathname = urlObject.pathname.replace(/\\/+$/, '') || '';\n }\n\n // Reconstruct the URL from its components\n // Note: The URL interface automatically handles encoding of the pathname\n return urlObject.toString().replace(/\\/+$/, '');\n } catch (e) {\n throw new Error('Invalid URL provided');\n }\n};\n","type ParsedApiKey = {\n environment: string;\n workspaceId: string;\n tenantId: string;\n baseUrl: string;\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n live: 'https://rjwzrk7gs1.execute-api.eu-central-1.amazonaws.com/'\n};\n\n/**\n * Parses an API key to extract workspaceId, tenantId, and baseUrl\n * Expected format: cs_{environment}_tenantId_workspaceId_secret\n * Matches backend parsing logic\n * \n * @param apiKey - The API key to parse\n * @returns ParsedApiKey object with extracted data\n * @throws Error if the API key format is invalid\n */\nexport const parseApiKey = (apiKey: string): ParsedApiKey => {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a non-empty string');\n }\n\n // Check if it starts with cs_ prefix\n if (!apiKey.startsWith('cs_')) {\n throw new Error('Invalid API key format. Must start with \"cs_\"');\n }\n\n // Find the environment (cs_live_, cs_test_, cs_dev_, etc.)\n const parts = apiKey.split('_');\n if (parts.length < 2) {\n throw new Error('Invalid API key format. Must include environment (e.g., cs_live_)');\n }\n\n const environment = parts[1];\n const prefix = `cs_${environment}_`;\n \n if (!apiKey.startsWith(prefix)) {\n throw new Error(`Invalid API key format. Must start with \"${prefix}\"`);\n }\n\n // Remove prefix (e.g., 'cs_live_')\n const withoutPrefix = apiKey.substring(prefix.length);\n\n // Split by underscore - format: tenantId_workspaceId_secret\n const keyParts = withoutPrefix.split('_');\n\n if (keyParts.length < 3) {\n throw new Error('Invalid API key format. Expected format: cs_{environment}_tenantId_workspaceId_secret');\n }\n\n const tenantId = keyParts[0];\n const workspaceId = keyParts[1];\n // The rest (keyParts[2] onwards) is the secret, but we don't need it for parsing\n\n if (!tenantId) {\n throw new Error('Tenant ID not found in API key');\n }\n\n if (!workspaceId) {\n throw new Error('Workspace ID not found in API key');\n }\n\n // Determine baseUrl from environment\n const baseUrl = DEFAULT_BASE_URLS[environment] || DEFAULT_BASE_URLS.live;\n\n return {\n environment,\n workspaceId,\n tenantId,\n baseUrl,\n };\n};\n\n","import { EventProperties } from '../api-client';\n\ntype TrackRequest = {\n eventName: string;\n eventProperties?: EventProperties;\n userProperties?: {\n email: string;\n }\n};\n\nexport const transformTrackRequestData = ({\n eventName,\n eventProperties,\n userProperties,\n}: TrackRequest) => {\n const transformedEvent = {\n type: eventName,\n data: eventProperties || {},\n timestamp: Date.now(),\n userEmail: userProperties?.email,\n };\n return JSON.stringify(transformedEvent);\n};\n\ntype IdentifyRequest = {\n email: string\n}\n\nexport const transformIdentifyRequestData = ({\n email\n}: IdentifyRequest) => {\n const transformedIdentify = {\n userEmail: email\n }\n return JSON.stringify(transformedIdentify);\n}","import {\n transformTrackRequestData,\n // transformIdentifyRequestData,\n} from './utils/request-transformations';\n\ntype ApiClientProps = {\n apiKey: string;\n baseUrl?: string;\n config: {\n workspaceId: string;\n tenantId?: string;\n };\n};\n\nexport type EventProperties = Record<string, any>;\n\ntype User = {\n email: string;\n};\n\nconst sdkConfig = {\n defaultHeaders: {\n 'Content-Type': 'application/json',\n },\n};\n\nconst API_PREFIX = 'sdk-prod';\n\nconst TRACK_ENDPOINT = `${API_PREFIX}/track`;\n// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;\n\nclass ApiClient {\n private apiKey: string;\n private baseUrl?: string;\n private workspaceId: string = '';\n private user?: User;\n\n constructor({ apiKey, baseUrl, config }: ApiClientProps) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.workspaceId = config.workspaceId;\n }\n\n // Wrapper function for fetch\n fetchWithConfig = (\n endpoint: string,\n options: RequestInit = { method: 'GET' }\n ) => {\n // Construct the full URL\n const url = `${this.getBaseUrl()}/${endpoint}`;\n\n // Merge the default headers with any headers provided in the options\n const headers = {\n ...sdkConfig.defaultHeaders,\n 'x-api-key': this.getApiKey(),\n ...(options.headers || {}),\n };\n\n // Merge the rest of the options with the headers\n const config = {\n ...options,\n headers,\n };\n\n // Execute the fetch call with the merged configuration\n return fetch(url, config);\n };\n\n getApiKey() {\n return this.apiKey;\n }\n\n getBaseUrl() {\n return this.baseUrl;\n }\n\n getWorkspaceId() {\n return this.workspaceId;\n }\n\n getUser() {\n return this.user;\n }\n\n identify(user: User) {\n this.user = user;\n // this.fetchWithConfig(IDENTIFY_USER_ENDPOINT, {\n // method: 'POST',\n // body: transformIdentifyRequestData({\n // ...user,\n // }),\n // });\n }\n\n track(eventName: string, eventProperties?: EventProperties, userEmail?: string) {\n // Use provided email, or fall back to identified user's email\n const email = userEmail || this.user?.email;\n \n if (!email) {\n throw new Error('User email must be provided either via identify() or as a parameter to track()');\n }\n \n this.fetchWithConfig(TRACK_ENDPOINT, {\n method: 'POST',\n body: transformTrackRequestData({\n eventName,\n eventProperties,\n userProperties: {\n email,\n },\n }),\n });\n }\n}\n\nexport default ApiClient;\n","import { sanitiseUrl } from '../utils/url-validator';\nimport { parseApiKey } from '../utils/api-key-parser';\nimport ApiClient from './../api-client';\n\ntype Config = {\n workspaceId: string;\n tenantId?: string;\n};\n\nclass SDKInstanceManager {\n private static instance: SDKInstanceManager;\n private isInitialised: boolean = false;\n private config: Config = { workspaceId: '' };\n private apiClient?: ApiClient;\n\n constructor() {\n if (!SDKInstanceManager.instance) {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n SDKInstanceManager.instance = this;\n }\n\n return SDKInstanceManager.instance;\n }\n\n /**\n * @throws Error in case validation of parameters fails\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns void\n */\n initialise(apiKey: string) {\n if (this.getIsInitialised()) {\n console.info('SDK is already initialised with API key');\n return;\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('SDK needs a valid API key to be initialised');\n }\n\n // Parse the API key to extract workspaceId, tenantId, and baseUrl for SDK configuration\n // The original unparsed API key will be sent to the API\n const parsed = parseApiKey(apiKey);\n \n this.config = {\n workspaceId: parsed.workspaceId,\n tenantId: parsed.tenantId,\n };\n \n const sanitisedUrl = sanitiseUrl(parsed.baseUrl);\n // Pass the original unparsed API key to ApiClient - it will be sent as-is to the API\n this.apiClient = new ApiClient({ apiKey, baseUrl: sanitisedUrl, config: this.config });\n this.isInitialised = true;\n }\n\n destroy() {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n }\n\n getIsInitialised() {\n return this.isInitialised;\n }\n\n getApiClient() {\n return this.apiClient;\n }\n\n getConfig() {\n return this.config;\n }\n}\n\nconst instance = new SDKInstanceManager();\nexport { instance as default };\n","import sdkInstanceManager from './../managers/sdk-instance-manager';\n\n/**\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns boolean indicating whether the initialisation of the sdk was successful or not\n */\nexport const initialise = (apiKey: string) => {\n try {\n sdkInstanceManager.initialise(apiKey);\n return true;\n } catch (e) {\n console.info((e as any)?.message);\n return false;\n }\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\nexport const identify = (user: { email: string }) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!user?.email) {\n console.error('User email must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.identify(user);\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\ntype Properties = Record<string, any>;\n\nexport const track = (eventName: string, eventProperties?: Properties, userEmail?: string) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!eventName || typeof eventName !== 'string') {\n console.error('Event name must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.track(eventName, eventProperties, userEmail);\n};\n"],"names":["urlRegex","isValidUrl","url","test","sanitiseUrl","sanitisedUrl","trim","Error","urlObject","URL","hostname","toLowerCase","pathname","replace","toString","e","DEFAULT_BASE_URLS","live","parseApiKey","apiKey","startsWith","parts","split","length","environment","prefix","withoutPrefix","substring","keyParts","tenantId","workspaceId","baseUrl","transformTrackRequestData","_ref","eventName","eventProperties","userProperties","transformedEvent","type","data","timestamp","Date","now","userEmail","email","JSON","stringify","sdkConfig","defaultHeaders","API_PREFIX","TRACK_ENDPOINT","ApiClient","config","endpoint","options","method","_this","getBaseUrl","headers","_extends","getApiKey","fetch","_proto","prototype","getWorkspaceId","getUser","user","identify","track","_this$user","fetchWithConfig","body","SDKInstanceManager","instance","isInitialised","initialise","getIsInitialised","console","info","parsed","apiClient","destroy","getApiClient","getConfig","sdkInstanceManager","message","error","_sdkInstanceManager$g"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"churnsignal-sdk-web.esm.js","sources":["../src/utils/url-validator.ts","../src/utils/api-key-parser.ts","../src/utils/request-transformations.ts","../src/api-client.ts","../src/managers/sdk-instance-manager.ts","../src/core/initialise.ts","../src/core/identify.ts","../src/core/track.ts"],"sourcesContent":["const urlRegex = /^https?:\\/\\//;\n\nexport const isValidUrl = (url: string) => urlRegex.test(url);\n\nexport const sanitiseUrl = (url: string) => {\n // Trim whitespace\n const sanitisedUrl = url.trim();\n\n // Validate scheme\n if (!isValidUrl(url)) {\n throw new Error(\"URL must start with 'http://' or 'https://'\");\n }\n\n try {\n let urlObject = new URL(sanitisedUrl);\n\n urlObject.hostname = urlObject.hostname.toLowerCase();\n\n // Remove trailing slash\n if (urlObject.pathname !== '/') {\n urlObject.pathname = urlObject.pathname.replace(/\\/+$/, '') || '';\n }\n\n // Reconstruct the URL from its components\n // Note: The URL interface automatically handles encoding of the pathname\n return urlObject.toString().replace(/\\/+$/, '');\n } catch (e) {\n throw new Error('Invalid URL provided');\n }\n};\n","type ParsedApiKey = {\n environment: string;\n workspaceId: string;\n tenantId: string;\n baseUrl: string;\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n live: 'https://b3tac2zudh.execute-api.eu-central-1.amazonaws.com/'\n};\n\n/**\n * Parses an API key to extract workspaceId, tenantId, and baseUrl\n * Expected format: cs_{environment}_tenantId_workspaceId_secret\n * Matches backend parsing logic\n * \n * @param apiKey - The API key to parse\n * @returns ParsedApiKey object with extracted data\n * @throws Error if the API key format is invalid\n */\nexport const parseApiKey = (apiKey: string): ParsedApiKey => {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a non-empty string');\n }\n\n // Check if it starts with cs_ prefix\n if (!apiKey.startsWith('cs_')) {\n throw new Error('Invalid API key format. Must start with \"cs_\"');\n }\n\n // Find the environment (cs_live_, cs_test_, cs_dev_, etc.)\n const parts = apiKey.split('_');\n if (parts.length < 2) {\n throw new Error('Invalid API key format. Must include environment (e.g., cs_live_)');\n }\n\n const environment = parts[1];\n const prefix = `cs_${environment}_`;\n \n if (!apiKey.startsWith(prefix)) {\n throw new Error(`Invalid API key format. Must start with \"${prefix}\"`);\n }\n\n // Remove prefix (e.g., 'cs_live_')\n const withoutPrefix = apiKey.substring(prefix.length);\n\n // Split by underscore - format: tenantId_workspaceId_secret\n const keyParts = withoutPrefix.split('_');\n\n if (keyParts.length < 3) {\n throw new Error('Invalid API key format. Expected format: cs_{environment}_tenantId_workspaceId_secret');\n }\n\n const tenantId = keyParts[0];\n const workspaceId = keyParts[1];\n // The rest (keyParts[2] onwards) is the secret, but we don't need it for parsing\n\n if (!tenantId) {\n throw new Error('Tenant ID not found in API key');\n }\n\n if (!workspaceId) {\n throw new Error('Workspace ID not found in API key');\n }\n\n // Determine baseUrl from environment\n const baseUrl = DEFAULT_BASE_URLS[environment] || DEFAULT_BASE_URLS.live;\n\n return {\n environment,\n workspaceId,\n tenantId,\n baseUrl,\n };\n};\n\n","import { EventProperties } from '../api-client';\n\ntype TrackRequest = {\n eventName: string;\n eventProperties?: EventProperties;\n userProperties?: {\n email: string;\n }\n};\n\nexport const transformTrackRequestData = ({\n eventName,\n eventProperties,\n userProperties,\n}: TrackRequest) => {\n const transformedEvent = {\n type: eventName,\n data: eventProperties || {},\n timestamp: Date.now(),\n userEmail: userProperties?.email,\n };\n return JSON.stringify(transformedEvent);\n};\n\ntype IdentifyRequest = {\n email: string\n}\n\nexport const transformIdentifyRequestData = ({\n email\n}: IdentifyRequest) => {\n const transformedIdentify = {\n userEmail: email\n }\n return JSON.stringify(transformedIdentify);\n}","import {\n transformTrackRequestData,\n // transformIdentifyRequestData,\n} from './utils/request-transformations';\n\ntype ApiClientProps = {\n apiKey: string;\n baseUrl?: string;\n config: {\n workspaceId: string;\n tenantId?: string;\n };\n};\n\nexport type EventProperties = Record<string, any>;\n\ntype User = {\n email: string;\n};\n\nconst sdkConfig = {\n defaultHeaders: {\n 'Content-Type': 'application/json',\n },\n};\n\nconst API_PREFIX = 'prod';\n\nconst TRACK_ENDPOINT = `${API_PREFIX}/track`;\n// const IDENTIFY_USER_ENDPOINT = `${API_PREFIX}/identify`;\n\nclass ApiClient {\n private apiKey: string;\n private baseUrl?: string;\n private workspaceId: string = '';\n private user?: User;\n\n constructor({ apiKey, baseUrl, config }: ApiClientProps) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl;\n this.workspaceId = config.workspaceId;\n }\n\n // Wrapper function for fetch\n fetchWithConfig = (\n endpoint: string,\n options: RequestInit = { method: 'GET' }\n ) => {\n // Construct the full URL\n const url = `${this.getBaseUrl()}/${endpoint}`;\n\n // Merge the default headers with any headers provided in the options\n const headers = {\n ...sdkConfig.defaultHeaders,\n 'x-api-key': this.getApiKey(),\n ...(options.headers || {}),\n };\n\n // Merge the rest of the options with the headers\n const config = {\n ...options,\n headers,\n };\n\n // Execute the fetch call with the merged configuration\n return fetch(url, config);\n };\n\n getApiKey() {\n return this.apiKey;\n }\n\n getBaseUrl() {\n return this.baseUrl;\n }\n\n getWorkspaceId() {\n return this.workspaceId;\n }\n\n getUser() {\n return this.user;\n }\n\n identify(user: User) {\n this.user = user;\n // this.fetchWithConfig(IDENTIFY_USER_ENDPOINT, {\n // method: 'POST',\n // body: transformIdentifyRequestData({\n // ...user,\n // }),\n // });\n }\n\n track(eventName: string, eventProperties?: EventProperties, userEmail?: string) {\n // Use provided email, or fall back to identified user's email\n const email = userEmail || this.user?.email;\n \n if (!email) {\n throw new Error('User email must be provided either via identify() or as a parameter to track()');\n }\n \n this.fetchWithConfig(TRACK_ENDPOINT, {\n method: 'POST',\n body: transformTrackRequestData({\n eventName,\n eventProperties,\n userProperties: {\n email,\n },\n }),\n });\n }\n}\n\nexport default ApiClient;\n","import { sanitiseUrl } from '../utils/url-validator';\nimport { parseApiKey } from '../utils/api-key-parser';\nimport ApiClient from './../api-client';\n\ntype Config = {\n workspaceId: string;\n tenantId?: string;\n};\n\nclass SDKInstanceManager {\n private static instance: SDKInstanceManager;\n private isInitialised: boolean = false;\n private config: Config = { workspaceId: '' };\n private apiClient?: ApiClient;\n\n constructor() {\n if (!SDKInstanceManager.instance) {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n SDKInstanceManager.instance = this;\n }\n\n return SDKInstanceManager.instance;\n }\n\n /**\n * @throws Error in case validation of parameters fails\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns void\n */\n initialise(apiKey: string) {\n if (this.getIsInitialised()) {\n console.info('SDK is already initialised with API key');\n return;\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('SDK needs a valid API key to be initialised');\n }\n\n // Parse the API key to extract workspaceId, tenantId, and baseUrl for SDK configuration\n // The original unparsed API key will be sent to the API\n const parsed = parseApiKey(apiKey);\n \n this.config = {\n workspaceId: parsed.workspaceId,\n tenantId: parsed.tenantId,\n };\n \n const sanitisedUrl = sanitiseUrl(parsed.baseUrl);\n // Pass the original unparsed API key to ApiClient - it will be sent as-is to the API\n this.apiClient = new ApiClient({ apiKey, baseUrl: sanitisedUrl, config: this.config });\n this.isInitialised = true;\n }\n\n destroy() {\n this.config = { workspaceId: '' };\n this.isInitialised = false;\n }\n\n getIsInitialised() {\n return this.isInitialised;\n }\n\n getApiClient() {\n return this.apiClient;\n }\n\n getConfig() {\n return this.config;\n }\n}\n\nconst instance = new SDKInstanceManager();\nexport { instance as default };\n","import sdkInstanceManager from './../managers/sdk-instance-manager';\n\n/**\n * @param apiKey - required string value representing the API key\n * Expected format: cs_{environment}_{workspaceId}_{tenantId}_{secret}\n * The API key is parsed to extract configuration data (workspaceId, tenantId, baseUrl)\n * but the original unparsed API key is sent to the API in requests\n * @returns boolean indicating whether the initialisation of the sdk was successful or not\n */\nexport const initialise = (apiKey: string) => {\n try {\n sdkInstanceManager.initialise(apiKey);\n return true;\n } catch (e) {\n console.info((e as any)?.message);\n return false;\n }\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\nexport const identify = (user: { email: string }) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!user?.email) {\n console.error('User email must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.identify(user);\n};\n","import sdkInstanceManager from '../managers/sdk-instance-manager';\n\ntype Properties = Record<string, any>;\n\nexport const track = (eventName: string, eventProperties?: Properties, userEmail?: string) => {\n if (!sdkInstanceManager.getIsInitialised()) {\n console.error('SDK must be initialised first');\n return;\n }\n if (!eventName || typeof eventName !== 'string') {\n console.error('Event name must be provided');\n return;\n }\n sdkInstanceManager.getApiClient()?.track(eventName, eventProperties, userEmail);\n};\n"],"names":["urlRegex","isValidUrl","url","test","sanitiseUrl","sanitisedUrl","trim","Error","urlObject","URL","hostname","toLowerCase","pathname","replace","toString","e","DEFAULT_BASE_URLS","live","parseApiKey","apiKey","startsWith","parts","split","length","environment","prefix","withoutPrefix","substring","keyParts","tenantId","workspaceId","baseUrl","transformTrackRequestData","_ref","eventName","eventProperties","userProperties","transformedEvent","type","data","timestamp","Date","now","userEmail","email","JSON","stringify","sdkConfig","defaultHeaders","API_PREFIX","TRACK_ENDPOINT","ApiClient","config","endpoint","options","method","_this","getBaseUrl","headers","_extends","getApiKey","fetch","_proto","prototype","getWorkspaceId","getUser","user","identify","track","_this$user","fetchWithConfig","body","SDKInstanceManager","instance","isInitialised","initialise","getIsInitialised","console","info","parsed","apiClient","destroy","getApiClient","getConfig","sdkInstanceManager","message","error","_sdkInstanceManager$g"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/api-client.ts
CHANGED