Skip to main content

Migrating to v41

This guide will help you migrate @krakentech/blueprint-auth to version 41, which introduces type-safe error policy inference and replaces the class-based GraphQL client with an interface-based design.

Overview​

Version 41 of @krakentech/blueprint-auth makes the error policy a first-class generic parameter. When you pass an errorPolicy to getUserScopedGraphQLClient, getOrganizationScopedGraphQLClient, or useGraphQLClient, the returned client's request() method now has a type-safe return type that reflects the policy:

  • "none" or "ignore": request() returns Promise<T> (data only)
  • "all": request() returns Promise<GraphQLClientResponse<T>> (full response envelope with data, errors, extensions, etc.)

This means TypeScript catches mismatches at compile time instead of at runtime.

Full API Reference

For complete details on the new BlueprintGraphQLClient<Policy> interface, see the API Reference.

Help us improve this guide

If you identify a breaking change we've missed, please reach out so we can add it to this page. If you run into any issues during migration, don't hesitate to reach out to the team for support.

Migration Steps​

Step 1: Update packages​

pnpm update @krakentech/blueprint-auth@^41

Step 2: Replace AuthenticatedGraphQLClient with BlueprintGraphQLClient​

The AuthenticatedGraphQLClient class has been replaced by the BlueprintGraphQLClient<Policy> interface. Update any type annotations that reference it.

tip

This also applies if you were using GraphQLClient from graphql-request to type functions that accept either a server-side or client-side client.

// Before
import type { AuthenticatedGraphQLClient } from "@krakentech/blueprint-auth/server";
import type { GraphQLClient } from "graphql-request";

function viewerQueryOptions(
client: GraphQLClient | AuthenticatedGraphQLClient,
) {
return queryOptions({
queryFn: () => client.request(ViewerQuery),
queryKey: ["viewer"],
});
}

// After
import type { BlueprintGraphQLClient } from "@krakentech/blueprint-auth";

function viewerQueryOptions(client: BlueprintGraphQLClient) {
return queryOptions({
queryFn: () => client.request(ViewerQuery),
queryKey: ["viewer"],
});
}
IsomorphicGraphQLClient also renamed

If you were importing IsomorphicGraphQLClient, it has been renamed to BlueprintGraphQLClient as well. The fix is the same: replace the import name.

Step 3: Update useGraphQLClient usage​

useGraphQLClient no longer returns an object with a graphQLClient property. It now returns the BlueprintGraphQLClient instance directly, aligning with how the server-side functions getUserScopedGraphQLClient and getOrganizationScopedGraphQLClient already work.

- const { graphQLClient } = useGraphQLClient();
+ const graphQLClient = useGraphQLClient();

The UseGraphQLClientResult type has been removed. If you referenced it, use BlueprintGraphQLClient<Policy> directly instead.

Step 4: Fix type errors from corrected return types​

No runtime change

The runtime return value of request() with errorPolicy: "all" was already GraphQLClientResponse<T> in v40. The only change in v41 is that the TypeScript type now correctly reflects this. If your code was already handling the response envelope at runtime, the only action is to remove any type workarounds (e.g., as casts, @ts-ignore).

Functions that return a GraphQL client now infer the Policy generic from the errorPolicy parameter. The request() return type varies by policy:

Error policyrequest() return typeAction required
"none" (default)Promise<T>None
"ignore"Promise<T>None
"all"Promise<GraphQLClientResponse<T>>Fix any new type errors (see below)

If you use errorPolicy: "all", run a type check and fix any errors that surface. The most common scenarios:

Your code was already destructuring correctly (with a cast). Remove the cast:

// Before: worked at runtime, but needed a cast to satisfy TypeScript
const { data, errors } = await client.request(MyQuery) as GraphQLClientResponse<T>;

// After: the type is inferred correctly, no cast needed
const { data, errors } = await client.request(MyQuery);

Your code was treating the return as T directly. This was a runtime bug that TypeScript now catches. Destructure the response envelope:

// Before: type said T, but runtime value was GraphQLClientResponse<T>
const client = await getUserScopedGraphQLClient({ context, errorPolicy: "all" });
const data = await client.request(MyQuery);
// ^? was typed as T, actually GraphQLClientResponse<T> at runtime

// After: type is now correct
const client = await getUserScopedGraphQLClient({ context, errorPolicy: "all" });
const { data, errors } = await client.request(MyQuery);
// ^? GraphQLClientResponse<T>

New Features​

Per-request error policy override​

You can now override the error policy on individual request() calls using the object configuration form. This is useful when you need a different policy for a specific query without creating a new client:

const client = await getUserScopedGraphQLClient({ context });
// Client defaults to errorPolicy: "none"

// Override for a single request: returns GraphQLClientResponse<T>
const { data, errors } = await client.request({
document: MyQuery,
errorPolicy: "all",
});

// Other requests still use the client default: returns T
const data = await client.request(AnotherQuery);

This also works on the client side with useGraphQLClient:

const graphQLClient = useGraphQLClient();

const { data, errors } = await graphQLClient.request({
document: MyQuery,
errorPolicy: "all",
});
warning

The old header-based approach using xErrorPolicyHeader is no longer supported. The x-error-policy header is now an internal transport mechanism set automatically by the client from useGraphQLClient.

ErrorPolicy type export​

The ErrorPolicy type is now exported from the root package:

import type { ErrorPolicy } from "@krakentech/blueprint-auth";

Breaking Changes Summary​

ChangeBeforeAfter
GraphQL client typeAuthenticatedGraphQLClient (class)BlueprintGraphQLClient<Policy> (interface)
Type exportIsomorphicGraphQLClientBlueprintGraphQLClient
request() type with "all"Promise<T> (incorrect)Promise<GraphQLClientResponse<T>> (correct)
Per-request error policyHeader-based (xErrorPolicyHeader)Options-based (errorPolicy in request config)
useGraphQLClient return shapeReturns { graphQLClient } objectReturns BlueprintGraphQLClient directly