dresende / node-orm2 Goto Github PK
View Code? Open in Web Editor NEWObject Relational Mapping
Home Page: http://github.com/dresende/node-orm2
License: MIT License
Object Relational Mapping
Home Page: http://github.com/dresende/node-orm2
License: MIT License
I'm uploading images to tables. The closest model data type i found was Buffer. However that refers to Blob which has a limit of 65535. I need LongBlob. Possible in the current implementation?
Using Postgres every time Model.sync is called a new index is generated for the id field. As an example, I created the User
model on the db
database. When I run psql database
on the command line and do \d user
after restarting the server a few times I get these results.
Indexes:
"user_id_idx" btree (id)
"user_id_idx1" btree (id)
"user_id_idx10" btree (id)
"user_id_idx2" btree (id)
"user_id_idx3" btree (id)
"user_id_idx4" btree (id)
"user_id_idx5" btree (id)
"user_id_idx6" btree (id)
"user_id_idx7" btree (id)
"user_id_idx8" btree (id)
"user_id_idx9" btree (id)
Hello,
is there any way to create "IS NULL" condition. Tried to do
Model.find({field: null}, ...
but that throws exception
500 TypeError: Cannot read property 'orm_special_object' of null
at Builder.build (.\node_modules\orm\lib\sql\Select.js:130:38)
at Driver.find(.\node_modules\orm\lib\Drivers\DML\mysql.js:94:34)
at Object.run (.\node_modules\orm\lib\ChainFind.js:75:16)
at Function.model.find (.\node_modules\orm\lib\Model.js:242:9)
Thank you for your great work on project.
Is it possible to catch and handle 'connection lost' event and try to reconnect to db now?
I use mysql driver and I have wait_timeout set in mysql config, so, if connection is inactive for some time, mysql closes it and node-mysql throws an error.
I tryed to catch it with db.driver.on
or db.driver.db.on
, but no success.
So, I have two questions:
db.driver.db.on
? As far as I understand, db.driver.on is an instance of node-mysql connection. But, when I do:var mysql = require('mysql');
var conn = mysql.createConnection(my_params);
conn.connect(my_cb);
conn.on('error', function (e) { ... }); // I'm doing this in node REPL, so error handler is attached after db is connected.
everything works well, and, when I do:
var orm = require('orm');
orm.connect(my_params, function (e, db) {
db.driver.db.on('error', function (e) { ... }); //There can be db.driver.on also
});
node-mysql just throws unhandled exception and the whole process ends.
Any help would be appreciated!
Running though the examples, in 2.0.0-alpha6. It appears hasMany is not extending the instance, so we have no getFirends etc on the instance object. Still digging in.
First I want to thank you for your work on the project, it helps me a lot. I think that I found a little issue, so there's a report.
Function Model.find throws exception when using sort array param.
code snippet
Product.find({}, {offset: param['offset']}, 10, ['name', 'Z'], function(err, products) {
res.json(products);
});
result
Cannot read property 'length' of null
at Function.model.find (.\node_modules\orm\lib\Model.js:206:16)
at exports.index (.\app\controllers\ProductController.js:6:10)
at Resource.map (.\node_modules\express-resource\index.js:163:7)
at callbacks (.\node_modules\express\lib\router\index.js:161:37)
at param (.\node_modules\express\lib\router\index.js:135:11)
at param (.\node_modules\express\lib\router\index.js:132:11)
at pass (.\node_modules\express\lib\router\index.js:142:5)
at Router._dispatch (.\node_modules\express\lib\router\index.js:170:5)
at Object.router (.\node_modules\express\lib\router\index.js:33:10)
at next (.\node_modules\express\node_modules\connect\lib\proto.js:199:15)
solution
file:Model.js
row:206
replace
if (order.length > 0) {
with
if (order == null || order.length == 0) {
I have multiple chunks of code in separate areas where on any given page request i perform a few db connections. eg auth, page logic etc... I am finding that any related records (hasMany) seem to bomb out once db.close is called in any other separate area. Its like there is a singleton connection hiding in there somewhere.
My error (running mysql): "Error: Cannot enqueue Query after being destroyed."
Some code which I have thrown in to app.js createServer ...
_db.openAndSync(function(db) {
console.log('1 opened db and performed sync');
// get artist
db.Artist.get(1, function (err, artist) {
if (err) throw err;
console.log('1 artist from first get: ' + artist.name);
// get associated artist genres
artist.getGenre(function(err, artistGenres) {
if (err) throw err;
console.log('1 artist: ' + artist.name);
db.close(); // < close it
// lets try that again ...
_db.openAndSync(function(db) {
console.log('2 opened db and performed sync');
// get artist
db.Artist.get(1, function (err, artist) {
if (err) throw err;
console.log('2 artist from first get: ' + artist.name);
// get associated artist genres
artist.getGenre(function(err, artistGenres) {
if (err) throw err;
console.log('2 artist: ' + artist.name);
db.close(); // < close it
});
});
});
});
});
});
my output to console:
1 opened db and performed sync
1 artist from first get: The Testers1
1 artist: The Testers1
2 opened db and performed sync
2 artist from first get: The Testers1
Error: Cannot enqueue Query after being destroyed.
Note:
It would help so much if anyone could chime in. I'd like to keep my app having separate connections for each db hit as opposed to 1 long running connection.
Is there any way to turn on SSL for psql or is it planned?
I noticed that require('pg').native
may be required for this.
Hi,
Thank you very much for your work on this interresting project. It helps me a lot.
It seems there is a problem with ordering of query through many association after the conversion to sql-query using.
Regarding to #68 model definition following code produced error.
var Category = require('../models/Category');
exports.subcategories = function(req, res, next) {
Category(Number(req.params['category'])).getSuccessors({distance: 1},['name', 'A'], function(err, categories) {
res.json(categories);
});
}
Produced SQL Code
SELECT
*
FROM
`category` AS `t1`
JOIN `category_tree` AS `t2` ON `t2`.`successor_id` = `t1`.`id`
WHERE
(`t2`.`predecessor_id` = 7 AND `distance` = 1)
ORDER BY
`category.name` ASC
There is a table name used instead of table alias in order by clause.
With regards,
Kody
Hi,
Amazon Redshift is build on top of PostgresSQL. But some types and functions do not work. What do you think about make node-orm2 compatible with this new Database?
The limitations:
http://awsdocs.s3.amazonaws.com/redshift/latest/redshift-dg.pdf
Best regards
I have a find call which brings in rows of data just fine. I can modify the data and save it back and all data is perfect.
However if i call the find method > results output > then go and change from the database directly some value in those records > results are the same as the original output.
I can stop the node app and restart it and the new db change comes in. Its like a singleton instance is created and is caching the results.
Note: I have tried adding {cache: false} in my find call. No luck.
Can anyone replicate my issue? I'm running on mysql.
I read briefly through the source, and as it seems, you use the id as an indicator of whether to insert or update. In other words, if I am not mistaken, there is not a separate "update()" method, only a context-dependent "save()"
My problem is that in the app that I am writing, ids in one of the models, come from another web service, and are well defined. The problem is that whenever I want to save an item that I got from the web service, I will always do:
var m = new MyModel({id:webServiceResult.id, name:webServiceResult.name});
which will create a problem, since it does not yet exist in my DB, but ORM will consider it worthy for an update, because of the id. As a result, my data won't get saved.
Of course, I can follow your logic and introduce a simple auto-increasing ID, just for ORM, and leave the original ID in the table as "entityID". This will work, but will bring a bit of redundancy, and in general I am not a huge fan of it.
Of course, if there is nothing else I can do (I think overriding the "save" is also not a good idea), I will have to live with it for now. What do you think?
Right now all fields defined in the model are returned when using .find()
(or .getFriends()
from the associations example).
Sometimes only a few of those fields are enough. Right now I fix this by defining a "lite" version of model next to the original model but that's not something I think is quite feasible.
Additionally: sometimes (when using associations) it can happen that the relation table contains an extra field (one that does not exist in either of the two entities). It should also be possible to inject extra fields to be selected.
Hey, say I have a model like:
User = db.define('user',{
email: String
},{
validations: {
email: orm.validators.unique()
},
hooks: {
beforeSave: function() {
this.email = email.toLowerCase();
}
}
});
All is jolly, however:
user1 = db.models.user.new({email: '[email protected]'});
user1.save(...);
...
user2 = db.models.user.new({email: '[email protected]'});
user2.save(...);
We now have two duplicate users.
(I actually have a unique index on the table to prevent this, but it throws an ugly error when saving)
I can think of two ways of solving this:
beforeValidate
hook.I imagine it working something like this:
User = db.define('user',{
email: String
},{
setters: {
email: function(val) {
return val.toLowerCase();
}
}
});
Or maybe even more fancy:
User = db.define('user',{
email: String
},{
methods: {
email: {
set: function(val) {
this.setAttribute('email', val.toLowerCase());
}
}
}
});
where it defaults to the standard getter as one isn't specified, and setAttribute
calls the default setter.
What do you think?
I think it would be nice to be able to access associations as soon as I initialize an object, not when I fetch an object from the database. Let me give you an example:
Currently, if i want to fetch the orders of a person, whose ID is known to me (coming from a URL or something), I have to fetch the person from scratch, and only then do I have the option to fetch the associated orders to that person. That implies one additional SQL query, which in many cases can be avoided.
wouldn't it be more efficient if I could do:
var me = new models.Person({id:7})
me.getOrders( function(err, myOrders) { .... } ):
Internally, ORM will anyway use the id of the parent entity.
Hello,
is possible to add countAccessor to Many association?
Model
var db = config.db;
var Category = db.define('category', {
//properties
id : Number,
name : String
},{
//options
});
Category.hasMany("successors", {distance : Number}, Category, {reverse: 'predecessors', mergeTable: 'category_tree', mergeId: 'predecessor_id', mergeAssocId: 'successor_id'});
Controller
var Category = require('../models/Category');
exports.countSuccessors = function(req, res, next) {
category_id = Number(req.params['category']);
Category(category_id).countSuccessors({distance:1}, function (err, count) {
res.json(count);
});
}
when I try to query
A.getB, the next sql is generated:
select * from A left join A_B on... where A.id=...
but I need to select B records, not A, so generated query should looks like:
select * from B left join A_B on... where B.id=...
Storing all numbers in float format is not always good idea in my opinion. I suggest you to add an optional({type:'int'}) integer type.
I am new for GitHub, how can I contribute this project and suggest you some patches?
1: Just noticed when connecting to database provider cleardb as an addon to heroku I run in to a connection lost issue. After connecting approx 2 mins the message of "The server closed the connection" appears in console and the app dies.
It seems my only work around is to manually call db.close()
eg....
app.get('/test', function(req, res) {
orm.connect("mysql://123456789.cleardb.com/heroku_987654321?reconnect=true", function (err, db) {
if (err) throw err;
var Artist = db.define("artist", {
name: String
});
Artist.find({}, function(err, artists) {
res.send('hello world - ' + artists[0].name);
db.close(); // <-- i need to add this
});
});
});
2: should i be opening a new connection (and defining models) every time I wish to make a set of db calls within an express route? Or defining once for the whole app is acceptable (which would fail in my instance with cleardb)?
i have such relation:
table1:{table1_id,val}
table2:{table2_id,val}
table1_table2:{table1_id,table2_id,val}
when I create db.models.table1.hasMany('table2',{val:Number},opts) relation, my "val" field ignored.
So driver sync function part should looks like this:
...
params=opts.many_associations[i].props.map(function(prop){
...create field signature for table creation...
})
...
"CREATE TABLE IF NOT EXISTS " + driver.escapeId(opts.many_associations[i].mergeTable) +
" (" +
params.join(',')+
driver.escapeId(opts.many_associations[i].mergeId) + " INTEGER NOT NULL, " +
driver.escapeId(opts.many_associations[i].mergeAssocId) + " INTEGER NOT NULL" +
")",
Take Person.getFriends(function (err, friends) { ... });
from the examples for example. What if I want to filter out only the female friends? Right now one would loop the results and filter them there.
To be more efficient it'd be great to have a syntax like Person.getFriends({'gender': 'female'}, function (err, friends) { ... });
which filters them out in the query (less rows returned from the database).
The same syntax (arguments and arguments order) as Model.find()
would be ideal.
Hi,
I'm just coming up to speed with ORM2. Great work so far!
I'm curious why you chose to implement hasMany by relying on a third join table between the associated models? In Downstairs (the ORM I created but probably won't continue) I assumed that if a Foo hasMany Bars, then the Bar table would have a foreign key called foo_id.
https://github.com/nicholasf/downstairs.js/blob/master/lib/collection.js#L127
Cheers,
Nicholas
If a property on a model is not given a value the sql string in the builder is not generated correctly.
ie if no last name is given:
insert into customer (first_name, last_name, age)
values ('bob', , 36)
Would it be correct if I made a change to the code which inserted a null into the missing field. ie:
insert into customer (first_name, last_name, age)
values ('bob', null, 36)
Trying to solve tree heirarchy through orm.
CREATE TABLE `category` (
`id` int(11) NOT NULL,
`name` varchar(1024) COLLATE utf8_czech_ci NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `category_tree` (
`predecessor_id` int(11) NOT NULL,
`successor_id` int(11) NOT NULL,
`distance` int(11) NOT NULL,
PRIMARY KEY (`predecessor_id`,`successor_id`),
KEY `FK_category_tree_successor` (`successor_id`),
CONSTRAINT `FK_category_tree_predecessor` FOREIGN KEY (`predecessor_id`) REFERENCES `category` (`id`),
CONSTRAINT `FK_category_tree_successor` FOREIGN KEY (`successor_id`) REFERENCES `category` (`id`)
);
Defined model
var db = config.db;
var Category = db.define('category', {
//properties
id : Number,
name : String
},{
//options
});
Category.hasMany("successors", {distance : Number}, Category, {reverse: 'predecessors', mergeTable: 'category_tree', mergeId: 'predecessor_id', mergeAssocId: 'successor_id'});
Executing this:
Category(6).getSuccessors({distance: 1}, ['name', 'A'], function(err, categories) {
res.json(categories);
});
generates:
SELECT * FROM `category` WHERE `distance` = 1 AND `category_tree`.`predecessor_id` = 6 ORDER BY `name` ASC
Hi dresende,
i tried many nodejs libraries (sequelizejs, resourceful, tubbs,..) but this one is most promising i've seen - it's well designed to be engine agnostic, has query builder, model is prepared for bussiness logic (not so tied with orm).
Can i help with some parts to speedup development? plugins, fields, validation, engines.
Andrew
Hi,
Thanks a lot for this project. I was wondering if I'm doing something wrong here—I expect to be able to modify the properties of a model in beforeCreate
, but Postgres shows the following in the database:
id | email | password | salt | created
----+---------------------+----------+------+---------
1 | [email protected] | visible? | |
var orm = require('orm'),
bcrypt = require('bcrypt');
orm.connect('postgres://localhost/database', function (err, db) {
var Person = db.define('Person', {
email: String,
password: String,
salt: String,
created: Date
}, {
validations: {
email: orm.validators.unique()
},
hooks: {
beforeCreate: function () {
if (!this.salt) {
console.log('Generating salt...');
this.salt = bcrypt.genSaltSync(10);
this.created = new Date();
}
if (this.password) {
console.log('Hashing password...');
this.password = bcrypt.hashSync(this.password, this.salt);
}
}
}
});
// Person.sync(function (err) { console.log(err); });
Person.create([{
email: '[email protected]',
password: 'visible?'
}], function (err, items) {
console.log(err);
// console.log(items);
});
});
Testing with beforeSave
yields different results for me, too: the password gets hashed, but salt
and created
go unset in the database.
var order = db.define("order", {
...
confirmed:{type:"boolean", default: false},
}
The 'default' property was just a wild guess so I don't know if it's supported yet. And by the way, can you please point me to a list of available options to use when creating columns like this?
Thanks.
I am trying to update a model after doing get. I am getting the following error and not able to solve the issue. Please guide me in resolving the issue
Error: Cannot enqueue Query after invoking quit.
at Protocol._validateEnqueue (/home/os/workspace/cronservice/node_modules/mysql/lib/protocol/Protocol.js:115:16)
My observation: This occurs after find. Looks like mysql is closing connection before update.
Here is the snippet of what i am trying to do.
function(updateParams,errCallBack,updateJobCallBack){
var url = CONFIG.db+"://"+CONFIG.user+":"+CONFIG.password+"@"+CONFIG.server+":"+CONFIG.port+"/"+CONFIG.database;
orm.connect(url,function(err,db){
Job = db.define('cron_job', {
id: String,
pattern: String,
url: String,
identifier: String
});
Job.get(updateParams.jobId,function(err,job){
job.pattern = updateParams.pattern;
job.url = updateParams.url;
job.save(function(err2){
if(err2) errCallBack(err2);
});
updateJobCallBack(job);
db.close();
});
});
};
Note: I am new to nodejs
sync(function(err) { /*...*/ }
in release 2.0.4 does neither produce an error nor create the underlying tables. Reproducable by this snippet on PostgreSQL 9.0:
var orm = require('orm'),
config = require('../config');
orm.connect('postgresql://' +
config.database.username + ':' + config.database.password +
'@' + config.database.host + '/' + config.database.name,
function(err, db) {
if(err) console.error(err);
var Test = db.define('test', {
val1: String,
val2: Number,
val3: Boolean,
val4: [ 'A', 'B', 'C' ],
val5: Buffer
});
Test.sync(function(err) {
if(err) console.error(err);
else console.log('Test synced');
})
db.sync(function(err) {
if(err) console.error(err);
else console.log('Database synced');
});
}
);
Output:
Test synced
Database synced
The database exists and the user does have the rights to access it and create tables.
is there support for MongoDB?
Assume I have a main.js file and a models.js file in the same directory (same setup as in the documentation under Loading Models).
If my main.js file calls db.load('./models')
I'll get an error Error: Cannot find module './models'
That's because ORM.js
's load
function simply calls require(file)(this, cb);
. This, then, looks for a models.js
in ./node_modules/orm/lib/
.
Instead I can call db.load("../../../dbmodels")
to get it to work.
I'd be willing to submit a fix but I'm a little new to node and not really sure what the best course of action is. Any ideas? Or, if this is expected behavior then I'd like to update the documentation to make note of it.
Sorry if this is a stupid question, but: How do you create tables with node-orm2?
The original node-orm wiki mentions the .sync()
method for models, which would create all the necessary tables...
But this method doesn't seem to exist in node-orm2. Am I supposed to create my tables manually? If so, I need some more information, like what kind of naming convention node-orm2 expects for association tables and foreign key field names, etc. (Or does this documentation already exist somewhere?)
in Many.js Instance[association.mergeId] must be used instead of Instance.id:
options.extra_info = {
table: association.mergeTable,
id: Instance[association.mergeId],
id_prop: association.mergeId,
assoc_prop: association.mergeAssocId
};
if (conditions === null) {
conditions = {};
}
conditions[association.mergeTable + "." + association.mergeId] = Instance[association.mergeId];
I may have a hasMany from Person to Pet. But what about the reverse lookup of all persons associated to a single pet?
Person.getPet
and
Pet.getPersons??
or is this functionality not yet in the build...
Is this how should date fields be specified in models
var Person = db.define('person', {
name : String,
surname : String,
age : Number,
registered : Date
});
Consider these models:
var Movie = db.define('movies', {
id: Number,
title: String,
year: Number,
rating: Number
});
var Genre = db.define('genres', {
id: Number,
title: String
});
Movie.hasMany('genres', Genre); // link genres, no autofetch
When calling this piece of code (I'll name it snippet A, as I'll refer back to it later on) ...
Movie.find({}, 100, function(err, movies) {
// ...
}
... and then outputting movies
on screen in the callback
you get this dataset for example:
[
{
"id": 1,
"title": "Futurama: Bender's Big Score",
"year": 2007,
"rating": 7.6
},
{
"id": 2,
"title": "Futurama: The Beast with a Billion Backs",
"year": 2008,
"rating": 7.2,
}
]
When then calling a different URL on the app to fetch one single movie with genres ...
Movie.get(id, function(err, movie) {
movie.getGenres(function(err, genres) {
movie.genres = genres;
// ...
}
});
... we get back this when outputting movie
from within the second callback
{
"id": 1,
"title": "Futurama: Bender's Big Score",
"year": 2007,
"rating": 7.6,
"genres": [
{"id": 1, "title: "Animation"},
{"id": 2, "title: "Action"},
{"id": 3, "title: "Comedy"}
]
}
Now comes the kicker: when now visiting the URL that executes snippet A again, you get back this dataset:
[
{
"id": 1,
"title": "Futurama: Bender's Big Score",
"year": 2007,
"rating": 7.6,
"genres": [
{"id": 1, "title: "Animation"},
{"id": 2, "title: "Action"},
{"id": 3, "title: "Comedy"}
]
},
{
"id": 2,
"title": "Futurama: The Beast with a Billion Backs",
"year": 2008,
"rating": 7.2,
}
]
As you can see the genres mysteriously appear here now, which shouldn't be the case.
It's important to support clear separation of model logic and the natural way to do it is via node modules.
The db.load(..) function is how this problem is solved, as it can load model definitions that are in separate modules. The way it locates them, however, is limited. You have to directly specify an index like file that is in the same directory as the file making the db.load call:
orm.connect(env.connectionString, function(err, db){
db.load("./models/index", function (err) {
//...
});
});
It would be nice if db.load could work with the traditional loading sequence described here: http://nodejs.org/api/modules.html#modules_folders_as_modules
In other words, I should be able to do this:
orm.connect(env.connectionString, function(err, db){
db.load("./models/", function (err) {
//...
});
});
Where models/index.js would be loaded if it exists.
Would be nice if the connection pooling that is already built in the mysql module was exposed.
I am trying to make a small nodejs app run under osx (10.6.8), and connect to my localhost Postgres database. I am using node-orm (https://github.com/dresende/node-orm2) as well as the Postgres bindings (https://github.com/brianc/node-postgres).
For some reason, when I use orm.connect
and give it the connection url as a string, it fails with:
Error: getaddrinfo ENOENT at errnoException (dns.js:31:11) at Object.onanswer [as oncomplete] (dns.js:123:16)
If I change localhost with 127.0.0.1. it also dies with a timeout exception.
Using the vanilla postgress bindings to connect to the DB, using the same connection string is successful, and I even managed to get a few test queries running, got results, etc.
I tried to set up the DB client manually using the vanilla postgress api, an pass it on to orm using orm.use
. This manages to connect successfully to the DB, but every time I try to execute a query, nothing happens. It does not generate an error, but sinply gets stuck in the QueryQueue
and does not call the success callback. I checked the DB logs, and it seems that it has not detected the query either.
What do I do? I am a bit confused
I can't find anything in the documentation about setting associations when you first create an object. Is this supported?
For example...
var Person = db.define('person', { name: String })
var Pet = db.define('pet', { name: String })
Person.hasMany(pet);
var jake = new Person({ name: "Jake" });
jake.save(function(err) {
var smokey = new Pet({ name: "Smokey" });
smokey.save(function(err) {
// Is this logic supported / correct?
jake.addPet(smokey);
jake.save();
});
});
Any clarification would be appreciated. Thanks!
when table is empty, model.getAssociation returns error: [Error: write after end] but it should return an empty array with no errors as the empty result is correct result
When I'm trying to connect to sqlite database:
var orm = require('orm');
orm.connect('db',function (err,db) {
if (err) {
throw err;
}
res.render('index');
});
It gets me an error
500 TypeError: Cannot call method 'replace' of undefined
at Object.exports.connect (D:\Dropbox\sites\myblog\node_modules\orm\lib\ORM.js:49:29)
It seems there are some issues related to this property type. I'm going to post some commits and relate them to this issue.
var Artist = db.define("artist", {
name: String,
});
Artist.hasMany("genres", Genre);
var Genre = db.define("genre", {
name: String
});
... calling getGenres doesn't return the many related genre records. Instead returns an object of the parent artist:
db.Artist.get(req.params.id, function (err, artist) {
artist.getGenres(function(err, genres) {
Looks like the context of escape is incorrect when this.escape
is called at line 120 of lib/sql/Select.js and therefore the timezone can't be read from the config.
Binding the escape function fixed it for the mysql driver, changing this to this:
var escapes = {
escape : this.db.escape.bind(this.db),
escapeId : escapeId
};
Not sure if there's any other issues with that or if you want to take a different approach.
Thanks
Well, i tried to add support for JSON type, and it needs both conversions - before save and after load. Property.js is global for all engines, so i was looking for engine related place. I think same situation will be with dates or boolean (some engines support bool, mysql not) etc.
Functions convertToValue and convertFromValue could be in:
I think first one is better.
Tables and relationships are created however primary key on id is not set.
Is it possible to do BETWEEN queries with the current code or would I need to develop new code to do this?
When inserting a record into Postgres the primary key (serial) id is not returned.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.