/** * Handler for `GET /api/v2/configs/eval-with-context/{base64url(ctx)}`. * * Mirrors api-delivery/internal/serve/eval_context.go so SDK clients see the * same EvalEnvelope shape they get in production. The fields are: * * { evaluations: { [key]: { * value: { type, value, confidential?, decryptWith? }, * configId, configType, valueType, reason, * ruleIndex?, weightedValueIndex? * } }, * meta: { version, environment } * } * * `reason` follows the cross-SDK spec * `project/plans/openfeature-resolution-details.md`: * - "SPLIT" for weighted-value flags * - "TARGETING_MATCH" for configs whose matched rule has a non-ALWAYS_TRUE criterion * - "STATIC" otherwise * * `ruleIndex` and `weightedValueIndex` are emitted only when the reason class * carries useful information (TARGETING_MATCH or SPLIT). This matches the Go * handler's "omit, don't null" rule. */ import type { IncomingMessage, ServerResponse } from 'node:http'; import type { Evaluator, ConfigStore } from '@quonfig/node'; export interface EvalEnvelope { evaluations: Record; meta: { version: string; environment: string; }; } export interface EvalResult { configId: string; configType: string; reason: string; ruleIndex?: number; value: { type: string; value: unknown; confidential?: boolean; decryptWith?: string; }; valueType: string; weightedValueIndex?: number; } export interface EvalHandlerDeps { /** * Snapshot accessor — returns the *current* store + evaluator + meta. We * read this on every request so that auto-reload swaps under us * transparently. * * Note (qfg-38sf.1 audit, F3): the sendToClientSdk filter is unconditional * and lives inside this handler. There is no `frontendFilter` toggle — * every qfg serve consumer is a frontend client by definition, so the * filter always applies. */ getSnapshot(): { store: ConfigStore; evaluator: Evaluator; environment: string; version: string; }; } export declare function handleEvalContext(req: IncomingMessage, res: ServerResponse, ctxToken: string, deps: EvalHandlerDeps): Promise;