@camunda/ccma-api 5.20.2 → 6.1.0

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.
Files changed (51) hide show
  1. package/dist/index.d.ts +8 -6
  2. package/dist/index.js +10 -2
  3. package/dist/index.js.map +2 -2
  4. package/dist/services/accounts/approvals.m2m.service.d.ts +41 -2
  5. package/dist/services/accounts/approvals.m2m.service.js +62 -0
  6. package/dist/services/accounts/approvals.m2m.service.js.map +2 -2
  7. package/dist/services/accounts/orgs.service.d.ts +2 -1
  8. package/dist/services/accounts/orgs.service.js.map +2 -2
  9. package/dist/services/ccma/ccma.openapi.service.d.ts +48 -0
  10. package/dist/services/ccma/ccma.openapi.service.js +88 -0
  11. package/dist/services/ccma/ccma.openapi.service.js.map +7 -0
  12. package/dist/services/ccma/ccma.openapi.service.spec.d.ts +1 -0
  13. package/dist/services/console/console.admin.service.d.ts +1 -0
  14. package/dist/services/console/console.admin.service.js.map +1 -1
  15. package/dist/services/console/console.approvals.m2m.service.d.ts +12 -2
  16. package/dist/services/console/console.approvals.m2m.service.js +18 -0
  17. package/dist/services/console/console.approvals.m2m.service.js.map +2 -2
  18. package/dist/services/console/console.channel.service.d.ts +10 -5
  19. package/dist/services/console/console.channel.service.js.map +2 -2
  20. package/dist/services/console/console.cluster-parameters.service.d.ts +2 -0
  21. package/dist/services/console/console.cluster-parameters.service.js.map +2 -2
  22. package/dist/services/console/generation.service.d.ts +4 -0
  23. package/dist/services/console/generation.service.js.map +2 -2
  24. package/dist/services/control/control.agent-grants.redact.spec.d.ts +1 -0
  25. package/dist/services/control/control.agent-grants.service.d.ts +26 -0
  26. package/dist/services/control/control.agent-grants.service.js +57 -0
  27. package/dist/services/control/control.agent-grants.service.js.map +7 -0
  28. package/dist/services/control/control.agent-grants.service.spec.d.ts +1 -0
  29. package/dist/services/control/control.agent-tokens.service.d.ts +19 -1
  30. package/dist/services/control/control.agent-tokens.service.js +34 -2
  31. package/dist/services/control/control.agent-tokens.service.js.map +2 -2
  32. package/dist/services/control/control.approvals.service.d.ts +74 -11
  33. package/dist/services/control/control.approvals.service.js +84 -11
  34. package/dist/services/control/control.approvals.service.js.map +2 -2
  35. package/dist/services/token-issuer/token-issuer.grant.service.d.ts +26 -0
  36. package/dist/services/token-issuer/token-issuer.grant.service.js +52 -0
  37. package/dist/services/token-issuer/token-issuer.grant.service.js.map +7 -0
  38. package/dist/services/token-issuer/token-issuer.grant.service.spec.d.ts +1 -0
  39. package/dist/types/general.types.d.ts +22 -0
  40. package/dist/utils/api.ccma-openapi-status.spec.d.ts +1 -0
  41. package/dist/utils/api.d.ts +13 -2
  42. package/dist/utils/api.js +55 -5
  43. package/dist/utils/api.js.map +2 -2
  44. package/dist/utils/api.on-failed-response.spec.d.ts +1 -0
  45. package/dist/utils/environments.d.ts +1 -1
  46. package/dist/utils/environments.js +0 -7
  47. package/dist/utils/environments.js.map +2 -2
  48. package/package.json +1 -1
  49. package/dist/services/mixpanel/mixpanel.service.d.ts +0 -16
  50. package/dist/services/mixpanel/mixpanel.service.js +0 -86
  51. package/dist/services/mixpanel/mixpanel.service.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/api.ts"],
4
- "sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type {\n RequestBaseCustomMetricsDetailsType,\n RequestBaseMethodType,\n RequestBaseParams,\n RequestBaseServiceContext,\n} from '../types/general.types.js'\nimport { getEnvParam, type ServiceName } from './environments.js'\nimport { frontendCache } from './frontendCache.js'\n\nexport interface RequestPayload extends RequestBaseParams {\n base?: {\n id: ServiceName\n }\n url: string\n method: RequestBaseMethodType\n headers?: { [key: string]: string }\n type?: 'json' | 'text' | 'form' | 'none'\n responseType?: 'json' | 'text' | 'blob' | 'none'\n retry?: {\n attempts: number\n remaining: number\n }\n /**\n * Opt-in: retry transient gateway failures (502/503/504 and network/fetch\n * errors) with backoff, mirroring the 429 retry. Retried attempts emit a\n * `transient-retry` metric instead of `error`, so a healed blip (e.g. an\n * envoy connection reset during a pod restart) doesn't count toward the\n * internal error-rate alert. Only enable for idempotent-safe calls \u2014 a\n * retried POST may execute twice.\n */\n retryTransientErrors?: boolean\n transientRetry?: {\n attempts: number\n remaining: number\n }\n /**\n * Opt-in: log a failure with no HTTP status (timeout, connection reset) at\n * `warn` instead of `error`. Use it for third-party sites that we cannot\n * fix. The `error` metric and the response stay the same.\n */\n warnOnNoStatus?: boolean\n /**\n * Opt-in: a log line of this request names the top-level keys of the body\n * and masks every value. Use it for a body that holds text with no fixed\n * key to mask, such as the env vars of a generation.\n */\n redactBody?: boolean\n body?: any\n metricsDetails: RequestBaseServiceContext\n}\n\nconst TRANSIENT_RETRY_STATUS = [502, 503, 504]\n/**\n * Cap on the error body kept as `statusText`. It ends up in the thrown error's\n * message, the log line, and the `ccma.errors` payload, and some upstreams\n * (LiteLLM, GCP load balancers) answer failures with a full HTML page \u2014 one\n * such response is kilobytes of markup standing in for a reason phrase. The\n * head is what carries the actual reason.\n */\nconst MAX_ERROR_BODY_LENGTH = 500\n/** Appended in place of what was cut, and counted against the cap above. */\nconst ERROR_BODY_TRUNCATION_MARKER = '\u2026 [truncated]'\nconst MAX_TRANSIENT_RETRIES = 3\n\nlet sendToAccountsNg: () => boolean = () => false\n\n/**\n * Sends the requests to accounts with the header `x-ccma-backend: next` while\n * `isOn` answers true. The gateway then routes them to accounts-ng (spec\n * `docs/specs/accounts-ng.md`, section 9). A frontend sets it to read the flag\n * `accounts.ngBackend`. A backend never sets it: the gateway weights move the\n * calls of the backends.\n */\nexport const setAccountsNgBackend = (isOn: () => boolean): void => {\n sendToAccountsNg = isOn\n}\n\n/**\n * The header that sends a request to accounts-ng, or none. A frontend helper\n * that calls `fetch` for accounts itself adds it too.\n */\nexport const accountsNgHeaders = (): Record<string, string> => {\n try {\n return sendToAccountsNg() ? { 'x-ccma-backend': 'next' } : {}\n } catch (_error) {\n // never let a flag read break a request\n return {}\n }\n}\n\n/**\n * True for an absolute URL on the accounts host of the stage. Many callers\n * send such a URL with no `base`.\n */\nfunction isAccountsUrl(payload: RequestPayload): boolean {\n if (payload.base) {\n return false\n }\n try {\n const accounts = getEnvParam('accounts', payload.config)\n return payload.url === accounts || payload.url.startsWith(`${accounts}/`)\n } catch (_error) {\n return false\n }\n}\n\nexport interface Response<T> {\n body?: T\n status: number\n statusText?: string\n ok: boolean\n meta: {\n duration: number\n }\n}\n\nfunction sendMetrics(\n payload: RequestPayload,\n type: RequestBaseCustomMetricsDetailsType,\n options?: {\n duration?: number\n statusCode?: string\n error?: string\n },\n) {\n if (payload.config.metrics) {\n if (payload.config.metrics.types.includes(type)) {\n let durationBucket: string | undefined\n if (options?.duration) {\n if (options.duration < 100) {\n durationBucket = '0 | <100ms'\n } else if (options.duration < 200) {\n durationBucket = '1 | <200ms'\n } else if (options.duration < 500) {\n durationBucket = '2 | <500ms'\n } else if (options.duration < 1000) {\n durationBucket = '3 | <1s'\n } else {\n durationBucket = '4 | >=1s'\n }\n }\n\n // only add normalized errors as labels\n let error = 'other'\n if (options?.error) {\n try {\n const errorMessage = options.error\n if (errorMessage.startsWith('<!DOCTYPE html>')) {\n error = 'html-response'\n } else if (errorMessage.includes('UND_ERR_CONNECT_TIMEOUT')) {\n error = 'connect-timeout'\n }\n } catch (_error) {\n // ignore it\n }\n } else {\n error = 'unset'\n }\n\n const metrics: RequestBaseServiceContext = {\n ...payload.metricsDetails,\n eventType: type,\n durationBucket,\n statusCode: options?.statusCode,\n error,\n }\n try {\n payload.config.metrics.callback(metrics)\n } catch (metricsCallbackError) {\n log(payload, 'debug', `Failed to send metrics`, {\n error: metricsCallbackError,\n metrics,\n })\n }\n }\n }\n}\n\nexport function log(\n payload: RequestPayload,\n type: 'debug' | 'info' | 'warn' | 'error',\n message: string,\n additionalData?: any,\n) {\n if (payload.config.logger) {\n const messageParts: string[] = []\n messageParts.push(payload.metricsDetails?.method?.name)\n messageParts.push(\n `${payload.metricsDetails?.target?.name} (${payload.metricsDetails?.target?.type})`,\n )\n messageParts.push(message)\n let body: any\n if (payload.body) {\n body = JSON.parse(JSON.stringify(payload.body))\n // A string has no keys to mask, and writing to its index throws.\n if (payload.redactBody && typeof body !== 'object') {\n body = '********'\n } else {\n for (const key of Object.keys(body)) {\n if (\n payload.redactBody ||\n key.toLowerCase().includes('password') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('token')\n ) {\n body[key] = '********'\n }\n }\n }\n }\n\n let fullUrl = 'unset'\n\n if (payload.base) {\n try {\n const base = getEnvParam(payload.base.id, payload.config)\n fullUrl = base ? `${base}/${payload.url}` : payload.url\n } catch (_error) {\n fullUrl = `failed to get base url for ${payload.base.id}`\n }\n }\n\n let url = `${payload.url}`.toLowerCase()\n if (url.includes('secret') || url.includes('password')) {\n url = url.split('?')[0]\n }\n\n const data = {\n base: payload.base,\n method: payload.method,\n url,\n fullUrl,\n retry: payload.retry,\n body,\n context: payload.metricsDetails,\n ...additionalData,\n }\n // `warn` is optional on the logger, so fall back to `error` and lose no log\n const { logger } = payload.config\n const fullMessage = messageParts.join(' > ')\n if (type === 'warn') {\n if (logger.warn) {\n logger.warn(fullMessage, { data })\n } else {\n logger.error(fullMessage, { data })\n }\n } else {\n logger[type](fullMessage, { data })\n }\n }\n}\n\nfunction rateLimitWaitingTime(attempt: number): number {\n const noise = Math.random() * 100\n const waitingTime = 2 ** attempt * 1000 + noise\n return Math.floor(waitingTime)\n}\n\nfunction transientRetryWaitingTime(attempt: number): number {\n const noise = Math.random() * 100\n // 500ms, 1s, 2s (+jitter) \u2014 bounded so a fire-and-forget call heals fast.\n return Math.floor(2 ** attempt * 250 + noise)\n}\n\nfunction canRetryTransient(payload: RequestPayload): boolean {\n if (!payload.retryTransientErrors) {\n return false\n }\n const remaining = payload.transientRetry?.remaining ?? MAX_TRANSIENT_RETRIES\n return remaining > 0\n}\n\nasync function scheduleTransientRetry(payload: RequestPayload): Promise<void> {\n const attempts = payload.transientRetry?.attempts ?? 1\n const remaining = payload.transientRetry?.remaining ?? MAX_TRANSIENT_RETRIES\n const waitingTime = transientRetryWaitingTime(attempts)\n log(\n payload,\n 'debug',\n `transient error, attempt ${attempts}, remaining ${remaining}, waiting ${waitingTime}ms`,\n )\n await new Promise((resolve) => {\n setTimeout(resolve, waitingTime)\n })\n // eslint-disable-next-line require-atomic-updates\n payload.transientRetry = {\n attempts: attempts + 1,\n remaining: remaining - 1,\n }\n}\n\nexport async function request<T>(\n payload: RequestPayload,\n): Promise<Response<T>> {\n log(payload, 'debug', 'starting request')\n sendMetrics(payload, 'request')\n // configure frontend cache if enabled (browser only)\n try {\n if (payload.config.frontendCaching?.enabled) {\n frontendCache.configure(payload.config.frontendCaching)\n }\n } catch (_cacheConfigError) {\n // ignore configuration errors silently\n }\n let token\n if (payload.config.auth) {\n token = await payload.config.auth.getToken()\n }\n // Dynamic (e.g. correlation) headers first, then explicit per-request headers\n // override them, then auth/content-type below take final precedence.\n //\n // Correlation headers (traceparent, x-cc-session-id) identify our internal\n // request/session, so they must only ever reach Camunda-owned systems. Every\n // third-party target is marked `type: 'external'`, so we gate on that here:\n // external targets never receive dynamic headers even if the caller's config\n // sets getDynamicHeaders. This makes propagation safe-by-default and removes\n // the footgun of a shared config that is used for both internal and\n // third-party calls (e.g. BASIC_API_CONFIG \u2192 token-issuer vs Slack).\n let dynamicHeaders: Record<string, string> = {}\n if (payload.metricsDetails?.target?.type !== 'external') {\n try {\n dynamicHeaders = payload.config.getDynamicHeaders?.() ?? {}\n } catch (_error) {\n // never let header evaluation break a request\n }\n }\n const headers: { [key: string]: string } = {\n ...dynamicHeaders,\n ...(payload.headers ?? {}),\n }\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n if (payload.base?.id === 'accounts' || isAccountsUrl(payload)) {\n Object.assign(headers, accountsNgHeaders())\n }\n const type = payload.type ?? 'json'\n let body\n if (type) {\n switch (type) {\n case 'json':\n headers['Content-Type'] = 'application/json'\n body = payload.body ? JSON.stringify(payload.body) : undefined\n break\n case 'text':\n headers['Content-Type'] = 'text/plain'\n body = payload.body ? JSON.stringify(payload.body) : undefined\n break\n case 'form':\n if (payload.body) {\n const formData = new URLSearchParams()\n Object.keys(payload.body).forEach((key) => {\n formData.append(key, payload.body[key])\n })\n body = formData\n }\n break\n }\n }\n let base\n if (payload.base) {\n try {\n base = getEnvParam(payload.base.id, payload.config)\n } catch (error) {\n log(payload, 'error', `Failed to get base url for ${payload.base.id}`, {\n error,\n })\n throw error\n }\n }\n const url = base ? `${base}/${payload.url}` : payload.url\n\n // Attempt cache read for GET requests (stale-while-revalidate when callback supplied)\n let serveCachedAndReturnAfterNetwork = false\n if (payload.method === 'get' && payload.config.frontendCaching?.enabled) {\n try {\n const cached = await frontendCache.get<T>('get', url)\n if (cached) {\n const fresh = frontendCache.isFresh(cached)\n if (payload.onCachedResponse) {\n payload.onCachedResponse(cached.payload, { fresh, source: 'cache' })\n if (!fresh) {\n log(payload, 'debug', 'cache stale, refreshing in background')\n serveCachedAndReturnAfterNetwork = true\n } else {\n log(payload, 'debug', 'cache fresh, returning early')\n sendMetrics(payload, 'success', { duration: 0, statusCode: '200' })\n return {\n // eslint-disable-next-line id-length\n ok: true,\n status: 200,\n statusText: 'cached',\n body: cached.payload,\n meta: { duration: 0 },\n }\n }\n } else if (fresh) {\n // no callback but fresh -> return directly\n log(payload, 'debug', 'cache hit, returning cached response')\n sendMetrics(payload, 'success', { duration: 0, statusCode: '200' })\n return {\n // eslint-disable-next-line id-length\n ok: true,\n status: 200,\n statusText: 'cached',\n body: cached.payload,\n meta: { duration: 0 },\n }\n } else {\n log(payload, 'debug', 'cache stale, proceeding with network request')\n }\n }\n } catch (_cacheGetError) {\n // ignore cache errors\n }\n }\n const start = performance.now()\n const proxyAgent = payload.config.proxyAgent ?? {}\n try {\n const fetchResponse = await fetch(url, {\n signal: payload.config.timeout\n ? AbortSignal.timeout(payload.config.timeout)\n : undefined,\n method: payload.method.toUpperCase(),\n headers,\n body,\n ...proxyAgent,\n })\n const end = performance.now()\n const duration = end - start\n\n if ([429].includes(fetchResponse.status)) {\n // rate limiting, retry\n log(payload, 'info', 'rate limited', { durationMs: Math.floor(duration) })\n sendMetrics(payload, 'rate-limit-retry', {\n duration,\n statusCode: String(fetchResponse.status),\n })\n const remaining = payload.retry?.remaining ?? 8\n const attempts = payload.retry?.attempts ?? 1\n if (remaining > 0) {\n let waitingTime = rateLimitWaitingTime(attempts)\n if (fetchResponse.headers.has('x-ratelimit-reset')) {\n const rateLimitHeader = fetchResponse.headers.get('x-ratelimit-reset')\n log(\n payload,\n 'debug',\n `rate limited, found x-ratelimit-reset header: ${rateLimitHeader}`,\n )\n const rateLimitHeaderNumber = Number(rateLimitHeader)\n if (Number.isNaN(rateLimitHeaderNumber)) {\n waitingTime = Date.parse(rateLimitHeader ?? '0') - Date.now()\n } else {\n waitingTime = rateLimitHeaderNumber - Date.now()\n }\n }\n if (waitingTime < 0 || waitingTime > 180000) {\n waitingTime = rateLimitWaitingTime(attempts)\n }\n log(\n payload,\n 'debug',\n `rate limited, attempt ${attempts}, remaining ${remaining}, waiting ${waitingTime}ms`,\n )\n await new Promise((resolve) => {\n setTimeout(resolve, waitingTime)\n })\n // eslint-disable-next-line require-atomic-updates\n payload.retry = {\n attempts: attempts + 1,\n remaining: remaining - 1,\n }\n return request(payload)\n }\n log(payload, 'debug', `rate limited, no more retries`, {\n durationMs: Math.floor(duration),\n })\n }\n\n const response: Response<T> = {\n // eslint-disable-next-line id-length\n ok: fetchResponse.ok,\n status: fetchResponse.status,\n statusText: fetchResponse.statusText,\n meta: {\n duration,\n },\n }\n\n const responseType = payload.responseType ?? type\n\n if (response.ok) {\n log(payload, 'debug', `request successful in ${Math.floor(duration)}ms`, {\n baseUrl: base,\n durationMs: Math.floor(duration),\n })\n sendMetrics(payload, 'success', {\n duration,\n statusCode: String(fetchResponse.status),\n })\n switch (responseType) {\n case 'json':\n try {\n response.body = await fetchResponse.json()\n } catch (_error) {\n log(\n payload,\n 'debug',\n `Failed to parse json body. Returning empty object.`,\n {\n baseUrl: base,\n },\n )\n response.body = {} as T\n try {\n const responseBodyText = await fetchResponse.text()\n log(payload, 'debug', `Response body text`, {\n baseUrl: base,\n responseBodyText,\n status: fetchResponse.status,\n })\n } catch (textError) {\n // this is fine\n log(payload, 'debug', `Failed to parse response body text.`, {\n baseUrl: base,\n status: fetchResponse.status,\n error: textError,\n })\n }\n }\n break\n case 'text':\n response.body = (await fetchResponse.text()) as T\n break\n case 'blob':\n // Binary payloads (file downloads, e.g. database dumps). Not cached.\n response.body = (await fetchResponse.blob()) as T\n break\n default:\n response.body = (await fetchResponse.text()) as T\n }\n // store in cache after parsing\n if (\n payload.method === 'get' &&\n payload.config.frontendCaching?.enabled &&\n response.body !== undefined &&\n responseType !== 'blob'\n ) {\n try {\n await frontendCache.set('get', url, response.body as any)\n log(payload, 'debug', 'cache store successful')\n } catch (_cacheSetError) {\n // ignore cache set error\n }\n }\n } else {\n let statusText = fetchResponse.statusText\n try {\n statusText = await fetchResponse.text()\n } catch (_error) {\n // this is fine\n }\n if (statusText.length > MAX_ERROR_BODY_LENGTH) {\n // The marker is part of the budget, so the stored value never exceeds\n // MAX_ERROR_BODY_LENGTH \u2014 appending it after slicing to the full cap\n // would put the result over the bound the constant advertises.\n statusText = `${statusText.slice(\n 0,\n MAX_ERROR_BODY_LENGTH - ERROR_BODY_TRUNCATION_MARKER.length,\n )}${ERROR_BODY_TRUNCATION_MARKER}`\n }\n response.statusText = statusText\n log(\n payload,\n 'debug',\n `request failed with status ${response.status}: ${statusText}`,\n {\n baseUrl: base,\n durationMs: Math.floor(duration),\n },\n )\n\n // Transient gateway failure (e.g. envoy \"connection termination\" 503\n // during a pod restart). When opted in, retry with backoff and record it\n // as `transient-retry` rather than `error`, so a healed blip stays off\n // the internal error-rate alert.\n if (\n TRANSIENT_RETRY_STATUS.includes(response.status) &&\n canRetryTransient(payload)\n ) {\n sendMetrics(payload, 'transient-retry', {\n duration,\n statusCode: String(fetchResponse.status),\n error: statusText,\n })\n await scheduleTransientRetry(payload)\n return request(payload)\n }\n\n // Special Handling for dedicated target systems to not count special status codes as errors\n // eslint-disable-next-line no-shadow\n let type: RequestBaseCustomMetricsDetailsType = 'error'\n const noErrorStatusCodes: number[] = []\n switch (payload.metricsDetails.target.name) {\n case 'auth0':\n noErrorStatusCodes.push(...[400, 404, 409])\n break\n case 'accounts':\n case 'console':\n noErrorStatusCodes.push(...[404, 409])\n if (payload.metricsDetails.method.name === 'createTemporaryCluster') {\n // case: cannot create temporary cluster\n noErrorStatusCodes.push(...[400, 403, 412])\n }\n if (\n [\n 'ConsoleM2MService.verifyZeebeClient',\n 'ConsoleM2MService.verifyApiClient',\n ].includes(payload.metricsDetails.method.name)\n ) {\n // case: api/zeebe client credentials are invalid\n noErrorStatusCodes.push(...[401])\n }\n if (\n payload.metricsDetails.method.name ===\n 'OrgsService.createAndReturnSocialLoginUser'\n ) {\n noErrorStatusCodes.push(\n ...[\n // onboard user, user already has an org\n 400,\n // existing extSSO-connection\n 412,\n ],\n )\n }\n break\n case 'control':\n if (\n payload.metricsDetails.method.name ===\n 'ControlAgentClientsInternalService.verify'\n ) {\n // case: the credentials of an agent client are invalid\n noErrorStatusCodes.push(401)\n }\n break\n }\n\n if (noErrorStatusCodes.includes(response.status)) {\n type = 'success'\n }\n\n sendMetrics(payload, type, {\n duration,\n statusCode: String(fetchResponse.status),\n error: statusText,\n })\n }\n if (serveCachedAndReturnAfterNetwork && response.ok) {\n // when we served stale via callback earlier, we now also return the fresh response\n log(payload, 'debug', 'stale cache updated, returning new data')\n }\n return response\n } catch (error: any) {\n const duration = performance.now() - start\n let errorMessage: string | undefined\n if (error?.cause?.code) {\n errorMessage = error?.cause?.code\n } else if (error?.message) {\n errorMessage = error?.message\n }\n // Network/fetch error with no HTTP status (e.g. connection reset, timeout).\n // Retry-on-opt-in before treating it as an error (see else branch above).\n if (canRetryTransient(payload)) {\n log(payload, 'debug', `request failed with no status, retrying`, {\n baseUrl: base,\n error,\n durationMs: Math.floor(duration),\n })\n sendMetrics(payload, 'transient-retry', {\n statusCode: 'fetch-error',\n duration,\n error: errorMessage,\n })\n await scheduleTransientRetry(payload)\n return request(payload)\n }\n log(\n payload,\n payload.warnOnNoStatus ? 'warn' : 'error',\n `request failed with no status`,\n {\n baseUrl: base,\n error,\n durationMs: Math.floor(duration),\n },\n )\n sendMetrics(payload, 'error', {\n statusCode: 'fetch-error',\n duration,\n error: errorMessage,\n })\n const response: Response<T> = {\n // eslint-disable-next-line id-length\n ok: false,\n status: 500,\n statusText: 'fetch error',\n meta: {\n duration,\n },\n }\n return response\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type {\n RequestBaseCustomMetricsDetailsType,\n RequestBaseMethodType,\n RequestBaseParams,\n RequestBaseServiceContext,\n} from '../types/general.types.js'\nimport { getEnvParam, type ServiceName } from './environments.js'\nimport { frontendCache } from './frontendCache.js'\n\nexport interface RequestPayload extends RequestBaseParams {\n base?: {\n id: ServiceName\n }\n url: string\n method: RequestBaseMethodType\n headers?: { [key: string]: string }\n type?: 'json' | 'text' | 'form' | 'none'\n responseType?: 'json' | 'text' | 'blob' | 'none'\n retry?: {\n attempts: number\n remaining: number\n }\n /**\n * Opt-in: retry transient gateway failures (502/503/504 and network/fetch\n * errors) with backoff, mirroring the 429 retry. Retried attempts emit a\n * `transient-retry` metric instead of `error`, so a healed blip (e.g. an\n * envoy connection reset during a pod restart) doesn't count toward the\n * internal error-rate alert. Only enable for idempotent-safe calls \u2014 a\n * retried POST may execute twice.\n */\n retryTransientErrors?: boolean\n transientRetry?: {\n attempts: number\n remaining: number\n }\n /**\n * Opt-in: log a failure with no HTTP status (timeout, connection reset) at\n * `warn` instead of `error`. Use it for third-party sites that we cannot\n * fix. The `error` metric and the response stay the same.\n */\n warnOnNoStatus?: boolean\n /**\n * Opt-in: a log line of this request names the top-level keys of the body\n * and masks every value, and it drops the query of the URL. Use it for a\n * body or a query that holds text with no fixed key to mask, such as the\n * env vars of a generation or an email in a lookup.\n */\n redactBody?: boolean\n /**\n * The URL that the log lines show in place of `url`. Use it when the path holds a value\n * that must not go to the logs, such as an email or a token. The request uses `url`.\n */\n logUrl?: string\n /**\n * Opt-in: with the type `json`, send the body when it is not undefined. Without it, a falsy\n * body (`null`, `0`, `false`, `\"\"`) is not sent.\n */\n bodyWhenGiven?: boolean\n body?: any\n metricsDetails: RequestBaseServiceContext\n}\n\n/**\n * Carries an error of `onFailedResponse` past the catch of `request`, which\n * would otherwise turn it into a fetch error.\n */\nclass FailedResponseHookError extends Error {\n constructor(readonly hookError: unknown) {\n super('onFailedResponse failed')\n }\n}\n\nconst TRANSIENT_RETRY_STATUS = [502, 503, 504]\n/**\n * Cap on the error body kept as `statusText`. It ends up in the thrown error's\n * message, the log line, and the `ccma.errors` payload, and some upstreams\n * (LiteLLM, GCP load balancers) answer failures with a full HTML page \u2014 one\n * such response is kilobytes of markup standing in for a reason phrase. The\n * head is what carries the actual reason.\n */\nconst MAX_ERROR_BODY_LENGTH = 500\n/** Appended in place of what was cut, and counted against the cap above. */\nconst ERROR_BODY_TRUNCATION_MARKER = '\u2026 [truncated]'\nconst MAX_TRANSIENT_RETRIES = 3\n\nlet sendToAccountsNg: () => boolean = () => false\n\n/**\n * Sends the requests to accounts with the header `x-ccma-backend: next` while\n * `isOn` answers true. The gateway then routes them to accounts-ng (spec\n * `docs/specs/accounts-ng.md`, section 9). A frontend sets it to read the flag\n * `accounts.ngBackend`. A backend never sets it: the gateway weights move the\n * calls of the backends.\n */\nexport const setAccountsNgBackend = (isOn: () => boolean): void => {\n sendToAccountsNg = isOn\n}\n\n/**\n * The header that sends a request to accounts-ng, or none. A frontend helper\n * that calls `fetch` for accounts itself adds it too.\n */\nexport const accountsNgHeaders = (): Record<string, string> => {\n try {\n return sendToAccountsNg() ? { 'x-ccma-backend': 'next' } : {}\n } catch (_error) {\n // never let a flag read break a request\n return {}\n }\n}\n\n/**\n * True for an absolute URL on the accounts host of the stage. Many callers\n * send such a URL with no `base`.\n */\nfunction isAccountsUrl(payload: RequestPayload): boolean {\n if (payload.base) {\n return false\n }\n try {\n const accounts = getEnvParam('accounts', payload.config)\n return payload.url === accounts || payload.url.startsWith(`${accounts}/`)\n } catch (_error) {\n return false\n }\n}\n\nexport interface Response<T> {\n body?: T\n status: number\n statusText?: string\n ok: boolean\n meta: {\n duration: number\n }\n}\n\nfunction sendMetrics(\n payload: RequestPayload,\n type: RequestBaseCustomMetricsDetailsType,\n options?: {\n duration?: number\n statusCode?: string\n error?: string\n },\n) {\n if (payload.config.metrics) {\n if (payload.config.metrics.types.includes(type)) {\n let durationBucket: string | undefined\n if (options?.duration) {\n if (options.duration < 100) {\n durationBucket = '0 | <100ms'\n } else if (options.duration < 200) {\n durationBucket = '1 | <200ms'\n } else if (options.duration < 500) {\n durationBucket = '2 | <500ms'\n } else if (options.duration < 1000) {\n durationBucket = '3 | <1s'\n } else {\n durationBucket = '4 | >=1s'\n }\n }\n\n // only add normalized errors as labels\n let error = 'other'\n if (options?.error) {\n try {\n const errorMessage = options.error\n if (errorMessage.startsWith('<!DOCTYPE html>')) {\n error = 'html-response'\n } else if (errorMessage.includes('UND_ERR_CONNECT_TIMEOUT')) {\n error = 'connect-timeout'\n }\n } catch (_error) {\n // ignore it\n }\n } else {\n error = 'unset'\n }\n\n const metrics: RequestBaseServiceContext = {\n ...payload.metricsDetails,\n eventType: type,\n durationBucket,\n statusCode: options?.statusCode,\n error,\n }\n try {\n payload.config.metrics.callback(metrics)\n } catch (metricsCallbackError) {\n log(payload, 'debug', `Failed to send metrics`, {\n error: metricsCallbackError,\n metrics,\n })\n }\n }\n }\n}\n\nexport function log(\n payload: RequestPayload,\n type: 'debug' | 'info' | 'warn' | 'error',\n message: string,\n additionalData?: any,\n) {\n if (payload.config.logger) {\n const messageParts: string[] = []\n messageParts.push(payload.metricsDetails?.method?.name)\n messageParts.push(\n `${payload.metricsDetails?.target?.name} (${payload.metricsDetails?.target?.type})`,\n )\n messageParts.push(message)\n let body: any\n if (payload.body) {\n body = JSON.parse(JSON.stringify(payload.body))\n // A string has no keys to mask, and writing to its index throws.\n if (payload.redactBody && typeof body !== 'object') {\n body = '********'\n } else {\n for (const key of Object.keys(body)) {\n if (\n payload.redactBody ||\n key.toLowerCase().includes('password') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('token')\n ) {\n body[key] = '********'\n }\n }\n }\n }\n\n const withoutQuery = (value: string) =>\n payload.redactBody ? value.split('?')[0] : value\n\n const shownUrl = payload.logUrl ?? payload.url\n let fullUrl = 'unset'\n\n if (payload.base) {\n try {\n const base = getEnvParam(payload.base.id, payload.config)\n fullUrl = withoutQuery(base ? `${base}/${shownUrl}` : shownUrl)\n } catch (_error) {\n fullUrl = `failed to get base url for ${payload.base.id}`\n }\n }\n\n let url = withoutQuery(`${shownUrl}`.toLowerCase())\n if (url.includes('secret') || url.includes('password')) {\n url = url.split('?')[0]\n }\n\n const context =\n payload.redactBody && payload.metricsDetails?.method\n ? {\n ...payload.metricsDetails,\n method: {\n ...payload.metricsDetails.method,\n url: withoutQuery(payload.metricsDetails.method.url),\n },\n }\n : payload.metricsDetails\n\n const data = {\n base: payload.base,\n method: payload.method,\n url,\n fullUrl,\n retry: payload.retry,\n body,\n context,\n ...additionalData,\n }\n // `warn` is optional on the logger, so fall back to `error` and lose no log\n const { logger } = payload.config\n const fullMessage = messageParts.join(' > ')\n if (type === 'warn') {\n if (logger.warn) {\n logger.warn(fullMessage, { data })\n } else {\n logger.error(fullMessage, { data })\n }\n } else {\n logger[type](fullMessage, { data })\n }\n }\n}\n\nfunction rateLimitWaitingTime(attempt: number): number {\n const noise = Math.random() * 100\n const waitingTime = 2 ** attempt * 1000 + noise\n return Math.floor(waitingTime)\n}\n\nfunction transientRetryWaitingTime(attempt: number): number {\n const noise = Math.random() * 100\n // 500ms, 1s, 2s (+jitter) \u2014 bounded so a fire-and-forget call heals fast.\n return Math.floor(2 ** attempt * 250 + noise)\n}\n\nfunction canRetryTransient(payload: RequestPayload): boolean {\n if (!payload.retryTransientErrors) {\n return false\n }\n const remaining = payload.transientRetry?.remaining ?? MAX_TRANSIENT_RETRIES\n return remaining > 0\n}\n\nasync function scheduleTransientRetry(payload: RequestPayload): Promise<void> {\n const attempts = payload.transientRetry?.attempts ?? 1\n const remaining = payload.transientRetry?.remaining ?? MAX_TRANSIENT_RETRIES\n const waitingTime = transientRetryWaitingTime(attempts)\n log(\n payload,\n 'debug',\n `transient error, attempt ${attempts}, remaining ${remaining}, waiting ${waitingTime}ms`,\n )\n await new Promise((resolve) => {\n setTimeout(resolve, waitingTime)\n })\n // eslint-disable-next-line require-atomic-updates\n payload.transientRetry = {\n attempts: attempts + 1,\n remaining: remaining - 1,\n }\n}\n\nexport async function request<T>(\n payload: RequestPayload,\n): Promise<Response<T>> {\n log(payload, 'debug', 'starting request')\n sendMetrics(payload, 'request')\n // configure frontend cache if enabled (browser only)\n try {\n if (payload.config.frontendCaching?.enabled) {\n frontendCache.configure(payload.config.frontendCaching)\n }\n } catch (_cacheConfigError) {\n // ignore configuration errors silently\n }\n let token\n if (payload.config.auth) {\n token = await payload.config.auth.getToken()\n }\n // Dynamic (e.g. correlation) headers first, then explicit per-request headers\n // override them, then auth/content-type below take final precedence.\n //\n // Correlation headers (traceparent, x-cc-session-id) identify our internal\n // request/session, so they must only ever reach Camunda-owned systems. Every\n // third-party target is marked `type: 'external'`, so we gate on that here:\n // external targets never receive dynamic headers even if the caller's config\n // sets getDynamicHeaders. This makes propagation safe-by-default and removes\n // the footgun of a shared config that is used for both internal and\n // third-party calls (e.g. BASIC_API_CONFIG \u2192 token-issuer vs Slack).\n let dynamicHeaders: Record<string, string> = {}\n if (payload.metricsDetails?.target?.type !== 'external') {\n try {\n dynamicHeaders = payload.config.getDynamicHeaders?.() ?? {}\n } catch (_error) {\n // never let header evaluation break a request\n }\n }\n const headers: { [key: string]: string } = {\n ...dynamicHeaders,\n ...(payload.headers ?? {}),\n }\n if (token) {\n headers.Authorization = `Bearer ${token}`\n }\n if (payload.base?.id === 'accounts' || isAccountsUrl(payload)) {\n Object.assign(headers, accountsNgHeaders())\n }\n const type = payload.type ?? 'json'\n let body\n if (type) {\n switch (type) {\n case 'json': {\n headers['Content-Type'] = 'application/json'\n const given = payload.bodyWhenGiven\n ? payload.body !== undefined\n : Boolean(payload.body)\n body = given ? JSON.stringify(payload.body) : undefined\n break\n }\n case 'text':\n headers['Content-Type'] = 'text/plain'\n body = payload.body ? JSON.stringify(payload.body) : undefined\n break\n case 'form':\n if (payload.body) {\n const formData = new URLSearchParams()\n Object.keys(payload.body).forEach((key) => {\n formData.append(key, payload.body[key])\n })\n body = formData\n }\n break\n }\n }\n let base\n if (payload.base) {\n try {\n base = getEnvParam(payload.base.id, payload.config)\n } catch (error) {\n log(payload, 'error', `Failed to get base url for ${payload.base.id}`, {\n error,\n })\n throw error\n }\n }\n const url = base ? `${base}/${payload.url}` : payload.url\n\n // Attempt cache read for GET requests (stale-while-revalidate when callback supplied)\n let serveCachedAndReturnAfterNetwork = false\n if (payload.method === 'get' && payload.config.frontendCaching?.enabled) {\n try {\n const cached = await frontendCache.get<T>('get', url)\n if (cached) {\n const fresh = frontendCache.isFresh(cached)\n if (payload.onCachedResponse) {\n payload.onCachedResponse(cached.payload, { fresh, source: 'cache' })\n if (!fresh) {\n log(payload, 'debug', 'cache stale, refreshing in background')\n serveCachedAndReturnAfterNetwork = true\n } else {\n log(payload, 'debug', 'cache fresh, returning early')\n sendMetrics(payload, 'success', { duration: 0, statusCode: '200' })\n return {\n // eslint-disable-next-line id-length\n ok: true,\n status: 200,\n statusText: 'cached',\n body: cached.payload,\n meta: { duration: 0 },\n }\n }\n } else if (fresh) {\n // no callback but fresh -> return directly\n log(payload, 'debug', 'cache hit, returning cached response')\n sendMetrics(payload, 'success', { duration: 0, statusCode: '200' })\n return {\n // eslint-disable-next-line id-length\n ok: true,\n status: 200,\n statusText: 'cached',\n body: cached.payload,\n meta: { duration: 0 },\n }\n } else {\n log(payload, 'debug', 'cache stale, proceeding with network request')\n }\n }\n } catch (_cacheGetError) {\n // ignore cache errors\n }\n }\n const start = performance.now()\n const proxyAgent = payload.config.proxyAgent ?? {}\n try {\n const fetchResponse = await fetch(url, {\n signal: payload.config.timeout\n ? AbortSignal.timeout(payload.config.timeout)\n : undefined,\n method: payload.method.toUpperCase(),\n headers,\n body,\n ...proxyAgent,\n })\n const end = performance.now()\n const duration = end - start\n\n if ([429].includes(fetchResponse.status)) {\n // rate limiting, retry\n log(payload, 'info', 'rate limited', { durationMs: Math.floor(duration) })\n sendMetrics(payload, 'rate-limit-retry', {\n duration,\n statusCode: String(fetchResponse.status),\n })\n const remaining = payload.retry?.remaining ?? 8\n const attempts = payload.retry?.attempts ?? 1\n if (remaining > 0) {\n let waitingTime = rateLimitWaitingTime(attempts)\n if (fetchResponse.headers.has('x-ratelimit-reset')) {\n const rateLimitHeader = fetchResponse.headers.get('x-ratelimit-reset')\n log(\n payload,\n 'debug',\n `rate limited, found x-ratelimit-reset header: ${rateLimitHeader}`,\n )\n const rateLimitHeaderNumber = Number(rateLimitHeader)\n if (Number.isNaN(rateLimitHeaderNumber)) {\n waitingTime = Date.parse(rateLimitHeader ?? '0') - Date.now()\n } else {\n waitingTime = rateLimitHeaderNumber - Date.now()\n }\n }\n if (waitingTime < 0 || waitingTime > 180000) {\n waitingTime = rateLimitWaitingTime(attempts)\n }\n log(\n payload,\n 'debug',\n `rate limited, attempt ${attempts}, remaining ${remaining}, waiting ${waitingTime}ms`,\n )\n await new Promise((resolve) => {\n setTimeout(resolve, waitingTime)\n })\n // eslint-disable-next-line require-atomic-updates\n payload.retry = {\n attempts: attempts + 1,\n remaining: remaining - 1,\n }\n return request(payload)\n }\n log(payload, 'debug', `rate limited, no more retries`, {\n durationMs: Math.floor(duration),\n })\n }\n\n const response: Response<T> = {\n // eslint-disable-next-line id-length\n ok: fetchResponse.ok,\n status: fetchResponse.status,\n statusText: fetchResponse.statusText,\n meta: {\n duration,\n },\n }\n\n const responseType = payload.responseType ?? type\n\n if (response.ok) {\n log(payload, 'debug', `request successful in ${Math.floor(duration)}ms`, {\n baseUrl: base,\n durationMs: Math.floor(duration),\n })\n sendMetrics(payload, 'success', {\n duration,\n statusCode: String(fetchResponse.status),\n })\n switch (responseType) {\n case 'json':\n try {\n response.body = await fetchResponse.json()\n } catch (_error) {\n log(\n payload,\n 'debug',\n `Failed to parse json body. Returning empty object.`,\n {\n baseUrl: base,\n },\n )\n response.body = {} as T\n try {\n const responseBodyText = await fetchResponse.text()\n log(payload, 'debug', `Response body text`, {\n baseUrl: base,\n responseBodyText,\n status: fetchResponse.status,\n })\n } catch (textError) {\n // this is fine\n log(payload, 'debug', `Failed to parse response body text.`, {\n baseUrl: base,\n status: fetchResponse.status,\n error: textError,\n })\n }\n }\n break\n case 'text':\n response.body = (await fetchResponse.text()) as T\n break\n case 'blob':\n // Binary payloads (file downloads, e.g. database dumps). Not cached.\n response.body = (await fetchResponse.blob()) as T\n break\n default:\n response.body = (await fetchResponse.text()) as T\n }\n // store in cache after parsing\n if (\n payload.method === 'get' &&\n payload.config.frontendCaching?.enabled &&\n response.body !== undefined &&\n responseType !== 'blob'\n ) {\n try {\n await frontendCache.set('get', url, response.body as any)\n log(payload, 'debug', 'cache store successful')\n } catch (_cacheSetError) {\n // ignore cache set error\n }\n }\n } else {\n let statusText = fetchResponse.statusText\n try {\n statusText = await fetchResponse.text()\n } catch (_error) {\n // this is fine\n }\n if (statusText.length > MAX_ERROR_BODY_LENGTH) {\n // The marker is part of the budget, so the stored value never exceeds\n // MAX_ERROR_BODY_LENGTH \u2014 appending it after slicing to the full cap\n // would put the result over the bound the constant advertises.\n statusText = `${statusText.slice(\n 0,\n MAX_ERROR_BODY_LENGTH - ERROR_BODY_TRUNCATION_MARKER.length,\n )}${ERROR_BODY_TRUNCATION_MARKER}`\n }\n response.statusText = statusText\n log(\n payload,\n 'debug',\n `request failed with status ${response.status}: ${statusText}`,\n {\n baseUrl: base,\n durationMs: Math.floor(duration),\n },\n )\n\n // Transient gateway failure (e.g. envoy \"connection termination\" 503\n // during a pod restart). When opted in, retry with backoff and record it\n // as `transient-retry` rather than `error`, so a healed blip stays off\n // the internal error-rate alert.\n if (\n TRANSIENT_RETRY_STATUS.includes(response.status) &&\n canRetryTransient(payload)\n ) {\n sendMetrics(payload, 'transient-retry', {\n duration,\n statusCode: String(fetchResponse.status),\n error: statusText,\n })\n await scheduleTransientRetry(payload)\n return request(payload)\n }\n\n // Special Handling for dedicated target systems to not count special status codes as errors\n // eslint-disable-next-line no-shadow\n let type: RequestBaseCustomMetricsDetailsType = 'error'\n const noErrorStatusCodes: number[] = []\n switch (payload.metricsDetails.target.name) {\n case 'auth0':\n noErrorStatusCodes.push(...[400, 404, 409])\n break\n case 'accounts':\n case 'console':\n noErrorStatusCodes.push(...[404, 409])\n if (payload.metricsDetails.method.name === 'createTemporaryCluster') {\n // case: cannot create temporary cluster\n noErrorStatusCodes.push(...[400, 403, 412])\n }\n if (\n [\n 'ConsoleM2MService.verifyZeebeClient',\n 'ConsoleM2MService.verifyApiClient',\n ].includes(payload.metricsDetails.method.name)\n ) {\n // case: api/zeebe client credentials are invalid\n noErrorStatusCodes.push(...[401])\n }\n if (\n payload.metricsDetails.method.name ===\n 'OrgsService.createAndReturnSocialLoginUser'\n ) {\n noErrorStatusCodes.push(\n ...[\n // onboard user, user already has an org\n 400,\n // existing extSSO-connection\n 412,\n ],\n )\n }\n break\n case 'control':\n if (\n payload.metricsDetails.method.name ===\n 'ControlAgentClientsInternalService.verify'\n ) {\n // case: the credentials of an agent client are invalid\n noErrorStatusCodes.push(401)\n }\n if (\n payload.metricsDetails.method.name ===\n 'ControlAgentClientsInternalService.redeemGrant'\n ) {\n // case: the grant code is wrong, used or expired\n noErrorStatusCodes.push(401)\n }\n if (\n payload.metricsDetails.method.name ===\n 'ControlAgentGrantsInternalService.create'\n ) {\n // case: control-backend refuses the grant\n noErrorStatusCodes.push(409)\n }\n break\n }\n\n const methodName = payload.metricsDetails.method.name\n if (methodName.startsWith('CcmaOpenApiService.send.')) {\n // case: the agent sent a wrong request, or the token cannot call the operation\n if (response.status >= 400 && response.status < 500) {\n noErrorStatusCodes.push(response.status)\n }\n }\n if (methodName === 'CcmaOpenApiService.getDocument') {\n // case: the agent token expired or its binding was revoked\n noErrorStatusCodes.push(401)\n }\n\n if (noErrorStatusCodes.includes(response.status)) {\n type = 'success'\n }\n\n sendMetrics(payload, type, {\n duration,\n statusCode: String(fetchResponse.status),\n error: statusText,\n })\n\n if (payload.config.onFailedResponse) {\n try {\n await payload.config.onFailedResponse({\n method: payload.method,\n baseId: payload.base?.id,\n url: payload.url,\n status: fetchResponse.status,\n headers: fetchResponse.headers,\n body: statusText,\n requestBody: payload.body,\n })\n } catch (hookError) {\n throw new FailedResponseHookError(hookError)\n }\n }\n }\n if (serveCachedAndReturnAfterNetwork && response.ok) {\n // when we served stale via callback earlier, we now also return the fresh response\n log(payload, 'debug', 'stale cache updated, returning new data')\n }\n return response\n } catch (error: any) {\n if (error instanceof FailedResponseHookError) {\n throw error.hookError\n }\n const duration = performance.now() - start\n let errorMessage: string | undefined\n if (error?.cause?.code) {\n errorMessage = error?.cause?.code\n } else if (error?.message) {\n errorMessage = error?.message\n }\n // Network/fetch error with no HTTP status (e.g. connection reset, timeout).\n // Retry-on-opt-in before treating it as an error (see else branch above).\n if (canRetryTransient(payload)) {\n log(payload, 'debug', `request failed with no status, retrying`, {\n baseUrl: base,\n error,\n durationMs: Math.floor(duration),\n })\n sendMetrics(payload, 'transient-retry', {\n statusCode: 'fetch-error',\n duration,\n error: errorMessage,\n })\n await scheduleTransientRetry(payload)\n return request(payload)\n }\n log(\n payload,\n payload.warnOnNoStatus ? 'warn' : 'error',\n `request failed with no status`,\n {\n baseUrl: base,\n error,\n durationMs: Math.floor(duration),\n },\n )\n sendMetrics(payload, 'error', {\n statusCode: 'fetch-error',\n duration,\n error: errorMessage,\n })\n const response: Response<T> = {\n // eslint-disable-next-line id-length\n ok: false,\n status: 500,\n statusText: 'fetch error',\n meta: {\n duration,\n },\n }\n return response\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["type"]
7
7
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  import type { RequestBaseParamsConfig } from '../types/general.types.js';
2
- export type ServiceName = 'accounts' | 'console' | 'control' | 'audit-logger' | 'notifications' | 'login' | 'login-internal' | 'comm-bridge' | 'telemetry' | 'mixpanel' | 'alert-distributor' | 'analytic-bridge' | 'wordpress-helpcenter';
2
+ export type ServiceName = 'accounts' | 'console' | 'control' | 'audit-logger' | 'notifications' | 'login' | 'login-internal' | 'comm-bridge' | 'telemetry' | 'alert-distributor' | 'analytic-bridge' | 'wordpress-helpcenter';
3
3
  export type ServiceAudience = 'camunda-cloud-audience' | 'comm-bridge-audience' | 'notification-audience' | 'analytics-audience';
4
4
  export interface EnvironmentParam {
5
5
  id: ServiceName | ServiceAudience;
@@ -72,13 +72,6 @@ const ENV_PARAMS = [
72
72
  int: "https://telemetry.cloud.ultrawombat.com",
73
73
  prod: "https://telemetry.cloud.camunda.io"
74
74
  },
75
- {
76
- id: "mixpanel",
77
- dev: "https://api.mixpanel.com",
78
- devAws: "https://api.mixpanel.com",
79
- int: "https://api.mixpanel.com",
80
- prod: "https://api.mixpanel.com"
81
- },
82
75
  {
83
76
  id: "alert-distributor",
84
77
  dev: "https://alert-distributor.cloud.dev.ultrawombat.com",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/environments.ts"],
4
- "sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type { RequestBaseParamsConfig } from '../types/general.types.js'\n\nexport type ServiceName =\n | 'accounts'\n | 'console'\n | 'control'\n | 'audit-logger'\n | 'notifications'\n | 'login'\n | 'login-internal'\n | 'comm-bridge'\n | 'telemetry'\n | 'mixpanel'\n | 'alert-distributor'\n | 'analytic-bridge'\n | 'wordpress-helpcenter'\n\nexport type ServiceAudience =\n | 'camunda-cloud-audience'\n | 'comm-bridge-audience'\n | 'notification-audience'\n | 'analytics-audience'\n\nexport interface EnvironmentParam {\n id: ServiceName | ServiceAudience\n dev: string\n devAws: string\n int: string\n prod: string\n}\n\nconst ENV_PARAMS: EnvironmentParam[] = [\n {\n id: 'notifications',\n dev: 'https://notifications.cloud.dev.ultrawombat.com',\n devAws: 'https://notifications.cloud.dev.ultrawombat.com',\n int: 'https://notifications.cloud.ultrawombat.com',\n prod: 'https://notifications.cloud.camunda.io',\n },\n {\n id: 'console',\n dev: 'https://console.cloud.dev.ultrawombat.com',\n devAws: 'https://console-aws.cloud.dev.ultrawombat.com',\n int: 'https://console.cloud.ultrawombat.com',\n prod: 'https://console.cloud.camunda.io',\n },\n {\n id: 'accounts',\n dev: 'https://accounts.cloud.dev.ultrawombat.com',\n devAws: 'https://accounts-aws.cloud.dev.ultrawombat.com',\n int: 'https://accounts.cloud.ultrawombat.com',\n prod: 'https://accounts.cloud.camunda.io',\n },\n {\n // control-backend, the four-eyes approval service. It deploys to dev, int\n // and prod, and the names follow the pattern of every other service of\n // the fleet.\n id: 'control',\n dev: 'https://control.cloud.dev.ultrawombat.com',\n devAws: 'https://control.cloud.dev.ultrawombat.com',\n int: 'https://control.cloud.ultrawombat.com',\n prod: 'https://control.cloud.camunda.io',\n },\n {\n id: 'audit-logger',\n dev: 'https://audit.cloud.dev.ultrawombat.com',\n devAws: 'https://audit-logger.cloud.dev.ultrawombat.com',\n int: 'https://audit.cloud.ultrawombat.com',\n prod: 'https://audit.cloud.camunda.io',\n },\n {\n id: 'analytic-bridge',\n dev: 'https://analytics.cloud.dev.ultrawombat.com',\n devAws: 'https://analytics-bridge.cloud.dev.ultrawombat.com',\n int: 'https://analytics.cloud.ultrawombat.com',\n prod: 'https://analytics.cloud.camunda.io',\n },\n {\n id: 'login',\n dev: 'https://login.cloud.dev.ultrawombat.com',\n devAws: 'https://login.cloud.dev.ultrawombat.com',\n int: 'https://login.cloud.ultrawombat.com',\n prod: 'https://login.cloud.camunda.io',\n },\n {\n id: 'login-internal',\n dev: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n devAws: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n int: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n prod: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n },\n {\n id: 'comm-bridge',\n dev: 'https://comm.cloud.dev.ultrawombat.com',\n devAws: 'https://comm.cloud.dev.ultrawombat.com',\n int: 'https://comm.cloud.ultrawombat.com',\n prod: 'https://comm.cloud.camunda.io',\n },\n {\n id: 'telemetry',\n dev: 'https://telemetry.cloud.dev.ultrawombat.com',\n devAws: 'https://telemetry.cloud.dev.ultrawombat.com',\n int: 'https://telemetry.cloud.ultrawombat.com',\n prod: 'https://telemetry.cloud.camunda.io',\n },\n {\n id: 'mixpanel',\n dev: 'https://api.mixpanel.com',\n devAws: 'https://api.mixpanel.com',\n int: 'https://api.mixpanel.com',\n prod: 'https://api.mixpanel.com',\n },\n {\n id: 'alert-distributor',\n dev: 'https://alert-distributor.cloud.dev.ultrawombat.com',\n devAws: 'https://alert-distributor.cloud.dev.ultrawombat.com',\n int: 'https://alert-distributor.cloud.ultrawombat.com',\n prod: 'https://alert-distributor.cloud.camunda.io',\n },\n {\n id: 'wordpress-helpcenter',\n dev: 'https://camunda-help-stg.mystagingwebsite.com',\n devAws: 'https://camunda-help-stg.mystagingwebsite.com',\n int: 'https://camunda-help-stg.mystagingwebsite.com',\n prod: 'https://camunda-helpcenter.mystagingwebsite.com',\n },\n // AUDIENCES\n {\n id: 'camunda-cloud-audience',\n dev: 'cloud.dev.ultrawombat.com',\n devAws: 'cloud.dev.ultrawombat.com',\n int: 'cloud.ultrawombat.com',\n prod: 'cloud.camunda.io',\n },\n {\n id: 'comm-bridge-audience',\n dev: 'comm.dev.ultrawombat.com',\n devAws: 'comm.dev.ultrawombat.com',\n int: 'comm.ultrawombat.com',\n prod: 'comm.camunda.io',\n },\n {\n id: 'notification-audience',\n dev: 'notifications.dev.ultrawombat.com',\n devAws: 'notifications.dev.ultrawombat.com',\n int: 'notifications.ultrawombat.com',\n prod: 'notifications.camunda.io',\n },\n {\n id: 'analytics-audience',\n dev: 'analytics.dev.ultrawombat.com',\n devAws: 'analytics.dev.ultrawombat.com',\n int: 'analytics.ultrawombat.com',\n prod: 'analytics.camunda.io',\n },\n]\n\nexport function getEnvParam(\n id: ServiceName | ServiceAudience,\n config: RequestBaseParamsConfig,\n) {\n if (config.envOverride?.[id] && config.envOverride[id].length > 0) {\n return config.envOverride[id]\n }\n\n if (\n (id === 'console' && config.stage === 'localconsole') ||\n (id === 'accounts' && config.stage === 'localaccounts')\n ) {\n // special handling if running console/accounts frontend and backend locally\n return `http://localhost:8080`\n }\n\n const envParam = ENV_PARAMS.find(\n (environmentParam) => environmentParam.id === id,\n )\n if (!envParam) {\n throw new Error(`Unknown id: ${id}`)\n }\n switch (config.stage) {\n case 'local':\n case 'localconsole':\n case 'localaccounts':\n case 'dev':\n return envParam.dev\n case 'devAws':\n return envParam.devAws\n case 'int':\n return envParam.int\n case 'prod':\n return envParam.prod\n default:\n throw new Error(`Unknown stage: ${config.stage}`)\n }\n}\n"],
5
- "mappings": "AAqCA,MAAM,aAAiC;AAAA,EACrC;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,IAIE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA;AAAA,EAEA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;AAEO,SAAS,YACd,IACA,QACA;AACA,MAAI,OAAO,cAAc,EAAE,KAAK,OAAO,YAAY,EAAE,EAAE,SAAS,GAAG;AACjE,WAAO,OAAO,YAAY,EAAE;AAAA,EAC9B;AAEA,MACG,OAAO,aAAa,OAAO,UAAU,kBACrC,OAAO,cAAc,OAAO,UAAU,iBACvC;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,WAAW;AAAA,IAC1B,CAAC,qBAAqB,iBAAiB,OAAO;AAAA,EAChD;AACA,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,eAAe,EAAE,EAAE;AAAA,EACrC;AACA,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,SAAS;AAAA,IAClB,KAAK;AACH,aAAO,SAAS;AAAA,IAClB,KAAK;AACH,aAAO,SAAS;AAAA,IAClB,KAAK;AACH,aAAO,SAAS;AAAA,IAClB;AACE,YAAM,IAAI,MAAM,kBAAkB,OAAO,KAAK,EAAE;AAAA,EACpD;AACF;",
4
+ "sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type { RequestBaseParamsConfig } from '../types/general.types.js'\n\nexport type ServiceName =\n | 'accounts'\n | 'console'\n | 'control'\n | 'audit-logger'\n | 'notifications'\n | 'login'\n | 'login-internal'\n | 'comm-bridge'\n | 'telemetry'\n | 'alert-distributor'\n | 'analytic-bridge'\n | 'wordpress-helpcenter'\n\nexport type ServiceAudience =\n | 'camunda-cloud-audience'\n | 'comm-bridge-audience'\n | 'notification-audience'\n | 'analytics-audience'\n\nexport interface EnvironmentParam {\n id: ServiceName | ServiceAudience\n dev: string\n devAws: string\n int: string\n prod: string\n}\n\nconst ENV_PARAMS: EnvironmentParam[] = [\n {\n id: 'notifications',\n dev: 'https://notifications.cloud.dev.ultrawombat.com',\n devAws: 'https://notifications.cloud.dev.ultrawombat.com',\n int: 'https://notifications.cloud.ultrawombat.com',\n prod: 'https://notifications.cloud.camunda.io',\n },\n {\n id: 'console',\n dev: 'https://console.cloud.dev.ultrawombat.com',\n devAws: 'https://console-aws.cloud.dev.ultrawombat.com',\n int: 'https://console.cloud.ultrawombat.com',\n prod: 'https://console.cloud.camunda.io',\n },\n {\n id: 'accounts',\n dev: 'https://accounts.cloud.dev.ultrawombat.com',\n devAws: 'https://accounts-aws.cloud.dev.ultrawombat.com',\n int: 'https://accounts.cloud.ultrawombat.com',\n prod: 'https://accounts.cloud.camunda.io',\n },\n {\n // control-backend, the four-eyes approval service. It deploys to dev, int\n // and prod, and the names follow the pattern of every other service of\n // the fleet.\n id: 'control',\n dev: 'https://control.cloud.dev.ultrawombat.com',\n devAws: 'https://control.cloud.dev.ultrawombat.com',\n int: 'https://control.cloud.ultrawombat.com',\n prod: 'https://control.cloud.camunda.io',\n },\n {\n id: 'audit-logger',\n dev: 'https://audit.cloud.dev.ultrawombat.com',\n devAws: 'https://audit-logger.cloud.dev.ultrawombat.com',\n int: 'https://audit.cloud.ultrawombat.com',\n prod: 'https://audit.cloud.camunda.io',\n },\n {\n id: 'analytic-bridge',\n dev: 'https://analytics.cloud.dev.ultrawombat.com',\n devAws: 'https://analytics-bridge.cloud.dev.ultrawombat.com',\n int: 'https://analytics.cloud.ultrawombat.com',\n prod: 'https://analytics.cloud.camunda.io',\n },\n {\n id: 'login',\n dev: 'https://login.cloud.dev.ultrawombat.com',\n devAws: 'https://login.cloud.dev.ultrawombat.com',\n int: 'https://login.cloud.ultrawombat.com',\n prod: 'https://login.cloud.camunda.io',\n },\n {\n id: 'login-internal',\n dev: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n devAws: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n int: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n prod: 'http://token-issuer.token-issuer.svc.cluster.local:8080',\n },\n {\n id: 'comm-bridge',\n dev: 'https://comm.cloud.dev.ultrawombat.com',\n devAws: 'https://comm.cloud.dev.ultrawombat.com',\n int: 'https://comm.cloud.ultrawombat.com',\n prod: 'https://comm.cloud.camunda.io',\n },\n {\n id: 'telemetry',\n dev: 'https://telemetry.cloud.dev.ultrawombat.com',\n devAws: 'https://telemetry.cloud.dev.ultrawombat.com',\n int: 'https://telemetry.cloud.ultrawombat.com',\n prod: 'https://telemetry.cloud.camunda.io',\n },\n {\n id: 'alert-distributor',\n dev: 'https://alert-distributor.cloud.dev.ultrawombat.com',\n devAws: 'https://alert-distributor.cloud.dev.ultrawombat.com',\n int: 'https://alert-distributor.cloud.ultrawombat.com',\n prod: 'https://alert-distributor.cloud.camunda.io',\n },\n {\n id: 'wordpress-helpcenter',\n dev: 'https://camunda-help-stg.mystagingwebsite.com',\n devAws: 'https://camunda-help-stg.mystagingwebsite.com',\n int: 'https://camunda-help-stg.mystagingwebsite.com',\n prod: 'https://camunda-helpcenter.mystagingwebsite.com',\n },\n // AUDIENCES\n {\n id: 'camunda-cloud-audience',\n dev: 'cloud.dev.ultrawombat.com',\n devAws: 'cloud.dev.ultrawombat.com',\n int: 'cloud.ultrawombat.com',\n prod: 'cloud.camunda.io',\n },\n {\n id: 'comm-bridge-audience',\n dev: 'comm.dev.ultrawombat.com',\n devAws: 'comm.dev.ultrawombat.com',\n int: 'comm.ultrawombat.com',\n prod: 'comm.camunda.io',\n },\n {\n id: 'notification-audience',\n dev: 'notifications.dev.ultrawombat.com',\n devAws: 'notifications.dev.ultrawombat.com',\n int: 'notifications.ultrawombat.com',\n prod: 'notifications.camunda.io',\n },\n {\n id: 'analytics-audience',\n dev: 'analytics.dev.ultrawombat.com',\n devAws: 'analytics.dev.ultrawombat.com',\n int: 'analytics.ultrawombat.com',\n prod: 'analytics.camunda.io',\n },\n]\n\nexport function getEnvParam(\n id: ServiceName | ServiceAudience,\n config: RequestBaseParamsConfig,\n) {\n if (config.envOverride?.[id] && config.envOverride[id].length > 0) {\n return config.envOverride[id]\n }\n\n if (\n (id === 'console' && config.stage === 'localconsole') ||\n (id === 'accounts' && config.stage === 'localaccounts')\n ) {\n // special handling if running console/accounts frontend and backend locally\n return `http://localhost:8080`\n }\n\n const envParam = ENV_PARAMS.find(\n (environmentParam) => environmentParam.id === id,\n )\n if (!envParam) {\n throw new Error(`Unknown id: ${id}`)\n }\n switch (config.stage) {\n case 'local':\n case 'localconsole':\n case 'localaccounts':\n case 'dev':\n return envParam.dev\n case 'devAws':\n return envParam.devAws\n case 'int':\n return envParam.int\n case 'prod':\n return envParam.prod\n default:\n throw new Error(`Unknown stage: ${config.stage}`)\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/ccma-api",
3
- "version": "5.20.2",
3
+ "version": "6.1.0",
4
4
  "description": "Centralized API service layer for Camunda Cloud Management Apps",
5
5
  "bugs": {
6
6
  "url": "https://github.com/camunda/camunda-cloud-management-apps/issues"
@@ -1,16 +0,0 @@
1
- import type { RequestBaseParams } from '../../types/general.types.js';
2
- export interface MixpanelSetGroupPropertiesOnceRequest extends RequestBaseParams {
3
- options: {
4
- token: string;
5
- groupKey: string;
6
- properties: {
7
- [key: string]: string;
8
- };
9
- groupId?: string;
10
- groupType: 'group-set-once' | 'group-set';
11
- retries?: number;
12
- };
13
- }
14
- export declare class MixpanelService {
15
- static setGroupPropertiesOnce(params: MixpanelSetGroupPropertiesOnceRequest): Promise<void>;
16
- }
@@ -1,86 +0,0 @@
1
- import { log, request } from "../../utils/api.js";
2
- import { HttpError } from "../../utils/errors.js";
3
- class MixpanelService {
4
- static async setGroupPropertiesOnce(params) {
5
- const serviceContext = {
6
- method: {
7
- name: `MixpanelService.setGroupPropertiesOnce`,
8
- url: `groups#${params.options.groupType}`,
9
- normalizedUrl: `groups#${params.options.groupType}`,
10
- type: "post"
11
- },
12
- source: params.config.metrics?.source || "unset",
13
- target: {
14
- name: "mixpanel",
15
- type: "external"
16
- }
17
- };
18
- const setPropertyName = params.options.groupType === "group-set-once" ? "set_once" : "set";
19
- const body = {
20
- $token: params.options.token,
21
- $group_key: params.options.groupKey,
22
- $group_id: params.options.groupId
23
- };
24
- body[`$${setPropertyName}`] = params.options.properties;
25
- const headers = {
26
- Accept: "text/plain",
27
- "Content-Type": "content-type: application/json"
28
- };
29
- const requestConfig = {
30
- config: params.config,
31
- base: {
32
- id: "mixpanel"
33
- },
34
- url: serviceContext.method.url,
35
- method: serviceContext.method.type,
36
- metricsDetails: serviceContext,
37
- type: "none",
38
- responseType: "none",
39
- body,
40
- headers
41
- };
42
- if (params.config.stage === "dev") {
43
- log(requestConfig, "debug", `Mixpanel setGroupPropertiesOnce`, {
44
- requestConfig
45
- });
46
- }
47
- if (!params.options.groupId || Object.keys(params.options.properties).length === 0) {
48
- log(requestConfig, "debug", "No group id or properties to set");
49
- return;
50
- }
51
- const response = await request(requestConfig);
52
- if (!response.ok) {
53
- const MAX_RETRIES = 5;
54
- let retries = params.options.retries || 0;
55
- if (retries > 0) {
56
- if (retries > MAX_RETRIES) {
57
- retries = MAX_RETRIES;
58
- }
59
- const retryWaitingTime = (MAX_RETRIES - retries + 1) * 500;
60
- log(
61
- requestConfig,
62
- "debug",
63
- `Mixpanel setGroupProperties error, retrying. Retries left: ${retries}`
64
- );
65
- await new Promise((resolve) => {
66
- setTimeout(() => {
67
- resolve();
68
- }, retryWaitingTime);
69
- });
70
- await MixpanelService.setGroupPropertiesOnce({
71
- ...params,
72
- options: { ...params.options, retries: retries - 1 }
73
- });
74
- }
75
- throw new HttpError(
76
- `${serviceContext.method.name}: ${response.status} ${response.statusText}`,
77
- response.status,
78
- response.statusText
79
- );
80
- }
81
- }
82
- }
83
- export {
84
- MixpanelService
85
- };
86
- //# sourceMappingURL=mixpanel.service.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/services/mixpanel/mixpanel.service.ts"],
4
- "sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type {\n RequestBaseParams,\n RequestBaseServiceContext,\n} from '../../types/general.types.js'\nimport { log, type RequestPayload, request } from '../../utils/api.js'\nimport { HttpError } from '../../utils/errors.js'\n\nexport interface MixpanelSetGroupPropertiesOnceRequest\n extends RequestBaseParams {\n options: {\n token: string\n groupKey: string\n properties: { [key: string]: string }\n groupId?: string\n groupType: 'group-set-once' | 'group-set'\n retries?: number\n }\n}\n\nexport class MixpanelService {\n public static async setGroupPropertiesOnce(\n params: MixpanelSetGroupPropertiesOnceRequest,\n ) {\n // 2021-09-16: mixpanel node lib doesn't support group handling\n // using http api instead: https://developer.mixpanel.com/reference/group-profiles\n const serviceContext: RequestBaseServiceContext = {\n method: {\n name: `MixpanelService.setGroupPropertiesOnce`,\n url: `groups#${params.options.groupType}`,\n normalizedUrl: `groups#${params.options.groupType}`,\n type: 'post',\n },\n source: params.config.metrics?.source || 'unset',\n target: {\n name: 'mixpanel',\n type: 'external',\n },\n }\n\n const setPropertyName =\n params.options.groupType === 'group-set-once' ? 'set_once' : 'set'\n\n const body: any = {\n $token: params.options.token,\n $group_key: params.options.groupKey,\n $group_id: params.options.groupId,\n }\n body[`$${setPropertyName}`] = params.options.properties\n\n const headers = {\n Accept: 'text/plain',\n 'Content-Type': 'content-type: application/json',\n }\n\n const requestConfig: RequestPayload = {\n config: params.config,\n base: {\n id: 'mixpanel',\n },\n url: serviceContext.method.url,\n method: serviceContext.method.type,\n metricsDetails: serviceContext,\n type: 'none',\n responseType: 'none',\n body,\n headers,\n }\n\n if (params.config.stage === 'dev') {\n log(requestConfig, 'debug', `Mixpanel setGroupPropertiesOnce`, {\n requestConfig,\n })\n }\n\n if (\n !params.options.groupId ||\n Object.keys(params.options.properties).length === 0\n ) {\n log(requestConfig, 'debug', 'No group id or properties to set')\n return\n }\n\n const response = await request(requestConfig)\n if (!response.ok) {\n const MAX_RETRIES = 5\n let retries = params.options.retries || 0\n if (retries > 0) {\n if (retries > MAX_RETRIES) {\n retries = MAX_RETRIES\n }\n const retryWaitingTime = (MAX_RETRIES - retries + 1) * 500\n log(\n requestConfig,\n 'debug',\n `Mixpanel setGroupProperties error, retrying. Retries left: ${retries}`,\n )\n await new Promise<void>((resolve) => {\n setTimeout(() => {\n resolve()\n }, retryWaitingTime)\n })\n await MixpanelService.setGroupPropertiesOnce({\n ...params,\n options: { ...params.options, retries: retries - 1 },\n })\n }\n\n throw new HttpError(\n `${serviceContext.method.name}: ${response.status} ${response.statusText}`,\n response.status,\n response.statusText,\n )\n }\n }\n}\n"],
5
- "mappings": "AAUA,SAAS,KAA0B,eAAe;AAClD,SAAS,iBAAiB;AAcnB,MAAM,gBAAgB;AAAA,EAC3B,aAAoB,uBAClB,QACA;AAGA,UAAM,iBAA4C;AAAA,MAChD,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,KAAK,UAAU,OAAO,QAAQ,SAAS;AAAA,QACvC,eAAe,UAAU,OAAO,QAAQ,SAAS;AAAA,QACjD,MAAM;AAAA,MACR;AAAA,MACA,QAAQ,OAAO,OAAO,SAAS,UAAU;AAAA,MACzC,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAEA,UAAM,kBACJ,OAAO,QAAQ,cAAc,mBAAmB,aAAa;AAE/D,UAAM,OAAY;AAAA,MAChB,QAAQ,OAAO,QAAQ;AAAA,MACvB,YAAY,OAAO,QAAQ;AAAA,MAC3B,WAAW,OAAO,QAAQ;AAAA,IAC5B;AACA,SAAK,IAAI,eAAe,EAAE,IAAI,OAAO,QAAQ;AAE7C,UAAM,UAAU;AAAA,MACd,QAAQ;AAAA,MACR,gBAAgB;AAAA,IAClB;AAEA,UAAM,gBAAgC;AAAA,MACpC,QAAQ,OAAO;AAAA,MACf,MAAM;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,MACA,KAAK,eAAe,OAAO;AAAA,MAC3B,QAAQ,eAAe,OAAO;AAAA,MAC9B,gBAAgB;AAAA,MAChB,MAAM;AAAA,MACN,cAAc;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAEA,QAAI,OAAO,OAAO,UAAU,OAAO;AACjC,UAAI,eAAe,SAAS,mCAAmC;AAAA,QAC7D;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QACE,CAAC,OAAO,QAAQ,WAChB,OAAO,KAAK,OAAO,QAAQ,UAAU,EAAE,WAAW,GAClD;AACA,UAAI,eAAe,SAAS,kCAAkC;AAC9D;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,QAAQ,aAAa;AAC5C,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,cAAc;AACpB,UAAI,UAAU,OAAO,QAAQ,WAAW;AACxC,UAAI,UAAU,GAAG;AACf,YAAI,UAAU,aAAa;AACzB,oBAAU;AAAA,QACZ;AACA,cAAM,oBAAoB,cAAc,UAAU,KAAK;AACvD;AAAA,UACE;AAAA,UACA;AAAA,UACA,8DAA8D,OAAO;AAAA,QACvE;AACA,cAAM,IAAI,QAAc,CAAC,YAAY;AACnC,qBAAW,MAAM;AACf,oBAAQ;AAAA,UACV,GAAG,gBAAgB;AAAA,QACrB,CAAC;AACD,cAAM,gBAAgB,uBAAuB;AAAA,UAC3C,GAAG;AAAA,UACH,SAAS,EAAE,GAAG,OAAO,SAAS,SAAS,UAAU,EAAE;AAAA,QACrD,CAAC;AAAA,MACH;AAEA,YAAM,IAAI;AAAA,QACR,GAAG,eAAe,OAAO,IAAI,KAAK,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,QACxE,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;",
6
- "names": []
7
- }