TypeError: client[procedureType] is not a function
Has anyone encountered this error before? I'm trying to implement an adapter for Auth.js that can communicate with my backend via tRPC proxy client but I keep getting this error for some reason.
This is how i call my route:
And this is my client:
This is how i call my route:
import { client } from "../data"
export default function StorefrontApiAdapter() {
return {
async createUser(user) {
const result = await client.authorization.createUser.mutate(user)
return { ...user, id: result.id }
},
async getUser(id) {
const user = await client.authorization.getUser.query(id)
return user
},
async getUserByEmail(email) {
const user = await client.authorization.getUserByEmail.query(email)
return user
},
async getUserByAccount({ providerAccountId, provider }) {
const userByAccount = await client.authorization.getUserByAccount.query(providerAccountId)
return userByAccount
},
async linkAccount(account) {
await client.authorization.linkAccount.mutate(account)
return account
},
[...]
}
}import { client } from "../data"
export default function StorefrontApiAdapter() {
return {
async createUser(user) {
const result = await client.authorization.createUser.mutate(user)
return { ...user, id: result.id }
},
async getUser(id) {
const user = await client.authorization.getUser.query(id)
return user
},
async getUserByEmail(email) {
const user = await client.authorization.getUserByEmail.query(email)
return user
},
async getUserByAccount({ providerAccountId, provider }) {
const userByAccount = await client.authorization.getUserByAccount.query(providerAccountId)
return userByAccount
},
async linkAccount(account) {
await client.authorization.linkAccount.mutate(account)
return account
},
[...]
}
}And this is my client:
export const client = createTRPCProxyClient<AppRouter>({
links: [
httpBatchLink({
url: `${PUBLIC_STOREFRONT_API}/trpc`,
}),
],
})export const client = createTRPCProxyClient<AppRouter>({
links: [
httpBatchLink({
url: `${PUBLIC_STOREFRONT_API}/trpc`,
}),
],
})Solution
I used sveltekit so the setup was a bit different and backend was just normal medusa.js node application, the methods are just built like this on the client:
and then that is imported by a the authjs middleware to be used as a custom adapter:
the config.client is just the tRPC
function StorefrontApiAdapter(client: AuthClient): Adapter {
return {
async createUser(user) {
const userSchema = z
.object({
email: z.string(),
emailVerified: z.date().nullable(),
})
.passthrough()
const validatedUser = userSchema.safeParse(user)
if (!validatedUser.success) throw new Error("Not a valid user")
// email magic link does not give a name and image field
const result = await client.authorization.createUser.mutate({
email: validatedUser.data.email,
name: user.name ?? null,
emailVerified: validatedUser.data.emailVerified as string | null, // turns into string on the way to api
image: user.image ?? null,
})
return { ...user, id: result.id }
},
async getUser(id: string): Promise<AdapterUser | null> {
const user = await client.authorization.getUser.query(id)
return transformToAdapterUser(user)
},
//...all the methods used by authjs (did not fit into the msg)function StorefrontApiAdapter(client: AuthClient): Adapter {
return {
async createUser(user) {
const userSchema = z
.object({
email: z.string(),
emailVerified: z.date().nullable(),
})
.passthrough()
const validatedUser = userSchema.safeParse(user)
if (!validatedUser.success) throw new Error("Not a valid user")
// email magic link does not give a name and image field
const result = await client.authorization.createUser.mutate({
email: validatedUser.data.email,
name: user.name ?? null,
emailVerified: validatedUser.data.emailVerified as string | null, // turns into string on the way to api
image: user.image ?? null,
})
return { ...user, id: result.id }
},
async getUser(id: string): Promise<AdapterUser | null> {
const user = await client.authorization.getUser.query(id)
return transformToAdapterUser(user)
},
//...all the methods used by authjs (did not fit into the msg)and then that is imported by a the authjs middleware to be used as a custom adapter:
const handleAuth: Handle = SvelteKitAuth(async () => {
return {
secret: config.authSecret,
strategy: "jwt",
trustHost: true,
adapter: StorefrontApiAdapter(config.client),
// ...rest of the object hereconst handleAuth: Handle = SvelteKitAuth(async () => {
return {
secret: config.authSecret,
strategy: "jwt",
trustHost: true,
adapter: StorefrontApiAdapter(config.client),
// ...rest of the object herethe config.client is just the tRPC
createTRPCProxyClientcreateTRPCProxyClient