tRPCttRPC
Powered by
emilE
tRPC•3y ago•
15 replies
emil

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:
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:
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 here
const handleAuth: Handle = SvelteKitAuth(async () => {
    return {
      secret: config.authSecret,
      strategy: "jwt",
      trustHost: true,
      adapter: StorefrontApiAdapter(config.client),
// ...rest of the object here

the config.client is just the tRPC
createTRPCProxyClient
createTRPCProxyClient
Jump to solution
tRPCJoin
Move Fast & Break Nothing. End-to-end typesafe APIs made easy.
5,015Members
Resources
Recent Announcements

Similar Threads

Was this page helpful?

Similar Threads

TypeError: cache is not a function
danyDdany / ❓-help
2y ago
"client[procedureType] is not a function" after upgrading NextJS to version 14.1.2+ ( tRPC v10)
Answer OverflowAAnswer Overflow / ❓-help
2y ago
TypeError: queryClient.getMutationDefaults is not a function (it is undefined)
tmy03Ttmy03 / ❓-help
3y ago