Is there a way to make PrismaClient return DateTime fields as Unix timestamps rather than JavaScript date objects?

When utilizing the PrismaClient for database interaction, DateTime fields are returned as JavaScript Date objects instead of Unix timestamp numbers. Despite being stored as Unix timestamp numbers in the database itself, I require the dates to be retrieved as Unix timestamps. How can I prevent PrismaClient from unnecessary conversion?

Here is an example of my model:

model Settings {
  id        Int        @id @default(autoincrement())
  updatedAt DateTime   @updatedAt
}

During interaction with the database:

const prisma = new PrismaClient()
const mySettings = await prisma.settings.findFirst()
console.log(mySettings.updatedAt) // An irritating javascript date object >:(

Answer №1

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.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for refreshing the 'state' of an Angular Router component

I'm facing an issue with passing data between pages using Angular routing. Everything works as expected when navigating to the "next" page for the first time. However, upon returning to the home page and selecting a different item, the Router's s ...

Having difficulty mastering the redux-form component typing

I am facing an issue while trying to export my component A by utilizing redux-form for accessing the form-state, which is primarily populated by another component. During the export process, I encountered this typing error: TS2322 Type A is not assignabl ...

The FileReader's onload event handler does not seem to be triggering as expected

In short, my issue revolves around reading a csv file from an android device using JavaScript's FileReader. Although my code was functioning properly a month ago, upon revisiting it recently I discovered that the onload function no longer seems to be ...

What is the best way to close ngx-simple-modal in angular7 when clicking outside of the modal component?

Can anyone help me with closing the modal in my angular7 app when the user clicks outside of the modal component? I have been using the ngx-simple-modal plugin, and I tried implementing the following code: this.SimpleModalService.addModal(LinkPopupCompone ...

Finding parameters in Angular 4

I am working on implementing a multilanguage feature in an Angular app and I need to establish the default language when the site loads. The two languages supported are Spanish and English, with Spanish being the default language. In order to achieve this, ...

Tips for refining search criteria with a combination of checkbox and range slider in Angular 2

In an attempt to refine the results for the array "db," I have implemented three filters: price, duration, and category. I have experimented with using the filter() method to apply these filters. You can find the code I have worked on here: https://stack ...

"Combining the power of AngularJS2 beta with Spring Boot: the ultimate

I am currently using Atom 1.4.0 with the atom-typescript package to develop AngularJS2 modules in TypeScript. On the backend, I have a spring-boot application for handling the REST APIs. After making changes to the .ts files in Atom, it seems to compile t ...

The error encountered is: "Unable to modify the 'x' property as it is readonly for the '[object Array]' object."

I've attempted various methods to modify this problem, regardless of how it's explained on different Stack Overflow threads. I am faced with an obstacle where I have an array composed of objects, and my goal is to iterate through the array and mo ...

Simple and quickest method for incorporating jQuery into Angular 2/4

Effective ways to combine jQuery and Angular? Simple steps for integrating jQuery in Angular2 TypeScript apps? Not sure if this approach is secure, but it can definitely be beneficial. Quite intriguing. ...

Using Typescript: Defining a function parameter that can be either of two interfaces

While browsing through this specific question, I noticed that it was somewhat related to my current issue, although there were notable differences. In my scenario, I have a function named parseScanResults which accepts an object as its argument. This obje ...

How can I dispatch multiple actions simultaneously within a single epic using redux-observable?

I am a newcomer to rxjs/redux observable and have two goals in mind: 1) enhance this epic to follow best practices 2) dispatch two actions from a single epic Many of the examples I've come across assume that the API library will throw an exception ...

Having trouble with Angular 2 Routing and loading components?

I am facing an issue with Angular 2 where it is searching for my component in app/app/aboutus.component, but I cannot pinpoint the source of the problem. Here is my app.component.ts code: import { Component } from '@angular/core'; import { ROUT ...

Exploring the World of Popper.js Modifiers

Within our React and Typescript application, we integrate the react-datepicker library, which utilizes popper.js. Attempting to configure PopperModifiers according to the example provided here: . Despite replicating the exact setup from the example, a typ ...

The dynamic form functionality is experiencing issues when incorporating ng-container and ng-template

I'm currently working on a dynamic form that fetches form fields from an API. I've attempted to use ng-container & ng-template to reuse the formgroup multiple times, but it's not functioning as anticipated. Interestingly, when I revert b ...

Form an object using elements of a string array

Trying to convert a string array into an object. The string array is as follows : let BaseArray = ['origin/develop', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world']; I want the resulting obje ...

Issue encountered when attempting to access disk JSON data: 404 error code detected

I am attempting to retrieve JSON data from the disk using a service: import { Product } from './../models/Product'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { HttpClient } from &apo ...

TypeScript: Defining an Array Type within a Namespace or Module

Within a specific namespace, I have the following code: const operation1 = Symbol("operation1"); const operation2 = Symbol("operation2"); export interface Array<T> extends IConjable<T>, ISeqable<T> {} Array.prototype[op ...

`Browser Extension Compatibility``

I am currently working on developing a TypeScript extension that is compatible with all major browsers. I have come across the package https://www.npmjs.com/package/web-ext-types which I have integrated into my package.json file. While coding in TypeScrip ...

Tips for arranging dates in descending order from the most recent to the least recent

I am trying to create a code snippet that will list all .zip files from a downloads folder in a tkinter listbox. However, I want the files to be ordered from most recent to least recent. Can someone help me with this? for line in downloads: u ...

The element is inferred to have an 'any' type due to the inability to use a 'string' type expression to index the 'Palette' type

Encountering an issue: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Palette'. No index signature with a parameter of type 'string' was found on type &ap ...