Skip to content

[BUG] @tsed/prisma: Bytes typed as Buffer against Prisma 7's Uint8Array, and generated code relies on decorator metadata #3465

Description

@Tomdrouv1

Describe the bug

Two problems in the code @tsed/prisma generates, seen with Prisma 7 (prisma-client generator) and an API bundled with esbuild:

1. Bytes fields are typed Buffer, which is not assignable to the type the Prisma client declares.

The Prisma 7 client types a Bytes field as Uint8Array<ArrayBuffer>. The generated model declares it as Buffer, so type-checking the generated models fails:

models/UserMfaPasskeyModel.ts:25:3 - error TS2416: Property 'publicKey' in type 'UserMfaPasskeyModel' is not assignable to the same property in base type '{ uuid: string; userId: string; createdAt: Date; updatedAt: Date; nickname: string; lastUsedAt: Date | null; credentialId: string; publicKey: Uint8Array<ArrayBuffer>; signCount: number; transports: string[]; aaguid: string | null; }'.
  Type 'Buffer<ArrayBufferLike>' is not assignable to type 'Uint8Array<ArrayBuffer>'.
    Types of property 'buffer' are incompatible.
      Type 'ArrayBufferLike' is not assignable to type 'ArrayBuffer'.
        Type 'SharedArrayBuffer' is not assignable to type 'ArrayBuffer'.

The mapping is hardcoded in lib/esm/generator/domain/ScalarTsTypes.js ([PrismaScalars.Bytes]: "Buffer"), and documentation attributes (/// @TsED.…) can add decorators but cannot change the property type, so there is no way around it from the schema.

2. The generated .ts code depends on decorator metadata for DI tokens and collection types.

  • PrismaService and every repository use @Inject() without a token (generatePrismaService.js, generateRepositories.js).
  • List fields use @CollectionOf(() => Model) without a collection type (transformFieldToDecorators.js).

Both fall back to design:type. A toolchain that does not emit decorator metadata (esbuild, which bundles our API) produces a server that fails at boot with:

Given token is undefined. Could mean a circular dependency problem. Try to use @Inject(() => Token) to solve it.

and, once the injections are given explicit tokens, list fields are mapped as plain objects instead of arrays.

Setting emitTranspiledCode = "true" on the generator works around both points: the output is compiled by ts-morph with emitDecoratorMetadata: true, and the Buffer type ends up in a .d.ts that skipLibCheck skips. Point 1 is still wrong there, only hidden.

To Reproduce

  1. Declare a model with a Bytes field and a one-to-many relation, with the prisma-client generator and the Ts.ED generator writing TypeScript (no emitTranspiledCode).
  2. Run prisma generate.
  3. Type-check the generated models: error from point 1.
  4. Bundle an app that injects a generated repository with esbuild and bootstrap it: error from point 2.

Expected behavior

  1. Bytes generated as Uint8Array<ArrayBuffer>, matching the Prisma client.
  2. The generated code names its tokens and collection types explicitly, so it works without decorator metadata:
    • @Inject(PrismaService) in repositories and @Inject(Logger) in PrismaService;
    • @CollectionOf(() => Model, "Array") on list fields.

Code snippets

// schema.prisma
generator client {
  provider = "prisma-client"
  output   = "./generated/prisma"
}

generator tsed {
  provider = "tsed-prisma"
  output   = "./generated/tsed"
}

// Generated today (generated/tsed/models/UserMfaPasskeyModel.ts)
@Property(Buffer)
@Required()
publicKey: Buffer;

// Generated today (generated/tsed/repositories/AccountsRepository.ts)
@Inject()
protected prisma: PrismaService;

// Generated today (generated/tsed/models/AccountModel.ts)
@CollectionOf(() => LinkedChannelModel)
@Required()
linkedChannels: LinkedChannelModel[];

OS

Linux

Node version

Node v24.21.0

Library version

@tsed/prisma 8.40.1 (all @tsed/* framework packages 8.40.1), prisma / @prisma/client 7.10.0, TypeScript 6.0.3

Additional context

We currently run with emitTranspiledCode = "true". The changes above would make the default TypeScript output work with bundlers that do not emit decorator metadata, and make it type-check against the Prisma 7 client.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions