arthurfiorette / prisma-json-types-generator

⚒️ Changes JsonValues to your custom typescript type.
https://npm.im/prisma-json-types-generator
MIT License
373 stars 21 forks source link

possible collision with prisma extensions #302

Open imsherrill opened 5 months ago

imsherrill commented 5 months ago

Prerequisites

Versions

"prisma": "^4.12.0", "prisma-json-types-generator": "3.0.4"

A minimal reproducible example

none

Description

My understanding is that the generator is supposed to go into the generated .d.ts file and find the field and replace the field's Prisma.JsonValue type with what I've provided and added to global names (in this case let's say it's CustomJsonType)

and it works in some cases for example:

  export type ProposalGroupByOutputType = {
    id: string
    ...
    jfield: PrismaJson.CustomJsonType
    ...
  }

but seems like in other cases its missing the default types and I think its because its already overloaded the type (instead of proposal its given Extension.GetResults)

export type ProposalPayload<ExtArgs extends $Extensions.Args = $Extensions.DefaultArgs> = {
  name: "Proposal"
  objects: {
    company: CompanyPayload<ExtArgs>
    ...
  }
  scalars: $Extensions.GetResult<{
    id: string
    ...
    /**
     * [CustomJsonType]
     */
    jfield: Prisma.JsonValue
  }, ExtArgs["result"]["proposal"]>
  composites: {}
}

I know it works by using prisma's abstract syntax tree so instead of replacing the type it seems like its leaving the comment there that informs what should be swapped out for the Prisma.JsonValue

is this a bug/ collision with extensions or am I misunderstanding whats going on here?

Steps to Reproduce

setup a simple prisma extension and try to use json prisma-json-types-generator

Expected Behavior

No response

arthurfiorette commented 5 months ago

Can you set up a minimal reproducible example?

snikch commented 3 weeks ago

We hit the same issue. Could no longer use this extension because it's overwritten by our custom RLS extension.

arthurfiorette commented 3 weeks ago

overwritten by our custom RLS extension

Im afraid I cant help with problems created by other extensions.

snikch commented 3 weeks ago

Apologies I didn't make myself clear. I mean that by us using another extension, it appears the functionality is removed. The extension shouldn't be affecting your extension as far as I can see. The types are correct, but the returned value is a string not an object.

Here's the extension we're using. I see no reason it would be interfering with yours, but I also admit I don't know too much about Prisma extensions.

export interface SupabaseRowLevelSecurityOptions {
  name?: string
  claimsSetting?: string
  claimsFn?: undefined | (() => Record<string, any>)
  policyError?: Error
  logging?: boolean
}

const defaultSupabaseRowLevelSecurityOptions: SupabaseRowLevelSecurityOptions =
  {
    name: "useSupabaseRowLevelSecurity",
    claimsSetting: "request.jwt.claims",
    claimsFn: undefined,
    logging: false,
  }

export const useSupabaseRowLevelSecurity = (
  options: SupabaseRowLevelSecurityOptions = defaultSupabaseRowLevelSecurityOptions,
) => {
  const name = options.name || defaultSupabaseRowLevelSecurityOptions.name
  const claimsFn =
    options.claimsFn || defaultSupabaseRowLevelSecurityOptions.claimsFn
  const claimsSetting =
    options.claimsSetting ||
    defaultSupabaseRowLevelSecurityOptions.claimsSetting
  const policyError =
    options.policyError || defaultSupabaseRowLevelSecurityOptions.policyError

  return Prisma.defineExtension((client: PrismaClient) =>
    client.$extends({
      name: name || "useSupabaseRowLevelSecurity",
      query: {
        $allModels: {
          async $allOperations({ args, query }: any) {
            const claims = claimsFn ? JSON.stringify(claimsFn() || {}) : ""
            try {
              const [, result] = await client.$transaction([
                client.$executeRaw`SELECT set_config(${claimsSetting}, ${claims}, TRUE)`,
                query(args),
              ])

              return result
            } catch (e) {
              if (options.logging) logger.error(e)
              throw policyError || e
            }
          },
        },
      },
    }),
  )
}

...

return client.$extends(useSupabaseRowLevelSecurity({
    claimsFn: () => ({
      role: "xxx",
    }),
  }))