import type { AuthInfo } from '../../mcp-server/transports/auth/lib/authTypes.js';
/**
 * Processed authentication data extracted from a validated JWT or OAuth token
 * and attached to a {@link RequestContext} by {@link requestContextService.withAuthInfo}.
 *
 * Fields map directly to standard JWT claims: `clientId` ← `cid`/`client_id`,
 * `scopes` ← `scp`/`scope` (split to array), `sub` ← `sub`, `tenantId` ← `tid`.
 *
 * @example
 * ```typescript
 * const auth: AuthContext = ctx.auth!;
 * if (auth.scopes.includes('tool:my_tool:read')) {
 *   // authorized
 * }
 * ```
 */
export interface AuthContext {
    /** The client application identifier (`cid` or `client_id` JWT claim). */
    clientId: string;
    /** Granted permission scopes derived from the `scp` or `scope` JWT claim. */
    scopes: string[];
    /** Subject identifier — the user or service principal (`sub` JWT claim). Falls back to `clientId` when `sub` is absent. */
    sub: string;
    /** Tenant identifier from the `tid` JWT claim. Present only for multi-tenant tokens. */
    tenantId?: string;
    /**
     * Raw bearer token from the validated request. Forwarded so handlers can
     * relay it to upstream APIs in on-behalf-of / PAT pass-through flows.
     * Redacted by the framework logger's pino-redact paths (`*.token`,
     * `*.*.token`); avoid passing it to telemetry sinks that bypass that layer.
     */
    token?: string;
    /** Additional token payload properties not mapped to named fields. */
    [key: string]: unknown;
}
/**
 * Core context object associated with a single request or operation.
 *
 * Every handler invocation receives a `RequestContext` (wrapped in `Context`).
 * It is the authoritative source for log correlation (`requestId`, `traceId`,
 * `spanId`), multi-tenancy isolation (`tenantId`), and auth (`auth`).
 *
 * Optional fields (`traceId`, `spanId`) are injected automatically when an
 * OpenTelemetry active span exists at context-creation time.
 *
 * @example
 * ```typescript
 * // Read-only access in a handler
 * ctx.log.info('Handling request', { requestId: ctx.requestId, tenantId: ctx.tenantId });
 * ```
 */
export interface RequestContext {
    /**
     * Authentication data populated by {@link requestContextService.withAuthInfo}.
     * `undefined` when the request is unauthenticated or auth mode is `none`.
     */
    auth?: AuthContext | undefined;
    /**
     * Unique identifier for this request, used to correlate log entries across
     * service boundaries. Inherited from a parent context when provided;
     * otherwise generated by {@link generateRequestContextId}.
     */
    requestId: string;
    /**
     * OpenTelemetry span ID from the active span at context-creation time.
     * `undefined` when no active span exists.
     */
    spanId?: string | undefined;
    /**
     * Tenant identifier used for multi-tenancy data isolation.
     * Resolved in priority order: `additionalContext.tenantId` →
     * rest params → `parentContext.tenantId` → AsyncLocalStorage auth store.
     */
    tenantId?: string | undefined;
    /**
     * ISO 8601 UTC timestamp recorded at the moment this context was created.
     */
    timestamp: string;
    /**
     * OpenTelemetry trace ID from the active span at context-creation time.
     * `undefined` when no active span exists.
     */
    traceId?: string | undefined;
    /**
     * Additional arbitrary key-value pairs for operation-specific context.
     * Consumers must type-check before accessing extended properties.
     *
     * Note: optional fields above are typed `?: T | undefined` (not just `?: T`)
     * so the handler-facing `Context` — which carries strict-optional fields
     * under `exactOptionalPropertyTypes` — is structurally assignable to
     * {@link RequestContextLike} (the closed canonical-field projection used by
     * service-layer signatures). `RequestContext` itself remains the open
     * "context bag" that the logger and `createRequestContext` build by spread.
     */
    [key: string]: unknown;
}
/**
 * Closed, canonical-field projection of {@link RequestContext} for service
 * signatures. The handler-facing `Context` carries strict-optional fields with
 * `| undefined` and lacks the `[key: string]: unknown` index signature, so it
 * is not assignable to `RequestContext` itself; this projection is what both
 * `Context` and `RequestContext` are structurally assignable to.
 *
 * Service and canvas method signatures accept `RequestContextLike` instead of
 * `RequestContext` so consumers can pass the handler `ctx` directly without a
 * slice helper. Internal context construction (`createRequestContext`,
 * `enriched` log dispatch) still produces `RequestContext`, preserving the
 * open-bag spread pattern.
 */
export type RequestContextLike = {
    auth?: AuthContext | undefined;
    requestId: string;
    spanId?: string | undefined;
    tenantId?: string | undefined;
    timestamp: string;
    traceId?: string | undefined;
};
/**
 * Parameters accepted by {@link requestContextService.createRequestContext}.
 *
 * Named fields (`parentContext`, `additionalContext`, `operation`) receive
 * special handling. All other properties are spread directly onto the resulting
 * {@link RequestContext} as-is, allowing ad-hoc context extension without
 * modifying this interface.
 *
 * @example
 * ```typescript
 * const ctx = requestContextService.createRequestContext({
 *   operation: 'fetchUser',
 *   parentContext: incomingCtx,
 *   additionalContext: { userId: '123' },
 * });
 * ```
 */
export interface CreateRequestContextParams {
    /**
     * Key-value pairs merged into the context after `parentContext` properties
     * but before `requestId`/`timestamp` are pinned. Takes precedence over
     * `parentContext` for overlapping keys. `requestId` and `timestamp` keys in
     * `additionalContext` are silently stripped to prevent overwrites.
     */
    additionalContext?: Record<string, unknown>;
    /**
     * Human-readable label for the operation creating this context.
     * Written onto the context as `context.operation` when provided.
     */
    operation?: string;
    /**
     * Parent context whose properties are inherited as the base. When
     * `parentContext.requestId` is a non-empty string it is reused as-is,
     * preserving the same request ID across a call chain.
     */
    parentContext?: Record<string, unknown> | RequestContext | undefined;
    /** Any additional key-value pairs spread directly onto the resulting context. */
    [key: string]: unknown;
}
/**
 * Service for creating and enriching {@link RequestContext} instances.
 *
 * The two primary methods cover the full lifecycle:
 * - {@link requestContextService.createRequestContext} — general-purpose context
 *   creation with parent propagation and OTel integration.
 * - {@link requestContextService.withAuthInfo} — enriches a context with
 *   structured auth data from a validated token.
 *
 * @example
 * ```typescript
 * import { requestContextService } from '../../utils/internal/requestContext.js';
 *
 * // Create a root context for an incoming request
 * const ctx = requestContextService.createRequestContext({ operation: 'handleRequest' });
 *
 * // Enrich with auth after token verification
 * const authCtx = requestContextService.withAuthInfo(verifiedAuthInfo, ctx);
 * ```
 */
export declare const requestContextService: {
    /**
     * Creates a new {@link RequestContext} with a guaranteed unique `requestId`
     * and current ISO 8601 `timestamp`.
     *
     * Merge order (later entries win, except `requestId`/`timestamp` which are
     * always generated fresh or inherited):
     * 1. `parentContext` properties (base)
     * 2. Remaining spread params (everything in `params` except named fields)
     * 3. `additionalContext` properties (`requestId`/`timestamp` stripped)
     * 4. Resolved `requestId` and `timestamp` (canonical, never overwritten)
     * 5. Resolved `tenantId` (see priority order in {@link RequestContext.tenantId})
     * 6. `operation` (written as `context.operation` when provided)
     * 7. OTel `traceId`/`spanId` from the active span (when present)
     *
     * @param params - Context creation parameters. Defaults to `{}`.
     * @returns A fully constructed `RequestContext`.
     *
     * @example
     * ```typescript
     * // Minimal — generates a fresh requestId and timestamp
     * const ctx = requestContextService.createRequestContext();
     *
     * // Propagate an existing request ID across a call chain
     * const childCtx = requestContextService.createRequestContext({
     *   parentContext: incomingCtx,
     *   operation: 'processItem',
     *   additionalContext: { itemId: item.id },
     * });
     * ```
     */
    createRequestContext(params?: CreateRequestContextParams): RequestContext;
    /**
     * Creates a new {@link RequestContext} enriched with authentication information.
     * This method populates the context with auth data from a validated token,
     * including tenant ID, client ID, scopes, and subject.
     *
     * **Note:** This method builds and returns a `RequestContext` object only.
     * It does NOT propagate auth into `AsyncLocalStorage`. ALS propagation is
     * handled by the auth middleware via `authContext.run()`. If you need
     * scope enforcement via `withRequiredScopes()`, ensure the call runs
     * inside the middleware's ALS continuation.
     *
     * @param authInfo - The validated authentication information from JWT/OAuth token.
     * @param parentContext - Optional parent context to inherit properties from.
     * @returns A new `RequestContext` object with auth information populated.
     *
     * @example
     * ```typescript
     * const authInfo = await jwtStrategy.verify(token);
     * const context = requestContextService.withAuthInfo(authInfo);
     * // context now includes: { requestId, timestamp, tenantId, auth: {...}, ... }
     * ```
     */
    withAuthInfo(authInfo: AuthInfo, parentContext?: Record<string, unknown> | RequestContext): RequestContext;
};
//# sourceMappingURL=requestContext.d.ts.map