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()returnsPromise<T>(data only)"all":request()returnsPromise<GraphQLClientResponse<T>>(full response envelope withdata,errors,extensions, etc.)
This means TypeScript catches mismatches at compile time instead of at runtime.
For complete details on the new BlueprintGraphQLClient<Policy> interface, see
the
API Reference.
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
- npm
- yarn
- bun
pnpm update @krakentech/blueprint-auth@^41
npm update @krakentech/blueprint-auth@^41
yarn upgrade @krakentech/blueprint-auth@^41
bun 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.
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 renamedIf 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​
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 policy | request() return type | Action 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:
- Server-side
- Client-side
// 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>
// Before: type said T, but runtime value was GraphQLClientResponse<T>
const graphQLClient = useGraphQLClient({ errorPolicy: "all" });
const data = await graphQLClient.request(MyQuery);
// ^? was typed as T, actually GraphQLClientResponse<T> at runtime
// After: type is now correct
const graphQLClient = useGraphQLClient({ errorPolicy: "all" });
const { data, errors } = await graphQLClient.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",
});
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​
| Change | Before | After |
|---|---|---|
| GraphQL client type | AuthenticatedGraphQLClient (class) | BlueprintGraphQLClient<Policy> (interface) |
| Type export | IsomorphicGraphQLClient | BlueprintGraphQLClient |
request() type with "all" | Promise<T> (incorrect) | Promise<GraphQLClientResponse<T>> (correct) |
| Per-request error policy | Header-based (xErrorPolicyHeader) | Options-based (errorPolicy in request config) |
useGraphQLClient return shape | Returns { graphQLClient } object | Returns BlueprintGraphQLClient directly |