{"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"]}