If you are using versions prior to 4.7.0
, you can utilize middlewares. On the other hand, starting from version 4.7.0
, you have the option to make use of extensions. Here's what is mentioned about Prisma Client extensions:
Prisma Client extensions became Generally Available in versions 4.16.0 and above. They were initially introduced in Preview mode with version 4.7.0. If your current version is earlier than 4.16.0, ensure that you enable the clientExtensions Preview feature flag.
Using Middleware
It's important to note that even with this approach, the type of the result will still remain as Date
.
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// Incorrect typings
prisma.$use(async (params, next) => {
const result = await next(params);
if (typeof result === "object" && result !== null) {
for (let [key, value] of Object.entries(result)) {
if (value instanceof Date) {
result[key as keyof typeof result] = Math.floor(
Date.parse(value.toString()) / 1000
);
}
}
return result;
} else {
return result;
}
});
async function main() {
const res = await prisma.settings.findUnique({ where: { id: 1 } });
console.dir(res, { depth: Infinity }); // { id: 1, updatedAt: 1691465195 }
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
Using Extension
With extensions, there are two options available. You can either modify through query or by result. The former can be applied to specific types of queries or models, while the latter only works for a particular model type but ensures correct typing.
Implementing an extension via query modification -
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// Export this instance for usage purposes
const exPrisma = prisma.$extends({
// Modify behavior for all queries and models
// Incorrect typings
query: {
$allModels: {
$allOperations({ args, model, operation, query }) {
const result = query(args).then((res) => {
if (typeof res === "object" && res !== null) {
let modifiedRes = { ...res };
for (let [key, value] of Object.entries(modifiedRes)) {
if (value instanceof Date) {
(modifiedRes[key as keyof typeof modifiedRes] as any) =
Math.floor(Date.parse(value.toString()) / 1000);
}
}
return modifiedRes;
} else {
return res;
}
});
return result;
},
},
}
});
async function main() {
const res = await exPrisma.settings.findUnique({ where: { id: 1 } });
console.dir(res, { depth: Infinity });
}
main()
.then(async () => {
await exPrisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await exPrisma.$disconnect();
process.exit(1);
});
Applying an extension via result modification -
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// Export this instance for usage
const exPrisma = prisma.$extends({
// Specific models with correct typings
result: {
settings: {
withUnixDate: {
compute(data) {
return {
...data,
updatedAt: Math.floor(Date.parse(data.updatedAt.toString()) / 1000),
};
},
},
},
},
});
async function main() {
const res = await exPrisma.settings.findUnique({ where: { id: 1 } });
console.dir(res?.withUnixDate, { depth: Infinity });
}
main()
.then(async () => {
await exPrisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await exPrisma.$disconnect();
process.exit(1);
});
Choose the method that best suits your needs.