UNPKG

@logsnag/remix

Version:

LogSnag client for Remix applications

1 lines 11.9 kB
{"version":3,"sources":["../../../../utilities/constants/src/endpoints.ts","../../../../utilities/core/src/utils/error.ts","../../../../utilities/core/src/utils/date.ts","../../../../utilities/core/src/client/logsnag.ts"],"sourcesContent":["/**\n * LogSnag Base Endpoint\n */\n\nconst LOGSNAG_BASE = 'https://api.logsnag.com';\nconst ENDPOINT_VERSION = '/v1';\n\nexport const ENDPOINTS = {\n /**\n * LogSnag Log Endpoint\n */\n LOG: LOGSNAG_BASE + ENDPOINT_VERSION + '/log',\n\n /**\n * LogSnag Identify Endpoint\n */\n IDENTIFY: LOGSNAG_BASE + ENDPOINT_VERSION + '/identify',\n\n /**\n * LogSnag Insight Endpoint\n */\n INSIGHT: LOGSNAG_BASE + ENDPOINT_VERSION + '/insight',\n\n /**\n * LogSnag Group Endpoint\n */\n GROUP: LOGSNAG_BASE + '/v1/group',\n\n /**\n * LogSnag Page Endpoint\n */\n PAGE: LOGSNAG_BASE + ENDPOINT_VERSION + '/page'\n};\n","/**\n * Fetch HTTP Response Error\n */\nexport class HTTPResponseError extends Error {\n public readonly message: string;\n\n constructor(status: number, statusText: string, body: any | undefined) {\n super(`HTTP Error Response: ${status} ${statusText}`);\n this.message = this.createReadableString(body);\n }\n\n /**\n * Create a readable string from the response body\n * @param body\n */\n createReadableString(body: any) {\n let error = '[LogSnag] Failed to publish: ';\n if (body && body.validation && Array.isArray(body.validation.body)) {\n error += body.validation.body\n .map((item: { message: string }) => item.message)\n .join(', ');\n } else {\n error += `: Please check our docs at https://docs.logsnag.com`;\n }\n return error;\n }\n\n toString() {\n return this.message;\n }\n\n /**\n * Get Error Info as JSON\n */\n toJSON() {\n return {\n message: this.message\n };\n }\n}\n","/**\n * Check if timestamp is in milliseconds\n * @param timestamp\n */\nfunction isTimestampInMilliseconds(timestamp: number): boolean {\n return (\n Math.abs(Date.now() - timestamp) < Math.abs(Date.now() - timestamp * 1000)\n );\n}\n\n/**\n * Convert optional timestamp to unix timestamp\n * @param timestamp\n */\nexport function toUnixTimestamp(timestamp?: number | Date): number | undefined {\n if (!timestamp) return undefined;\n\n if (timestamp instanceof Date) {\n timestamp = timestamp.getTime();\n }\n\n if (isTimestampInMilliseconds(timestamp)) {\n timestamp = Math.floor(timestamp / 1000);\n }\n\n return timestamp;\n}\n","import { ENDPOINTS } from '@logsnag/constants/endpoints';\nimport { HTTPResponseError } from '../utils/error';\nimport { TrackOptions } from '../types';\nimport { InsightIncrementOptions, InsightTrackOptions } from '../types';\nimport { toUnixTimestamp } from '../utils/date';\nimport { IdentifyOptions } from '../types';\nimport { GroupOptions } from '../types';\n\n/**\n * LogSnag Client\n */\nexport default class LogSnag {\n private readonly token: string;\n private readonly project: string;\n private disabled = false;\n\n /**\n * Construct a new LogSnag instance\n * @param token LogSnag API token\n * @param project LogSnag project name\n * @param disableTracking Disable tracking\n * for more information, see: docs.logsnag.com\n */\n constructor({\n token,\n project,\n disableTracking = false\n }: {\n token: string;\n project: string;\n disableTracking?: boolean;\n }) {\n this.token = token;\n this.project = project;\n this.disabled = disableTracking || false;\n }\n\n /**\n * Disable tracking for this instance\n * (this is useful for development)\n */\n disableTracking() {\n this.disabled = true;\n }\n\n /**\n * Enable tracking for this instance\n * (this is useful for development)\n */\n enableTracking() {\n this.disabled = false;\n }\n\n /**\n * Check if tracking is disabled\n */\n isTrackingDisabled() {\n return this.disabled;\n }\n\n /**\n * Get project name\n * @returns project name\n */\n getProject(): string {\n return this.project;\n }\n\n /**\n * Creates authorization header\n * @returns Authorization header value\n */\n protected createAuthorizationHeader(): string {\n return `Bearer ${this.token}`;\n }\n\n /**\n * Creates headers for requests\n * @private\n */\n private createHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Authorization: this.createAuthorizationHeader()\n };\n }\n\n /**\n * Get insight methods\n */\n get insight() {\n return {\n track: this.insightTrack.bind(this),\n increment: this.insightIncrement.bind(this)\n };\n }\n\n /**\n * Publish a new event to LogSnag\n * @param options\n * @returns true when successfully published\n */\n public async track(options: TrackOptions): Promise<boolean> {\n if (this.isTrackingDisabled()) return true;\n const headers = this.createHeaders();\n const method = 'POST';\n\n // Convert timestamp to unix timestamp if needed\n options.timestamp = toUnixTimestamp(options.timestamp);\n\n const body = JSON.stringify({\n ...options,\n project: this.getProject()\n });\n\n const response = await fetch(ENDPOINTS.LOG, { method, body, headers });\n if (!response.ok) {\n throw new HTTPResponseError(\n response.status,\n response.statusText,\n await response.json()\n );\n }\n\n return true;\n }\n\n /**\n * Identify a user\n * @param options\n * @returns true when successfully published\n */\n public async identify(options: IdentifyOptions): Promise<boolean> {\n if (this.isTrackingDisabled()) return true;\n const headers = this.createHeaders();\n const method = 'POST';\n\n const body = JSON.stringify({\n ...options,\n project: this.getProject()\n });\n\n const response = await fetch(ENDPOINTS.IDENTIFY, { method, body, headers });\n if (!response.ok) {\n throw new HTTPResponseError(\n response.status,\n response.statusText,\n await response.json()\n );\n }\n\n return true;\n }\n\n /**\n * Group a user or update group properties\n * @param options\n * @returns true when successfully published\n */\n public async group(options: GroupOptions): Promise<boolean> {\n if (this.isTrackingDisabled()) return true;\n const headers = this.createHeaders();\n const method = 'POST';\n\n const body = JSON.stringify({\n ...options,\n project: this.getProject()\n });\n\n const response = await fetch(ENDPOINTS.GROUP, { method, body, headers });\n if (!response.ok) {\n throw new HTTPResponseError(\n response.status,\n response.statusText,\n await response.json()\n );\n }\n\n return true;\n }\n\n /**\n * Publish a new insight to LogSnag\n * @param options\n * @returns true when successfully published\n */\n protected async insightTrack(options: InsightTrackOptions): Promise<boolean> {\n if (this.isTrackingDisabled()) return true;\n const headers = this.createHeaders();\n const method = 'POST';\n const body = JSON.stringify({\n ...options,\n project: this.getProject()\n });\n\n const response = await fetch(ENDPOINTS.INSIGHT, { method, body, headers });\n if (!response.ok) {\n throw new HTTPResponseError(\n response.status,\n response.statusText,\n await response.json()\n );\n }\n\n return true;\n }\n\n /**\n * Increment an insight value\n * @param options\n * @returns true when successfully published\n */\n protected async insightIncrement(\n options: InsightIncrementOptions\n ): Promise<boolean> {\n if (this.isTrackingDisabled()) return true;\n const headers = this.createHeaders();\n const method = 'PATCH';\n const body = JSON.stringify({\n project: this.getProject(),\n icon: options.icon,\n title: options.title,\n value: {\n $inc: options.value\n }\n });\n\n const response = await fetch(ENDPOINTS.INSIGHT, { method, body, headers });\n if (!response.ok) {\n throw new HTTPResponseError(\n response.status,\n response.statusText,\n await response.json()\n );\n }\n\n return true;\n }\n}\n"],"mappings":"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","names":["LOGSNAG_BASE","ENDPOINT_VERSION","ENDPOINTS","HTTPResponseError","status","statusText","body","__publicField","error","item","isTimestampInMilliseconds","timestamp","toUnixTimestamp","LogSnag","token","project","disableTracking","__publicField","options","headers","method","toUnixTimestamp","body","response","ENDPOINTS","HTTPResponseError"]}