@camunda/ccma-api 5.15.0 → 5.17.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.
package/dist/utils/api.js CHANGED
@@ -449,6 +449,11 @@ async function request(payload) {
449
449
  );
450
450
  }
451
451
  break;
452
+ case "control":
453
+ if (payload.metricsDetails.method.name === "ControlAgentClientsInternalService.verify") {
454
+ noErrorStatusCodes.push(401);
455
+ }
456
+ break;
452
457
  }
453
458
  if (noErrorStatusCodes.includes(response.status)) {
454
459
  type2 = "success";
@@ -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 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 for (const key of Object.keys(body)) {\n if (\n key.toLowerCase().includes('password') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('token')\n ) {\n body[key] = '********'\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 }\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 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 for (const key of Object.keys(body)) {\n if (\n key.toLowerCase().includes('password') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('token')\n ) {\n body[key] = '********'\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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",
6
6
  "names": ["type"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/ccma-api",
3
- "version": "5.15.0",
3
+ "version": "5.17.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"
@@ -41,7 +41,7 @@
41
41
  }
42
42
  },
43
43
  "dependencies": {
44
- "@camunda/ccma-shared-types": "10.2.0"
44
+ "@camunda/ccma-shared-types": "10.4.0"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "node esbuild.mjs && tsc --emitDeclarationOnly --outDir dist",