Type Issue When Extending Core Auth Schema Via Plugin
Introduction
When creating custom plugins for authentication, it's common to extend the core schema to accommodate additional features. However, this can lead to type errors when using the extended schema with existing components. In this article, we'll explore a type issue that arises when extending the core auth schema via a plugin and provide a solution to resolve the error.
The Issue
Let's take a closer look at the code snippet provided:
providers.tsx
<AuthUIProvider
authClient={authClient}
additionalField={{
publicKey: {
label: "Public Key",
placeholder: "Your public key",
description: "Enter your public key",
required: true,
type: "string",
},
}}
navigate={router.push}
replace={router.replace}
onSessionChange={() => router.refresh()}
LinkComponent={Link}
>
{props.children}
</AuthUIProvider>
The code snippet above attempts to add a publicKey
field to the core user schema using the additionalField
prop of the AuthUIProvider
component. However, this results in a type error:
Type error:
Property 'publicKey' is missing in type 'Prettify<{ email: string; name: string; password: string; image?: string | undefined; callbackURL?: string | undefined; fetchOptions?: any; }>' but required in type 'Prettify<InferSignUpEmailCtx<{ plugins: ({ id: "sign-in-with-ethereum"; $InferServerPlugin: { id: "sign-in-with-ethereum"; schema: { user: { fields: { publicKey: { type: "string"; unique: true; }; }; }; };
The expected type comes from property 'authClient'
Understanding the Error
The error message indicates that the publicKey
field is missing in the type of the additionalField
prop, but it's required in the type of the authClient
property. This suggests that the type of the authClient
property is not compatible with the extended schema.
The Plugin Code
Let's take a look at the plugin code:
export const siwe = (options: SIWEPluginOptions) =>
({
id: "sign-in-with-ethereum",
schema: {
user: {
fields: {
publicKey: {
type: "string",
unique: true,
},
},
},
},
}) satisfies BetterAuthPlugin;
The plugin code defines a custom plugin that adds a publicKey
field to the core user schema. However, the type of the authClient
property is not updated to reflect the extended schema.
Resolving the Error
To resolve the error, we need to update the type of the authClient
property to include the publicKey
field. We can do this by creating a new type that extends the original type with the additional field:
type ExtendedAuthClient = Prettify<{
email: string;
name: string;
password: string;
image?: string | undefined;
callbackURL?: string | undefined;
fetchOptions?: any;
publicKey: string;
}>;
const authClient: ExtendedAuthClient = {
// ...
};
We can then update the AuthUIProvider
component to use the new type:
<AuthUIProvider
authClient={authClient}
additionalField={{
publicKey: {
label: "Public Key",
placeholder: "Your public key",
description: "Enter your public key",
required: true,
type: "string",
},
}}
navigate={router.push}
replace={router.replace}
onSessionChange={() => router.refresh()}
LinkComponent={Link}
>
{props.children}
</AuthUIProvider>
By updating the type of the authClient
property, we can resolve the type error and use the extended schema with the AuthUIProvider
component.
Conclusion
Introduction
In our previous article, we explored a type issue that arises when extending the core auth schema via a plugin. We identified the error and provided a solution to resolve it by updating the type of the authClient
property to include the publicKey
field. In this article, we'll answer some frequently asked questions related to this topic.
Q: What is the cause of the type error?
A: The type error occurs because the type of the authClient
property is not updated to reflect the extended schema. When you add a new field to the core user schema, the type of the authClient
property must also be updated to include the new field.
Q: How do I update the type of the authClient
property?
A: To update the type of the authClient
property, you can create a new type that extends the original type with the additional field. For example:
type ExtendedAuthClient = Prettify<{
email: string;
name: string;
password: string;
image?: string | undefined;
callbackURL?: string | undefined;
fetchOptions?: any;
publicKey: string;
}>;
const authClient: ExtendedAuthClient = {
// ...
};
Q: What if I have multiple plugins that extend the core schema?
A: If you have multiple plugins that extend the core schema, you'll need to update the type of the authClient
property to include all the additional fields. You can do this by creating a new type that extends the original type with all the additional fields.
type ExtendedAuthClient = Prettify<{
email: string;
name: string;
password: string;
image?: string | undefined;
callbackURL?: string | undefined;
fetchOptions?: any;
publicKey: string;
anotherField: string;
yetAnotherField: string;
}>;
const authClient: ExtendedAuthClient = {
// ...
};
Q: Can I use a library or tool to generate the updated type?
A: Yes, you can use a library or tool to generate the updated type. For example, you can use the ts-morph
library to generate the updated type based on the schema definition.
import { generateType } from 'ts-morph';
const schema = {
// ...
};
const type = generateType(schema);
Q: What if I'm using a framework that doesn't support type extensions?
A: If you're using a framework that doesn't support type extensions, you may need to use a different approach to resolve the type error. For example, you can use a library or tool that generates the updated type based on the schema definition.
Q: Can I use a custom type guard to resolve the type error?
A: Yes, you can use a custom type guard to resolve the type error. A type guard is a function that takes an object as an argument and returns a boolean indicating whether the object conforms to a certain type. You can use a type guard to check whether the authClient
property conforms to the updated type.
function isExtendedAuthClient(authClient: any): authClient is ExtendedAuthClient {
// ...
}
if (isExtendedAuthClient(authClient)) {
// ...
}
Conclusion
In this article, we answered some frequently asked questions related to the type issue that arises when extending the core auth schema via a plugin. We provided solutions to resolve the type error, including updating the type of the authClient
property, using a library or tool to generate the updated type, and using a custom type guard. By following these steps, you can resolve similar type errors and use the extended schema with existing components.