Closed gagermaniac closed 1 year ago
This is correct. Because $extends()
returns a new Prisma Client instance with the extension applied, rather than modifying the original one.
const prisma = new PrismaClient()
// Declare an extended client that has pagination applied
const prismaA = prisma.$extends(pagination)
// prisma remains unchanged
// prismaA has pagination applied
You need to use a modified instance with the extension applied. Unfortunately, I don't have enough experience with NestJS to know how to do this.
Ah, i see ended up using it like this
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
pg() {
return this.$extends({
model: {
$allModels: {
paginate,
},
},
});
}
}
and usage
findAll(id: string) {
return this.prismaService.pg().instances.paginate().withPages({
limit: 10,
});
}
Many Thanks, for this awesome lib
Ah, i see ended up using it like this
@Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { async onModuleInit() { await this.$connect(); } pg() { return this.$extends({ model: { $allModels: { paginate, }, }, }); } }
and usage
findAll(id: string) { return this.prismaService.pg().instances.paginate().withPages({ limit: 10, }); }
Many Thanks, for this awesome lib
@gagermaniac Wouldn't that extend the prisma client every time you call the PrismaService.pg()
function? I got a workaround for when you want to install extension on certain models, I didn't like it much either though. It consists of extending the prisma client just once per model in the constructor of the model service class.
@Injectable()
export class EntityService {
private redonly prismaExtended
constructor(private readonly prisma: PrismaService) {
this.prismaExtended = this.prisma.$extends({
model: {
product: {
paginate,
},
},
})
}
findAllPaginated() {
return this.prismaExtended.entity
.paginate()
.withPages({
limit: 10,
})
}
}
Probably this can be done too to install the extension to all models in the PrismaService installing the extension only once.
Ok. I think I got it. This installs the extension to all models.
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
public readonly pg
constructor() {
super()
this.pg = this.$extends(pagination)
}
async onModuleInit() {
await this.$connect()
}
}
Usage:
findAll(id: string) {
return this.prismaService.pg.instances.paginate().withPages({
limit: 10,
});
}
@jdavidferreira did you get the typing to working. When I do this.prismaService.pg.instances
I don't get any type interference
@jdavidferreira did you get the typing to working. When I do
this.prismaService.pg.instances
I don't get any type interference
It's necessary to type the variable pg
in the PrismaService class, but I don't know what the type is
@hisabimbola, @btd1337 Sorry, let me fix and improve the example:
import pagination from 'prisma-extension-pagination'
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
public readonly prismaExtended
constructor() {
super()
// This will install the extension to all models. You can also install the extension on some models only, see: https://github.com/deptyped/prisma-extension-pagination#install-extension-on-some-models
this.prismaExtended = this.$extends(pagination())
}
async onModuleInit() {
await this.$connect()
}
}
Usage:
@Injectable()
export class ProductsService {
constructor(private readonly prisma: PrismaService) {}
findAll() {
return this.prisma.prismaExtended.product.paginate().withPages({
limit: 10,
})
}
}
@jdavidferreira the issue is not this. The real problem is that if you write your code without typing the prismaExtended
variable, all type recognition is lost. No changes made in the Prisma schema will be detected or flagged. You won't know if there were breakchanges when you alter your schema. Do you understand?
Therefore, it is necessary to type the prismaExtended
variable correctly.
Reference: https://github.com/deptyped/prisma-extension-pagination/issues/19
@hisabimbola Did you try my new implementation?
My previous example was wrong and the prismaExtended
type (previously pg
) was not being infered. I fixed the implementation. TypeScript is able to infer the type based on the assignment inside the constructor without typing it at declaration.
Evidence:
@hisabimbola Did you try my new implementation?
My previous example was wrong and the
prismaExtended
type (previouslypg
) was not being infered. I fixed the implementation. TypeScript is able to infer the type based on the assignment inside the constructor without typing it at declaration.
@jdavidferreira what TypeScript version is your project using? And could you please share your tsconfig?
This behavior is not occurring in my VSCode IDE.
That could be the issue. I'm using the TypeScript version 5.2.2
.
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2020",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}
@jdavidferreira I found the problem:
The property "noImplicitAny": false
in tsconfig
file.
I removed this property, and autocomplete now works correctly, but the code break with errors:
I removed this property, and autocomplete now works correctly, but the code break with errors:
@btd1337 You have to type all those fields. 😬 It will be tedious but you will have more type safety throughout your project.
Hi @jdavidferreira ! Im following this setup :
@hisabimbola, @btd1337 Sorry, let me fix and improve the example:
import pagination from 'prisma-extension-pagination' @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { public readonly prismaExtended constructor() { super() // This will install the extension to all models. You can also install the extension on some models only, see: https://github.com/deptyped/prisma-extension-pagination#install-extension-on-some-models this.prismaExtended = this.$extends(pagination()) } async onModuleInit() { await this.$connect() } }
Usage:
@Injectable() export class ProductsService { constructor(private readonly prisma: PrismaService) {} findAll() { return this.prisma.prismaExtended.product.paginate().withPages({ limit: 10, }) } }
But the prismaExtended type is not being infered. This is my tsconfig.json (i remove the "noImplicitAny": false value)
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "ES2021",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false,
"esModuleInterop": true
}
}
Demo:
Is there another configuration to check?
Sorry for making an issue here, is there any way to use this extension on nestjs?
I've been using it like this
but it doesn't seems work as it say
Property 'paginate' does not exist on type 'GetModel<InstancesDelegate<RejectOnNotFound | RejectPerOperation, DefaultArgs>, unknown>'