@interopio/gateway
Version:
[](https://www.npmjs.com/package/@interopio/gateway)
8 lines (7 loc) • 10.4 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/metrics/publisher/rest.ts"],
"sourcesContent": ["import type { PublishCommand } from './types.ts';\nimport { Metrics } from '../../../types/metrics/api';\nimport type { Logger } from '../../../types/logging/api';\nimport type { RestPublisherConfig } from '../../../types/metrics/publisher/rest';\n\nasync function discardResponseBody(response: Response) {\n if (!response.bodyUsed) {\n await response.blob();\n }\n}\n\nconst SUCCESS_STATUSES = new Set<number>([200/*OK*/, 201/*CREATED*/, 202/*ACCEPTED*/]);\n\nfunction basicAuthCredentials({user, password}: { user: string; password: string }) {\n const data = `${user}:${password}`;\n if (typeof process !== 'undefined') {\n return Buffer.from(data).toString('base64');\n } else {\n return globalThis.btoa(data);\n }\n}\n\nexport const name = 'rest';\n\nasync function login(url: URL, {logger, fetch: fetchFn, headers, timeout}: HandleContext) {\n\n if (logger.enabledFor('debug')) {\n logger.debug(`sending initial GET to do auth dance. url: ${url}`);\n }\n try {\n const response = await fetchFn(url, initRequest(timeout, headers));\n if (response.ok) {\n logger.info(`initial GET request completed successfully.`);\n if (logger.enabledFor('debug')) {\n const setCookie = response.headers.getSetCookie();\n if (setCookie.length > 0) {\n if (logger.enabledFor('debug')) {\n logger.debug(`will set following cookies: ${setCookie}`);\n }\n }\n }\n } else {\n logger.warn(`initial GET request did not completed successfully. Status: ${response.status}`);\n }\n } catch (e) {\n logger.warn(`error executing initial GET request`, e);\n throw e;\n }\n}\n\nasync function handleStart(auth: RestPublisherConfig['authentication'], context: HandleContext) {\n if (!isBasicAuthorization(auth) && auth !== false) {\n const url = new context.URL(context.endpoint);\n if (auth?.path) {\n url.pathname = auth.path;\n }\n await login(url, context)\n }\n context.logger.info('rest publisher started');\n}\n\nfunction handleStop({logger}: HandleContext) {\n logger.info('rest publisher stopped');\n}\n\nfunction initRequest(timeout: number, headers: Headers, m?: Metrics.Update): RequestInit {\n return m ?\n {\n method: 'POST',\n redirect: 'manual',\n credentials: 'include',\n signal: AbortSignal.timeout(timeout),\n headers,\n body: JSON.stringify(m)\n }\n :\n {\n method: 'GET',\n redirect: 'follow',\n credentials: 'include',\n signal: AbortSignal.timeout(timeout),\n headers\n }\n}\n\n// a helper type to track state changes\n// good -> bad\n// bad -> good\ntype PublisherState = {\n // indicates if the previous state was healthy\n prev: boolean\n // indicates\n now: boolean\n};\n\nasync function handleUpdate(m: Metrics.Update, state: PublisherState, {\n endpoint,\n headers,\n timeout,\n fetch: fetchFn,\n logger\n}: HandleContext) {\n const request = initRequest(timeout, headers, m);\n\n try {\n let response = await fetchFn(endpoint, request);\n if (response.redirected) {\n logger.info(`Redirect detected will do GET to allow auth dance and re-POST`);\n await discardResponseBody(response);\n const getResponse = await fetchFn(endpoint, initRequest(timeout, headers));\n await discardResponseBody(getResponse);\n if (getResponse.ok) {\n response = await fetchFn(endpoint, request);\n } else {\n logger.error(`GET failed with status: ${getResponse.status} headers: ${JSON.stringify(getResponse.headers)}`);\n }\n }\n await discardResponseBody(response);\n state.prev = state.now;\n state.now = SUCCESS_STATUSES.has(response.status);\n if (state.prev && !state.now) {\n logger.error(`Unable to publish metrics. status ${response.status} headers: ${JSON.stringify(response.headers)} msg: ${JSON.stringify(m)}`);\n } else if (state.now && !state.prev) {\n logger.info(`Publishing metrics.`);\n }\n } catch (e) {\n const logError = state.now;\n state.prev = state.now;\n state.now = false;\n if (logError) {\n logger.error(`Unable to publish metrics. msg ${JSON.stringify(m)}`, e);\n }\n }\n}\n\ntype HandleContext = {\n endpoint: string | URL\n headers: Headers\n timeout: number\n fetch: typeof fetch\n URL: typeof URL\n logger: Logger\n}\n\nfunction isBasicAuthorization(auth?: RestPublisherConfig['authentication']): auth is {user: string, password: string} {\n return auth !== undefined && auth && (auth['user'] !== undefined);\n}\n\nexport async function create(cfg: RestPublisherConfig, logger: Logger) {\n const endpoint = cfg.endpoint;\n const timeout = cfg.timeout ?? 1000;\n const HeadersCtor: typeof Headers = cfg.Headers ?? globalThis.Headers ?? Headers;\n const headers = new HeadersCtor(cfg.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json');\n }\n if (!headers.has('User-Agent')) {\n headers.set('User-Agent', cfg['user-agent'] ?? 'metrics-rest/0.2.x');\n }\n if (isBasicAuthorization(cfg.authentication) && !headers.has('Authorization')) {\n headers.set('Authorization', `Basic ${basicAuthCredentials(cfg.authentication)}`);\n }\n\n const fetchFn: typeof fetch = cfg.fetch ?? globalThis.fetch ?? fetch;\n const URLCtor: typeof URL = cfg.URL ?? globalThis.URL ?? URL;\n const state = { prev: false, now: true };\n const context: HandleContext = {endpoint, headers, timeout, fetch: fetchFn, URL: URLCtor, logger};\n return async (m: PublishCommand) => {\n if (logger.enabledFor('debug')) {\n logger.debug(`handling publish request: ${JSON.stringify(m)}`);\n }\n switch (m) {\n case 'start': {\n await handleStart(cfg.authentication, context);\n break;\n }\n case 'stop': {\n handleStop(context);\n break;\n }\n default: {\n await handleUpdate(m, state, context);\n break;\n }\n }\n }\n}\n"],
"mappings": "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",
"names": ["rest_exports", "__export", "create", "name", "__toCommonJS", "discardResponseBody", "response", "SUCCESS_STATUSES", "basicAuthCredentials", "user", "password", "data", "login", "url", "logger", "fetchFn", "headers", "timeout", "initRequest", "setCookie", "e", "handleStart", "auth", "context", "isBasicAuthorization", "handleStop", "m", "handleUpdate", "state", "endpoint", "request", "getResponse", "logError", "cfg", "HeadersCtor", "URLCtor"]
}