feathers-sequelize icon indicating copy to clipboard operation
feathers-sequelize copied to clipboard

app.service('users').get(message.userId, params) returns createdAt and updatedAt dates as string rather than Date object on SQLite

Open cirosantilli opened this issue 4 years ago • 0 comments

Steps to reproduce

I'm not 100% sure if this is a bug or if I'm misusing something, but here goes.

This is a port of the chat app to sequelize:

git clone https://github.com/cirosantilli/feathers-chat
cd feathers-chat
git checkout 5afa75a26b4d7b29c4b0d4caa798012cf153c948

Now, uncomment the following test that is unexpectedly failing:

diff --git a/test/services/messages.test.js b/test/services/messages.test.js
index 3481590..aaddd39 100644
--- a/test/services/messages.test.js
+++ b/test/services/messages.test.js
@@ -37,6 +37,6 @@ describe('messages service', () => {
     // and the return of that has a string for date.
     //console.error(message.user.createdAt.constructor);
     //console.error(user.createdAt.constructor);
-    //assert.deepEqual(message.user, user);
+    assert.deepEqual(message.user, user);
   });
 });

and run:

npm i
npm test

or for greater isolation:

NODE_ENV=test mocha --recursive --exit --require test/utils.js test/ -- -g 'creates and processes message, adds user information'

The test fails because service.create and service.get are returning different things, one is a string and the other is a Date object:

       {
         "avatar": "https://s.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s=60"
      -  "createdAt": "2021-04-08 16:56:54.338 +00:00"
      +  "createdAt": [Date: 2021-04-08T16:56:54.338Z]
         "email": "[email protected]"
         "id": 108
         "name": "Some One"
         "password": "$2a$10$wVennwlZ1nJK9wg/1/xTGe/fD2cGWTpJ5B6YqL.0pSpXlif8g9JuK"
      -  "updatedAt": "2021-04-08 16:56:54.338 +00:00"
      +  "updatedAt": [Date: 2021-04-08T16:56:54.338Z]
       }

If I put a print on:

function populateUser(options = {}) { // eslint-disable-line no-unused-vars
  return async context => {
    const { app, method, result, params } = context;
    // Function that adds the user to a single message object
    const addUser = async message => {
      // Get the user based on their id, pass the `params` along so
      // that we get a safe version of the user data
      const user = await app.service('users').get(message.userId, params);

the user variable there has the strings and not date objects, so it feels like it could be a bug on this module.

Sequelize itself does seem to do the conversion correctly on a minimal example: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/461aa04b8b79336c5f9a0b69ee5cf0004a5b5f19/rootfs_overlay/lkmc/nodejs/sequelize.js#L116 so it feels like something inside feathers is converting it to string at some point.

The sqlite schema does have DATETIME:

sqlite3 data/test.sqlite3 '.schema users'

gives:

CREATE TABLE `users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255) NOT NULL, `email` VARCHAR(255) NOT NULL UNIQUE, `password` VARCHAR(255) NOT NULL, `avatar` VARCHAR(255) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);

I also tried to go a bit further now and hack into this repo:

  _get (id, params = {}) {
    const { query: where } = this.filterQuery(params);

    // Attach 'where' constraints, if any were used.
    const q = Object.assign({
      raw: this.raw,
      where: Object.assign({
        [this.Op.and]: { [this.id]: id }
      }, where)
    }, params.sequelize);

    const Model = this.applyScope(params);

    // findById calls findAll under the hood. We use findAll so that
    // eager loading can be used without a separate code path.
    return Model.findAll(q).then(result => {
+      console.error(q);
+      console.error(Model);
+      console.error(result);

and sequelize itself does appear to be returning strings...:

{ raw: true, where: { [Symbol(and)]: { id: 128 } } }
users
[
  {
    id: 125,
    name: 'Some One',
    email: '[email protected]',
    password: '$2a$10$nKCZEzlO7fnRwuWKdqxxUOE4F9nEhoqCGKtnQ6N1aAW1aDkVvjLFm',
    avatar: 'https://s.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s=60',
    createdAt: '2021-04-08 17:19:36.260 +00:00',
    updatedAt: '2021-04-08 17:19:36.260 +00:00'
  }
]

so not sure how that is possible.

System configuration

Tell us about the applicable parts of your setup.

Module versions (especially the part that's not working):

    "feathers-sequelize": {
      "version": "6.2.0",

sqlite 3.33

NodeJS version: 14.16.0

Operating System: Ubuntu 20.10

Browser Version:

React Native Version:

Module Loader:

cirosantilli avatar Apr 08 '21 17:04 cirosantilli