diff --git a/src/__tests__/x-glean.test.ts b/src/__tests__/x-glean.test.ts index 342e1c6a..ad9927ca 100644 --- a/src/__tests__/x-glean.test.ts +++ b/src/__tests__/x-glean.test.ts @@ -2,12 +2,19 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { XGlean } from "../hooks/x-glean.js"; import { BeforeRequestContext } from "../hooks/types.js"; import { SDKOptions } from "../lib/config.js"; +import { XGleanOptions } from "../hooks/x-glean-options.js"; function createMockRequest(): Request { return new Request("https://example.com/api/test"); } -function createMockContext(options: SDKOptions = {}): BeforeRequestContext { +/** + * Creates a mock BeforeRequestContext for testing. + * Uses intersection type to support both base SDKOptions and X-Glean custom options. + */ +function createMockContext( + options: SDKOptions & XGleanOptions = {}, +): BeforeRequestContext { return { baseURL: "https://example.com", operationID: "test-operation", diff --git a/src/hooks/x-glean-options.ts b/src/hooks/x-glean-options.ts new file mode 100644 index 00000000..f4a20d39 --- /dev/null +++ b/src/hooks/x-glean-options.ts @@ -0,0 +1,29 @@ +/** + * X-Glean custom options for configuring deprecation and experimental headers. + * + * These properties allow configuring X-Glean headers through the SDK constructor. + * Since SDKOptions in lib/config.ts is generated by Speakeasy and gets overwritten + * during regeneration, we define these as a separate type that can be used with + * intersection types. + */ + +/** + * Custom SDK options for X-Glean header configuration. + * Use these options when constructing the SDK client to configure + * experimental features and deprecation testing. + */ +export interface XGleanOptions { + /** + * Exclude API endpoints that will be deprecated after this date. + * Use this to test your integration against upcoming deprecations. + * Format: YYYY-MM-DD (e.g., '2026-10-15') + * + * More information: https://developers.glean.com/deprecations/overview + */ + excludeDeprecatedAfter?: string | undefined; + /** + * When true, enables experimental API features that are not yet generally available. + * Use this to preview and test new functionality. + */ + includeExperimental?: boolean | undefined; +} diff --git a/src/hooks/x-glean.ts b/src/hooks/x-glean.ts index 491ecf84..01a0fc5f 100644 --- a/src/hooks/x-glean.ts +++ b/src/hooks/x-glean.ts @@ -1,4 +1,5 @@ import { BeforeRequestContext, BeforeRequestHook } from "./types.js"; +import { XGleanOptions } from "./x-glean-options.js"; /** * Get the first non-empty value from the provided arguments. @@ -14,14 +15,18 @@ function getFirstValue( export class XGlean implements BeforeRequestHook { beforeRequest(hookCtx: BeforeRequestContext, request: Request): Request { + // Cast options to include X-Glean custom properties + // These properties may be passed by users but aren't in the generated SDKOptions type + const options = hookCtx.options as XGleanOptions; + const deprecatedValue = getFirstValue( process.env["X_GLEAN_EXCLUDE_DEPRECATED_AFTER"], - hookCtx.options.excludeDeprecatedAfter, + options.excludeDeprecatedAfter, ); const experimentalValue = getFirstValue( process.env["X_GLEAN_INCLUDE_EXPERIMENTAL"], - hookCtx.options.includeExperimental === true ? "true" : undefined, + options.includeExperimental === true ? "true" : undefined, ); if (deprecatedValue) { diff --git a/src/lib/config.ts b/src/lib/config.ts index 259cb401..20bc3868 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -40,19 +40,6 @@ export type SDKOptions = { retryConfig?: RetryConfig; timeoutMs?: number; debugLogger?: Logger; - /** - * Exclude API endpoints that will be deprecated after this date. - * Use this to test your integration against upcoming deprecations. - * Format: YYYY-MM-DD (e.g., '2026-10-15') - * - * More information: https://developers.glean.com/deprecations/overview - */ - excludeDeprecatedAfter?: string | undefined; - /** - * When true, enables experimental API features that are not yet generally available. - * Use this to preview and test new functionality. - */ - includeExperimental?: boolean | undefined; }; export function serverURLFromOptions(options: SDKOptions): URL | null {