GithubHelp home page GithubHelp logo

forestadmin / forest-express-sequelize Goto Github PK

View Code? Open in Web Editor NEW
190.0 14.0 47.0 5.77 MB

🌱 Express/Sequelize agent for Forest Admin to integrate directly to your existing Express/Sequelize backend application.

Home Page: https://www.forestadmin.com

License: GNU General Public License v3.0

JavaScript 99.96% Shell 0.04%
admin expressjs sequelize package backend backend-api admin-panel internal-tool

forest-express-sequelize's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

forest-express-sequelize's Issues

Validation error on JSONB fields with defaultValue

Expected behavior

When using a JSONB field it should not trigger a "can't be blank" error on validation.

Actual behavior

Error when submitting the edition form.

Failure Logs

https://ibb.co/fySeiy

Context

deck: {
    type: Sequelize.JSONB,
    defaultValue: [],
    allowNull: false,
},
  • Package Version: 2.8.6
  • Express Version: 4.16.3
  • Sequelize Version: 4.37.7
  • Database Dialect: PostgreSQL
  • Database Version: 9.6.6

Keep a changelog file

Hi guys, I'd like to suggest to mantain a changelog file. Today I wanted to update the library, but I don't really know what exactly has changed.

[*] Support - Does not appear to work with sequelize 5

Expected behavior

It should upload field information for models when using sequelize 5

Actual behavior

It doesn't

Failure Logs

None that I can tell

Context

I spent over 2 hours trying to figure out why my fields were showing up with a lumber generated app but not in my own express app. Please consider adding a peerDependency to this package for sequelize in order to recommend versions that are known to work.

  • Package Version: 2.17.2
  • Express Version: 4.16.4
  • Sequelize Version: 5.1.0
  • Database Dialect: pg
  • Database Version:

Using smart fields to convert postgresql POINT GEOMETRY to string

Hi,

Trying to use http://doc.forestadmin.com/developers-guide/#smart-field to allow myself to edit postgresql geometry fields in forest admin, specifically the points type as shown here, however I can't seem to get it to work.

Steps:
I attempted the following code:

Liana.collection('Job', {
  fields: [{
    field: 'location',
    type: 'String',
    value: function(object) {
      console.log('object Liana', object)
      return object.latitude + ', ' + object.longitude
    }
  }]
})

At this point, I am getting the following error:

[forest] 🌳🌳🌳  Cannot customize your collection named "Job" properly. Did you call the "collection" method in the /forest directory?

My table is called Job but in forest it's showing as Jobs. I attempted both Job and Jobs with no luck and the same error above.

Couldn't get this to work, any help is appreciated :)

Poor customization possibilities on entry pages (Summary/Details...)

Expected behavior

TODO:

It would be perfect to have an equivalent of Smart Views, but for entry pages (like Summary/Details), and it seems it's not possible after some experimentation.
Indeed right now I find Summary/Details very limited, as it's very hard to really customize it.
The idea would be, when I click on an entry line in Table view, to be able to get crazy on Summary page, based on entry data.

For example, having a link with a text, based on entry data (<a href="http://some-link-computed-from-data.com">Some text from data</a>) does not seem possible. I have to create to separate custom fields, set one into link, and display them both.

Or, create a completely custom form (for example, with inputs with default values computed from data, right now I am limited with custom actions fields, because their default value does not seem to be able to derive from data)

So something like multiple custom "Smart Widgets", (similar as Smart Views) that could be placed in Summary/Details pages, with entry data accessible in them, would be very nice.

##Β Actual behavior

"Smart Widgets" do not exist for entry details pages. There is only Smart Views to customize entries lists.

[regression] missing timezone query parameter now breaks all "list" routes

Expected behavior

When querying the following kind of route:
http://domain.com/forest/Model?filterType=and&filter[status]=active
I used to be able to get all matching records.

##Β Actual behavior

Now my server returns a 500 with the following error:

Cannot read property 'format' of undefined
    at new OperatorDateIntervalParser (/home/louisremi/Workspace/cheznestor_backoffice/node_modules/forest-express-sequelize/services/operator-date-interval-parser.js:32:52)

Failure Logs

The culprit seems to be this commit: 41c2768
A modification of the timezone query param parsing has made this param mandatory

Context

I've upgraded forest-express-sequelize from 1.5.4 to 1.5.5, and wasn't expecting to break my frontend.

Smart field example - fullName - doesn't work

I'm using [email protected] although I had [email protected] earlier today and it's the same problem I think.

I got this example from your website on Smart Fields:

// /forest/user.js
'use strict';
var Liana = require('forest-express-sequelize');

Liana.collection('user', {
  fields: [{
    field: 'fullname',
    type: 'String',
    value: function (object) {
      return object.firstName + ' ' + object.lastName;
    }
  }]
});

What I did:

First, I used the Layout editor to change the User table. For "When a user is referenced, I want to see the field…", I chose fullName. I had created the forest/user.js field as instructed.

I used the Forest Admin website to create a new record. I was creating a Credit Check record, which belongs to Users. I put my cursor in the User textbox and started typing a name.

What I expected to happen:

The list of auto-suggested values to give full names of users from the Users table.

What I actually saw happen:

Each name showed undefined undefined. If I log object, I can see it's a Sequelize object whose only value is { id: 1 }, which would explain it. So it has no values besides id, thus object.firstName + ' ' + object.lastName would be undefined undefined.

My question is why do the Sequelize records only have the id field? Why don't they have all fields?

Other hints:

In the table view of Credit Checks, the "user" field sometimes shows the email address (no idea how it picked that field), sometimes it shows "undefined undefined".

In the detail view, the "user" field sometimes shows the user's ID, e.g. 1.

How to output a json log?

Expected behavior

I'm using Bunyan logger for my entire application, but forest admin still printing to STDOUT, can I force forest admin to use custom logger?

Actual behavior

Able to usse custom logger.

Failure Logs

Context

  • Need to log to JSON to a log aggregation service
  • Package Version: ^2.16.9
  • Express Version: ^4.16.3
  • Sequelize Version: ^4.39.0
  • Database Dialect: psql
  • Database Version:

Can't create rows for a belongsTo model, truncated column error

Expected behavior

Able to create a row in my Question model via the Forest interface.

Actual behavior

Fails to create the row for my Question model; Insert statement uses an invalid string for the foreign key.

Failure Logs

When I create my Question row in the Admin interface for job id=1, the result I get in SQL is:

INSERT INTO `question` (`question_id`,`job_id`,`question_type_id`,`is_premium_question`,`text`,`created_at`,`updated_at`) VALUES (1,'1-1','1',true,'Whats your favourite food?','2018-02-19 06:28:49','2018-02-19 06:28:49');

It throws the following error because '1-1' doesn't exist as an integer for job_id on my Questions table.

[forest] 🌳🌳🌳  Unexpected error: WARN_DATA_TRUNCATED: Data truncated for column 'job_id' at row 1
SequelizeBaseError: WARN_DATA_TRUNCATED: Data truncated for column 'job_id' at row 1
    at Query.formatError (C:\node-univjobs-back\forest\node_modules\sequelize\lib\dialects\mysql\query.js:175:14)
    at Query._callback (C:\node-univjobs-back\forest\node_modules\sequelize\lib\dialects\mysql\query.js:49:21)
    at Query.Sequence.end (C:\node-univjobs-back\forest\node_modules\mysql\lib\protocol\sequences\Sequence.js:86:24)
    at Query.ErrorPacket (C:\node-univjobs-back\forest\node_modules\mysql\lib\protocol\sequences\Query.js:94:8)
    at Protocol._parsePacket (C:\node-univjobs-back\forest\node_modules\mysql\lib\protocol\Protocol.js:280:23)
    at Parser.write (C:\node-univjobs-back\forest\node_modules\mysql\lib\protocol\Parser.js:74:12)
    at Protocol.write (C:\node-univjobs-back\forest\node_modules\mysql\lib\protocol\Protocol.js:39:16)
    at Socket.<anonymous> (C:\node-univjobs-back\forest\node_modules\mysql\lib\Connection.js:109:28)    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at addChunk (_stream_readable.js:266:12)
    at readableAddChunk (_stream_readable.js:253:11)
    at Socket.Readable.push (_stream_readable.js:211:10)
    at TCP.onread (net.js:587:20)

Context

I'm hoping that I've just configured something wrong with my sequelize relationships. Here's what the two relevant models look like.

My Question model:

module.exports = function(sequelize, DataTypes) {
  const Question =  sequelize.define('question', {
    question_id: {
      type: DataTypes.INTEGER(11),
      primaryKey: true,
      autoIncrement: true
    },
    job_id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: false,
      references: {
        model: 'job',
        key: 'job_id'
      },
      onDelete: 'cascade',
      onUpdate: 'cascade'
    },
    question_type_id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      references: {
        model: 'lists_question_types',
        key: 'question_type_id'
      }
    },
    is_premium_question: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
      default: 0
    },
    text: {
      type: DataTypes.STRING(160),
      allowNull: false
    }
  },{
    timestamps: true,
    underscored: true, // force createdAt, updatedAt => created_at, updated_at
    tableName: 'question',
    instanceMethods: {

    }
  });

  Question.associate = (models) => {
    Question.belongsTo(models.Job, { foreignKey: 'job_id', targetKey: 'job_id', as: 'Job' })
    Question.belongsTo(models.ListsQuestionTypes, { foreignKey: 'question_type_id', targetKey: 'question_type_id', as: 'QuestionType' })
  }

  return Question;
};

My Job model

const Job =  sequelize.define('job', {
    job_id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      autoIncrement: true,
      primaryKey: true
    },
    employer_id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'employer',
        key: 'employer_id'
      },
      onDelete: 'cascade',
      onUpdate: 'cascade'
    },
    title: {
      type: DataTypes.STRING(30),
      allowNull: false
    }
  },{
    timestamps: true,
    underscored: true,
    tableName: 'job'
  });

Job.associate = (models) => {
    Job.hasMany(models.Question, { as: 'Questions', foreignKey: 'job_id', sourceKey: 'job_id' })
}
  • Package Version: 2.4.2
  • Express Version: 4.13.4
  • Sequelize Version: 3.24.8
  • Database Dialect: MySQL
  • Database Version:

[*] Smart Fields - `option` parameter for a custom field is different when called by a listing view or a detail view

Hi,

I defined my relations using Sequelize 4.11.3.
I have a custom field on a model subscription that has to show data from a deep relation.

subscription.user.cards[0].number

This code is working on the listing view :

Liana.collection('subscription', {
  fields: [{
    field: 'card',
    type: 'String',
    get: (subscription) => {
      return subscription.getUser({
        include: [{
          model: models.user_card,
          as: 'cards'
        }]
      })
      .then(user => {
        return user.cards[0].number
      })
    }
  }]
});

However, when I want to see the details of a subscription, I've got the following error:

[forest] 🌳🌳🌳  Unexpected error: subscription.getUser is not a function

It seems that a subscription.user property is set with the raw content of the user, but the Subscription instance does not comes with the getter that would allow me to use the Sequelize relations to get my content.

I think the parameter of get(object) should be the same in both cases.

Is it correct?

Text area widgets do not respond to 'read-only'

My use case: I had an editable text area for a model, but for UX reasons, I changed my mind and decided to mark it as read-only.

Reproduction steps:

  • Edit the fields of any model
  • Set a field's type to 'text-area' and check 'read-only'
  • Save and refresh the page
  • Open the edit or new form of the model. The attribute can still be written to.

[*] Default Values - Field DATEONLY with defaultValue shows incorrect data on form

Hi!

I have a model defined like this:

const BalanceUpdate = sequelize.define('BalanceUpdate', {
    amount: DataTypes.DECIMAL(10, 5),
    date: {
      type: DataTypes.DATEONLY,
      defaultValue: DataTypes.NOW
    }
  });

When I open the "create new" page, the Date field comes pre-filled with the contents: [object Object].

Expected behavior

The field should display the current date.

##Β Actual behavior

The field displays an invalid value, and if I try to save as is I get an error: invalid input syntax for type date: "Invalid date".

Failure Logs

23:38:38 web.1   |  Executing (default): INSERT INTO "BalanceUpdates" ("id","amount","date","createdAt","updatedAt","InvestmentId") VALUES (DEFAULT,3,'Invalid date','2018-02-10 01:38:37.426 +00:00','2018-02-10 01:38:37.426 +00:00','1') RETURNING *;

Context

  • Package Version: 2.4.2
  • Express Version: 4.16.2
  • Sequelize Version: 4.33.2
  • Database Dialect: postgres
  • Database Version: 10.1

Pagination breaks on some sequelize models

Hi there.

Thank you for the great product.

We are finding good uses for it in our system. During development however we encountered an issue.

It seems as if with most sequelize models pagination works. In other words, if we go to the tables on the Forest Admin panel and if we have 21 entries, we see 10 on the first page etc.

On some models, this behaviour breaks. We have a table with 1093 records and displaying all of it grinds the system to a halt.

We saw the following in our logs (i.e. sequelize logs this out) when comparing the queries made for the working and non-working models.

  1. The first model works and we see:
Executing (default): SELECT "DbUser"."Id", "DbUser"."Name"  FROM "Users" AS "DbUser" LEFT OUTER JOIN "JuristicEntities" AS "JuristicEntity" ON "DbUser"."JuristicEntityId" = "JuristicEntity"."Id" ORDER BY "DbUser"."Id"
DESC LIMIT 10 OFFSET 0;
  1. The second model breaks and we see:

Executing (default): SELECT "Id", "Name"
FROM "JuristicEntities" AS "DbJuristicEntity";

We noticed that the LIMIT is missing on the second query.

This issue seems to be related to an issue that was addressed with the following pull request: #134

After some digging around, we saw that if we remove the include property on line 132 of the resources-getter.js file, we seem to get pagination working again. (But we are unsure what we are breaking in the process)

Any advice or assistance with this will be highly appreciated.

Searching UUID is broken

On this line, a regex should be defined, but it is a string that is created.

The result is that UUID detection tries to match the string /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i instead of the pattern.

Tested on node 8.4

[*] Sequelize Getters - Support getters that return Promises for belongsTo relationships

Expected behavior

I have a table (let's say Post) with a foreign key to another table (let's say Author). The "REFERENCE FIELD" of the table Author is set to the username. I expect to see the username in the column author of each post and on the "details" view of each post.

##Β Actual behavior

Even tho the foreign key in the database is present, the author is missing from both views (table, and details)

Context

  • Package Version: ^2.14.1
  • Express Version: ^4.16.3
  • Sequelize Version: ^4.37.5
  • Database Dialect: postgres

It should be possible to customize the `include` prop of queries generated by smart segments

Right now it's possible to customize the where property of the queries generated by smart-segments. And it's also possible to specify a scope that will be used in the query (undocumented, afaik).
That scope should make it possible to include additional models in the query, unfortunately, they often end up overridden by resources-getter.js's logic, which automatically includes models associated with hasOne and belongsTo.
As is, the scope option is of little use, and it would be much more useful to be able to customize the final include used in the query.
I hope to find the time to draft a PR next week, but don't hesitate to provide feedback on the idea :-)

[*] Smart Fields - Smart Fields not working inside hasMany relation

Expected behavior

Smart fields should work inside hasMany relation

Actual Behaviour

Smart fields based on relation (Any type of relation) does not work when we click on a relations.
The model in the smart fields is a simple object, no function attached to it.

Failure Logs

[forest] 🌳🌳🌳 Cannot retrieve the brand value because of an internal error in the getter implementation: TypeError: object.getParent is not a function

Context

The model is recursive. It has childs and parent.

  • Package Version:2.5.6
  • Express Version: 4.13.4
  • Sequelize Version: 4.8.0
  • Database Dialect: MariaDB
  • Database Version: 10.2.13-MariaDB-10.2.13+maria~xenial

ID created as '[object Object]'

I'm not sure why but when adding new records via the ForestAdmin interface, the ID field on my models is autogenerated as '[object Object]'. This also leads to me not being able to add any new records after adding one since they would have the same ID. My models are defined with the ID fields being DataType.UUID.

Any idea what is wrong?

I am not able to see model changes in the Admin UI

Hi guys,

First of all, I really love what you are doing with the ForestAdmin app ❀️🌲 and thank you even for giving us the opportunity to use it for free.

I have just one question for you. I have generated the Admin using Lumber🌲, and everything went smoothly. Then I have added some new fields in some DB tables and lastly, I have updated the sequelize models in order to see the new fields in the Admin but I am not able to see any changes.

I have even added a smart field and it seems that the code is computing my code but it is not showing anything. Is there a way to force the client side to refresh based on the model changes?

This should be related to #62.

getIncludes on HasOne and BelongsTo associations forces required true

I noticed that all queries generated in the dashboard when listing resources were made using INNER JOIN and not LEFT JOIN. Looking for an explanation for this behavior, I noticed that the getIncludes method in the resources-getter was forcing required: true on HasOne and BelongsTo associations, which is not sequelize default behavior.
Say we're using HasOne / BelongsTo associations to describe foreign keys that can be null (player.belongsTo(team), team_id can be null if player does not have a team currently). We still need to visualize all the resources. We currently can't unless we remove that required: true from the module source code.
Is there a reason why you're forcing this behavior ? Could you possibly make this a custom parameter so that we can decide wether we want INNER JOIN or LEFT JOIN ?

Unexpected error in the list view: TypeError: Cannot read property 'type' of null

I'm not sure why some of my tables are doing this, but this is the error in the console when I try to load the data.

vendor-70f3d283c05843483820f9adb8823679.js:112 [forest] 🌳🌳🌳 Unexpected error in the list view:  TypeError: Cannot read property 'type' of null
    at r._pushInternalModel (vendor-70f3d283c05843483820f9adb8823679.js:119)
    at vendor-70f3d283c05843483820f9adb8823679.js:119
    at d.run (vendor-70f3d283c05843483820f9adb8823679.js:7)
    at d.join (vendor-70f3d283c05843483820f9adb8823679.js:7)
    at r._push (vendor-70f3d283c05843483820f9adb8823679.js:119)
    at vendor-70f3d283c05843483820f9adb8823679.js:119
    at A (vendor-70f3d283c05843483820f9adb8823679.js:23)
    at k (vendor-70f3d283c05843483820f9adb8823679.js:23)
    at C (vendor-70f3d283c05843483820f9adb8823679.js:23)
    at invokeWithOnError (vendor-70f3d283c05843483820f9adb8823679.js:7)

I see the data that was loaded and type is referenced. Here is a snippet:

{  
   "meta":{  
      "count":5
   },
   "data":[  
      {  
         "type":"faq-section",
         "id":"a9b9b870-a3d2-11e7-88c1-91b093414a29",
         "attributes":{  
            "id":"a9b9b870-a3d2-11e7-88c1-91b093414a29",
            "section":"Basics",
            "order":1,
            "createdAt":"2017-09-28T02:06:29.000Z",
            "updatedAt":"2017-09-28T02:06:29.000Z"
         },
         "relationships":{  
            "faqs":{  
               "links":{  
                  "related":{  
                     "href":"/forest/FAQSection/a9b9b870-a3d2-11e7-88c1-91b093414a29/relationships/faqs"
                  }
               }
            }
         }
      },
      ...

Here's that object:

const FAQSection = Model.define('FAQSection', {
  id: {
    type: DataType.UUID,
    defaultValue: DataType.UUIDV1,
    primaryKey: true,
  },
  section: {
    type: DataType.STRING(120),
  },
  order: {
    type: DataType.INTEGER,
  },
});

And the relationship:

FAQSection.FAQ = FAQSection.hasMany(FAQ, {
  foreignKey: 'faqSectionId',
  as: 'faqs',
  onUpdate: 'cascade',
  onDelete: 'cascade'
});

Let me know what else info you need to track this down.

Cannot edit record on model with two primary keys

Expected behavior

Forest should be able to update records even if model has multiple primary keys.

Actual behavior

On models with multiple primary keys, updates requests are wrongly crafted.
The id field (my first PK) appears as a concatenation of my two PK in Forest.
This id field is expected to be a uuid format and feeding the concatenation triggers an error in sequelize.

Failure Logs

[forest] 🌳🌳🌳  Unexpected error: invalid input syntax for type uuid: "9ed9c7e0-463a-465b-a147-3220380a7702-PHOTON-DEV1"                                                                        
SequelizeDatabaseError: invalid input syntax for type uuid: "9ed9c7e0-463a-465b-a147-3220380a7702-PHOTON-DEV1"                                                                                   
    at Query.formatError (/opt/node_modules/sequelize/lib/dialects/postgres/query.js:363:16)                                                                                                    
    at query.catch.err (/opt/node_modules/sequelize/lib/dialects/postgres/query.js:86:18)                                                                                                       
    at tryCatcher (/opt/node_modules/bluebird/js/release/util.js:16:23)                                                                                                                         
    at Promise._settlePromiseFromHandler (/opt/node_modules/bluebird/js/release/promise.js:512:31)                                                                                              
    at Promise._settlePromise (/opt/node_modules/bluebird/js/release/promise.js:569:18)                                                                                                         
    at Promise._settlePromise0 (/opt/node_modules/bluebird/js/release/promise.js:614:10)                                                                                                        
    at Promise._settlePromises (/opt/node_modules/bluebird/js/release/promise.js:689:18)                                                                                                        
    at Async._drainQueue (/opt/node_modules/bluebird/js/release/async.js:133:16)                                                                                                                
    at Async._drainQueues (/opt/node_modules/bluebird/js/release/async.js:143:10)                                                                                                               
    at Immediate.Async.drainQueues [as _onImmediate] (/opt/node_modules/bluebird/js/release/async.js:17:14)                                                                                     
    at runCallback (timers.js:763:18)                                                                                                                                                           
    at tryOnImmediate (timers.js:734:5)                                                                                                                                                         
    at processImmediate (timers.js:716:5)  

Context

Here is my model:

sequelize.define('Machine', {
  id: {
    type: DataTypes.UUID,
    defaultValue: DataTypes.UUIDV4,
    primaryKey: true,
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false,
    primaryKey: true,
  },
  status: {
    type: DataTypes.STRING,
    allowNull: false,
  },
})

The id field is shown as a concatenation of id and name (my two primary keys) in Forest:

screen shot 2018-09-25 at 2 10 20 pm

  • Package Version: 2.16.0
  • Express Version: 4.16.3
  • Sequelize Version: 4.38.0"
  • Database Dialect: postgres
  • Database Version: 10.4

TypeError: Cannot read property 'get' of null

Expected behavior

I have two models involved: guides and steps. I expect to be able to create a guide and create steps associated with that guide from the Forest Admin web interface. I sent this issue to [email protected] but I'm posting it here in case someone from the community has had a similar issue and might have a solution.

Actual behavior

I am able to create a guide but when I try to create a step associated with that guide no network request is made and an error is logged to the console. This error was not occurring the last time I tried it (September 19) and we've made no model/code changes in several months.

Steps to reproduce:

  • login to Forest admin and create a guide
  • click on steps (from the left of this guide details, so that it will be associated with this guide)
  • click on the + -> create new step
  • fill out the required fields and click save
  • nothing happens. no network request is made and the error below is logged to the console

guides model:

"use strict";
module.exports = function(sequelize, DataTypes) {
    var guides = sequelize.define("guides", {
        title: {
            type: DataTypes.STRING,
            allowNull: true
        },
        subtitle: {
            type: DataTypes.STRING,
            allowNull: true
        },
        image: {
            type: DataTypes.STRING,
            allowNull: true
        },
        image_thumbnail: {
            type: DataTypes.STRING,
            allowNull: true
        },
        description: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        product_identifier: {
            type: DataTypes.STRING,
            allowNull: true
        },
        archive: {
            type: DataTypes.STRING,
            allowNull: true
        },
        reduced_mobility: {
            type: DataTypes.BOOLEAN,
            defaultValue: false,
            allowNull: false
        },
        language: {
            type: DataTypes.ENUM("fr", "en"),
            defaultValue: "fr",
            allowNull: false
        },
        credit_image: {
            type: DataTypes.STRING,
            allowNull: true
        },
        link: {
            type: DataTypes.STRING,
            allowNull: true
        },
        archive_size_string: {
            type: DataTypes.STRING,
            allowNull: true
        },
        archive_size_bytes: {
            type: DataTypes.INTEGER,
            allowNull: true
        },
        order: {
            type: DataTypes.INTEGER,
            allowNull: false,
            defaultValue: 1
        },
        autoplay: {
            type: DataTypes.BOOLEAN,
            allowNull: false,
            defaultValue: false
        },
        onsite_limit: {
            type: DataTypes.BOOLEAN,
            allowNull: false,
            defaultValue: false
        },
        environment: {
            type: DataTypes.ENUM("development", "staging", "production"),
            defaultValue: "development",
            allowNull: false
        },
        guide_type: {
            type: DataTypes.ENUM("navigation", "audio", "parcour"),
            defaultValue: "navigation",
            allowNull: false
        },
        is_free: {
            type: DataTypes.BOOLEAN,
            allowNull: false,
            defaultValue: false
        }
    });

    guides.associate = function(models) {
        guides.hasMany(models.steps);
        guides.belongsTo(models.locations, {
            foreignKey: "start_location_id",
            as: "start_location"
        });
        guides.belongsTo(models.locations, {
            foreignKey: "end_location_id",
            as: "end_location"
        });
    };

    return guides;
};

steps model:

'use strict';
module.exports = function(sequelize, DataTypes) {
    var steps = sequelize.define('steps', {
        order: {
            type: DataTypes.INTEGER,
            allowNull: true,
            validate: {
                min: 0,
            },
        },
        playlist_title: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        playlist_instruction: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        title: {
            type: DataTypes.STRING,
            allowNull: false,
        },
        meta: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        description: {
            type: DataTypes.TEXT,
            allowNull: true,
        },
        image: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        image_thumbnail: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        audio: {
            type: DataTypes.STRING,
            allowNull: true,
        },
        guide_id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            references: {
                model: 'guides',
                key: 'id',
            },
        },
        step_type: {
            type: DataTypes.STRING,
            allowNull: false,
            defaultValue: 'other',
        },
        autoplay_group: {
            type: DataTypes.STRING,
            allowNull: false,
            defaultValue: 'none',
        },
        ext_id: {
            type: DataTypes.INTEGER,
            allowNull: true,
        },
        ext_data: {
            type: DataTypes.TEXT,
            allowNull: true,
        },
        ext_updated_at: {
            type: DataTypes.STRING,
            allowNull: true,
        },
    });

    steps.associate = function(models) {
        steps.belongsTo(models.guides);
        steps.belongsToMany(models.beacons, { through: 'step_beacon' });
    }

    return steps;
};

Failure Logs

TypeError: Cannot read property 'get' of null
    at client-5fdff9cef7c56…54b566218f6.js:1177
    at o.forEach (vendor-039ff5e8d2118…4f25499893e.js:3532)
    at o.saveNewRecord (client-5fdff9cef7c56…54b566218f6.js:1176)
    at o.y (vendor-039ff5e8d2118…4f25499893e.js:3287)
    at d (vendor-039ff5e8d2118…4f25499893e.js:3932)
    at E.trigger (vendor-039ff5e8d2118…4f25499893e.js:4089)
    at o.send (vendor-039ff5e8d2118…4f25499893e.js:3323)
    at o.send (vendor-039ff5e8d2118…4f25499893e.js:3494)
    at o.triggerAction (vendor-039ff5e8d2118…4f25499893e.js:3600)
    at o.sendAction (vendor-039ff5e8d2118…4f25499893e.js:3759)

Context

  • Package Version: 2.16.2 (in dev and staging) 2.8.2 (in production)
  • Express Version: 4.15.2
  • Sequelize Version: 4.8.3
  • Database Dialect: mysql
  • Database Version: mysql Ver 14.14 Distrib 5.5.60, for debian-linux-gnu (x86_64) using readline 6.3

Thanks!

unable to upload UI configurations to production

Expected behavior

Modify UI configuration on local. It should update on production after save.

Actual behavior

Even after getting mail production UI configuration not changed

Failure Logs

Context

I changed my UI configurations on local and follow all steps given in documentation but when I am trying to deploy it on production(Steps: Copy your layout configuration -> select production in Copy Layout Configuration To.. -> Copy -> Save changes) it is not reflecting there.

I got the mail of successfully deployed but unable to see changes.

  • Package Version:2.12.2
  • Express Version:4.15.5
  • Sequelize Version:4.0.0
  • Database Dialect:postgres
  • Database Version:9.5

Does not work when deployed on AWS Lambda (serverless framework)

It works when running it locally. Tried deploying it on serverless (AWS Api Gateway + Lambda) but app.forestadmin.com console is not able to connect to it. I checked the environment variables which were initially wrong and logging errors. Now that is fixed but not getting anywhere with it.

The error I get when trying to setup forest on app.forestadmin.com:
"Forest did not received your apimap to finalize the deployment. Please, double-check that you set the correct FOREST_ENV_SECRET environment variable and then restart your production server."

  1. How can I debug this? Manually see if the rest api returns apimap?
  2. How is the Authorization Bearer token generated so I can try the auto-generated rest API endpoints (they seem accessible but my token is invalid)?

Composite primary key breaks if null

A null value in a composite primary key breaks detail view in forest. Forest correctly creates the url:

record/451836/fielda-fieldb-null/details

But forest-express-sequelize gives the following error:

Unexpected error: invalid input syntax for integer: "null"

Koa support

Just quick note to let you know that forest-express-sequelize seems to work with Koa when used with this forked version of express-to-koa.

Would love to see a more official support of Koa!

Cheers πŸ‘‹

[*] Default Values - Field UID with defaultValue shows incorrect data on form

Expected behavior

UID field to have a correct default value or not have it and let Sequelize to handle the creation of UID.

Actual behavior

Currently the UID field is automatically populated with [object Object] which causes an error on the backend.

image

Failure Logs

[forest] 🌳🌳🌳  Unexpected error: invalid input syntax for type uuid: "[object Object]"
SequelizeDatabaseError: invalid input syntax for type uuid: "[object Object]"

Context

You had similar issues on:

  1. #121
  2. #164

The only difference between the problem we are facing and the one from issue #121 is that the UID on our models is not a primaryKey.

uid: {
  type: Sequelize.UUID,
  defaultValue: Sequelize.UUIDV4
}

I found a workaround for the bug by deleting [object Object] when creating an instance of a model on the frontend, but that could be a pain for users internally.

  • Package Version: forest-express-sequelize 2.16.3
  • Express Version: 4.16.2
  • Sequelize Version: 4.37.10
  • Database Dialect: Postgres
  • Database Version:

Thanks!

Working around segment pagination.

Expected behavior

I need a way of overriding pagination parameters for segments, or otherwise creating a query that fools Forest into allowing me to view multiple pages of requests.

Actual behaviour

I can get a paginated list of users from a third party service that matches the page size of what my Forest UI requests – theparams.page.size passed to the where in a Smart Segment definition.

I can get my app to request a paginated list of users from my local DB that matches the returned list that obeys the params.page.size and params.page.number that Forest is requesting.

My problem is, because the Forest UI seems to only show multiple pages if the where returns a list of IDs that's larger than params.page.size, I can only ever see the first page of users.

Context

I'm working on extending the current Intercom integration so that mapped entities in Sequelize can be viewed in Forest grouped by a Intercom segment.

Intercom returns a paginated list of users/leads (in an Intercom segment) which I would ideally like to see in Forest. Assuming that my Intercom users/leads map 1:1 with my Sequelize entities, I'd like the ability to browse a filtered and paginated list of users received from Intercom. Every page of users, not just the first one.

I think that I can work around this if we allow for SQL defined segments – I can get my list of IDs from Intercom and then run something like SELECT * WHERE id IN intercom_ids UNION (SELECT * WHERE id NOT in intercom_ids ORDER_BY updated_at LIMIT intercom_total_users). https://github.com/ForestAdmin/forest-express-sequelize/pull/177/files#diff-59c56020e087ce7c31dfd435686bd140R85 is close to what I'd need, but I'd still need to resolve an async promise to get my list of users out of Intercom.

Have folks asked for something like this before?

  • Package Version: ~2.8.6
  • Express Version: ~4.16.1
  • Sequelize Version: ~4.37.1
  • Database Dialect: PSQL
  • Database Version:

Support for other Node Platforms

Hi @VinzGhyz
Just got your mail and was quite interested in your project.

Any plans to support other node applications, particularly HapiJS, or you could setup a guide for extending this to other node platforms.

PS. How about Bookshelf.js and Knex.

Cheers

Field Type: Support DATEONLY column type

Hi there,
the support for DATEONLY is missing. While it is easy to be added, the Forest UI needs to support it. While the normal date picker can be used, it is very difficult to set a date that is +10 years into the past or future.

Sequelize - Projects using the very recent Sequelize version cannot display the data due to old operators deprecation

Expected behavior

Collections working in admin

Actual behavior

Any collection tab in the admin shows error:

Oops, something went wrong
An error occured while retrieving your data. Please contact [email protected] for further investigation.

Failure Logs

This example is for table User, but same problem occurs with all other tables.

 db_1       | 2018-01-25 13:04:05.512 UTC [33] STATEMENT:  SELECT count("User"."id") AS "count" FROM "public"."User" AS "User" LEFT OUTER JOIN "public"."Profile" AS "profile" ON "User"."id" = "profile"."userId" WHERE "User"."$and" IN (NULL);
[1] [forest] 🌳🌳🌳  Unexpected error: column User.$and does not exist
[1] SequelizeDatabaseError: column User.$and does not exist

Context

The Forest admin was all working fine before, but stopped working now.

  • Package Version: "forest-express-sequelize": "^2.1.1"
  • Express Version: "express": "~4.15.5"
  • Sequelize Version: "^4.32.1"
  • Database Dialect: postgres
  • Database Version: postgres (PostgreSQL) 10.1

Can't do a combination of AND and OR operators in Segment

Is there a way to use AND and OR operators in a Segment?

I want to create a Segment called Unverified Students where

  • (is_email_verified is 0 OR is_profile_complete is 0) AND is_a_student is 1

Every time that I click on one of the AND/OR buttons in this setup to change it, they both change.
Wondering if this is possible.

image

[*] DateOnly - Sequelize 4 returns date strings not timestamps so don't shift

As of Sequelize 4 dateonly fields are returned as date strings not
dateTime strings. Therefore the formatting functionality here will
return incorrect values for dateonly fields in Sequelize 4 if the server
is in a timezone with a negative UTC shift.

Ex: I have 1990-10-02 stored in my DB. The formatting function will
shift that to 1990-10-01T16:00:00 if I am in PST. In the UI 01/10/1990
will be shown

sequelize/sequelize#4858

I made a pull request for this #153 but forgot to make an issue.

Please also take a look at ForestAdmin/forest-express#123 where this also needed to be fixed

Smart Action Not Rendering Button And Breaking UI

Here is the code in my forest/user.js

var Liana = require('forest-express-sequelize');
console.log('liana object', Liana);

Liana.collection('user', {
  actions: [
    {
      name: 'Test Add Admin User',
      fields: [
        {
          field: 'First Name',
          type: 'String'
        }
      ]
    }
  ]
});

It causes wonky rendering across the Forest Admin UI but no smart action button to use.

screen shot 2017-05-07 at 9 20 10 pm

screen shot 2017-05-07 at 9 20 03 pm

screen shot 2017-05-07 at 9 19 47 pm

screen shot 2017-05-07 at 9 19 32 pm

Pie chart shows an error : "Forest cannot render this chart."

Expected behavior

Pie Chart should display

Actual behavior

An error is shown

Failure Logs

[forest] 🌳🌳🌳  Unexpected error: Cannot read property 'fields' of undefined
TypeError: Cannot read property 'fields' of undefined
    at new PieStatGetter (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express-sequelize/services/pie-stat-getter.js:28:43)
    at create (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/routes/stats.js:18:19)
    at Layer.handle [as handle_request] (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/route.js:137:13)
    at exports.ensureAuthenticated (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/services/auth.js:6:5)
    at Layer.handle [as handle_request] (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/layer.js:95:5)
    at /Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express/lib/router/index.js:275:10)
    at /Users/manu/developer/@escorts/escorts-admin/node_modules/forest-express/node_modules/express-jwt/lib/index.js:128:7
    at /Users/manu/developer/@escorts/escorts-admin/node_modules/async/lib/async.js:52:16
    at Immediate.<anonymous> (/Users/manu/developer/@escorts/escorts-admin/node_modules/async/lib/async.js:1206:34)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)
POST /forest/stats/users 500 76.607 ms - 81

Context

I am trying to create a pie chart showing users with various roles

#users
'use strict';

module.exports = (sequelize, DataTypes) => {
  var Model = sequelize.define(
    'users',
    {
      id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      role_id: {
        type: DataTypes.INTEGER,
        allowNull: false
      },
      first_name: {
        type: DataTypes.STRING,
        allowNull: false
      },
      last_name: {
        type: DataTypes.STRING,
        allowNull: false
      },
      phone: {
        type: DataTypes.INTEGER,
        allowNull: false
      },
      address: {
        type: DataTypes.STRING
      },
      village_id: {
        type: DataTypes.INTEGER,
        allowNull: false
      },
      profile_verified: {
        type: DataTypes.INTEGER,
        defaultValue: 1
      },
      active: {
        type: DataTypes.BOOLEAN,
        defaultValue: 1
      }
    },
    {
      tableName: 'users',
      underscored: true,
      timestamps: false
    }
  );

  Model.associate = models => {
    Model.belongsTo(models.villages, {
      foreignKey: 'village_id',
      targetKey: 'id'
    }),
      Model.belongsTo(models.user_roles, {
        foreignKey: 'role_id',
        targetKey: 'id'
      }),
      Model.hasMany(models.implements, {
        foreignKey: 'owner_user_id',
        sourceKey: 'id'
      }),
      Model.hasMany(models.tractors, {
        foreignKey: 'owner_user_id',
        sourceKey: 'id'
      }),
      Model.hasMany(models.fields, {
        foreignKey: 'owner_user_id',
        sourceKey: 'id'
      }),
      Model.hasMany(models.requests, {
        foreignKey: 'create_user_id',
        sourceKey: 'id'
      }),
      Model.hasMany(models.documents, {
        foreignKey: 'user_id',
        sourceKey: 'id'
      });
  };

  return Model;
};
#user_roles
'use strict';

module.exports = (sequelize, DataTypes) => {
  var Model = sequelize.define('user_roles', {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },
    role: {
      type: DataTypes.STRING,
    },
  }, {
    tableName: 'user_roles',
    
    timestamps: false,
    
  });

  Model.associate = (models) => {
  };

  return Model;
};
  • Package Version:
  • Express Version:
  • Sequelize Version: 1.5.6
  • Database Dialect: MySQL
  • Database Version:

Cannot modify a file once it is uploaded

I'm not sure if this is intentional or not, but it appears that uploaded images cannot be modified once they have been uploaded? Here's a screenshot from my dashboard where I'm attempting to edit an existing model with an image:
edit_image

No models directory

Hi,

Sorry for deleting the template, but this is a question.
How can I setup this liana if I my models are in multiple directories?
My sequelize setup requires each model and adds them to the sequelize connection.

Thanks,
Dragos

smart filed return object

Hi, I am trying to return an object to a smart field, here is my code ;

 varvar  LianaLiana  ==  requirerequire(('forest-express-mongoose''forest-express );

Liana.collection('users', {
  fields: [{
    field: 'feed answer',
   type: 'Object',
    get: function (object) {
      return {1:'text',2:'texrt'};
    }
  }]
});

but I am getting
screen shot 2018-05-01 at 14 27 10

[*] Package Support - Ensure compatibility with Hierarchy package

Expected behavior

https://github.com/overlookmotel/sequelize-hierarchy
Sequelize plugin that helps setup hierarchy functions doesn't work with Forest.

##Β Actual behavior

Upon create:
[forest] 🌳🌳🌳 Unexpected error: record[("set" + _.capitalize(...))] is not a function

Tries setting associations for descendants and ancestors. Is there a way to disable this within Forest? The issue is occurring in resource-creator.js around line 33

Context

Using the basic setup for the plugin.

category.isHierarchy();

  • Package Version: 2.5.9
  • Express Version: feathersjs/[email protected]
  • Sequelize Version: 4.37.4
  • Database Dialect: postgres
  • Database Version: 10

Sequelize scopes for `countAssociations()` method in defining smart fields does not seem work

Expected behavior

I have a table that defines scopes and smart fields that are attached to it.

  1. model.countAssociatedModel({ scope: 'someScope' }).
  2. model.countAssociatedModel({ scope: 'someOppositeScope' }).

someScope is defined as

          someScope: () => {
            include: [
              {
                model: anotherAssociatedModel,
                where: {
                  field1: { $ne: null },
                  field2: { $ne: null },
                  field3: { $ne: null },
                },
                attributes: [],
              },
            ],
          },
          someOppositeScope: () => {
            include: [
              {
                model: anotherAssociatedModel,
                where: {
                  $or: [{ field1: null }, { field2: null }, { field3: null }],
                },
                attributes: [],
              },
            ],
          },
         

I expect the field for someScope + someOppositeScope to sum up to model.countAssociatedModel().

This actually works fine in my forest dev environment hitting my local dev server, but for whatever reason would fail when I deployed to production (not sure if it helps but it's running mounted on a Hapi server via Hecks on AWS ECS behind load balancers)

I was able to get the smart field to work by using where instead of using the scopes I defined.

Actual behavior

The scopes don't seem to be applied. Both someScope and someOppositeScope return the same number as if they weren't defined.

In fact, checking my production logs, it doesn't look like the sql queries for these scopes are being made at all. I wonder if there might be some caching being applied incorrectly?

Context

  • Package Version: 2.15.4
  • Express Version: 4.16.2
  • Sequelize Version: 4.38.0
  • Database Dialect: postgres
  • Database Version: 9.6.6 (prod, AWS RDS), 9.6.2 (dev)

How to stub liana.ensureAuthenticated?

Expected behavior

sinon.stub(liana, 'ensureAuthenticated') should stub the ensureAuthenticated

Actual behavior

stub does not address liana 'ensureAuthenticated', and code in forest-express-sequelize and forest-express seem to obscure how ensureAuthenticated is exposed

Context

I use liana.ensureAuthenticated as a middleware as suggested by Forest docs https://doc.forestadmin.com/developer-guide/express-sequelize.html#uploading-images and am hoping to unit test my controller.

Increase Request TimeOut

Expected behavior

Be able to customize the request timeout when connecting to a given database (specially when using VIEWS that might take longer than a table).

Actual behavior

On DEV environment everything works fine, but when we are using PROD, we are getting an TimeOut exception (see logs).

Failure Logs

[forest] 🌳🌳🌳 Unexpected error: ResourceRequest timed out TimeoutError: ResourceRequest timed out at ResourceRequest._fireTimeout (/xxx/node_modules/generic-pool/lib/ResourceRequest.js:62:17) at Timeout.bound (/xxx/node_modules/generic-pool/lib/ResourceRequest.js:8:15) at ontimeout (timers.js:460:11) at tryOnTimeout (timers.js:298:5) at Timer.listOnTimeout (timers.js:261:5)

Context

It's running in a AWS Linux AMI, with the following versions:

  • Package Version: 2.12.8
  • Express Version: 4.13.4
  • Sequelize Version: 4.8.0
  • Database Dialect: MySQL
  • Database Version: Aurora MySQL 5.6.10a

Forest Admin throws error on login

Expected behavior

On login to forest admin ,it should render the graphs and all other details of the models should be rendered.

Actual behavior

Currently , forest admin throws error in UI as follows:
Oops, something went wrong.An error occurred in retrieving your data. On logging out and logging in back there is no occurrence of the error. And backend throws error: invalid byte sequence for encoding utf8

There is a token being set during the time of login forest_session_token . This token is being generated by forest admin server. On relogin this token changes and the data is fetched correctly without error. This error occurs repeatedly.

Database used: Postgres

I need to know why this error occurs?

Issues caused by User class not having id as the primary key

The User class on one of our apps uses a primary key called 'uuid' instead of 'id'. I assume that Forest expects an 'id' column by default because the default Dashboard tab throws this exception every time the Dashboard is accessed:
PG::UndefinedColumn: ERROR: column "id" does not exist LINE 1: SELECT DISTINCT COUNT(DISTINCT id) FROM "users" LEFT OUTER J... ^ : SELECT DISTINCT COUNT(DISTINCT id) FROM "users" LEFT OUTER JOIN "users" "primary_accounts_users" ON "primary_accounts_users"."uuid" = "users"."primary_account_id"

This is also preventing us from deleting users. Is there a way to change the default primary key name that forest expects?

Cann't custom title of belongsTo field

Expected behavior

I have two tables
One is "student", One is "school"
and I have set their relationship in
/models/student.js

  Model.associate = (models) => {
    Model.belongsTo(models.school);
  };

Now I reboot server and visit http://app.forestadmin.com/xxxxxxxx/data/xxxxxx/index

What I expected is that I can custom the title of school instead of meaningless id.

Actual behavior

I can see every student displays as a line with school displayed as a link to school detail and text is school's id.

Failure Logs

no logs

Context

  • Package Version:1.4.5
  • Express Version:4.13.4
  • Sequelize Version:4.8.0
  • Database Dialect:postgresql
  • Database Version:PostgreSQL 9.6.4 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.