@kyncode/sdk 0.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.
- package/README.md +231 -0
- package/dist/index.cjs +1434 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +103 -0
- package/dist/index.d.ts +103 -0
- package/dist/index.js +1404 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/sanitizer.ts","../src/request-capture.ts","../src/adapters/express.ts","../src/adapters/fastify.ts","../src/adapters/node.ts","../src/dispatch.ts","../src/loly.ts"],"sourcesContent":["import { Loly } from './loly.js';\r\n\r\nexport { Loly, onRequestError, register, SDK_VERSION } from './loly.js';\r\nexport type {\r\n CapturedError,\r\n CapturedFrameworkContext,\r\n CapturedHttpMethod,\r\n CapturedRequestContext,\r\n ConnectivityDiagnostic,\r\n ConnectivityRuntime,\r\n ConnectivityStatus,\r\n ExpressErrorHandler,\r\n ExpressNextFunction,\r\n ExpressRequestLike,\r\n FastifyErrorHandler,\r\n FastifyReplyLike,\r\n FastifyRequestLike,\r\n FlushDiagnostic,\r\n FlushOptions,\r\n LolyApi,\r\n LolyConfig,\r\n LolyEnvironment,\r\n ProcessEventCleanup,\r\n RouteHandlerFn,\r\n SdkCodePayload,\r\n} from './types.js';\r\n\r\nexport default Loly;\r\n","export const MAX_SANITIZE_DEPTH = 6;\r\nexport const MAX_SANITIZE_NODES = 500;\r\nexport const MAX_SANITIZED_STRING_LENGTH = 4_096;\r\nexport const MAX_SANITIZED_COLLECTION_SIZE = 100;\r\nexport const MAX_SANITIZER_INPUT_LENGTH = MAX_SANITIZED_STRING_LENGTH * 4;\r\n\r\nconst REDACTED_SECRET = '[REDACTED_SECRET]';\r\nconst REDACTED_BEARER_TOKEN = '[REDACTED_BEARER_TOKEN]';\r\nconst REDACTED_JWT = '[REDACTED_JWT]';\r\nconst REDACTED_CARD = '[REDACTED_CARD]';\r\nconst REDACTED_PRIVATE_KEY = '[REDACTED_PRIVATE_KEY]';\r\nconst REDACTED_DATABASE_URL = '[REDACTED_DATABASE_URL]';\r\nconst CIRCULAR_REFERENCE = '[CIRCULAR]';\r\nconst DEPTH_LIMIT = '[TRUNCATED_DEPTH]';\r\nconst NODE_LIMIT = '[TRUNCATED_NODES]';\r\nconst COLLECTION_LIMIT_KEY = '__kyncode_truncated__';\r\n\r\nconst SENSITIVE_KEY_NAMES: ReadonlySet<string> = new Set([\r\n 'accesskey',\r\n 'accesstoken',\r\n 'apikey',\r\n 'auth',\r\n 'authorization',\r\n 'bearer',\r\n 'card',\r\n 'clientsecret',\r\n 'connectionstring',\r\n 'cookie',\r\n 'creditcard',\r\n 'credential',\r\n 'credentials',\r\n 'cvv',\r\n 'databaseurl',\r\n 'dburl',\r\n 'code',\r\n 'csrftoken',\r\n 'idtoken',\r\n 'invitecode',\r\n 'jwt',\r\n 'nonce',\r\n 'otp',\r\n 'pan',\r\n 'pass',\r\n 'passwd',\r\n 'password',\r\n 'pin',\r\n 'privatekey',\r\n 'refreshtoken',\r\n 'resetcode',\r\n 'secret',\r\n 'session',\r\n 'setcookie',\r\n 'sig',\r\n 'signature',\r\n 'state',\r\n 'token',\r\n 'verificationcode',\r\n 'xapikey',\r\n]);\r\n\r\nconst SENSITIVE_SEGMENTS: ReadonlySet<string> = new Set([\r\n 'authorization',\r\n 'cookie',\r\n 'credential',\r\n 'cvv',\r\n 'jwt',\r\n 'passwd',\r\n 'password',\r\n 'secret',\r\n 'session',\r\n 'token',\r\n]);\r\n\r\nconst PRIVATE_KEY_PATTERN =\r\n /-----BEGIN [A-Z\\d ]*PRIVATE KEY-----[\\s\\S]*?-----END [A-Z\\d ]*PRIVATE KEY-----/giu;\r\nconst PARTIAL_PRIVATE_KEY_PATTERN = /-----BEGIN [A-Z\\d ]*PRIVATE KEY-----[\\s\\S]*$/giu;\r\nconst DATABASE_URL_PATTERN =\r\n /\\b(?:mongodb(?:\\+srv)?|mysql|postgres(?:ql)?|redis|rediss):\\/\\/[^\\s'\"<>]+/giu;\r\nconst URL_CREDENTIAL_PATTERN = /(https?:\\/\\/)[^\\s/@:]+:[^\\s/@]+@/giu;\r\nconst BEARER_TOKEN_PATTERN = /\\bBearer\\s+[A-Za-z0-9\\-._~+/]{8,}=*/giu;\r\nconst JWT_PATTERN =\r\n /(?<![A-Za-z0-9_-])[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_+/=-]{8,}(?![A-Za-z0-9_+/=-])/gu;\r\nconst KYNCODE_KEY_PATTERN = /\\bkyn_(?:live|test)_[a-f0-9]{16,}\\b/giu;\r\nconst PROVIDER_TOKEN_PATTERN =\r\n /\\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}|xox[baprs]-[A-Za-z0-9-]{10,}|(?:AKIA|ASIA)[A-Z0-9]{16}|sk-[A-Za-z0-9_-]{20,})\\b/gu;\r\nconst SECRET_ASSIGNMENT_HEADER_PATTERN =\r\n /(?<![A-Za-z0-9_-])([\"'`]?)([A-Za-z0-9_-]{1,256})\\1\\s*[:=]\\s*/gimu;\r\nconst CARD_PATTERN = /(?<!\\d)(?:\\d[ -]?){12,18}\\d(?!\\d)/gu;\r\n\r\ninterface SanitizationState {\r\n nodes: number;\r\n readonly seen: WeakSet<object>;\r\n}\r\n\r\nexport function sanitizeClientData(input: unknown): unknown {\r\n return sanitizeValue(input, { nodes: 0, seen: new WeakSet<object>() }, 0);\r\n}\r\n\r\nexport function sanitizeStringRecord(\r\n input: Readonly<Record<string, string>>,\r\n): Readonly<Record<string, string>> {\r\n const entries = Object.entries(input).slice(0, MAX_SANITIZED_COLLECTION_SIZE);\r\n const sanitized = entries.map(([key, value], index): [string, string] => [\r\n sanitizeOutputKey(key, index),\r\n isSensitiveKey(key) ? REDACTED_SECRET : sanitizeText(value),\r\n ]);\r\n\r\n if (Object.keys(input).length > entries.length) {\r\n sanitized.push([COLLECTION_LIMIT_KEY, 'Additional fields were omitted']);\r\n }\r\n\r\n return Object.fromEntries(sanitized);\r\n}\r\n\r\nexport function sanitizeText(value: string): string {\r\n const boundedValue = value.slice(0, MAX_SANITIZER_INPUT_LENGTH);\r\n const omittedInputCharacters = value.length - boundedValue.length;\r\n const embeddedSecretsRedacted = boundedValue\r\n .replace(PRIVATE_KEY_PATTERN, REDACTED_PRIVATE_KEY)\r\n .replace(PARTIAL_PRIVATE_KEY_PATTERN, REDACTED_PRIVATE_KEY)\r\n .replace(DATABASE_URL_PATTERN, REDACTED_DATABASE_URL)\r\n .replace(URL_CREDENTIAL_PATTERN, `$1${REDACTED_SECRET}@`)\r\n .replace(BEARER_TOKEN_PATTERN, REDACTED_BEARER_TOKEN)\r\n .replace(JWT_PATTERN, REDACTED_JWT)\r\n .replace(KYNCODE_KEY_PATTERN, REDACTED_SECRET)\r\n .replace(PROVIDER_TOKEN_PATTERN, REDACTED_SECRET);\r\n const assignmentsRedacted = redactSecretAssignments(embeddedSecretsRedacted);\r\n const redacted = assignmentsRedacted.replace(CARD_PATTERN, REDACTED_CARD);\r\n\r\n return truncateString(redacted, omittedInputCharacters);\r\n}\r\n\r\nfunction redactSecretAssignments(value: string): string {\r\n SECRET_ASSIGNMENT_HEADER_PATTERN.lastIndex = 0;\r\n let cursor = 0;\r\n let output = '';\r\n let match: RegExpExecArray | null;\r\n\r\n while ((match = SECRET_ASSIGNMENT_HEADER_PATTERN.exec(value)) !== null) {\r\n const quote = match[1] ?? '';\r\n const key = match[2];\r\n if (key === undefined || !isSensitiveKey(key)) continue;\r\n\r\n const valueStart = SECRET_ASSIGNMENT_HEADER_PATTERN.lastIndex;\r\n const valueEnd = findAssignmentValueEnd(value, valueStart, match.index, quote);\r\n output += value.slice(cursor, match.index);\r\n output += `${quote}${key}${quote}=${REDACTED_SECRET}`;\r\n cursor = valueEnd;\r\n SECRET_ASSIGNMENT_HEADER_PATTERN.lastIndex = Math.max(valueEnd, valueStart);\r\n }\r\n\r\n SECRET_ASSIGNMENT_HEADER_PATTERN.lastIndex = 0;\r\n return `${output}${value.slice(cursor)}`;\r\n}\r\n\r\nfunction findAssignmentValueEnd(\r\n value: string,\r\n valueStart: number,\r\n headerStart: number,\r\n keyQuote: string,\r\n): number {\r\n const valueQuote = value[valueStart];\r\n if (isQuote(valueQuote)) return scanToClosingQuote(value, valueStart + 1, valueQuote, true);\r\n\r\n const enclosingQuote = keyQuote === '' ? value[headerStart - 1] : undefined;\r\n if (isQuote(enclosingQuote) && !isEscapedAt(value, headerStart - 1)) {\r\n return scanToClosingQuote(value, valueStart, enclosingQuote, false);\r\n }\r\n\r\n let cursor = valueStart;\r\n while (cursor < value.length && !isUnquotedAssignmentDelimiter(value[cursor])) cursor += 1;\r\n return cursor;\r\n}\r\n\r\nfunction scanToClosingQuote(\r\n value: string,\r\n start: number,\r\n quote: '\"' | \"'\" | '`',\r\n includeClosingQuote: boolean,\r\n): number {\r\n let escaped = false;\r\n for (let cursor = start; cursor < value.length; cursor += 1) {\r\n const character = value[cursor];\r\n if (character === '\\r' || character === '\\n') return cursor;\r\n if (escaped) {\r\n escaped = false;\r\n continue;\r\n }\r\n if (character === '\\\\') {\r\n escaped = true;\r\n continue;\r\n }\r\n if (character === quote) return includeClosingQuote ? cursor + 1 : cursor;\r\n }\r\n return value.length;\r\n}\r\n\r\nfunction isEscapedAt(value: string, index: number): boolean {\r\n let backslashes = 0;\r\n for (let cursor = index - 1; cursor >= 0 && value[cursor] === '\\\\'; cursor -= 1) {\r\n backslashes += 1;\r\n }\r\n return backslashes % 2 === 1;\r\n}\r\n\r\nfunction isQuote(value: string | undefined): value is '\"' | \"'\" | '`' {\r\n return value === '\"' || value === \"'\" || value === '`';\r\n}\r\n\r\nfunction isUnquotedAssignmentDelimiter(value: string | undefined): boolean {\r\n return (\r\n value === undefined ||\r\n value === '\\r' ||\r\n value === '\\n' ||\r\n value === ',' ||\r\n value === ';' ||\r\n value === '&'\r\n );\r\n}\r\n\r\nexport function isSensitiveKey(key: string): boolean {\r\n const separated = key.replace(/([a-z\\d])([A-Z])/gu, '$1_$2').toLowerCase();\r\n const segments = separated.split(/[^a-z0-9]+/u).filter((segment) => segment !== '');\r\n const canonical = segments.join('');\r\n\r\n return (\r\n SENSITIVE_KEY_NAMES.has(canonical) ||\r\n segments.some((segment) => SENSITIVE_SEGMENTS.has(segment)) ||\r\n (segments.includes('api') && segments.includes('key')) ||\r\n (segments.includes('private') && segments.includes('key')) ||\r\n (segments.includes('database') && segments.includes('url')) ||\r\n (segments.includes('connection') && segments.includes('string'))\r\n );\r\n}\r\n\r\nfunction sanitizeValue(value: unknown, state: SanitizationState, depth: number): unknown {\r\n state.nodes += 1;\r\n if (state.nodes > MAX_SANITIZE_NODES) return NODE_LIMIT;\r\n if (depth > MAX_SANITIZE_DEPTH) return DEPTH_LIMIT;\r\n\r\n if (value === null || value === undefined || typeof value === 'boolean') return value;\r\n if (typeof value === 'number') return Number.isFinite(value) ? value : String(value);\r\n if (typeof value === 'string') return sanitizeText(value);\r\n if (typeof value === 'bigint') return value.toString();\r\n if (typeof value === 'function' || typeof value === 'symbol') {\r\n return `[${(typeof value).toUpperCase()}]`;\r\n }\r\n\r\n if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) return '[REDACTED_BUFFER]';\r\n if (isDateLike(value)) return sanitizeDate(value);\r\n if (state.seen.has(value)) return CIRCULAR_REFERENCE;\r\n\r\n state.seen.add(value);\r\n const sanitized = Array.isArray(value)\r\n ? sanitizeArray(value, state, depth)\r\n : sanitizeObject(value, state, depth);\r\n state.seen.delete(value);\r\n return sanitized;\r\n}\r\n\r\nfunction sanitizeArray(\r\n value: readonly unknown[],\r\n state: SanitizationState,\r\n depth: number,\r\n): readonly unknown[] {\r\n const sanitized = value\r\n .slice(0, MAX_SANITIZED_COLLECTION_SIZE)\r\n .map((item) => sanitizeValue(item, state, depth + 1));\r\n\r\n return value.length > sanitized.length\r\n ? [...sanitized, `[TRUNCATED_${String(value.length - sanitized.length)}_ITEMS]`]\r\n : sanitized;\r\n}\r\n\r\nfunction sanitizeObject(value: object, state: SanitizationState, depth: number): unknown {\r\n const entries = safeEntries(value);\r\n if (entries === undefined) return '[UNREADABLE_OBJECT]';\r\n\r\n const limitedEntries = entries.slice(0, MAX_SANITIZED_COLLECTION_SIZE);\r\n const sanitized = limitedEntries.map(([key, childValue], index): [string, unknown] => [\r\n sanitizeOutputKey(key, index),\r\n isSensitiveKey(key) ? REDACTED_SECRET : sanitizeValue(childValue, state, depth + 1),\r\n ]);\r\n\r\n if (entries.length > limitedEntries.length) {\r\n sanitized.push([\r\n COLLECTION_LIMIT_KEY,\r\n `Omitted ${String(entries.length - limitedEntries.length)} fields`,\r\n ]);\r\n }\r\n\r\n return Object.fromEntries(sanitized);\r\n}\r\n\r\nfunction safeEntries(value: object): readonly [string, unknown][] | undefined {\r\n try {\r\n return Object.entries(value);\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction isDateLike(value: object): boolean {\r\n try {\r\n return Object.prototype.toString.call(value) === '[object Date]';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nfunction sanitizeDate(value: object): string {\r\n try {\r\n const milliseconds = Date.prototype.getTime.call(value);\r\n return Number.isNaN(milliseconds) ? '[INVALID_DATE]' : new Date(milliseconds).toISOString();\r\n } catch {\r\n return '[INVALID_DATE]';\r\n }\r\n}\r\n\r\nfunction truncateString(value: string, omittedInputCharacters = 0): string {\r\n const omittedOutputCharacters = Math.max(0, value.length - MAX_SANITIZED_STRING_LENGTH);\r\n const totalOmittedCharacters = omittedInputCharacters + omittedOutputCharacters;\r\n if (totalOmittedCharacters === 0) return value;\r\n return `${value.slice(0, MAX_SANITIZED_STRING_LENGTH)}[TRUNCATED_${String(totalOmittedCharacters)}_CHARS]`;\r\n}\r\n\r\nfunction sanitizeOutputKey(key: string, index: number): string {\r\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\r\n return `[UNSAFE_KEY_${String(index)}]`;\r\n }\r\n return sanitizeText(key) === key ? key : `[REDACTED_KEY_${String(index)}]`;\r\n}\r\n","import { sanitizeClientData, sanitizeStringRecord, sanitizeText } from './sanitizer.js';\r\nimport type {\r\n CapturedFrameworkContext,\r\n CapturedHttpMethod,\r\n CapturedRequestContext,\r\n} from './types.js';\r\n\r\nconst BODY_CAPTURE_TIMEOUT_MS = 50;\r\nexport const MAX_CAPTURED_BODY_BYTES = 32_768;\r\nconst REDACTED_QUERY_VALUE = '[REDACTED_QUERY_VALUE]';\r\n\r\nconst ALLOWED_HEADER_NAMES: ReadonlySet<string> = new Set([\r\n 'content-type',\r\n 'sentry-trace',\r\n 'traceparent',\r\n 'user-agent',\r\n 'x-correlation-id',\r\n 'x-request-id',\r\n 'x-vercel-id',\r\n]);\r\n\r\nconst VALID_METHODS: ReadonlySet<CapturedHttpMethod> = new Set([\r\n 'DELETE',\r\n 'GET',\r\n 'HEAD',\r\n 'OPTIONS',\r\n 'PATCH',\r\n 'POST',\r\n 'PUT',\r\n]);\r\n\r\nexport type RequestCapture = () => Promise<CapturedRequestContext>;\r\n\r\nexport interface RequestCaptureOptions {\r\n readonly captureBody?: boolean;\r\n}\r\n\r\nexport interface StructuredRequestInput {\r\n readonly body?: unknown;\r\n readonly headers?: unknown;\r\n readonly method?: string;\r\n readonly route?: string;\r\n}\r\n\r\nexport function captureStructuredRequest(\r\n input: StructuredRequestInput,\r\n options: RequestCaptureOptions = {},\r\n): CapturedRequestContext {\r\n const route = input.route ?? 'unknown';\r\n const method = normalizeMethod(input.method);\r\n const baseContext: CapturedRequestContext = {\r\n headers: captureAllowedHeaders(input.headers),\r\n ...(method === undefined ? {} : { method }),\r\n queryParams: extractQueryParams(route),\r\n route: extractRoute(route),\r\n };\r\n\r\n if (options.captureBody !== true || input.body === undefined) return baseContext;\r\n\r\n return {\r\n ...baseContext,\r\n body: toBodyRecord(sanitizeClientData(input.body)),\r\n };\r\n}\r\n\r\nexport function prepareRequestCapture(\r\n request: unknown,\r\n context: unknown,\r\n handlerArguments?: readonly unknown[],\r\n options: RequestCaptureOptions = {},\r\n): RequestCapture {\r\n if (isWebRequestLike(request)) return prepareWebRequestCapture(request, options);\r\n\r\n const requestRecord = asRecord(request);\r\n const contextRecord = asRecord(context);\r\n const route =\r\n readString(requestRecord, 'path') ?? readString(contextRecord, 'routePath') ?? 'server-action';\r\n const method = readString(requestRecord, 'method');\r\n const normalizedMethod = normalizeMethod(method);\r\n const framework = captureNextFrameworkContext(contextRecord);\r\n const baseSnapshot: CapturedRequestContext = {\r\n ...(framework === undefined ? {} : { framework }),\r\n headers: captureAllowedHeaders(readUnknown(requestRecord, 'headers')),\r\n ...(normalizedMethod === undefined ? {} : { method: normalizedMethod }),\r\n queryParams: extractQueryParams(route),\r\n route: extractRoute(route),\r\n };\r\n\r\n if (options.captureBody !== true || handlerArguments === undefined) {\r\n return () => Promise.resolve(baseSnapshot);\r\n }\r\n\r\n const body = toBodyRecord(sanitizeClientData({ arguments: handlerArguments }));\r\n const snapshot: CapturedRequestContext = { ...baseSnapshot, body };\r\n return () => Promise.resolve(snapshot);\r\n}\r\n\r\nfunction prepareWebRequestCapture(\r\n request: WebRequestLike,\r\n options: RequestCaptureOptions,\r\n): RequestCapture {\r\n const method = normalizeMethod(request.method);\r\n const baseContext: CapturedRequestContext = {\r\n headers: captureAllowedHeaders(request.headers),\r\n ...(method === undefined ? {} : { method }),\r\n queryParams: extractQueryParams(request.url),\r\n route: extractRoute(request.url),\r\n };\r\n\r\n if (options.captureBody !== true || method === 'GET' || method === 'HEAD') {\r\n return () => Promise.resolve(baseContext);\r\n }\r\n\r\n const declaredContentLength = readHeader(request.headers, 'content-length');\r\n if (\r\n declaredContentLength !== undefined &&\r\n Number(declaredContentLength) > MAX_CAPTURED_BODY_BYTES\r\n ) {\r\n return () =>\r\n Promise.resolve({\r\n ...baseContext,\r\n body: { value: '[BODY_OMITTED_SIZE_LIMIT]' },\r\n });\r\n }\r\n\r\n const clonedRequest = safeClone(request);\r\n if (clonedRequest === undefined) return () => Promise.resolve(baseContext);\r\n\r\n return async () => {\r\n const body = await readRequestBody(clonedRequest);\r\n return body === undefined ? baseContext : { ...baseContext, body };\r\n };\r\n}\r\n\r\nasync function readRequestBody(\r\n request: WebRequestLike,\r\n): Promise<Readonly<Record<string, unknown>> | undefined> {\r\n const contentLength = readHeader(request.headers, 'content-length');\r\n if (contentLength !== undefined && Number(contentLength) > MAX_CAPTURED_BODY_BYTES) {\r\n cancelReadableBody(request.body, 'KYNCODE body capture declared size limit');\r\n return { value: '[BODY_OMITTED_SIZE_LIMIT]' };\r\n }\r\n const body = request.body;\r\n if (body === null || body === undefined) return undefined;\r\n if (!hasBodyReader(body)) {\r\n cancelReadableBody(body, 'KYNCODE body capture received an unreadable clone');\r\n return undefined;\r\n }\r\n const bytes = await readBoundedBody(body);\r\n if (bytes === 'limit') return { value: '[BODY_OMITTED_SIZE_LIMIT]' };\r\n if (bytes === undefined || bytes.byteLength === 0) return undefined;\r\n const text = new TextDecoder().decode(bytes);\r\n\r\n const contentType = readHeader(request.headers, 'content-type')?.toLowerCase() ?? '';\r\n if (contentType.includes('application/json') || contentType.includes('+json')) {\r\n try {\r\n const parsed: unknown = JSON.parse(text);\r\n return toBodyRecord(sanitizeClientData(parsed));\r\n } catch {\r\n return { value: '[INVALID_JSON_BODY]' };\r\n }\r\n }\r\n\r\n if (contentType.includes('application/x-www-form-urlencoded')) {\r\n return toBodyRecord(sanitizeClientData(Object.fromEntries(new URLSearchParams(text))));\r\n }\r\n\r\n return { value: '[BODY_OMITTED_UNSUPPORTED_CONTENT_TYPE]' };\r\n}\r\n\r\nfunction captureAllowedHeaders(value: unknown): Readonly<Record<string, string>> {\r\n const headers = normalizeHeaderRecord(value);\r\n const allowed = Object.fromEntries(\r\n Object.entries(headers).filter(([key]) => ALLOWED_HEADER_NAMES.has(key.toLowerCase())),\r\n );\r\n return sanitizeStringRecord(allowed);\r\n}\r\n\r\nfunction normalizeHeaderRecord(value: unknown): Readonly<Record<string, string>> {\r\n const entries = readHeaderEntries(value);\r\n if (entries !== undefined) return Object.fromEntries(entries);\r\n\r\n const record = asRecord(value);\r\n if (record === undefined) return {};\r\n\r\n return Object.fromEntries(\r\n safeObjectEntries(record).flatMap(([key, headerValue]) => {\r\n if (typeof headerValue === 'string') return [[key.toLowerCase(), headerValue]];\r\n if (Array.isArray(headerValue) && headerValue.every((item) => typeof item === 'string')) {\r\n return [[key.toLowerCase(), headerValue.join(', ')]];\r\n }\r\n return [];\r\n }),\r\n );\r\n}\r\n\r\nfunction readHeaderEntries(value: unknown): readonly [string, string][] | undefined {\r\n const record = asRecord(value);\r\n const entriesMethod = record?.['entries'];\r\n if (typeof entriesMethod !== 'function') return undefined;\r\n\r\n try {\r\n const rawEntries: unknown = Reflect.apply(entriesMethod, value, []);\r\n if (!isIterable(rawEntries)) return undefined;\r\n const entries: [string, string][] = [];\r\n for (const entry of rawEntries) {\r\n if (Array.isArray(entry) && typeof entry[0] === 'string' && typeof entry[1] === 'string') {\r\n entries.push([entry[0].toLowerCase(), entry[1]]);\r\n }\r\n }\r\n return entries;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction extractRoute(value: string): string {\r\n if (value === 'server-action' || value === 'unknown') return value;\r\n\r\n try {\r\n return sanitizeText(new URL(value, 'https://sdk.kyncode.invalid').pathname);\r\n } catch {\r\n return sanitizeText(value.split('?')[0] ?? value);\r\n }\r\n}\r\n\r\nfunction extractQueryParams(value: string): Readonly<Record<string, string>> {\r\n try {\r\n const url = new URL(value, 'https://sdk.kyncode.invalid');\r\n return sanitizeStringRecord(\r\n Object.fromEntries(\r\n [...url.searchParams.keys()].map((key): [string, string] => [key, REDACTED_QUERY_VALUE]),\r\n ),\r\n );\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\nfunction normalizeMethod(value: string | undefined): CapturedHttpMethod | undefined {\r\n const candidate = value?.toUpperCase();\r\n return candidate !== undefined && VALID_METHODS.has(candidate as CapturedHttpMethod)\r\n ? (candidate as CapturedHttpMethod)\r\n : undefined;\r\n}\r\n\r\nfunction captureNextFrameworkContext(\r\n context: Readonly<Record<string, unknown>> | undefined,\r\n): CapturedFrameworkContext | undefined {\r\n if (context === undefined) return undefined;\r\n const routePath = readString(context, 'routePath');\r\n const routeType = readString(context, 'routeType');\r\n const routerKind = readString(context, 'routerKind');\r\n const renderSource = readString(context, 'renderSource');\r\n if (\r\n routePath === undefined &&\r\n routeType === undefined &&\r\n routerKind === undefined &&\r\n renderSource === undefined\r\n )\r\n return undefined;\r\n\r\n return {\r\n name: 'nextjs',\r\n ...(renderSource === undefined ? {} : { renderSource: sanitizeText(renderSource) }),\r\n ...(routePath === undefined ? {} : { routePath: sanitizeText(routePath) }),\r\n ...(routeType === undefined ? {} : { routeType: sanitizeText(routeType) }),\r\n ...(routerKind === undefined ? {} : { routerKind: sanitizeText(routerKind) }),\r\n };\r\n}\r\n\r\nfunction toBodyRecord(value: unknown): Readonly<Record<string, unknown>> {\r\n return isPlainRecord(value) ? value : { value };\r\n}\r\n\r\nfunction asRecord(value: unknown): Readonly<Record<string, unknown>> | undefined {\r\n return isPlainRecord(value) ? value : undefined;\r\n}\r\n\r\nfunction isPlainRecord(value: unknown): value is Readonly<Record<string, unknown>> {\r\n return typeof value === 'object' && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction readString(\r\n record: Readonly<Record<string, unknown>> | undefined,\r\n key: string,\r\n): string | undefined {\r\n const value = readUnknown(record, key);\r\n return typeof value === 'string' ? value : undefined;\r\n}\r\n\r\nfunction readUnknown(record: Readonly<Record<string, unknown>> | undefined, key: string): unknown {\r\n try {\r\n return record?.[key];\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction safeObjectEntries(\r\n record: Readonly<Record<string, unknown>>,\r\n): readonly [string, unknown][] {\r\n try {\r\n return Object.entries(record);\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\ninterface WebRequestLike {\r\n readonly body?: ReadableBodyLike | null;\r\n readonly headers?: unknown;\r\n readonly method: string;\r\n readonly url: string;\r\n readonly clone?: () => unknown;\r\n}\r\n\r\ninterface ReadableBodyLike {\r\n cancel?(reason?: unknown): Promise<void> | void;\r\n getReader(): BodyReaderLike;\r\n}\r\n\r\ninterface BodyReaderLike {\r\n cancel(reason?: unknown): Promise<void> | void;\r\n read(): Promise<{ readonly done: boolean; readonly value?: unknown }>;\r\n}\r\n\r\nfunction isWebRequestLike(value: unknown): value is WebRequestLike {\r\n const record = asRecord(value);\r\n return (\r\n typeof readUnknown(record, 'url') === 'string' &&\r\n typeof readUnknown(record, 'method') === 'string'\r\n );\r\n}\r\n\r\nfunction safeClone(request: WebRequestLike): WebRequestLike | undefined {\r\n if (typeof request.clone !== 'function') return undefined;\r\n try {\r\n const clone: unknown = request.clone.call(request);\r\n if (isWebRequestLike(clone)) return clone;\r\n cancelReadableBody(\r\n readUnknown(asRecord(clone), 'body'),\r\n 'KYNCODE body capture received an invalid clone',\r\n );\r\n return undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction readHeader(headers: unknown, name: string): string | undefined {\r\n return normalizeHeaderRecord(headers)[name];\r\n}\r\n\r\nasync function readBoundedBody(body: ReadableBodyLike): Promise<Uint8Array | 'limit' | undefined> {\r\n let reader: BodyReaderLike;\r\n try {\r\n reader = body.getReader();\r\n } catch {\r\n cancelReadableBody(body, 'KYNCODE body capture could not acquire a reader');\r\n return undefined;\r\n }\r\n const chunks: Uint8Array[] = [];\r\n let totalBytes = 0;\r\n const deadline = Date.now() + BODY_CAPTURE_TIMEOUT_MS;\r\n\r\n try {\r\n while (Date.now() < deadline) {\r\n const remainingMs = Math.max(1, deadline - Date.now());\r\n const result = await readWithin(reader, remainingMs);\r\n if (result === undefined) {\r\n cancelReader(reader, 'KYNCODE body capture timeout');\r\n return undefined;\r\n }\r\n if (result.done) return concatenateBytes(chunks, totalBytes);\r\n const chunk = toByteChunk(result.value);\r\n if (chunk === undefined) {\r\n cancelReader(reader, 'KYNCODE body capture received a non-byte chunk');\r\n return undefined;\r\n }\r\n totalBytes += chunk.byteLength;\r\n if (totalBytes > MAX_CAPTURED_BODY_BYTES) {\r\n cancelReader(reader, 'KYNCODE body capture size limit');\r\n return 'limit';\r\n }\r\n chunks.push(chunk);\r\n }\r\n cancelReader(reader, 'KYNCODE body capture timeout');\r\n return undefined;\r\n } catch {\r\n cancelReader(reader, 'KYNCODE body capture failed');\r\n return undefined;\r\n }\r\n}\r\n\r\nasync function readWithin(\r\n reader: BodyReaderLike,\r\n timeoutMs: number,\r\n): Promise<{ readonly done: boolean; readonly value?: unknown } | undefined> {\r\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\r\n const timeout = new Promise<undefined>((resolve) => {\r\n timeoutId = setTimeout(() => {\r\n resolve(undefined);\r\n }, timeoutMs);\r\n });\r\n try {\r\n return await Promise.race([reader.read(), timeout]);\r\n } finally {\r\n if (timeoutId !== undefined) clearTimeout(timeoutId);\r\n }\r\n}\r\n\r\nfunction cancelReader(reader: BodyReaderLike, reason: string): void {\r\n try {\r\n const cancellation = reader.cancel(reason);\r\n if (cancellation !== undefined) void cancellation.catch(() => undefined);\r\n } catch {\r\n // Cancellation is best-effort; the host request is a clone and remains untouched.\r\n }\r\n}\r\n\r\nfunction cancelReadableBody(body: unknown, reason: string): void {\r\n const record = asRecord(body);\r\n const cancel = readUnknown(record, 'cancel');\r\n if (typeof cancel !== 'function') return;\r\n try {\r\n const cancellation: unknown = Reflect.apply(cancel, body, [reason]);\r\n if (isPromiseLike(cancellation)) {\r\n void Promise.resolve(cancellation).catch(() => undefined);\r\n }\r\n } catch {\r\n // Cancellation is best-effort and must never affect the host request.\r\n }\r\n}\r\n\r\nfunction concatenateBytes(chunks: readonly Uint8Array[], totalBytes: number): Uint8Array {\r\n const result = new Uint8Array(totalBytes);\r\n let offset = 0;\r\n for (const chunk of chunks) {\r\n result.set(chunk, offset);\r\n offset += chunk.byteLength;\r\n }\r\n return result;\r\n}\r\n\r\nfunction toByteChunk(value: unknown): Uint8Array | undefined {\r\n if (!ArrayBuffer.isView(value)) return undefined;\r\n return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\r\n}\r\n\r\nfunction isIterable(value: unknown): value is Iterable<unknown> {\r\n if (typeof value !== 'object' || value === null) return false;\r\n try {\r\n return Symbol.iterator in value;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nfunction hasBodyReader(value: unknown): value is ReadableBodyLike {\r\n const record = asRecord(value);\r\n return typeof readUnknown(record, 'getReader') === 'function';\r\n}\r\n\r\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\r\n if (typeof value !== 'object' || value === null) return false;\r\n try {\r\n return typeof (value as Readonly<Record<string, unknown>>)['then'] === 'function';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n","import { captureStructuredRequest } from '../request-capture.js';\r\nimport type { ExpressErrorHandler } from '../types.js';\r\nimport type { AdapterCapture } from './shared.js';\r\n\r\nexport function createExpressErrorHandler(\r\n capture: AdapterCapture,\r\n shouldCaptureBody: () => boolean = () => false,\r\n): ExpressErrorHandler {\r\n return (error, request, response, next): void => {\r\n void response;\r\n\r\n try {\r\n capture(\r\n error,\r\n captureStructuredRequest(\r\n {\r\n ...(request.body === undefined ? {} : { body: request.body }),\r\n ...(request.headers === undefined ? {} : { headers: request.headers }),\r\n ...(request.method === undefined ? {} : { method: request.method }),\r\n route: request.originalUrl ?? request.url ?? 'unknown',\r\n },\r\n { captureBody: shouldCaptureBody() },\r\n ),\r\n 'express',\r\n );\r\n } catch {\r\n // The host middleware chain must continue even if SDK capture fails.\r\n }\r\n\r\n next(error);\r\n };\r\n}\r\n","import { captureStructuredRequest } from '../request-capture.js';\r\nimport type { FastifyErrorHandler } from '../types.js';\r\nimport type { AdapterCapture } from './shared.js';\r\n\r\nexport function createFastifyErrorHandler(\r\n capture: AdapterCapture,\r\n shouldCaptureBody: () => boolean = () => false,\r\n): FastifyErrorHandler {\r\n return (error, request, reply): unknown => {\r\n try {\r\n capture(\r\n error,\r\n captureStructuredRequest(\r\n {\r\n ...(request.body === undefined ? {} : { body: request.body }),\r\n ...(request.headers === undefined && request.raw?.headers === undefined\r\n ? {}\r\n : { headers: request.headers ?? request.raw?.headers }),\r\n ...(request.method === undefined ? {} : { method: request.method }),\r\n route: request.raw?.url ?? request.url ?? 'unknown',\r\n },\r\n { captureBody: shouldCaptureBody() },\r\n ),\r\n 'fastify',\r\n );\r\n } catch {\r\n // Native Fastify response handling must never depend on telemetry success.\r\n }\r\n\r\n return reply.send(error);\r\n };\r\n}\r\n","import type { ProcessEventCleanup } from '../types.js';\r\nimport type { AdapterCapture } from './shared.js';\r\n\r\nexport function registerNodeProcessListeners(capture: AdapterCapture): ProcessEventCleanup {\r\n const onUncaughtExceptionMonitor = (\r\n error: Error,\r\n origin: NodeJS.UncaughtExceptionOrigin,\r\n ): void => {\r\n captureProcessError(capture, error, origin);\r\n };\r\n\r\n // Unlike `uncaughtException`, this observer never changes Node's fatal exit semantics.\r\n // Fatal unhandled rejections are reported here with origin `unhandledRejection` as well.\r\n process.on('uncaughtExceptionMonitor', onUncaughtExceptionMonitor);\r\n\r\n return (): void => {\r\n process.off('uncaughtExceptionMonitor', onUncaughtExceptionMonitor);\r\n };\r\n}\r\n\r\nfunction captureProcessError(\r\n capture: AdapterCapture,\r\n error: unknown,\r\n eventName: NodeJS.UncaughtExceptionOrigin,\r\n): void {\r\n try {\r\n capture(\r\n error,\r\n {\r\n headers: {},\r\n queryParams: {},\r\n route: `/process/${eventName}`,\r\n },\r\n 'node',\r\n );\r\n } catch {\r\n // Process-level telemetry must never throw from a fatal event listener.\r\n }\r\n}\r\n","import { sanitizeText } from './sanitizer.js';\r\nimport type {\r\n ConnectivityRuntime,\r\n FlushDiagnostic,\r\n FlushOptions,\r\n SdkCodePayload,\r\n} from './types.js';\r\n\r\nexport const DISPATCH_TIMEOUT_MS = 2_000;\r\nexport const MAX_PAYLOAD_BYTES = 64 * 1_024;\r\nexport const MAX_PENDING_EVENTS = 100;\r\nexport const MAX_CONCURRENT_DISPATCHES = 2;\r\nexport const MAX_DISPATCHES_PER_MINUTE = 60;\r\nexport const MAX_DELIVERY_ATTEMPTS = 3;\r\nexport const STARTUP_CONNECTIVITY_TIMEOUT_MS = 500;\r\n\r\nconst DEFAULT_FLUSH_TIMEOUT_MS = 2_000;\r\nconst RATE_WINDOW_MS = 60_000;\r\nconst RETRY_BASE_DELAY_MS = 100;\r\nconst RUNTIME_REQUEST_CONTEXT_SYMBOLS = [\r\n Symbol.for('@vercel/request-context'),\r\n Symbol.for('@next/request-context'),\r\n] as const;\r\n\r\nexport interface DispatchConfig {\r\n readonly apiKey: string;\r\n readonly debug: boolean;\r\n readonly endpoint: string;\r\n}\r\n\r\nexport type DispatchStatus = 'failed' | 'queue_full' | 'rate_limited' | 'sent';\r\n\r\nexport interface DispatchOutcome {\r\n readonly httpStatus?: number;\r\n readonly message: string;\r\n readonly ok: boolean;\r\n readonly status: DispatchStatus;\r\n}\r\n\r\ninterface QueuedDispatch {\r\n readonly config: DispatchConfig;\r\n readonly idempotencyKey: string;\r\n readonly maxDeliveryAttempts: number;\r\n readonly resolve: (outcome: DispatchOutcome) => void;\r\n readonly serializedBody: string;\r\n}\r\n\r\nclass BoundedDispatcher {\r\n #active = 0;\r\n readonly #pending: QueuedDispatch[] = [];\r\n readonly #recentDispatches: number[] = [];\r\n readonly #flushWaiters = new Set<() => void>();\r\n\r\n enqueue(\r\n payload: SdkCodePayload,\r\n config: DispatchConfig,\r\n maxDeliveryAttempts = MAX_DELIVERY_ATTEMPTS,\r\n ): Promise<DispatchOutcome> {\r\n if (this.#pending.length >= MAX_PENDING_EVENTS) {\r\n debug(config, 'Event dropped because the bounded delivery queue is full');\r\n return Promise.resolve({\r\n message: 'The bounded delivery queue is full',\r\n ok: false,\r\n status: 'queue_full',\r\n });\r\n }\r\n\r\n const serializedBody = serializePayload(payload);\r\n return new Promise<DispatchOutcome>((resolve) => {\r\n this.#pending.push({\r\n config,\r\n idempotencyKey: payload.eventId,\r\n maxDeliveryAttempts,\r\n resolve,\r\n serializedBody,\r\n });\r\n this.#pump();\r\n });\r\n }\r\n\r\n async flush(options: FlushOptions = {}): Promise<FlushDiagnostic> {\r\n if (this.#isIdle()) return { completed: true, pending: 0, timedOut: false };\r\n const timeoutMs = normalizeFlushTimeout(options.timeoutMs);\r\n\r\n return new Promise<FlushDiagnostic>((resolve) => {\r\n let settled = false;\r\n const settle = (timedOut: boolean): void => {\r\n if (settled) return;\r\n settled = true;\r\n this.#flushWaiters.delete(onIdle);\r\n clearTimeout(timeoutId);\r\n const pending = this.#active + this.#pending.length;\r\n resolve({ completed: pending === 0, pending, timedOut });\r\n };\r\n const onIdle = (): void => {\r\n settle(false);\r\n };\r\n const timeoutId = setTimeout(() => {\r\n settle(true);\r\n }, timeoutMs);\r\n this.#flushWaiters.add(onIdle);\r\n if (this.#isIdle()) settle(false);\r\n });\r\n }\r\n\r\n reset(): void {\r\n const dropped: DispatchOutcome = {\r\n message: 'Delivery state was reset',\r\n ok: false,\r\n status: 'failed',\r\n };\r\n for (const queued of this.#pending.splice(0)) queued.resolve(dropped);\r\n this.#recentDispatches.splice(0);\r\n this.#notifyIfIdle();\r\n }\r\n\r\n #pump(): void {\r\n while (this.#active < MAX_CONCURRENT_DISPATCHES) {\r\n const queued = this.#pending.shift();\r\n if (queued === undefined) break;\r\n\r\n if (!this.#consumeRateSlot()) {\r\n queued.resolve({\r\n message: 'The SDK delivery rate limit was reached',\r\n ok: false,\r\n status: 'rate_limited',\r\n });\r\n debug(queued.config, 'Event dropped by the client-side delivery rate limit');\r\n continue;\r\n }\r\n\r\n this.#active += 1;\r\n void postSerializedJson(\r\n queued.config.endpoint,\r\n queued.serializedBody,\r\n queued.idempotencyKey,\r\n queued.config,\r\n queued.maxDeliveryAttempts,\r\n )\r\n .then(queued.resolve)\r\n .finally(() => {\r\n this.#active -= 1;\r\n this.#pump();\r\n this.#notifyIfIdle();\r\n });\r\n }\r\n this.#notifyIfIdle();\r\n }\r\n\r\n #consumeRateSlot(): boolean {\r\n const now = Date.now();\r\n while ((this.#recentDispatches[0] ?? now) <= now - RATE_WINDOW_MS) {\r\n this.#recentDispatches.shift();\r\n }\r\n if (this.#recentDispatches.length >= MAX_DISPATCHES_PER_MINUTE) return false;\r\n this.#recentDispatches.push(now);\r\n return true;\r\n }\r\n\r\n #isIdle(): boolean {\r\n return this.#active === 0 && this.#pending.length === 0;\r\n }\r\n\r\n #notifyIfIdle(): void {\r\n if (!this.#isIdle()) return;\r\n for (const waiter of [...this.#flushWaiters]) waiter();\r\n }\r\n}\r\n\r\nconst dispatcher = new BoundedDispatcher();\r\n\r\nexport function dispatchInBackground(payload: SdkCodePayload, config: DispatchConfig): void {\r\n const delivery = dispatcher.enqueue(payload, config);\r\n void scheduleWithRuntime(delivery, config);\r\n}\r\n\r\nexport async function dispatchWithRuntime(\r\n payload: SdkCodePayload,\r\n config: DispatchConfig,\r\n): Promise<void> {\r\n const waitUntil = resolveRuntimeWaitUntil();\r\n if (waitUntil === undefined) {\r\n debug(config, 'Runtime waitUntil unavailable; using one bounded delivery attempt');\r\n await Promise.allSettled([dispatcher.enqueue(payload, config, 1)]);\r\n return;\r\n }\r\n\r\n let settleRuntimeDelivery = (): void => undefined;\r\n const runtimeDelivery = new Promise<void>((resolve) => {\r\n settleRuntimeDelivery = resolve;\r\n });\r\n try {\r\n waitUntil(runtimeDelivery);\r\n } catch (error: unknown) {\r\n settleRuntimeDelivery();\r\n debug(config, 'Runtime waitUntil rejected delivery; using one bounded delivery attempt', error);\r\n await Promise.allSettled([dispatcher.enqueue(payload, config, 1)]);\r\n return;\r\n }\r\n\r\n void dispatcher.enqueue(payload, config).then(() => {\r\n settleRuntimeDelivery();\r\n });\r\n}\r\n\r\nexport function dispatchAndWait(\r\n payload: SdkCodePayload,\r\n config: DispatchConfig,\r\n): Promise<DispatchOutcome> {\r\n return dispatcher.enqueue(payload, config);\r\n}\r\n\r\nexport async function dispatchConnectivity(\r\n config: DispatchConfig,\r\n runtime: ConnectivityRuntime,\r\n sdkVersion: string,\r\n): Promise<DispatchOutcome> {\r\n const idempotencyKey = `connect_${createRandomIdentifier()}`;\r\n const serializedBody = serializeConnectivity(runtime, sdkVersion);\r\n return postSerializedJson(\r\n connectivityEndpoint(config.endpoint),\r\n serializedBody,\r\n idempotencyKey,\r\n config,\r\n );\r\n}\r\n\r\nexport function dispatchStartupConnectivity(\r\n config: DispatchConfig,\r\n runtime: ConnectivityRuntime,\r\n sdkVersion: string,\r\n): Promise<DispatchOutcome> {\r\n return postOnce(\r\n connectivityEndpoint(config.endpoint),\r\n serializeConnectivity(runtime, sdkVersion),\r\n `connect_${createRandomIdentifier()}`,\r\n config,\r\n STARTUP_CONNECTIVITY_TIMEOUT_MS,\r\n );\r\n}\r\n\r\nexport function flushDispatches(options?: FlushOptions): Promise<FlushDiagnostic> {\r\n return dispatcher.flush(options);\r\n}\r\n\r\nexport function resetDispatchState(): void {\r\n dispatcher.reset();\r\n}\r\n\r\nasync function scheduleWithRuntime(\r\n dispatchPromise: Promise<DispatchOutcome>,\r\n config: DispatchConfig,\r\n): Promise<void> {\r\n try {\r\n const waitUntil = resolveRuntimeWaitUntil();\r\n if (waitUntil === undefined) throw new Error('waitUntil is unavailable');\r\n waitUntil(dispatchPromise);\r\n } catch (error: unknown) {\r\n debug(config, 'Runtime waitUntil unavailable; using the bounded Node queue', error);\r\n await Promise.allSettled([dispatchPromise]);\r\n }\r\n}\r\n\r\nfunction resolveRuntimeWaitUntil(): ((promise: Promise<unknown>) => void) | undefined {\r\n for (const contextSymbol of RUNTIME_REQUEST_CONTEXT_SYMBOLS) {\r\n try {\r\n const globalRecord = globalThis as unknown as Readonly<Record<PropertyKey, unknown>>;\r\n const accessor = globalRecord[contextSymbol];\r\n if (typeof accessor !== 'object' || accessor === null) continue;\r\n\r\n const get = (accessor as Readonly<Record<string, unknown>>)['get'];\r\n if (typeof get !== 'function') continue;\r\n const context: unknown = get.call(accessor);\r\n if (typeof context !== 'object' || context === null) continue;\r\n\r\n const waitUntil = (context as Readonly<Record<string, unknown>>)['waitUntil'];\r\n if (typeof waitUntil !== 'function') continue;\r\n return (promise: Promise<unknown>): void => {\r\n void waitUntil.call(context, promise);\r\n };\r\n } catch {\r\n // A provider-owned context accessor may throw outside an active invocation.\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nasync function postSerializedJson(\r\n endpoint: string,\r\n serializedBody: string,\r\n idempotencyKey: string,\r\n config: DispatchConfig,\r\n maxDeliveryAttempts = MAX_DELIVERY_ATTEMPTS,\r\n): Promise<DispatchOutcome> {\r\n let lastOutcome: DispatchOutcome = {\r\n message: 'KYNCODE dispatch failed safely',\r\n ok: false,\r\n status: 'failed',\r\n };\r\n for (let attempt = 1; attempt <= maxDeliveryAttempts; attempt += 1) {\r\n lastOutcome = await postOnce(endpoint, serializedBody, idempotencyKey, config);\r\n if (lastOutcome.ok || !isRetryable(lastOutcome) || attempt === maxDeliveryAttempts) {\r\n return lastOutcome;\r\n }\r\n await delay(RETRY_BASE_DELAY_MS * attempt);\r\n }\r\n return lastOutcome;\r\n}\r\n\r\nasync function postOnce(\r\n endpoint: string,\r\n serializedBody: string,\r\n idempotencyKey: string,\r\n config: DispatchConfig,\r\n timeoutMs = DISPATCH_TIMEOUT_MS,\r\n): Promise<DispatchOutcome> {\r\n const controller = new AbortController();\r\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\r\n const timeout = new Promise<undefined>((resolve) => {\r\n timeoutId = setTimeout(() => {\r\n controller.abort();\r\n resolve(undefined);\r\n }, timeoutMs);\r\n });\r\n\r\n try {\r\n const response = await Promise.race([\r\n fetch(endpoint, {\r\n body: serializedBody,\r\n credentials: 'omit',\r\n headers: {\r\n Authorization: `Bearer ${config.apiKey}`,\r\n 'Content-Type': 'application/json',\r\n 'Idempotency-Key': idempotencyKey,\r\n },\r\n method: 'POST',\r\n redirect: 'error',\r\n referrerPolicy: 'no-referrer',\r\n signal: controller.signal,\r\n }),\r\n timeout,\r\n ]);\r\n\r\n if (response === undefined) {\r\n const message = `KYNCODE dispatch timed out after ${String(timeoutMs)}ms`;\r\n debug(config, message);\r\n return { message, ok: false, status: 'failed' };\r\n }\r\n cancelResponseBody(response);\r\n\r\n if (!response.ok) {\r\n debug(config, `KYNCODE ingestion returned HTTP ${String(response.status)}`);\r\n return {\r\n httpStatus: response.status,\r\n message: `KYNCODE ingestion returned HTTP ${String(response.status)}`,\r\n ok: false,\r\n status: response.status === 429 ? 'rate_limited' : 'failed',\r\n };\r\n }\r\n\r\n return {\r\n httpStatus: response.status,\r\n message: 'Event delivered to KYNCODE',\r\n ok: true,\r\n status: 'sent',\r\n };\r\n } catch (error: unknown) {\r\n const message = controller.signal.aborted\r\n ? `KYNCODE dispatch timed out after ${String(timeoutMs)}ms`\r\n : 'KYNCODE dispatch failed safely';\r\n debug(config, message, error);\r\n return { message, ok: false, status: 'failed' };\r\n } finally {\r\n if (timeoutId !== undefined) clearTimeout(timeoutId);\r\n }\r\n}\r\n\r\nfunction serializeConnectivity(runtime: ConnectivityRuntime, sdkVersion: string): string {\r\n return JSON.stringify({ runtime, sdk: '@kyncode/sdk', sdkVersion });\r\n}\r\n\r\nfunction serializePayload(payload: SdkCodePayload): string {\r\n const serialized = JSON.stringify(payload);\r\n if (byteLength(serialized) <= MAX_PAYLOAD_BYTES) return serialized;\r\n\r\n const compactPayload: SdkCodePayload = {\r\n ...payload,\r\n context: {\r\n ...(payload.context.framework === undefined ? {} : { framework: payload.context.framework }),\r\n headers: payload.context.headers,\r\n ...(payload.context.method === undefined ? {} : { method: payload.context.method }),\r\n queryParams: {},\r\n route: payload.context.route,\r\n },\r\n error: {\r\n ...(payload.error.digest === undefined ? {} : { digest: payload.error.digest }),\r\n message: payload.error.message,\r\n name: payload.error.name,\r\n stack: payload.error.stack,\r\n },\r\n metadata: {\r\n ...(payload.metadata ?? {}),\r\n payloadTruncated: 'true',\r\n truncationReason: 'payload_size_limit',\r\n },\r\n };\r\n const compact = JSON.stringify(compactPayload);\r\n if (byteLength(compact) <= MAX_PAYLOAD_BYTES) return compact;\r\n\r\n const minimalPayload: SdkCodePayload = {\r\n context: {\r\n headers: {},\r\n ...(compactPayload.context.method === undefined\r\n ? {}\r\n : { method: compactPayload.context.method }),\r\n queryParams: {},\r\n route: compactPayload.context.route.slice(0, 1_024),\r\n },\r\n environment: compactPayload.environment,\r\n error: {\r\n message: compactPayload.error.message.slice(0, 1_024),\r\n name: compactPayload.error.name.slice(0, 128),\r\n stack: compactPayload.error.stack.slice(0, 4_096),\r\n },\r\n eventId: compactPayload.eventId,\r\n ...(compactPayload.runtime === undefined ? {} : { runtime: compactPayload.runtime }),\r\n sdkVersion: compactPayload.sdkVersion,\r\n source: 'sdk_code',\r\n timestamp: compactPayload.timestamp,\r\n };\r\n const minimal = JSON.stringify(minimalPayload);\r\n if (byteLength(minimal) <= MAX_PAYLOAD_BYTES) return minimal;\r\n\r\n return JSON.stringify({\r\n ...minimalPayload,\r\n context: {\r\n headers: {},\r\n ...(minimalPayload.context.method === undefined\r\n ? {}\r\n : { method: minimalPayload.context.method }),\r\n queryParams: {},\r\n route: 'unknown',\r\n },\r\n error: {\r\n message: 'Application error exceeded the SDK payload limit',\r\n name: 'Error',\r\n stack: 'Error details omitted by the SDK payload limit',\r\n },\r\n } satisfies SdkCodePayload);\r\n}\r\n\r\nfunction connectivityEndpoint(ingestionEndpoint: string): string {\r\n const endpoint = new URL(ingestionEndpoint);\r\n endpoint.pathname = '/v1/telemetry/ping';\r\n endpoint.search = '';\r\n endpoint.hash = '';\r\n return endpoint.toString();\r\n}\r\n\r\nfunction normalizeFlushTimeout(value: number | undefined): number {\r\n return typeof value === 'number' && Number.isFinite(value) && value > 0\r\n ? Math.min(Math.floor(value), 30_000)\r\n : DEFAULT_FLUSH_TIMEOUT_MS;\r\n}\r\n\r\nfunction isRetryable(outcome: DispatchOutcome): boolean {\r\n if (outcome.ok) return false;\r\n if (outcome.httpStatus === undefined) return true;\r\n return (\r\n outcome.httpStatus === 408 ||\r\n outcome.httpStatus === 425 ||\r\n outcome.httpStatus === 429 ||\r\n outcome.httpStatus >= 500\r\n );\r\n}\r\n\r\nfunction delay(milliseconds: number): Promise<void> {\r\n return new Promise((resolve) => {\r\n setTimeout(resolve, milliseconds);\r\n });\r\n}\r\n\r\nfunction createRandomIdentifier(): string {\r\n try {\r\n if (typeof globalThis.crypto.randomUUID === 'function') return globalThis.crypto.randomUUID();\r\n } catch {\r\n // Fall through to a non-cryptographic correlation identifier.\r\n }\r\n return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;\r\n}\r\n\r\nfunction cancelResponseBody(response: Response): void {\r\n try {\r\n const cancellation = response.body?.cancel();\r\n if (cancellation !== undefined) void cancellation.catch(() => undefined);\r\n } catch {\r\n // Status is all the SDK needs; body cancellation is best-effort connection hygiene.\r\n }\r\n}\r\n\r\nfunction byteLength(value: string): number {\r\n if (typeof TextEncoder !== 'undefined') return new TextEncoder().encode(value).byteLength;\r\n return value.length;\r\n}\r\n\r\nfunction debug(config: DispatchConfig, message: string, detail?: unknown): void {\r\n if (!config.debug) return;\r\n const detailMessage = readErrorMessage(detail);\r\n console.debug(\r\n `[KYNCODE SDK] ${sanitizeText(message)}`,\r\n detailMessage === undefined ? '' : sanitizeText(detailMessage),\r\n );\r\n}\r\n\r\nfunction readErrorMessage(value: unknown): string | undefined {\r\n if (typeof value === 'string') return value;\r\n if (typeof value !== 'object' || value === null) return undefined;\r\n try {\r\n const message = (value as Readonly<Record<string, unknown>>)['message'];\r\n return typeof message === 'string' ? message : undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n","import { createExpressErrorHandler } from './adapters/express.js';\r\nimport { createFastifyErrorHandler } from './adapters/fastify.js';\r\nimport { registerNodeProcessListeners } from './adapters/node.js';\r\nimport {\r\n dispatchAndWait,\r\n dispatchConnectivity,\r\n dispatchInBackground,\r\n dispatchStartupConnectivity,\r\n dispatchWithRuntime,\r\n flushDispatches,\r\n resetDispatchState,\r\n type DispatchOutcome,\r\n} from './dispatch.js';\r\nimport { prepareRequestCapture, type RequestCapture } from './request-capture.js';\r\nimport { sanitizeText } from './sanitizer.js';\r\nimport type {\r\n CapturedError,\r\n CapturedRequestContext,\r\n ConnectivityDiagnostic,\r\n ConnectivityRuntime,\r\n ExpressErrorHandler,\r\n FastifyErrorHandler,\r\n FlushDiagnostic,\r\n FlushOptions,\r\n LolyApi,\r\n LolyConfig,\r\n LolyEnvironment,\r\n ProcessEventCleanup,\r\n RouteHandlerFn,\r\n SdkCodePayload,\r\n} from './types.js';\r\n\r\ndeclare const __KYNCODE_SDK_VERSION__: string | undefined;\r\n\r\nexport const SDK_VERSION =\r\n typeof __KYNCODE_SDK_VERSION__ === 'string' ? __KYNCODE_SDK_VERSION__ : '0.1.0';\r\n\r\nconst DEFAULT_ENDPOINT = 'https://api.kyncode.com/v1/ingest';\r\nconst LIVE_API_KEY_PATTERN = /^kyn_live_[a-f0-9]{64}$/u;\r\nconst DEDUPE_WINDOW_MS = 5_000;\r\nconst MAX_PRIMITIVE_DEDUPE_ENTRIES = 256;\r\n\r\ninterface ResolvedLolyConfig {\r\n readonly apiKey: string;\r\n readonly captureBody: boolean;\r\n readonly debug: boolean;\r\n readonly enabled: boolean;\r\n readonly endpoint: string;\r\n readonly environment: LolyEnvironment;\r\n}\r\n\r\nclass LolyClient implements LolyApi {\r\n #configOverrides: Partial<LolyConfig> = {};\r\n #processEventCleanup: ProcessEventCleanup | undefined;\r\n #recentErrors = new WeakMap<object, number>();\r\n readonly #recentPrimitiveErrors = new Map<string, number>();\r\n\r\n readonly init = (config: Partial<LolyConfig> = {}): void => {\r\n enableRuntimeSourceMaps();\r\n this.#configOverrides = { ...config };\r\n this.#recentErrors = new WeakMap<object, number>();\r\n this.#recentPrimitiveErrors.clear();\r\n if (readEnvironment('NODE_ENV') === 'test') resetDispatchState();\r\n };\r\n\r\n readonly connect = async (\r\n runtime: ConnectivityRuntime = 'Node.js',\r\n ): Promise<ConnectivityDiagnostic> => {\r\n enableRuntimeSourceMaps();\r\n const config = this.#resolveConfig();\r\n const unavailable = this.#connectConfigurationDiagnostic(config, runtime);\r\n if (unavailable !== undefined) return unavailable;\r\n\r\n const outcome = await dispatchConnectivity(\r\n { apiKey: config.apiKey, debug: config.debug, endpoint: config.endpoint },\r\n runtime,\r\n SDK_VERSION,\r\n );\r\n return connectivityDiagnosticFromOutcome(runtime, outcome);\r\n };\r\n\r\n readonly connectForStartup = async (\r\n runtime: ConnectivityRuntime,\r\n ): Promise<ConnectivityDiagnostic> => {\r\n enableRuntimeSourceMaps();\r\n const config = this.#resolveConfig();\r\n const unavailable = this.#connectConfigurationDiagnostic(config, runtime);\r\n if (unavailable !== undefined) return unavailable;\r\n\r\n const outcome = await dispatchStartupConnectivity(\r\n { apiKey: config.apiKey, debug: config.debug, endpoint: config.endpoint },\r\n runtime,\r\n SDK_VERSION,\r\n );\r\n return connectivityDiagnosticFromOutcome(runtime, outcome);\r\n };\r\n\r\n readonly expressErrorHandler = (): ExpressErrorHandler =>\r\n createExpressErrorHandler(\r\n (error, requestContext, runtime) => {\r\n this.#captureSafely(error, requestContext, runtime);\r\n },\r\n () => this.#resolveConfig().captureBody,\r\n );\r\n\r\n readonly fastifyErrorHandler = (): FastifyErrorHandler =>\r\n createFastifyErrorHandler(\r\n (error, requestContext, runtime) => {\r\n this.#captureSafely(error, requestContext, runtime);\r\n },\r\n () => this.#resolveConfig().captureBody,\r\n );\r\n\r\n readonly flush = (options?: FlushOptions): Promise<FlushDiagnostic> => flushDispatches(options);\r\n\r\n readonly listenToProcessEvents = (): ProcessEventCleanup => {\r\n if (this.#processEventCleanup !== undefined) return this.#processEventCleanup;\r\n\r\n const unregister = registerNodeProcessListeners((error, requestContext, runtime) => {\r\n this.#captureSafely(error, requestContext, runtime);\r\n });\r\n const cleanup = (): void => {\r\n unregister();\r\n if (this.#processEventCleanup === cleanup) this.#processEventCleanup = undefined;\r\n };\r\n this.#processEventCleanup = cleanup;\r\n return cleanup;\r\n };\r\n\r\n readonly shield = <TArguments extends readonly unknown[], TResult>(\r\n handler: RouteHandlerFn<TArguments, TResult>,\r\n ): ((...arguments_: TArguments) => Promise<TResult>) => {\r\n return async (...arguments_: TArguments): Promise<TResult> => {\r\n const config = this.#resolveConfig();\r\n const captureRequest = this.#prepareRequestSafely(arguments_, config.captureBody);\r\n\r\n try {\r\n return await handler(...arguments_);\r\n } catch (error: unknown) {\r\n if (this.#canSend(config) && this.#reserveError(error)) {\r\n scheduleMicrotask(() => {\r\n void captureRequest()\r\n .catch((captureError: unknown) => {\r\n this.#debug(config, 'Request capture failed safely', captureError);\r\n return createFallbackRequestContext();\r\n })\r\n .then((requestContext) => {\r\n this.#captureReserved(error, requestContext, config);\r\n });\r\n });\r\n }\r\n\r\n // Never await telemetry before preserving the host application's exact rejection.\r\n throw error;\r\n }\r\n };\r\n };\r\n\r\n readonly captureGlobalError = async (\r\n error: unknown,\r\n request?: unknown,\r\n context?: unknown,\r\n ): Promise<void> => {\r\n const config = this.#resolveConfig();\r\n if (!this.#canSend(config) || !this.#reserveError(error)) return;\r\n\r\n const requestContext = await this.#captureGlobalRequestContext(request, context, config);\r\n\r\n try {\r\n const runtime = requestContext.framework?.name === 'nextjs' ? 'nextjs' : undefined;\r\n const payload = this.#preparePayload(error, requestContext, config.environment, runtime);\r\n await dispatchAndWait(payload, toDispatchConfig(config));\r\n } catch (captureError: unknown) {\r\n this.#debug(config, 'Global error dispatch failed safely', captureError);\r\n }\r\n };\r\n\r\n readonly captureGlobalErrorForInstrumentation = async (\r\n error: unknown,\r\n request?: unknown,\r\n context?: unknown,\r\n ): Promise<void> => {\r\n const config = this.#resolveConfig();\r\n if (!this.#canSend(config) || !this.#reserveError(error)) return;\r\n\r\n const requestContext = await this.#captureGlobalRequestContext(request, context, config);\r\n try {\r\n const runtime = requestContext.framework?.name === 'nextjs' ? 'nextjs' : undefined;\r\n const payload = this.#preparePayload(error, requestContext, config.environment, runtime);\r\n await dispatchWithRuntime(payload, toDispatchConfig(config));\r\n } catch (captureError: unknown) {\r\n this.#debug(config, 'Global instrumentation dispatch failed safely', captureError);\r\n }\r\n };\r\n\r\n async #captureGlobalRequestContext(\r\n request: unknown,\r\n context: unknown,\r\n config: ResolvedLolyConfig,\r\n ): Promise<CapturedRequestContext> {\r\n try {\r\n return await prepareRequestCapture(request, context, undefined, {\r\n captureBody: config.captureBody,\r\n })();\r\n } catch (captureError: unknown) {\r\n this.#debug(config, 'Global error capture failed safely', captureError);\r\n return createFallbackRequestContext();\r\n }\r\n }\r\n\r\n #prepareRequestSafely(arguments_: readonly unknown[], captureBody: boolean): RequestCapture {\r\n try {\r\n return prepareRequestCapture(arguments_[0], arguments_[1], arguments_, { captureBody });\r\n } catch {\r\n return () => Promise.resolve(createFallbackRequestContext());\r\n }\r\n }\r\n\r\n #captureSafely(\r\n error: unknown,\r\n requestContext: CapturedRequestContext,\r\n runtime?: SdkCodePayload['runtime'],\r\n ): void {\r\n const config = this.#resolveConfig();\r\n if (!this.#canSend(config) || !this.#reserveError(error)) return;\r\n this.#captureReserved(error, requestContext, config, runtime);\r\n }\r\n\r\n #captureReserved(\r\n error: unknown,\r\n requestContext: CapturedRequestContext,\r\n config: ResolvedLolyConfig,\r\n runtime?: SdkCodePayload['runtime'],\r\n ): void {\r\n try {\r\n const payload = this.#preparePayload(error, requestContext, config.environment, runtime);\r\n dispatchInBackground(payload, toDispatchConfig(config));\r\n } catch (captureError: unknown) {\r\n this.#debug(config, 'Error normalization failed safely', captureError);\r\n }\r\n }\r\n\r\n #preparePayload(\r\n error: unknown,\r\n requestContext: CapturedRequestContext,\r\n environment: LolyEnvironment,\r\n runtime?: SdkCodePayload['runtime'],\r\n ): SdkCodePayload {\r\n const basePayload: SdkCodePayload = {\r\n context: requestContext,\r\n environment,\r\n error: normalizeError(error),\r\n eventId: createEventId(),\r\n sdkVersion: SDK_VERSION,\r\n source: 'sdk_code',\r\n timestamp: new Date().toISOString(),\r\n };\r\n return runtime === undefined ? basePayload : { ...basePayload, runtime };\r\n }\r\n\r\n #reserveError(error: unknown): boolean {\r\n const now = Date.now();\r\n if (typeof error === 'object' && error !== null) {\r\n const capturedAt = this.#recentErrors.get(error);\r\n if (capturedAt !== undefined && now - capturedAt < DEDUPE_WINDOW_MS) return false;\r\n this.#recentErrors.set(error, now);\r\n return true;\r\n }\r\n\r\n for (const [fingerprint, capturedAt] of this.#recentPrimitiveErrors) {\r\n if (now - capturedAt >= DEDUPE_WINDOW_MS) this.#recentPrimitiveErrors.delete(fingerprint);\r\n }\r\n const fingerprint = `${typeof error}:${sanitizeText(String(error))}`;\r\n const capturedAt = this.#recentPrimitiveErrors.get(fingerprint);\r\n if (capturedAt !== undefined && now - capturedAt < DEDUPE_WINDOW_MS) return false;\r\n if (this.#recentPrimitiveErrors.size >= MAX_PRIMITIVE_DEDUPE_ENTRIES) {\r\n const oldest = this.#recentPrimitiveErrors.keys().next().value;\r\n if (typeof oldest === 'string') this.#recentPrimitiveErrors.delete(oldest);\r\n }\r\n this.#recentPrimitiveErrors.set(fingerprint, now);\r\n return true;\r\n }\r\n\r\n #canSend(config: ResolvedLolyConfig): boolean {\r\n if (!config.enabled) {\r\n this.#debug(config, 'SDK capture is disabled; event was not sent');\r\n return false;\r\n }\r\n if (!LIVE_API_KEY_PATTERN.test(config.apiKey)) {\r\n this.#debug(config, 'KYNCODE_API_KEY is missing or invalid; event was not sent');\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n #connectConfigurationDiagnostic(\r\n config: ResolvedLolyConfig,\r\n runtime: ConnectivityRuntime,\r\n ): ConnectivityDiagnostic | undefined {\r\n if (!config.enabled) {\r\n return {\r\n message: 'KYNCODE SDK is disabled in this runtime',\r\n ok: false,\r\n runtime,\r\n status: 'disabled',\r\n };\r\n }\r\n if (!LIVE_API_KEY_PATTERN.test(config.apiKey)) {\r\n return {\r\n message: 'KYNCODE_API_KEY is missing or invalid',\r\n ok: false,\r\n runtime,\r\n status: 'invalid_api_key',\r\n };\r\n }\r\n return undefined;\r\n }\r\n\r\n #resolveConfig(): ResolvedLolyConfig {\r\n return resolveConfig(this.#configOverrides);\r\n }\r\n\r\n #debug(config: ResolvedLolyConfig, message: string, detail?: unknown): void {\r\n if (!config.debug) return;\r\n console.debug(\r\n `[KYNCODE SDK] ${sanitizeText(message)}`,\r\n detail === undefined ? '' : sanitizeText(readErrorMessage(detail) ?? 'Unknown diagnostic'),\r\n );\r\n }\r\n}\r\n\r\nconst lolyClient = new LolyClient();\r\nexport const Loly: LolyApi = lolyClient;\r\nexport const onRequestError = (\r\n error: unknown,\r\n request?: unknown,\r\n context?: unknown,\r\n): Promise<void> => lolyClient.captureGlobalErrorForInstrumentation(error, request, context);\r\nexport const register = async (): Promise<void> => {\r\n enableRuntimeSourceMaps();\r\n await lolyClient.connectForStartup('Next.js instrumentation');\r\n};\r\n\r\nfunction enableRuntimeSourceMaps(): void {\r\n const processValue = (globalThis as { readonly process?: unknown }).process;\r\n if (processValue === null || typeof processValue !== 'object') return;\r\n const setter = (processValue as Readonly<Record<string, unknown>>)['setSourceMapsEnabled'];\r\n if (typeof setter !== 'function') return;\r\n try {\r\n Reflect.apply(setter, processValue, [true]);\r\n } catch {\r\n // Edge-like and restricted runtimes may expose a partial process shim.\r\n }\r\n}\r\n\r\nfunction resolveConfig(config: Partial<LolyConfig>): ResolvedLolyConfig {\r\n const nodeEnvironment = readEnvironment('NODE_ENV');\r\n const environment = config.environment ?? resolveNodeEnvironment(nodeEnvironment);\r\n const enabled =\r\n config.enabled ?? readBooleanEnvironment('KYNCODE_SDK_ENABLED') ?? nodeEnvironment !== 'test';\r\n\r\n return {\r\n apiKey: config.apiKey ?? readEnvironment('KYNCODE_API_KEY') ?? '',\r\n captureBody:\r\n config.captureBody ?? readBooleanEnvironment('KYNCODE_CAPTURE_REQUEST_BODY') ?? false,\r\n debug: config.debug ?? readBooleanEnvironment('KYNCODE_DEBUG') ?? false,\r\n enabled,\r\n endpoint: DEFAULT_ENDPOINT,\r\n environment,\r\n };\r\n}\r\n\r\nfunction resolveNodeEnvironment(value: string | undefined): LolyEnvironment {\r\n return value === 'development' || value === 'staging' || value === 'production'\r\n ? value\r\n : 'production';\r\n}\r\n\r\nfunction normalizeError(error: unknown): CapturedError {\r\n const errorRecord = asRecord(error);\r\n const rawMessage =\r\n readString(errorRecord, 'message') ??\r\n (typeof error === 'string' ? error : 'Unknown application error');\r\n const message = nonEmptySanitized(rawMessage, 'Unknown application error');\r\n const name = nonEmptySanitized(readString(errorRecord, 'name') ?? 'Error', 'Error');\r\n const rawStack =\r\n readString(errorRecord, 'stack') ?? new Error(message).stack ?? `${name}: ${message}`;\r\n const stack = nonEmptySanitized(rawStack, `${name}: ${message}`);\r\n const rawDigest = readString(errorRecord, 'digest');\r\n const normalized: CapturedError = { message, name, stack };\r\n if (rawDigest === undefined) return normalized;\r\n const digest = sanitizeText(rawDigest);\r\n return digest === '' ? normalized : { ...normalized, digest };\r\n}\r\n\r\nfunction createFallbackRequestContext(): CapturedRequestContext {\r\n return { headers: {}, queryParams: {}, route: 'unknown' };\r\n}\r\n\r\nfunction asRecord(value: unknown): Readonly<Record<string, unknown>> | undefined {\r\n return typeof value === 'object' && value !== null\r\n ? (value as Readonly<Record<string, unknown>>)\r\n : undefined;\r\n}\r\n\r\nfunction readString(\r\n record: Readonly<Record<string, unknown>> | undefined,\r\n key: string,\r\n): string | undefined {\r\n try {\r\n const value = record?.[key];\r\n return typeof value === 'string' ? value : undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction nonEmptySanitized(value: string, fallback: string): string {\r\n const sanitized = sanitizeText(value).trim();\r\n return sanitized === '' ? fallback : sanitized;\r\n}\r\n\r\nfunction readEnvironment(name: string): string | undefined {\r\n try {\r\n return typeof process === 'undefined' ? undefined : process.env[name];\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction readBooleanEnvironment(name: string): boolean | undefined {\r\n const value = readEnvironment(name)?.trim().toLowerCase();\r\n if (value === 'true' || value === '1') return true;\r\n if (value === 'false' || value === '0') return false;\r\n return undefined;\r\n}\r\n\r\nfunction toDispatchConfig(config: ResolvedLolyConfig): {\r\n readonly apiKey: string;\r\n readonly debug: boolean;\r\n readonly endpoint: string;\r\n} {\r\n return { apiKey: config.apiKey, debug: config.debug, endpoint: config.endpoint };\r\n}\r\n\r\nfunction createEventId(): string {\r\n try {\r\n if (typeof globalThis.crypto.randomUUID === 'function') {\r\n return `evt_${globalThis.crypto.randomUUID().replaceAll('-', '')}`;\r\n }\r\n } catch {\r\n // Fall through to a portable correlation identifier.\r\n }\r\n return `evt_${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;\r\n}\r\n\r\nfunction scheduleMicrotask(callback: () => void): void {\r\n if (typeof queueMicrotask === 'function') {\r\n queueMicrotask(callback);\r\n return;\r\n }\r\n void Promise.resolve().then(callback);\r\n}\r\n\r\nfunction connectivityDiagnosticFromOutcome(\r\n runtime: ConnectivityRuntime,\r\n outcome: DispatchOutcome,\r\n): ConnectivityDiagnostic {\r\n if (outcome.ok) {\r\n return {\r\n ...(outcome.httpStatus === undefined ? {} : { httpStatus: outcome.httpStatus }),\r\n message: 'KYNCODE connectivity verified',\r\n ok: true,\r\n runtime,\r\n status: 'connected',\r\n };\r\n }\r\n const credentialsRejected = outcome.httpStatus === 401 || outcome.httpStatus === 403;\r\n return {\r\n ...(outcome.httpStatus === undefined ? {} : { httpStatus: outcome.httpStatus }),\r\n message: outcome.message,\r\n ok: false,\r\n runtime,\r\n status: credentialsRejected\r\n ? 'invalid_api_key'\r\n : outcome.status === 'rate_limited'\r\n ? 'rate_limited'\r\n : 'failed',\r\n };\r\n}\r\n\r\nfunction readErrorMessage(value: unknown): string | undefined {\r\n if (typeof value === 'string') return value;\r\n return readString(asRecord(value), 'message');\r\n}\r\n"],"mappings":"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","names":["capturedAt","fingerprint","readErrorMessage","asRecord","readString"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
type LolyEnvironment = 'development' | 'production' | 'staging';
|
|
2
|
+
type AdapterRuntime = 'express' | 'fastify' | 'nextjs' | 'node';
|
|
3
|
+
type ConnectivityRuntime = 'Express' | 'Fastify' | 'Next.js instrumentation' | 'Node.js';
|
|
4
|
+
type CapturedHttpMethod = 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT';
|
|
5
|
+
type ConnectivityStatus = 'connected' | 'disabled' | 'failed' | 'invalid_api_key' | 'rate_limited';
|
|
6
|
+
interface ConnectivityDiagnostic {
|
|
7
|
+
readonly httpStatus?: number;
|
|
8
|
+
readonly message: string;
|
|
9
|
+
readonly ok: boolean;
|
|
10
|
+
readonly runtime: ConnectivityRuntime;
|
|
11
|
+
readonly status: ConnectivityStatus;
|
|
12
|
+
}
|
|
13
|
+
interface LolyConfig {
|
|
14
|
+
readonly apiKey: string;
|
|
15
|
+
/** Request bodies are excluded by default. Enabling this may capture sensitive user data. */
|
|
16
|
+
readonly captureBody?: boolean;
|
|
17
|
+
readonly debug?: boolean;
|
|
18
|
+
/** Defaults to false when NODE_ENV=test, and true otherwise. */
|
|
19
|
+
readonly enabled?: boolean;
|
|
20
|
+
readonly environment?: LolyEnvironment;
|
|
21
|
+
}
|
|
22
|
+
type RouteHandlerFn<TArguments extends readonly unknown[] = readonly unknown[], TResult = unknown> = (...arguments_: TArguments) => Promise<TResult> | TResult;
|
|
23
|
+
interface CapturedError {
|
|
24
|
+
readonly digest?: string;
|
|
25
|
+
readonly message: string;
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly stack: string;
|
|
28
|
+
}
|
|
29
|
+
interface CapturedRequestContext {
|
|
30
|
+
readonly body?: Readonly<Record<string, unknown>>;
|
|
31
|
+
readonly framework?: CapturedFrameworkContext;
|
|
32
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
33
|
+
readonly method?: CapturedHttpMethod;
|
|
34
|
+
readonly queryParams: Readonly<Record<string, string>>;
|
|
35
|
+
readonly route: string;
|
|
36
|
+
}
|
|
37
|
+
interface CapturedFrameworkContext {
|
|
38
|
+
readonly name: 'nextjs';
|
|
39
|
+
readonly renderSource?: string;
|
|
40
|
+
readonly routePath?: string;
|
|
41
|
+
readonly routeType?: string;
|
|
42
|
+
readonly routerKind?: string;
|
|
43
|
+
}
|
|
44
|
+
interface SdkCodePayload {
|
|
45
|
+
readonly context: CapturedRequestContext;
|
|
46
|
+
readonly environment: LolyEnvironment;
|
|
47
|
+
readonly error: CapturedError;
|
|
48
|
+
readonly eventId: string;
|
|
49
|
+
readonly metadata?: Readonly<Record<string, string>>;
|
|
50
|
+
readonly runtime?: AdapterRuntime;
|
|
51
|
+
readonly sdkVersion: string;
|
|
52
|
+
readonly source: 'sdk_code';
|
|
53
|
+
readonly timestamp: string;
|
|
54
|
+
}
|
|
55
|
+
interface ExpressRequestLike {
|
|
56
|
+
readonly body?: unknown;
|
|
57
|
+
readonly headers?: unknown;
|
|
58
|
+
readonly method?: string;
|
|
59
|
+
readonly originalUrl?: string;
|
|
60
|
+
readonly url?: string;
|
|
61
|
+
}
|
|
62
|
+
type ExpressNextFunction = (error?: unknown) => void;
|
|
63
|
+
type ExpressErrorHandler = (error: unknown, request: ExpressRequestLike, response: unknown, next: ExpressNextFunction) => void;
|
|
64
|
+
interface FastifyRequestLike {
|
|
65
|
+
readonly body?: unknown;
|
|
66
|
+
readonly headers?: unknown;
|
|
67
|
+
readonly method?: string;
|
|
68
|
+
readonly raw?: {
|
|
69
|
+
readonly headers?: unknown;
|
|
70
|
+
readonly url?: string | undefined;
|
|
71
|
+
};
|
|
72
|
+
readonly url?: string;
|
|
73
|
+
}
|
|
74
|
+
interface FastifyReplyLike {
|
|
75
|
+
send(payload: unknown): unknown;
|
|
76
|
+
}
|
|
77
|
+
type FastifyErrorHandler = (error: unknown, request: FastifyRequestLike, reply: FastifyReplyLike) => unknown;
|
|
78
|
+
type ProcessEventCleanup = () => void;
|
|
79
|
+
interface FlushOptions {
|
|
80
|
+
readonly timeoutMs?: number;
|
|
81
|
+
}
|
|
82
|
+
interface FlushDiagnostic {
|
|
83
|
+
readonly completed: boolean;
|
|
84
|
+
readonly pending: number;
|
|
85
|
+
readonly timedOut: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface LolyApi {
|
|
88
|
+
readonly captureGlobalError: (error: unknown, request?: unknown, context?: unknown) => Promise<void>;
|
|
89
|
+
readonly connect: (runtime?: ConnectivityRuntime) => Promise<ConnectivityDiagnostic>;
|
|
90
|
+
readonly expressErrorHandler: () => ExpressErrorHandler;
|
|
91
|
+
readonly fastifyErrorHandler: () => FastifyErrorHandler;
|
|
92
|
+
readonly flush: (options?: FlushOptions) => Promise<FlushDiagnostic>;
|
|
93
|
+
readonly init: (config?: Partial<LolyConfig>) => void;
|
|
94
|
+
readonly listenToProcessEvents: () => ProcessEventCleanup;
|
|
95
|
+
readonly shield: <TArguments extends readonly unknown[], TResult>(handler: RouteHandlerFn<TArguments, TResult>) => (...arguments_: TArguments) => Promise<TResult>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
declare const SDK_VERSION: string;
|
|
99
|
+
declare const Loly: LolyApi;
|
|
100
|
+
declare const onRequestError: (error: unknown, request?: unknown, context?: unknown) => Promise<void>;
|
|
101
|
+
declare const register: () => Promise<void>;
|
|
102
|
+
|
|
103
|
+
export { type CapturedError, type CapturedFrameworkContext, type CapturedHttpMethod, type CapturedRequestContext, type ConnectivityDiagnostic, type ConnectivityRuntime, type ConnectivityStatus, type ExpressErrorHandler, type ExpressNextFunction, type ExpressRequestLike, type FastifyErrorHandler, type FastifyReplyLike, type FastifyRequestLike, type FlushDiagnostic, type FlushOptions, Loly, type LolyApi, type LolyConfig, type LolyEnvironment, type ProcessEventCleanup, type RouteHandlerFn, SDK_VERSION, type SdkCodePayload, Loly as default, onRequestError, register };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
type LolyEnvironment = 'development' | 'production' | 'staging';
|
|
2
|
+
type AdapterRuntime = 'express' | 'fastify' | 'nextjs' | 'node';
|
|
3
|
+
type ConnectivityRuntime = 'Express' | 'Fastify' | 'Next.js instrumentation' | 'Node.js';
|
|
4
|
+
type CapturedHttpMethod = 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT';
|
|
5
|
+
type ConnectivityStatus = 'connected' | 'disabled' | 'failed' | 'invalid_api_key' | 'rate_limited';
|
|
6
|
+
interface ConnectivityDiagnostic {
|
|
7
|
+
readonly httpStatus?: number;
|
|
8
|
+
readonly message: string;
|
|
9
|
+
readonly ok: boolean;
|
|
10
|
+
readonly runtime: ConnectivityRuntime;
|
|
11
|
+
readonly status: ConnectivityStatus;
|
|
12
|
+
}
|
|
13
|
+
interface LolyConfig {
|
|
14
|
+
readonly apiKey: string;
|
|
15
|
+
/** Request bodies are excluded by default. Enabling this may capture sensitive user data. */
|
|
16
|
+
readonly captureBody?: boolean;
|
|
17
|
+
readonly debug?: boolean;
|
|
18
|
+
/** Defaults to false when NODE_ENV=test, and true otherwise. */
|
|
19
|
+
readonly enabled?: boolean;
|
|
20
|
+
readonly environment?: LolyEnvironment;
|
|
21
|
+
}
|
|
22
|
+
type RouteHandlerFn<TArguments extends readonly unknown[] = readonly unknown[], TResult = unknown> = (...arguments_: TArguments) => Promise<TResult> | TResult;
|
|
23
|
+
interface CapturedError {
|
|
24
|
+
readonly digest?: string;
|
|
25
|
+
readonly message: string;
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly stack: string;
|
|
28
|
+
}
|
|
29
|
+
interface CapturedRequestContext {
|
|
30
|
+
readonly body?: Readonly<Record<string, unknown>>;
|
|
31
|
+
readonly framework?: CapturedFrameworkContext;
|
|
32
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
33
|
+
readonly method?: CapturedHttpMethod;
|
|
34
|
+
readonly queryParams: Readonly<Record<string, string>>;
|
|
35
|
+
readonly route: string;
|
|
36
|
+
}
|
|
37
|
+
interface CapturedFrameworkContext {
|
|
38
|
+
readonly name: 'nextjs';
|
|
39
|
+
readonly renderSource?: string;
|
|
40
|
+
readonly routePath?: string;
|
|
41
|
+
readonly routeType?: string;
|
|
42
|
+
readonly routerKind?: string;
|
|
43
|
+
}
|
|
44
|
+
interface SdkCodePayload {
|
|
45
|
+
readonly context: CapturedRequestContext;
|
|
46
|
+
readonly environment: LolyEnvironment;
|
|
47
|
+
readonly error: CapturedError;
|
|
48
|
+
readonly eventId: string;
|
|
49
|
+
readonly metadata?: Readonly<Record<string, string>>;
|
|
50
|
+
readonly runtime?: AdapterRuntime;
|
|
51
|
+
readonly sdkVersion: string;
|
|
52
|
+
readonly source: 'sdk_code';
|
|
53
|
+
readonly timestamp: string;
|
|
54
|
+
}
|
|
55
|
+
interface ExpressRequestLike {
|
|
56
|
+
readonly body?: unknown;
|
|
57
|
+
readonly headers?: unknown;
|
|
58
|
+
readonly method?: string;
|
|
59
|
+
readonly originalUrl?: string;
|
|
60
|
+
readonly url?: string;
|
|
61
|
+
}
|
|
62
|
+
type ExpressNextFunction = (error?: unknown) => void;
|
|
63
|
+
type ExpressErrorHandler = (error: unknown, request: ExpressRequestLike, response: unknown, next: ExpressNextFunction) => void;
|
|
64
|
+
interface FastifyRequestLike {
|
|
65
|
+
readonly body?: unknown;
|
|
66
|
+
readonly headers?: unknown;
|
|
67
|
+
readonly method?: string;
|
|
68
|
+
readonly raw?: {
|
|
69
|
+
readonly headers?: unknown;
|
|
70
|
+
readonly url?: string | undefined;
|
|
71
|
+
};
|
|
72
|
+
readonly url?: string;
|
|
73
|
+
}
|
|
74
|
+
interface FastifyReplyLike {
|
|
75
|
+
send(payload: unknown): unknown;
|
|
76
|
+
}
|
|
77
|
+
type FastifyErrorHandler = (error: unknown, request: FastifyRequestLike, reply: FastifyReplyLike) => unknown;
|
|
78
|
+
type ProcessEventCleanup = () => void;
|
|
79
|
+
interface FlushOptions {
|
|
80
|
+
readonly timeoutMs?: number;
|
|
81
|
+
}
|
|
82
|
+
interface FlushDiagnostic {
|
|
83
|
+
readonly completed: boolean;
|
|
84
|
+
readonly pending: number;
|
|
85
|
+
readonly timedOut: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface LolyApi {
|
|
88
|
+
readonly captureGlobalError: (error: unknown, request?: unknown, context?: unknown) => Promise<void>;
|
|
89
|
+
readonly connect: (runtime?: ConnectivityRuntime) => Promise<ConnectivityDiagnostic>;
|
|
90
|
+
readonly expressErrorHandler: () => ExpressErrorHandler;
|
|
91
|
+
readonly fastifyErrorHandler: () => FastifyErrorHandler;
|
|
92
|
+
readonly flush: (options?: FlushOptions) => Promise<FlushDiagnostic>;
|
|
93
|
+
readonly init: (config?: Partial<LolyConfig>) => void;
|
|
94
|
+
readonly listenToProcessEvents: () => ProcessEventCleanup;
|
|
95
|
+
readonly shield: <TArguments extends readonly unknown[], TResult>(handler: RouteHandlerFn<TArguments, TResult>) => (...arguments_: TArguments) => Promise<TResult>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
declare const SDK_VERSION: string;
|
|
99
|
+
declare const Loly: LolyApi;
|
|
100
|
+
declare const onRequestError: (error: unknown, request?: unknown, context?: unknown) => Promise<void>;
|
|
101
|
+
declare const register: () => Promise<void>;
|
|
102
|
+
|
|
103
|
+
export { type CapturedError, type CapturedFrameworkContext, type CapturedHttpMethod, type CapturedRequestContext, type ConnectivityDiagnostic, type ConnectivityRuntime, type ConnectivityStatus, type ExpressErrorHandler, type ExpressNextFunction, type ExpressRequestLike, type FastifyErrorHandler, type FastifyReplyLike, type FastifyRequestLike, type FlushDiagnostic, type FlushOptions, Loly, type LolyApi, type LolyConfig, type LolyEnvironment, type ProcessEventCleanup, type RouteHandlerFn, SDK_VERSION, type SdkCodePayload, Loly as default, onRequestError, register };
|