mirror of https://github.com/nocodb/nocodb
oof1lab
7 years ago
commit
67515e05df
13 changed files with 6899 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||||||
|
{ |
||||||
|
"parserOptions": { |
||||||
|
"ecmaVersion": 6 |
||||||
|
}, |
||||||
|
"rules": { |
||||||
|
"eol-last": "error", |
||||||
|
"indent": ["error", 2, { "SwitchCase": 1 }], |
||||||
|
"no-trailing-spaces": "error", |
||||||
|
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }] |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
# OS |
||||||
|
# =========== |
||||||
|
.DS_Store |
||||||
|
ehthumbs.db |
||||||
|
Icon? |
||||||
|
Thumbs.db |
||||||
|
|
||||||
|
# Node and related ecosystem |
||||||
|
# ========================== |
||||||
|
.nodemonignore |
||||||
|
.sass-cache/ |
||||||
|
node_modules/ |
||||||
|
help/ |
||||||
|
a |
||||||
|
public/lib/ |
||||||
|
app/tests/coverage/ |
||||||
|
.bower-*/ |
||||||
|
.idea/ |
||||||
|
coverage/ |
||||||
|
|
||||||
|
# MEAN.js app and assets |
||||||
|
# ====================== |
||||||
|
public/dist/ |
||||||
|
uploads |
||||||
|
modules/users/client/img/profile/uploads |
||||||
|
config/env/local.js |
||||||
|
*.pem |
||||||
|
|
||||||
|
# Ignoring MEAN.JS's gh-pages branch for documenation |
||||||
|
_site/ |
||||||
|
|
||||||
|
# General |
||||||
|
# ======= |
||||||
|
*.log |
||||||
|
*.csv |
||||||
|
*.dat |
||||||
|
*.out |
||||||
|
*.pid |
||||||
|
*.gz |
||||||
|
*.tmp |
||||||
|
*.bak |
||||||
|
*.swp |
||||||
|
logs/ |
||||||
|
build/ |
||||||
|
uploads/ |
||||||
|
|
||||||
|
# Sublime editor |
||||||
|
# ============== |
||||||
|
.sublime-project |
||||||
|
*.sublime-project |
||||||
|
*.sublime-workspace |
||||||
|
|
||||||
|
# Eclipse project files |
||||||
|
# ===================== |
||||||
|
.project |
||||||
|
.settings/ |
||||||
|
.*.md.html |
||||||
|
.metadata |
||||||
|
*~.nib |
||||||
|
local.properties |
||||||
|
|
||||||
|
# IntelliJ |
||||||
|
# ======== |
||||||
|
*.iml |
||||||
|
|
||||||
|
# Cloud9 IDE |
||||||
|
# ========= |
||||||
|
.c9/ |
||||||
|
data/ |
||||||
|
mongod |
||||||
|
|
||||||
|
# Visual Studio |
||||||
|
# ========= |
||||||
|
*.suo |
||||||
|
*.ntvs* |
||||||
|
*.njsproj |
||||||
|
*.sln |
@ -0,0 +1,146 @@ |
|||||||
|
# xmysql: one command to generate REST APIs for **any** MySql database |
||||||
|
|
||||||
|
> Requires node >= 7.6.0 |
||||||
|
|
||||||
|
## Why this ? |
||||||
|
Deriving REST APIs for a database which do not follow conventions of frameworks such as rails, django etc |
||||||
|
is like a small adventure .. |
||||||
|
|
||||||
|
<p align="center"> |
||||||
|
<img src="https://media.giphy.com/media/8gWrk3QZrjF1C/giphy.gif" alt="Rick & Morty"/> |
||||||
|
</p> |
||||||
|
|
||||||
|
Hence this. |
||||||
|
|
||||||
|
Powered by node packages : (express, mysql) => { xmysql } |
||||||
|
|
||||||
|
## FEATURES |
||||||
|
* Generates API for **ANY** MySql database |
||||||
|
* Serves APIs irrespective of naming conventions of primary keys, foreign keys, tables etc |
||||||
|
* CRUD : Usual suspects |
||||||
|
* Support for composite primary keys |
||||||
|
* Pagination |
||||||
|
* Sorting |
||||||
|
* Fields |
||||||
|
* Relations |
||||||
|
* Run dynamic queries |
||||||
|
|
||||||
|
## Sample usage |
||||||
|
* npm install -g xmysql |
||||||
|
* xmysql -h localhost -u mysqlUsername -p mysqlPassword -d databaseName |
||||||
|
* [http://localhost:3000](#http://localhost:3000) |
||||||
|
|
||||||
|
|
||||||
|
Run HTTP client [Postman](https://www.getpostman.com/) or [similar tools](https://chrome.google.com/webstore/search/http%20client?_category=apps) to invoke REST API calls |
||||||
|
|
||||||
|
## CRUD APIs Usual Suspects |
||||||
|
* GET /api/:tableName |
||||||
|
* POST /api/:tableName |
||||||
|
* GET /api/:tableName/:id |
||||||
|
* PUT /api/:tableName/:id |
||||||
|
* GET /api/:tableName/count |
||||||
|
* GET /api/:tableName/exists |
||||||
|
* GET /api/:parentTable/:id/:childTable |
||||||
|
* DELETE /api/:tableName/:id |
||||||
|
* POST /dynamic |
||||||
|
|
||||||
|
## Other APIS |
||||||
|
* GET /api/:tableName/describe |
||||||
|
* GET /api/tables |
||||||
|
|
||||||
|
## Support for composite primary keys |
||||||
|
|
||||||
|
#### ___ (three underscores) |
||||||
|
|
||||||
|
``` |
||||||
|
/api/payments/103___JM555205 |
||||||
|
``` |
||||||
|
*___* : If there are multiple primary keys - seperate them by three underscores as shown |
||||||
|
|
||||||
|
## Pagination |
||||||
|
|
||||||
|
#### _p & _size |
||||||
|
|
||||||
|
_p indicates page and _size indicates size of response rows |
||||||
|
|
||||||
|
By default 20 records and max of 100 are returned per GET request on a table. |
||||||
|
|
||||||
|
``` |
||||||
|
/api/payments?_size=50 |
||||||
|
``` |
||||||
|
``` |
||||||
|
/api/payments?_p=2 |
||||||
|
``` |
||||||
|
``` |
||||||
|
/api/payments?_p=2&_size=50 |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
## Sorting |
||||||
|
|
||||||
|
#### _sort |
||||||
|
|
||||||
|
``` |
||||||
|
/api/payments?_sort=column1 |
||||||
|
``` |
||||||
|
eg: sorts ascending by column1 |
||||||
|
|
||||||
|
``` |
||||||
|
/api/payments?_sort=-column1 |
||||||
|
``` |
||||||
|
eg: sorts descending by column1 |
||||||
|
|
||||||
|
``` |
||||||
|
/api/payments?_sort=column1,-column2 |
||||||
|
``` |
||||||
|
eg: sorts ascending by column1 and descending by column2 |
||||||
|
|
||||||
|
|
||||||
|
## Fields |
||||||
|
``` |
||||||
|
/api/payments?_fields=customerNumber,checkNumber |
||||||
|
``` |
||||||
|
eg: gets only customerNumber and checkNumber in response of each record |
||||||
|
``` |
||||||
|
/api/payments?_fields=-checkNumber |
||||||
|
``` |
||||||
|
eg: gets all fields in table row but not checkNumber |
||||||
|
|
||||||
|
|
||||||
|
## Run dynamic queries |
||||||
|
Dynamic queries on a database can be run by POST method to URL localhost:3000/dynamic |
||||||
|
|
||||||
|
This is enabled only in local i.e -h localhost or -h 127.0.0.1 option. |
||||||
|
|
||||||
|
Post body takes two fields : query and params. |
||||||
|
|
||||||
|
>query: SQL query or SQL prepared query (ones with ?? and ?) |
||||||
|
|
||||||
|
>params : parameters for SQL prepared query |
||||||
|
``` |
||||||
|
POST /dynamic |
||||||
|
|
||||||
|
{ |
||||||
|
"query": "select * from ?? limit 1,20", |
||||||
|
"params": ["customers"] |
||||||
|
} |
||||||
|
``` |
||||||
|
## Relational Tables |
||||||
|
xmysql identifies foreign key relations automatically and provides GET api. |
||||||
|
``` |
||||||
|
/api/customers/103/payments |
||||||
|
``` |
||||||
|
eg: Customers is parent table and payments is child table. API invocation will result in all payments with customer 103. |
||||||
|
|
||||||
|
|
||||||
|
## When to use ? |
||||||
|
* You need REST APIs without much hassle for (ANY) MySql database |
||||||
|
* You are learning new frontend frameworks and need REST APIs for your MySql database. |
||||||
|
* You are working on a demo, hacks etc |
||||||
|
|
||||||
|
## When NOT to use ? |
||||||
|
* Other times not mentioned in when to use section |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,39 @@ |
|||||||
|
#! /usr/bin/env node
|
||||||
|
|
||||||
|
const morgan = require('morgan'); |
||||||
|
const bodyParser = require('body-parser'); |
||||||
|
const express = require('express'); |
||||||
|
const sqlConfig = require('commander'); |
||||||
|
const mysql = require('mysql'); |
||||||
|
|
||||||
|
const Xapi = require('../lib/xapi.js'); |
||||||
|
const cmdargs = require('../lib/util/cmd.helper.js'); |
||||||
|
|
||||||
|
cmdargs.handle(sqlConfig) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************** START : setup express ****************/ |
||||||
|
let app = express(); |
||||||
|
app.use(morgan('tiny')) |
||||||
|
app.use(bodyParser.json()) |
||||||
|
app.use(bodyParser.urlencoded({ |
||||||
|
extended: true |
||||||
|
})) |
||||||
|
/**************** END : setup express ****************/ |
||||||
|
|
||||||
|
|
||||||
|
/**************** START : setup mysql ****************/ |
||||||
|
let mysqlPool = mysql.createPool(sqlConfig); |
||||||
|
/**************** END : setup mysql ****************/ |
||||||
|
|
||||||
|
|
||||||
|
/**************** START : setup Xapi ****************/ |
||||||
|
let moreApis = new Xapi(sqlConfig,mysqlPool,app); |
||||||
|
|
||||||
|
moreApis.init((err, results) => { |
||||||
|
|
||||||
|
app.listen(sqlConfig.portNumber) |
||||||
|
|
||||||
|
}) |
||||||
|
/**************** END : setup Xapi ****************/ |
@ -0,0 +1,39 @@ |
|||||||
|
#! /usr/bin/env node
|
||||||
|
|
||||||
|
const morgan = require('morgan'); |
||||||
|
const bodyParser = require('body-parser'); |
||||||
|
const express = require('express'); |
||||||
|
const sqlConfig = require('commander'); |
||||||
|
const mysql = require('mysql'); |
||||||
|
|
||||||
|
const Xapi = require('./lib/xapi.js'); |
||||||
|
const cmdargs = require('./lib/util/cmd.helper.js'); |
||||||
|
|
||||||
|
cmdargs.handle(sqlConfig) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************** START : setup express ****************/ |
||||||
|
let app = express(); |
||||||
|
app.use(morgan('tiny')) |
||||||
|
app.use(bodyParser.json()) |
||||||
|
app.use(bodyParser.urlencoded({ |
||||||
|
extended: true |
||||||
|
})) |
||||||
|
/**************** END : setup express ****************/ |
||||||
|
|
||||||
|
|
||||||
|
/**************** START : setup mysql ****************/ |
||||||
|
let mysqlPool = mysql.createPool(sqlConfig); |
||||||
|
/**************** END : setup mysql ****************/ |
||||||
|
|
||||||
|
|
||||||
|
/**************** START : setup Xapi ****************/ |
||||||
|
let moreApis = new Xapi(sqlConfig,mysqlPool,app); |
||||||
|
|
||||||
|
moreApis.init((err, results) => { |
||||||
|
|
||||||
|
app.listen(sqlConfig.portNumber) |
||||||
|
|
||||||
|
}) |
||||||
|
/**************** END : setup Xapi ****************/ |
@ -0,0 +1,70 @@ |
|||||||
|
'use strict'; |
||||||
|
const program = require('commander'); |
||||||
|
const colors = require('colors'); |
||||||
|
|
||||||
|
program.on('--help', () => { |
||||||
|
console.log('') |
||||||
|
console.log(' Examples:'.blue) |
||||||
|
console.log('') |
||||||
|
console.log(' $ xmysql -u username -p password -d databaseSchema'.blue) |
||||||
|
console.log('') |
||||||
|
}) |
||||||
|
|
||||||
|
program |
||||||
|
.version('0.0.2') |
||||||
|
.option('-h, --host <n>', 'hostname') |
||||||
|
.option('-d, --database <n>', 'database schema name') |
||||||
|
.option('-u, --user <n>', 'username of database / root by default') |
||||||
|
.option('-p, --password <n>', 'password of database / empty by default') |
||||||
|
.option('-n, --portNumber <n>', 'port number : 3000 by default') |
||||||
|
.parse(process.argv) |
||||||
|
|
||||||
|
|
||||||
|
function paintHelp(txt) { |
||||||
|
return colors.magenta(txt) //display the help text in a color
|
||||||
|
} |
||||||
|
|
||||||
|
function processInvalidArguments(program) { |
||||||
|
|
||||||
|
let err = ''; |
||||||
|
|
||||||
|
if (!program.password) { |
||||||
|
err += 'Error: password for database is missing\n'; |
||||||
|
} |
||||||
|
|
||||||
|
if (!program.database) { |
||||||
|
err += 'Error: database name is missing\n'; |
||||||
|
} |
||||||
|
|
||||||
|
if (err !== '') { |
||||||
|
program.outputHelp(paintHelp) |
||||||
|
console.log(err.red) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
exports.handle = program => { |
||||||
|
|
||||||
|
/**************** START : default values ****************/ |
||||||
|
program.portNumber = program.portNumber || 3000; |
||||||
|
program.user = program.user || 'root'; |
||||||
|
program.password = program.password || ''; |
||||||
|
program.host = program.host || 'localhost'; |
||||||
|
|
||||||
|
|
||||||
|
program.connectionLimit = 10; |
||||||
|
|
||||||
|
if (program.host === 'localhost' || program.host === '127.0.0.1') { |
||||||
|
program.dynamic = 1 |
||||||
|
} |
||||||
|
//console.log(program.rawArgs);
|
||||||
|
/**************** END : default values ****************/ |
||||||
|
|
||||||
|
|
||||||
|
if (program.database && program.host && program.user) { |
||||||
|
console.log('Starting server at:', 'http://'+program.host + ':' + program.portNumber) |
||||||
|
} else { |
||||||
|
processInvalidArguments(program) |
||||||
|
process.exit(1) |
||||||
|
} |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,63 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
exports.findOrInsertObjectArrayByKey = (obj, key, array) => { |
||||||
|
|
||||||
|
let found = 0; |
||||||
|
let i = 0; |
||||||
|
|
||||||
|
for (i = 0; i < array.length; ++i) { |
||||||
|
if (key in array[i]) { |
||||||
|
if (obj[key] === array[i][key]) { |
||||||
|
found = 1; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!found) { |
||||||
|
array.push(obj) |
||||||
|
} |
||||||
|
|
||||||
|
return array[i]; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
exports.findObjectInArrayByKey = (key, value, objArray) => { |
||||||
|
|
||||||
|
for (let i = 0; i < objArray.length; ++i) { |
||||||
|
if (objArray[i][key] === value) { |
||||||
|
return objArray[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
exports.getSchemaQuery = function () { |
||||||
|
return 'select c.table_name, c.column_name, c.ordinal_position,c.column_key,c.is_nullable, c.data_type, c.column_type,c.extra,c.privileges, ' + |
||||||
|
'c.column_comment,c.column_default,c.data_type,c.character_maximum_length, ' + |
||||||
|
'c.character_octet_length,c.numeric_precision,c.numeric_scale,c.datetime_precision,c.character_set_name, ' + |
||||||
|
'c.collation_name, ' + |
||||||
|
'k.constraint_name, k.referenced_table_name, k.referenced_column_name, ' + |
||||||
|
's.index_name,s.seq_in_index ' + |
||||||
|
'from ' + |
||||||
|
'information_schema.columns as c ' + |
||||||
|
'left join ' + |
||||||
|
'information_schema.key_column_usage as k ' + |
||||||
|
'on ' + |
||||||
|
'c.column_name=k.column_name and ' + |
||||||
|
'c.table_schema = k.referenced_table_schema and ' + |
||||||
|
'c.table_name = k.table_name ' + |
||||||
|
'left join ' + |
||||||
|
'information_schema.statistics as s ' + |
||||||
|
'on ' + |
||||||
|
'c.column_name = s.column_name and ' + |
||||||
|
'c.table_schema = s.index_schema and ' + |
||||||
|
'c.table_name = s.table_name ' + |
||||||
|
'where ' + |
||||||
|
'c.table_schema=? ' + |
||||||
|
'order by ' + |
||||||
|
'c.table_name, c.ordinal_position'; |
||||||
|
}; |
@ -0,0 +1,324 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
var Xsql = require('./xsql.js'); |
||||||
|
|
||||||
|
//define class
|
||||||
|
class Xapi { |
||||||
|
|
||||||
|
constructor(args, mysqlPool, app) { |
||||||
|
|
||||||
|
this.sqlConfig = args; |
||||||
|
this.mysql = new Xsql(args, mysqlPool) |
||||||
|
this.app = app; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
init(cbk) { |
||||||
|
|
||||||
|
this.mysql.init((err, results) => { |
||||||
|
|
||||||
|
this.setupRoutes() |
||||||
|
this.app.use(this.errorMiddleware) |
||||||
|
cbk(err, results) |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
errorMiddleware(err, req, res, next) { |
||||||
|
|
||||||
|
if(err && err.code) |
||||||
|
res.status(400).json({error: err}); |
||||||
|
else |
||||||
|
res.status(500).json({error: 'Internal server error : ' + err.message}); |
||||||
|
|
||||||
|
next(err); |
||||||
|
} |
||||||
|
|
||||||
|
asyncMiddleware(fn) { |
||||||
|
return (req, res, next) => { |
||||||
|
Promise.resolve(fn(req, res, next)) |
||||||
|
.catch((err) => { |
||||||
|
next(err); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
root(req, res) { |
||||||
|
|
||||||
|
//res.sendFile(path + "index.html")
|
||||||
|
let v = []; |
||||||
|
|
||||||
|
v = this.mysql.getSchemaRoutes(req.protocol + '://' + req.get('host') + '/api/'); |
||||||
|
v = v.concat(this.mysql.globalRoutesPrint(req.protocol + '://' + req.get('host') + '/api/')) |
||||||
|
|
||||||
|
res.json(v) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
setupRoutes() { |
||||||
|
|
||||||
|
this.app.get('/', this.asyncMiddleware(this.root.bind(this))) |
||||||
|
|
||||||
|
/**************** START : tables apis ****************/ |
||||||
|
this.app.route('/api/tables') |
||||||
|
.get(this.asyncMiddleware(this.tables.bind(this))); |
||||||
|
|
||||||
|
this.app.route('/api/:tableName/describe') |
||||||
|
.get(this.asyncMiddleware(this.tableDescribe.bind(this))); |
||||||
|
/**************** END : tables apis ****************/ |
||||||
|
|
||||||
|
|
||||||
|
/**************** START : basic apis ****************/ |
||||||
|
this.app.route('/api/:tableName/count') |
||||||
|
.get(this.asyncMiddleware(this.count.bind(this))); |
||||||
|
|
||||||
|
this.app.route('/api/:tableName') |
||||||
|
.get(this.asyncMiddleware(this.list.bind(this))) |
||||||
|
.post(this.asyncMiddleware(this.create.bind(this))); |
||||||
|
|
||||||
|
this.app.route('/api/:tableName/:id') |
||||||
|
.get(this.asyncMiddleware(this.read.bind(this))) |
||||||
|
.put(this.asyncMiddleware(this.update.bind(this))) |
||||||
|
.delete(this.asyncMiddleware(this.delete.bind(this))); |
||||||
|
|
||||||
|
this.app.route('/api/:tableName/:id/exists') |
||||||
|
.get(this.asyncMiddleware(this.exists.bind(this))); |
||||||
|
|
||||||
|
this.app.route('/api/:parentTable/:id/:childTable') |
||||||
|
.get(this.asyncMiddleware(this.nestedList.bind(this))); |
||||||
|
/**************** END : basic apis ****************/ |
||||||
|
|
||||||
|
if (this.sqlConfig.dynamic === 1) { |
||||||
|
|
||||||
|
this.app.route('/dynamic*') |
||||||
|
.post(this.asyncMiddleware(this.runQuery.bind(this))); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async create(req, res) { |
||||||
|
|
||||||
|
let query = 'INSERT INTO ?? SET ?'; |
||||||
|
let params = []; |
||||||
|
|
||||||
|
params.push(req.params.tableName); |
||||||
|
params.push(req.body); |
||||||
|
|
||||||
|
var results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async list(req, res) { |
||||||
|
|
||||||
|
let cols = this.mysql.getColumnsForSelectStmt(req.params.tableName, req.query); |
||||||
|
let query = 'select ' + cols + ' from ?? '; |
||||||
|
let params = []; |
||||||
|
params.push(req.params.tableName); |
||||||
|
|
||||||
|
query = query + this.mysql.getOrderByClause(req.query, req.params.tableName); |
||||||
|
|
||||||
|
query = query + ' limit ?,? ' |
||||||
|
params = params.concat(this.mysql.getLimitClause(req.query)); |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async nestedList(req, res) { |
||||||
|
|
||||||
|
let cols = this.mysql.getColumnsForSelectStmt(req.params.childTable, req.query); |
||||||
|
let query = 'select ' + cols + ' from ?? where '; |
||||||
|
let params = []; |
||||||
|
|
||||||
|
params.push(req.params.childTable); |
||||||
|
|
||||||
|
let whereClause = this.mysql.getForeignKeyWhereClause(req.params.parentTable, |
||||||
|
req.params.id, |
||||||
|
req.params.childTable); |
||||||
|
|
||||||
|
if (!whereClause) { |
||||||
|
return res.status(400).send({ |
||||||
|
error: "Table is made of composite primary keys - all keys were not in input" |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
query += whereClause; |
||||||
|
|
||||||
|
query = query + this.mysql.getOrderByClause(req.query, req.params.parentTable); |
||||||
|
|
||||||
|
query = query + ' limit ?,? ' |
||||||
|
params = params.concat(this.mysql.getLimitClause(req.query)); |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async read(req, res) { |
||||||
|
|
||||||
|
let query = 'select * from ?? where '; |
||||||
|
let params = []; |
||||||
|
|
||||||
|
params.push(req.params.tableName); |
||||||
|
|
||||||
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
||||||
|
req.params.id.split('___')); |
||||||
|
|
||||||
|
|
||||||
|
if (!clause) { |
||||||
|
return res.status(400).send({ |
||||||
|
error: "Table is made of composite primary keys - all keys were not in input" |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
query += clause; |
||||||
|
query += ' LIMIT 1' |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async exists(req, res) { |
||||||
|
|
||||||
|
let query = 'select * from ?? where '; |
||||||
|
let params = []; |
||||||
|
|
||||||
|
params.push(req.params.tableName); |
||||||
|
|
||||||
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
||||||
|
req.params.id.split('___')); |
||||||
|
|
||||||
|
if (!clause) { |
||||||
|
return res.status(400).send({ |
||||||
|
error: "Table is made of composite primary keys - all keys were not in input" |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
query += clause; |
||||||
|
query += ' LIMIT 1' |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async update(req, res) { |
||||||
|
|
||||||
|
let query = 'UPDATE ?? SET '; |
||||||
|
let keys = Object.keys(req.body); |
||||||
|
|
||||||
|
// SET clause
|
||||||
|
let updateKeys = ''; |
||||||
|
for (let i = 0; i < keys.length; ++i) { |
||||||
|
updateKeys += keys[i] + ' = ? ' |
||||||
|
if (i !== keys.length - 1) |
||||||
|
updateKeys += ', ' |
||||||
|
} |
||||||
|
|
||||||
|
// where clause
|
||||||
|
query += updateKeys + ' where ' |
||||||
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
||||||
|
req.params.id.split('___')); |
||||||
|
|
||||||
|
if (!clause) { |
||||||
|
return res.status(400).send({ |
||||||
|
error: "Table is made of composite primary keys - all keys were not in input" |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
query += clause; |
||||||
|
|
||||||
|
// params
|
||||||
|
let params = []; |
||||||
|
params.push(req.params.tableName); |
||||||
|
params = params.concat(Object.values(req.body)); |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async delete(req, res) { |
||||||
|
|
||||||
|
let query = 'DELETE FROM ?? WHERE '; |
||||||
|
let params = []; |
||||||
|
|
||||||
|
params.push(req.params.tableName); |
||||||
|
|
||||||
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
||||||
|
req.params.id.split('___')); |
||||||
|
|
||||||
|
if (!clause) { |
||||||
|
return res.status(400).send({ |
||||||
|
error: "Table is made of composite primary keys - all keys were not in input" |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
query += clause; |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async count(req, res) { |
||||||
|
|
||||||
|
let query = 'select count(1) as no_of_rows from ??'; |
||||||
|
let params = []; |
||||||
|
|
||||||
|
params.push(req.params.tableName); |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async tables(req, res) { |
||||||
|
|
||||||
|
let query = 'show tables'; |
||||||
|
let params = []; |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params) |
||||||
|
res.status(200).json(results) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async runQuery(req, res) { |
||||||
|
|
||||||
|
let query = req.body.query; |
||||||
|
let params = req.body.params; |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
async tableDescribe(req, res) { |
||||||
|
|
||||||
|
let query = 'describe ??'; |
||||||
|
let params = [req.params.tableName]; |
||||||
|
|
||||||
|
let results = await this.mysql.exec(query, params); |
||||||
|
res.status(200).json(results); |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
//expose class
|
||||||
|
module.exports = Xapi; |
||||||
|
|
@ -0,0 +1,463 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const mysql = require('mysql'); |
||||||
|
const dataHelp = require('./util/data.helper.js'); |
||||||
|
const assert = require('assert') |
||||||
|
|
||||||
|
//define class
|
||||||
|
class Xsql { |
||||||
|
|
||||||
|
constructor(sqlConfig, pool) { |
||||||
|
|
||||||
|
//define this variables
|
||||||
|
this.sqlConfig = {} |
||||||
|
this.pool = {} |
||||||
|
this.metaDb = {}; |
||||||
|
this.metaDb.tables = {}; |
||||||
|
|
||||||
|
this.sqlConfig = sqlConfig; |
||||||
|
this.pool = pool; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
init(cbk) { |
||||||
|
this.dbCacheInitAsync((err, results) => { |
||||||
|
cbk(err, results) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
dbCacheInitAsync(cbk) { |
||||||
|
|
||||||
|
let self = this; |
||||||
|
|
||||||
|
self.pool.query(dataHelp.getSchemaQuery(), [this.sqlConfig.database], (err, results) => { |
||||||
|
|
||||||
|
if (err) { |
||||||
|
console.log('Cache init failed during database reading') |
||||||
|
console.log(err, results) |
||||||
|
cbk(err, results) |
||||||
|
} else { |
||||||
|
|
||||||
|
self.iterateToCacheTables(results) |
||||||
|
self.iterateToCacheTablePks(results) |
||||||
|
self.iterateToCacheTableColumns(results) |
||||||
|
self.iterateToCacheTableFks(results) |
||||||
|
|
||||||
|
// osx mysql server has limitations related to open_tables
|
||||||
|
self.pool.query('FLUSH TABLES', [], (err, results) => { |
||||||
|
cbk(null, null) |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
iterateToCacheTables(schemaResults) { |
||||||
|
|
||||||
|
for (let i = 0; i < schemaResults.length; ++i) { |
||||||
|
|
||||||
|
let schemaRow = schemaResults[i]; |
||||||
|
|
||||||
|
let tableName = schemaRow['table_name']; |
||||||
|
|
||||||
|
if (!(tableName in this.metaDb.tables)) { |
||||||
|
this.metaDb.tables[tableName] = {} |
||||||
|
this.metaDb.tables[tableName]['primaryKeys'] = [] |
||||||
|
this.metaDb.tables[tableName]['foreignKeys'] = [] |
||||||
|
this.metaDb.tables[tableName]['columns'] = [] |
||||||
|
this.metaDb.tables[tableName]['indicies'] = [] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
iterateToCacheTableColumns(schemaResults) { |
||||||
|
|
||||||
|
for (let i = 0; i < schemaResults.length; ++i) { |
||||||
|
let schemaRow = schemaResults[i]; |
||||||
|
let tableName = schemaRow['table_name']; |
||||||
|
let col = {}; |
||||||
|
col['column_name'] = schemaRow['column_name'] |
||||||
|
col['ordinal_position'] = schemaRow['ordinal_position'] |
||||||
|
col['column_key'] = schemaRow['column_key'] |
||||||
|
col['data_type'] = schemaRow['data_type'] |
||||||
|
col['column_type'] = schemaRow['column_type'] |
||||||
|
|
||||||
|
dataHelp.findOrInsertObjectArrayByKey(col, 'column_name', this.metaDb.tables[tableName]['columns']) |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
iterateToCacheTablePks(schemaResults) { |
||||||
|
|
||||||
|
for (let i = 0; i < schemaResults.length; ++i) { |
||||||
|
let schemaRow = schemaResults[i]; |
||||||
|
let tableName = schemaRow['table_name']; |
||||||
|
|
||||||
|
if (schemaRow['column_key'] === 'PRI') { |
||||||
|
|
||||||
|
let pk = {}; |
||||||
|
pk['column_name'] = schemaRow['column_name'] |
||||||
|
pk['ordinal_position'] = schemaRow['ordinal_position'] |
||||||
|
pk['column_key'] = schemaRow['column_key'] |
||||||
|
pk['data_type'] = schemaRow['data_type'] |
||||||
|
pk['column_type'] = schemaRow['column_type'] |
||||||
|
|
||||||
|
dataHelp.findOrInsertObjectArrayByKey(pk, 'column_name', this.metaDb.tables[tableName]['primaryKeys']) |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
iterateToCacheTableFks(schemaResults) { |
||||||
|
|
||||||
|
for (let i = 0; i < schemaResults.length; ++i) { |
||||||
|
|
||||||
|
let schemaRow = schemaResults[i]; |
||||||
|
let tableName = schemaRow['table_name']; |
||||||
|
|
||||||
|
if (schemaRow['referenced_table_name']) { |
||||||
|
|
||||||
|
let fk = {}; |
||||||
|
|
||||||
|
fk['column_name'] = schemaRow['column_name'] |
||||||
|
fk['table_name'] = schemaRow['table_name'] |
||||||
|
fk['referenced_table_name'] = schemaRow['referenced_table_name'] |
||||||
|
fk['referenced_column_name'] = schemaRow['referenced_column_name'] |
||||||
|
fk['data_type'] = schemaRow['data_type'] |
||||||
|
fk['column_type'] = schemaRow['column_type'] |
||||||
|
|
||||||
|
dataHelp.findOrInsertObjectArrayByKey(fk, 'column_name', this.metaDb.tables[tableName]['foreignKeys']) |
||||||
|
|
||||||
|
//console.log(fk['referenced_table_name'],fk['referenced_column_name'],tableName, schemaRow['column_name'], this.metaDb.tables[tableName]['foreignKeys'].length)
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
exec(query, params) { |
||||||
|
|
||||||
|
let _this = this; |
||||||
|
return new Promise(function (resolve, reject) { |
||||||
|
//console.log('mysql>', query, params);
|
||||||
|
_this.pool.query(query, params, function (error, rows, _fields) { |
||||||
|
if (error) { |
||||||
|
console.log('mysql> ', error); |
||||||
|
return reject(error); |
||||||
|
} |
||||||
|
return resolve(rows); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
getLimitClause(reqParams) { |
||||||
|
|
||||||
|
//defaults
|
||||||
|
reqParams._index = 0; |
||||||
|
reqParams._len = 20; |
||||||
|
|
||||||
|
if ('_size' in reqParams && parseInt(reqParams._size) < 100) { |
||||||
|
reqParams._len = parseInt(reqParams._size) |
||||||
|
} |
||||||
|
|
||||||
|
if ('_p' in reqParams && parseInt(reqParams._p) > 0) { |
||||||
|
reqParams._index = (parseInt(reqParams._p)-1) * reqParams._len + 1; |
||||||
|
} |
||||||
|
|
||||||
|
//console.log(reqParams._index, reqParams._len);
|
||||||
|
|
||||||
|
return [reqParams._index, reqParams._len] |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
getOrderByClause(queryparams, tableName) { |
||||||
|
|
||||||
|
//defaults
|
||||||
|
let orderBy = ''; |
||||||
|
|
||||||
|
if (queryparams._sort) { |
||||||
|
|
||||||
|
orderBy += ' ORDER BY ' |
||||||
|
|
||||||
|
let orderByCols = queryparams._sort.split(',') |
||||||
|
|
||||||
|
for (let i = 0; i < orderByCols.length; ++i) { |
||||||
|
if (i) { |
||||||
|
orderBy = orderBy + ', ' |
||||||
|
} |
||||||
|
if (orderByCols[i][0] === '-') { |
||||||
|
let len = orderByCols[i].length; |
||||||
|
orderBy = orderBy + orderByCols[i].substring(1, len) + ' DESC' |
||||||
|
} else { |
||||||
|
orderBy = orderBy + orderByCols[i] + ' ASC' |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return orderBy |
||||||
|
} |
||||||
|
|
||||||
|
getColumnsForSelectStmt(tableName, reqQueryParams) { |
||||||
|
|
||||||
|
let table = this.metaDb.tables[tableName]; |
||||||
|
let cols = []; |
||||||
|
let _fieldsInQuery = []; |
||||||
|
let removeFieldsObj = {}; |
||||||
|
|
||||||
|
// populate _fields array from query params
|
||||||
|
if ('_fields' in reqQueryParams) { |
||||||
|
_fieldsInQuery = reqQueryParams['_fields'].split(',') |
||||||
|
} else { |
||||||
|
return " * "; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// get column name in _fields and mark column name which start with '-'
|
||||||
|
for (let i = 0; i < _fieldsInQuery.length; ++i) { |
||||||
|
if (_fieldsInQuery[i][0] == '-') { |
||||||
|
removeFieldsObj[_fieldsInQuery[i].substring(1, _fieldsInQuery[i].length)] = 1; |
||||||
|
} else { |
||||||
|
cols.push(_fieldsInQuery[i]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!cols.length) { |
||||||
|
// for each column in table - add only which are not in removeFieldsObj
|
||||||
|
for (let i = 0; i < table['columns'].length; ++i) { |
||||||
|
if (!(table['columns'][i]['column_name'] in removeFieldsObj)) { |
||||||
|
cols.push(table['columns'][i]['column_name']) |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
|
||||||
|
cols = this.removeUnknownColumns(cols, tableName) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return cols.join(',') |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
removeUnknownColumns(inputColumns, tableName) { |
||||||
|
|
||||||
|
let cols = inputColumns; |
||||||
|
let unknown_cols_in_input = [] |
||||||
|
let shadowCols = []; |
||||||
|
let tableColumns = this.metaDb.tables[tableName]['columns'] |
||||||
|
|
||||||
|
// find unknown fields if any
|
||||||
|
for (var j = 0; j < cols.length; ++j) { |
||||||
|
|
||||||
|
let found = 0; |
||||||
|
|
||||||
|
for (var i = 0; i < tableColumns.length; ++i) { |
||||||
|
if (tableColumns[i]['column_name'] === cols[j]) { |
||||||
|
found = 1; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!found) { |
||||||
|
unknown_cols_in_input.push(j) |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// if there are unknown fields - remove and ignore 'em
|
||||||
|
if (unknown_cols_in_input.length) { |
||||||
|
|
||||||
|
for (var i = 0; i < cols.length; ++i) { |
||||||
|
if (unknown_cols_in_input.indexOf(i) === -1) { |
||||||
|
shadowCols.push(cols[i]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
cols = []; |
||||||
|
cols = shadowCols; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return cols; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
getPrimaryKeyWhereClause(tableName, pksValues) { |
||||||
|
|
||||||
|
let whereClause = ''; |
||||||
|
let whereCol = ''; |
||||||
|
let whereValue = ''; |
||||||
|
let pks = [] |
||||||
|
|
||||||
|
if (tableName in this.metaDb.tables) { |
||||||
|
pks = this.metaDb.tables[tableName].primaryKeys; |
||||||
|
} else { |
||||||
|
return null |
||||||
|
} |
||||||
|
|
||||||
|
// number of primary keys in table and one sent should be same
|
||||||
|
if (pksValues.length !== pks.length) { |
||||||
|
return null |
||||||
|
} |
||||||
|
|
||||||
|
// get a where clause out of the above columnNames and their values
|
||||||
|
for (let i = 0; i < pks.length; ++i) { |
||||||
|
|
||||||
|
let type = getColumnType(pks[i]); |
||||||
|
|
||||||
|
whereCol = pks[i]['column_name'] |
||||||
|
|
||||||
|
if (type === 'string') { |
||||||
|
whereValue = mysql.escape(pksValues[i]) |
||||||
|
} else if (type === 'int') { |
||||||
|
whereValue = parseInt(pksValues[i]) |
||||||
|
} else if (type === 'float') { |
||||||
|
whereValue = parseFloat(pksValues[i]) |
||||||
|
} else if (type === 'date') { |
||||||
|
whereValue = Date(pksValues[i]) |
||||||
|
} else { |
||||||
|
console.error(pks[i]) |
||||||
|
assert(false, 'Unhandled type of primary key') |
||||||
|
} |
||||||
|
|
||||||
|
if (i) { |
||||||
|
whereClause += ' and ' |
||||||
|
} |
||||||
|
|
||||||
|
whereClause += whereCol + ' = ' + whereValue; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return whereClause; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
getForeignKeyWhereClause(parentTable, parentId, childTable) { |
||||||
|
|
||||||
|
let whereValue = ''; |
||||||
|
|
||||||
|
//get all foreign keys of child table
|
||||||
|
let fks = this.metaDb.tables[childTable].foreignKeys; |
||||||
|
let fk = dataHelp.findObjectInArrayByKey('referenced_table_name', parentTable, fks); |
||||||
|
let whereCol = fk['column_name'] |
||||||
|
let colType = getColumnType(fk); |
||||||
|
|
||||||
|
if (colType === 'string') { |
||||||
|
whereValue = mysql.escape(parentId) |
||||||
|
} else if (colType === 'int') { |
||||||
|
whereValue = mysql.escape(parseInt(parentId)) |
||||||
|
} else if (colType === 'float') { |
||||||
|
whereValue = mysql.escape(parseFloat(parentId)) |
||||||
|
} else if (colType === 'date') { |
||||||
|
whereValue = mysql.escape(Date(parentId)) |
||||||
|
} else { |
||||||
|
console.error(pks[i]) |
||||||
|
assert(false, 'Unhandled column type in foreign key handling') |
||||||
|
} |
||||||
|
|
||||||
|
return whereCol + ' = ' + whereValue; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
prepareRoute(httpType, apiPrefix, urlRoute) { |
||||||
|
|
||||||
|
let route = {}; |
||||||
|
route['httpType'] = httpType; |
||||||
|
route['routeUrl'] = apiPrefix + urlRoute; |
||||||
|
return route; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
getSchemaRoutes(apiPrefix) { |
||||||
|
|
||||||
|
let schemaRoutes = []; |
||||||
|
|
||||||
|
for (var tableName in this.metaDb.tables) { |
||||||
|
|
||||||
|
let routes = [] |
||||||
|
let tableObj = {} |
||||||
|
|
||||||
|
let table = this.metaDb.tables[tableName]; |
||||||
|
|
||||||
|
tableObj['resource'] = tableName; |
||||||
|
|
||||||
|
routes.push(this.prepareRoute('get', apiPrefix, tableName)) |
||||||
|
routes.push(this.prepareRoute('post', apiPrefix, tableName)) |
||||||
|
routes.push(this.prepareRoute('get', apiPrefix, tableName + '/:id')) |
||||||
|
routes.push(this.prepareRoute('put', apiPrefix, tableName + '/:id')) |
||||||
|
routes.push(this.prepareRoute('delete', apiPrefix, tableName + '/:id')) |
||||||
|
routes.push(this.prepareRoute('get', apiPrefix, tableName + '/:id/count')) |
||||||
|
routes.push(this.prepareRoute('get', apiPrefix, tableName + '/:id/exists')) |
||||||
|
|
||||||
|
for (var j = 0; j < table['foreignKeys'].length; ++j) { |
||||||
|
let fk = table['foreignKeys'][j] |
||||||
|
routes.push(this.prepareRoute('get', apiPrefix, fk['referenced_table_name'] + '/:id/' + fk['table_name'])) |
||||||
|
} |
||||||
|
|
||||||
|
tableObj['routes'] = routes; |
||||||
|
|
||||||
|
schemaRoutes.push(tableObj); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return schemaRoutes; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
globalRoutesPrint(apiPrefix) { |
||||||
|
|
||||||
|
let r = [] |
||||||
|
|
||||||
|
r.push(apiPrefix + "tables") |
||||||
|
r.push(apiPrefix + ":tableName/describe") |
||||||
|
|
||||||
|
if (this.sqlConfig.dynamic) |
||||||
|
r.push(apiPrefix + "dynamic") |
||||||
|
|
||||||
|
return r; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
//expose class
|
||||||
|
module.exports = Xsql; |
||||||
|
|
||||||
|
|
||||||
|
function getDataType(colType, typesArr) { |
||||||
|
// console.log(colType,typesArr);
|
||||||
|
for (let i = 0; i < typesArr.length; ++i) { |
||||||
|
if (colType.indexOf(typesArr[i]) !== -1) { |
||||||
|
return 1; |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
function getColumnType(column) { |
||||||
|
|
||||||
|
let strTypes = ['varchar', 'text', 'char', 'tinytext', 'mediumtext', 'longtext', 'blob', 'mediumblob', 'longblob', 'tinyblob', 'binary', 'varbinary']; |
||||||
|
let intTypes = ['int', 'long', 'smallint', 'mediumint', 'bigint', 'tinyint']; |
||||||
|
let flatTypes = ['float', 'double', 'decimal']; |
||||||
|
let dateTypes = ['date', 'datetime', 'timestamp', 'time', 'year']; |
||||||
|
|
||||||
|
//console.log(column);
|
||||||
|
if (getDataType(column['data_type'], strTypes)) { |
||||||
|
return "string" |
||||||
|
} else if (getDataType(column['data_type'], intTypes)) { |
||||||
|
return "int" |
||||||
|
} else if (getDataType(column['data_type'], flatTypes)) { |
||||||
|
return "float" |
||||||
|
} else if (getDataType(column['data_type'], dateTypes)) { |
||||||
|
return "date" |
||||||
|
} else { |
||||||
|
return "string" |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,918 @@ |
|||||||
|
{ |
||||||
|
"name": "More-Apis", |
||||||
|
"version": "0.0.2", |
||||||
|
"lockfileVersion": 1, |
||||||
|
"requires": true, |
||||||
|
"dependencies": { |
||||||
|
"accepts": { |
||||||
|
"version": "1.3.4", |
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", |
||||||
|
"integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", |
||||||
|
"requires": { |
||||||
|
"mime-types": "2.1.17", |
||||||
|
"negotiator": "0.6.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"append-field": { |
||||||
|
"version": "0.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", |
||||||
|
"integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" |
||||||
|
}, |
||||||
|
"array-flatten": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", |
||||||
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" |
||||||
|
}, |
||||||
|
"assert": { |
||||||
|
"version": "1.4.1", |
||||||
|
"resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", |
||||||
|
"integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", |
||||||
|
"requires": { |
||||||
|
"util": "0.10.3" |
||||||
|
} |
||||||
|
}, |
||||||
|
"asynckit": { |
||||||
|
"version": "0.4.0", |
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", |
||||||
|
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"balanced-match": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", |
||||||
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" |
||||||
|
}, |
||||||
|
"basic-auth": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz", |
||||||
|
"integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=", |
||||||
|
"requires": { |
||||||
|
"safe-buffer": "5.1.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"bignumber.js": { |
||||||
|
"version": "4.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.0.4.tgz", |
||||||
|
"integrity": "sha512-LDXpJKVzEx2/OqNbG9mXBNvHuiRL4PzHCGfnANHMJ+fv68Ads3exDVJeGDJws+AoNEuca93bU3q+S0woeUaCdg==" |
||||||
|
}, |
||||||
|
"body-parser": { |
||||||
|
"version": "1.18.2", |
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", |
||||||
|
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", |
||||||
|
"requires": { |
||||||
|
"bytes": "3.0.0", |
||||||
|
"content-type": "1.0.4", |
||||||
|
"debug": "2.6.9", |
||||||
|
"depd": "1.1.1", |
||||||
|
"http-errors": "1.6.2", |
||||||
|
"iconv-lite": "0.4.19", |
||||||
|
"on-finished": "2.3.0", |
||||||
|
"qs": "6.5.1", |
||||||
|
"raw-body": "2.3.2", |
||||||
|
"type-is": "1.6.15" |
||||||
|
} |
||||||
|
}, |
||||||
|
"brace-expansion": { |
||||||
|
"version": "1.1.8", |
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", |
||||||
|
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", |
||||||
|
"requires": { |
||||||
|
"balanced-match": "1.0.0", |
||||||
|
"concat-map": "0.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"browser-stdout": { |
||||||
|
"version": "1.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", |
||||||
|
"integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" |
||||||
|
}, |
||||||
|
"busboy": { |
||||||
|
"version": "0.2.14", |
||||||
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", |
||||||
|
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", |
||||||
|
"requires": { |
||||||
|
"dicer": "0.2.5", |
||||||
|
"readable-stream": "1.1.14" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"isarray": { |
||||||
|
"version": "0.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", |
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" |
||||||
|
}, |
||||||
|
"readable-stream": { |
||||||
|
"version": "1.1.14", |
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", |
||||||
|
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", |
||||||
|
"requires": { |
||||||
|
"core-util-is": "1.0.2", |
||||||
|
"inherits": "2.0.3", |
||||||
|
"isarray": "0.0.1", |
||||||
|
"string_decoder": "0.10.31" |
||||||
|
} |
||||||
|
}, |
||||||
|
"string_decoder": { |
||||||
|
"version": "0.10.31", |
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", |
||||||
|
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"bytes": { |
||||||
|
"version": "3.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", |
||||||
|
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" |
||||||
|
}, |
||||||
|
"colors": { |
||||||
|
"version": "1.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", |
||||||
|
"integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" |
||||||
|
}, |
||||||
|
"combined-stream": { |
||||||
|
"version": "1.0.5", |
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", |
||||||
|
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"delayed-stream": "1.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"commander": { |
||||||
|
"version": "2.11.0", |
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", |
||||||
|
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" |
||||||
|
}, |
||||||
|
"component-emitter": { |
||||||
|
"version": "1.2.1", |
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", |
||||||
|
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"concat-map": { |
||||||
|
"version": "0.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" |
||||||
|
}, |
||||||
|
"concat-stream": { |
||||||
|
"version": "1.6.0", |
||||||
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", |
||||||
|
"integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", |
||||||
|
"requires": { |
||||||
|
"inherits": "2.0.3", |
||||||
|
"readable-stream": "2.3.3", |
||||||
|
"typedarray": "0.0.6" |
||||||
|
} |
||||||
|
}, |
||||||
|
"content-disposition": { |
||||||
|
"version": "0.5.2", |
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", |
||||||
|
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" |
||||||
|
}, |
||||||
|
"content-type": { |
||||||
|
"version": "1.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", |
||||||
|
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" |
||||||
|
}, |
||||||
|
"cookie": { |
||||||
|
"version": "0.3.1", |
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", |
||||||
|
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" |
||||||
|
}, |
||||||
|
"cookie-signature": { |
||||||
|
"version": "1.0.6", |
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", |
||||||
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" |
||||||
|
}, |
||||||
|
"cookiejar": { |
||||||
|
"version": "2.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz", |
||||||
|
"integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"core-util-is": { |
||||||
|
"version": "1.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", |
||||||
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" |
||||||
|
}, |
||||||
|
"debug": { |
||||||
|
"version": "2.6.9", |
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", |
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", |
||||||
|
"requires": { |
||||||
|
"ms": "2.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"delayed-stream": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", |
||||||
|
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"depd": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", |
||||||
|
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" |
||||||
|
}, |
||||||
|
"destroy": { |
||||||
|
"version": "1.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", |
||||||
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" |
||||||
|
}, |
||||||
|
"dicer": { |
||||||
|
"version": "0.2.5", |
||||||
|
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", |
||||||
|
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", |
||||||
|
"requires": { |
||||||
|
"readable-stream": "1.1.14", |
||||||
|
"streamsearch": "0.1.2" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"isarray": { |
||||||
|
"version": "0.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", |
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" |
||||||
|
}, |
||||||
|
"readable-stream": { |
||||||
|
"version": "1.1.14", |
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", |
||||||
|
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", |
||||||
|
"requires": { |
||||||
|
"core-util-is": "1.0.2", |
||||||
|
"inherits": "2.0.3", |
||||||
|
"isarray": "0.0.1", |
||||||
|
"string_decoder": "0.10.31" |
||||||
|
} |
||||||
|
}, |
||||||
|
"string_decoder": { |
||||||
|
"version": "0.10.31", |
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", |
||||||
|
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"diff": { |
||||||
|
"version": "3.3.1", |
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", |
||||||
|
"integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==" |
||||||
|
}, |
||||||
|
"ee-first": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", |
||||||
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" |
||||||
|
}, |
||||||
|
"encodeurl": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", |
||||||
|
"integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" |
||||||
|
}, |
||||||
|
"escape-html": { |
||||||
|
"version": "1.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", |
||||||
|
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" |
||||||
|
}, |
||||||
|
"escape-string-regexp": { |
||||||
|
"version": "1.0.5", |
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", |
||||||
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" |
||||||
|
}, |
||||||
|
"etag": { |
||||||
|
"version": "1.8.1", |
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", |
||||||
|
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" |
||||||
|
}, |
||||||
|
"express": { |
||||||
|
"version": "4.16.1", |
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-4.16.1.tgz", |
||||||
|
"integrity": "sha512-STB7LZ4N0L+81FJHGla2oboUHTk4PaN1RsOkoRh9OSeEKylvF5hwKYVX1xCLFaCT7MD0BNG/gX2WFMLqY6EMBw==", |
||||||
|
"requires": { |
||||||
|
"accepts": "1.3.4", |
||||||
|
"array-flatten": "1.1.1", |
||||||
|
"body-parser": "1.18.2", |
||||||
|
"content-disposition": "0.5.2", |
||||||
|
"content-type": "1.0.4", |
||||||
|
"cookie": "0.3.1", |
||||||
|
"cookie-signature": "1.0.6", |
||||||
|
"debug": "2.6.9", |
||||||
|
"depd": "1.1.1", |
||||||
|
"encodeurl": "1.0.1", |
||||||
|
"escape-html": "1.0.3", |
||||||
|
"etag": "1.8.1", |
||||||
|
"finalhandler": "1.1.0", |
||||||
|
"fresh": "0.5.2", |
||||||
|
"merge-descriptors": "1.0.1", |
||||||
|
"methods": "1.1.2", |
||||||
|
"on-finished": "2.3.0", |
||||||
|
"parseurl": "1.3.2", |
||||||
|
"path-to-regexp": "0.1.7", |
||||||
|
"proxy-addr": "2.0.2", |
||||||
|
"qs": "6.5.1", |
||||||
|
"range-parser": "1.2.0", |
||||||
|
"safe-buffer": "5.1.1", |
||||||
|
"send": "0.16.1", |
||||||
|
"serve-static": "1.13.1", |
||||||
|
"setprototypeof": "1.1.0", |
||||||
|
"statuses": "1.3.1", |
||||||
|
"type-is": "1.6.15", |
||||||
|
"utils-merge": "1.0.1", |
||||||
|
"vary": "1.1.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"extend": { |
||||||
|
"version": "3.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", |
||||||
|
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"finalhandler": { |
||||||
|
"version": "1.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", |
||||||
|
"integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", |
||||||
|
"requires": { |
||||||
|
"debug": "2.6.9", |
||||||
|
"encodeurl": "1.0.1", |
||||||
|
"escape-html": "1.0.3", |
||||||
|
"on-finished": "2.3.0", |
||||||
|
"parseurl": "1.3.2", |
||||||
|
"statuses": "1.3.1", |
||||||
|
"unpipe": "1.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"form-data": { |
||||||
|
"version": "2.3.1", |
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", |
||||||
|
"integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"asynckit": "0.4.0", |
||||||
|
"combined-stream": "1.0.5", |
||||||
|
"mime-types": "2.1.17" |
||||||
|
} |
||||||
|
}, |
||||||
|
"formidable": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz", |
||||||
|
"integrity": "sha1-lriIb3w8NQi5Mta9cMTTqI818ak=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"forwarded": { |
||||||
|
"version": "0.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", |
||||||
|
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" |
||||||
|
}, |
||||||
|
"fresh": { |
||||||
|
"version": "0.5.2", |
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", |
||||||
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" |
||||||
|
}, |
||||||
|
"fs.realpath": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", |
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" |
||||||
|
}, |
||||||
|
"glob": { |
||||||
|
"version": "7.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", |
||||||
|
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", |
||||||
|
"requires": { |
||||||
|
"fs.realpath": "1.0.0", |
||||||
|
"inflight": "1.0.6", |
||||||
|
"inherits": "2.0.3", |
||||||
|
"minimatch": "3.0.4", |
||||||
|
"once": "1.4.0", |
||||||
|
"path-is-absolute": "1.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"growl": { |
||||||
|
"version": "1.10.3", |
||||||
|
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", |
||||||
|
"integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" |
||||||
|
}, |
||||||
|
"has-flag": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", |
||||||
|
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" |
||||||
|
}, |
||||||
|
"he": { |
||||||
|
"version": "1.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", |
||||||
|
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" |
||||||
|
}, |
||||||
|
"http-errors": { |
||||||
|
"version": "1.6.2", |
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", |
||||||
|
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", |
||||||
|
"requires": { |
||||||
|
"depd": "1.1.1", |
||||||
|
"inherits": "2.0.3", |
||||||
|
"setprototypeof": "1.0.3", |
||||||
|
"statuses": "1.3.1" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"setprototypeof": { |
||||||
|
"version": "1.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", |
||||||
|
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"iconv-lite": { |
||||||
|
"version": "0.4.19", |
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", |
||||||
|
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" |
||||||
|
}, |
||||||
|
"inflight": { |
||||||
|
"version": "1.0.6", |
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", |
||||||
|
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", |
||||||
|
"requires": { |
||||||
|
"once": "1.4.0", |
||||||
|
"wrappy": "1.0.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"inherits": { |
||||||
|
"version": "2.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", |
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" |
||||||
|
}, |
||||||
|
"ipaddr.js": { |
||||||
|
"version": "1.5.2", |
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", |
||||||
|
"integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" |
||||||
|
}, |
||||||
|
"isarray": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", |
||||||
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" |
||||||
|
}, |
||||||
|
"media-typer": { |
||||||
|
"version": "0.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", |
||||||
|
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" |
||||||
|
}, |
||||||
|
"merge-descriptors": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", |
||||||
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" |
||||||
|
}, |
||||||
|
"methods": { |
||||||
|
"version": "1.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", |
||||||
|
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" |
||||||
|
}, |
||||||
|
"mime": { |
||||||
|
"version": "1.4.1", |
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", |
||||||
|
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" |
||||||
|
}, |
||||||
|
"mime-db": { |
||||||
|
"version": "1.30.0", |
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", |
||||||
|
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" |
||||||
|
}, |
||||||
|
"mime-types": { |
||||||
|
"version": "2.1.17", |
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", |
||||||
|
"integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", |
||||||
|
"requires": { |
||||||
|
"mime-db": "1.30.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minimatch": { |
||||||
|
"version": "3.0.4", |
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", |
||||||
|
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", |
||||||
|
"requires": { |
||||||
|
"brace-expansion": "1.1.8" |
||||||
|
} |
||||||
|
}, |
||||||
|
"minimist": { |
||||||
|
"version": "0.0.8", |
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", |
||||||
|
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" |
||||||
|
}, |
||||||
|
"mkdirp": { |
||||||
|
"version": "0.5.1", |
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", |
||||||
|
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", |
||||||
|
"requires": { |
||||||
|
"minimist": "0.0.8" |
||||||
|
} |
||||||
|
}, |
||||||
|
"mocha": { |
||||||
|
"version": "4.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", |
||||||
|
"integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", |
||||||
|
"requires": { |
||||||
|
"browser-stdout": "1.3.0", |
||||||
|
"commander": "2.11.0", |
||||||
|
"debug": "3.1.0", |
||||||
|
"diff": "3.3.1", |
||||||
|
"escape-string-regexp": "1.0.5", |
||||||
|
"glob": "7.1.2", |
||||||
|
"growl": "1.10.3", |
||||||
|
"he": "1.1.1", |
||||||
|
"mkdirp": "0.5.1", |
||||||
|
"supports-color": "4.4.0" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"debug": { |
||||||
|
"version": "3.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", |
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", |
||||||
|
"requires": { |
||||||
|
"ms": "2.0.0" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"morgan": { |
||||||
|
"version": "1.9.0", |
||||||
|
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", |
||||||
|
"integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=", |
||||||
|
"requires": { |
||||||
|
"basic-auth": "2.0.0", |
||||||
|
"debug": "2.6.9", |
||||||
|
"depd": "1.1.1", |
||||||
|
"on-finished": "2.3.0", |
||||||
|
"on-headers": "1.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"ms": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", |
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" |
||||||
|
}, |
||||||
|
"multer": { |
||||||
|
"version": "1.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", |
||||||
|
"integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", |
||||||
|
"requires": { |
||||||
|
"append-field": "0.1.0", |
||||||
|
"busboy": "0.2.14", |
||||||
|
"concat-stream": "1.6.0", |
||||||
|
"mkdirp": "0.5.1", |
||||||
|
"object-assign": "3.0.0", |
||||||
|
"on-finished": "2.3.0", |
||||||
|
"type-is": "1.6.15", |
||||||
|
"xtend": "4.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"mysql": { |
||||||
|
"version": "2.15.0", |
||||||
|
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.15.0.tgz", |
||||||
|
"integrity": "sha512-C7tjzWtbN5nzkLIV+E8Crnl9bFyc7d3XJcBAvHKEVkjrYjogz3llo22q6s/hw+UcsE4/844pDob9ac+3dVjQSA==", |
||||||
|
"requires": { |
||||||
|
"bignumber.js": "4.0.4", |
||||||
|
"readable-stream": "2.3.3", |
||||||
|
"safe-buffer": "5.1.1", |
||||||
|
"sqlstring": "2.3.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"nan": { |
||||||
|
"version": "2.7.0", |
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz", |
||||||
|
"integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"negotiator": { |
||||||
|
"version": "0.6.1", |
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", |
||||||
|
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" |
||||||
|
}, |
||||||
|
"object-assign": { |
||||||
|
"version": "3.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", |
||||||
|
"integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" |
||||||
|
}, |
||||||
|
"on-finished": { |
||||||
|
"version": "2.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", |
||||||
|
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", |
||||||
|
"requires": { |
||||||
|
"ee-first": "1.1.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"on-headers": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", |
||||||
|
"integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" |
||||||
|
}, |
||||||
|
"once": { |
||||||
|
"version": "1.4.0", |
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", |
||||||
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", |
||||||
|
"requires": { |
||||||
|
"wrappy": "1.0.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"parseurl": { |
||||||
|
"version": "1.3.2", |
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", |
||||||
|
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" |
||||||
|
}, |
||||||
|
"path-is-absolute": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", |
||||||
|
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" |
||||||
|
}, |
||||||
|
"path-to-regexp": { |
||||||
|
"version": "0.1.7", |
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", |
||||||
|
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" |
||||||
|
}, |
||||||
|
"process-nextick-args": { |
||||||
|
"version": "1.0.7", |
||||||
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", |
||||||
|
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" |
||||||
|
}, |
||||||
|
"proxy-addr": { |
||||||
|
"version": "2.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", |
||||||
|
"integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", |
||||||
|
"requires": { |
||||||
|
"forwarded": "0.1.2", |
||||||
|
"ipaddr.js": "1.5.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"qs": { |
||||||
|
"version": "6.5.1", |
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", |
||||||
|
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" |
||||||
|
}, |
||||||
|
"range-parser": { |
||||||
|
"version": "1.2.0", |
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", |
||||||
|
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" |
||||||
|
}, |
||||||
|
"raw-body": { |
||||||
|
"version": "2.3.2", |
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", |
||||||
|
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", |
||||||
|
"requires": { |
||||||
|
"bytes": "3.0.0", |
||||||
|
"http-errors": "1.6.2", |
||||||
|
"iconv-lite": "0.4.19", |
||||||
|
"unpipe": "1.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"readable-stream": { |
||||||
|
"version": "2.3.3", |
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", |
||||||
|
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", |
||||||
|
"requires": { |
||||||
|
"core-util-is": "1.0.2", |
||||||
|
"inherits": "2.0.3", |
||||||
|
"isarray": "1.0.0", |
||||||
|
"process-nextick-args": "1.0.7", |
||||||
|
"safe-buffer": "5.1.1", |
||||||
|
"string_decoder": "1.0.3", |
||||||
|
"util-deprecate": "1.0.2" |
||||||
|
} |
||||||
|
}, |
||||||
|
"safe-buffer": { |
||||||
|
"version": "5.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", |
||||||
|
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" |
||||||
|
}, |
||||||
|
"send": { |
||||||
|
"version": "0.16.1", |
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", |
||||||
|
"integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", |
||||||
|
"requires": { |
||||||
|
"debug": "2.6.9", |
||||||
|
"depd": "1.1.1", |
||||||
|
"destroy": "1.0.4", |
||||||
|
"encodeurl": "1.0.1", |
||||||
|
"escape-html": "1.0.3", |
||||||
|
"etag": "1.8.1", |
||||||
|
"fresh": "0.5.2", |
||||||
|
"http-errors": "1.6.2", |
||||||
|
"mime": "1.4.1", |
||||||
|
"ms": "2.0.0", |
||||||
|
"on-finished": "2.3.0", |
||||||
|
"range-parser": "1.2.0", |
||||||
|
"statuses": "1.3.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"serve-favicon": { |
||||||
|
"version": "2.4.5", |
||||||
|
"resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.4.5.tgz", |
||||||
|
"integrity": "sha512-s7F8h2NrslMkG50KxvlGdj+ApSwaLex0vexuJ9iFf3GLTIp1ph/l1qZvRe9T9TJEYZgmq72ZwJ2VYiAEtChknw==", |
||||||
|
"requires": { |
||||||
|
"etag": "1.8.1", |
||||||
|
"fresh": "0.5.2", |
||||||
|
"ms": "2.0.0", |
||||||
|
"parseurl": "1.3.2", |
||||||
|
"safe-buffer": "5.1.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"serve-static": { |
||||||
|
"version": "1.13.1", |
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", |
||||||
|
"integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", |
||||||
|
"requires": { |
||||||
|
"encodeurl": "1.0.1", |
||||||
|
"escape-html": "1.0.3", |
||||||
|
"parseurl": "1.3.2", |
||||||
|
"send": "0.16.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"setprototypeof": { |
||||||
|
"version": "1.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", |
||||||
|
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" |
||||||
|
}, |
||||||
|
"should": { |
||||||
|
"version": "13.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/should/-/should-13.1.2.tgz", |
||||||
|
"integrity": "sha512-oiGqKOuE4t98vdCs4ICifvzL2u9nWMaziSXVwHOYPyqqY1gBzGZS6LvzIc5uEFN0PiS69Sbvcqyw9hbYXkF4og==", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"should-equal": "2.0.0", |
||||||
|
"should-format": "3.0.3", |
||||||
|
"should-type": "1.4.0", |
||||||
|
"should-type-adaptors": "1.0.1", |
||||||
|
"should-util": "1.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"should-equal": { |
||||||
|
"version": "2.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", |
||||||
|
"integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"should-type": "1.4.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"should-format": { |
||||||
|
"version": "3.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", |
||||||
|
"integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"should-type": "1.4.0", |
||||||
|
"should-type-adaptors": "1.0.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"should-type": { |
||||||
|
"version": "1.4.0", |
||||||
|
"resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", |
||||||
|
"integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"should-type-adaptors": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz", |
||||||
|
"integrity": "sha1-7+VVPN9oz/ZuXF9RtxLcNRx3vqo=", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"should-type": "1.4.0", |
||||||
|
"should-util": "1.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"should-util": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", |
||||||
|
"integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", |
||||||
|
"dev": true |
||||||
|
}, |
||||||
|
"sleep": { |
||||||
|
"version": "5.1.1", |
||||||
|
"resolved": "https://registry.npmjs.org/sleep/-/sleep-5.1.1.tgz", |
||||||
|
"integrity": "sha1-h4+h1E0I7rDyb7IBjvhinrGjq5Q=", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"nan": "2.7.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"sqlstring": { |
||||||
|
"version": "2.3.0", |
||||||
|
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.0.tgz", |
||||||
|
"integrity": "sha1-UluKT9Jtb3GqYegipsr5dtMa0qg=" |
||||||
|
}, |
||||||
|
"statuses": { |
||||||
|
"version": "1.3.1", |
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", |
||||||
|
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" |
||||||
|
}, |
||||||
|
"streamsearch": { |
||||||
|
"version": "0.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", |
||||||
|
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" |
||||||
|
}, |
||||||
|
"string_decoder": { |
||||||
|
"version": "1.0.3", |
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", |
||||||
|
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", |
||||||
|
"requires": { |
||||||
|
"safe-buffer": "5.1.1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"superagent": { |
||||||
|
"version": "3.6.3", |
||||||
|
"resolved": "https://registry.npmjs.org/superagent/-/superagent-3.6.3.tgz", |
||||||
|
"integrity": "sha512-GjsfCFijfjqoz2tRiStSOoTdy7gNZOcK3ar4zONP9D8dXQWE+Qg7cbePHimRpapo06WUvoU3dmgi2e4q+sab5A==", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"component-emitter": "1.2.1", |
||||||
|
"cookiejar": "2.1.1", |
||||||
|
"debug": "3.1.0", |
||||||
|
"extend": "3.0.1", |
||||||
|
"form-data": "2.3.1", |
||||||
|
"formidable": "1.1.1", |
||||||
|
"methods": "1.1.2", |
||||||
|
"mime": "1.4.1", |
||||||
|
"qs": "6.5.1", |
||||||
|
"readable-stream": "2.3.3" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"debug": { |
||||||
|
"version": "3.1.0", |
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", |
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"ms": "2.0.0" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"supertest": { |
||||||
|
"version": "3.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/supertest/-/supertest-3.0.0.tgz", |
||||||
|
"integrity": "sha1-jUu2j9GDDuBwM7HFpamkAhyWUpY=", |
||||||
|
"dev": true, |
||||||
|
"requires": { |
||||||
|
"methods": "1.1.2", |
||||||
|
"superagent": "3.6.3" |
||||||
|
} |
||||||
|
}, |
||||||
|
"supports-color": { |
||||||
|
"version": "4.4.0", |
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", |
||||||
|
"integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", |
||||||
|
"requires": { |
||||||
|
"has-flag": "2.0.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"type-is": { |
||||||
|
"version": "1.6.15", |
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", |
||||||
|
"integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", |
||||||
|
"requires": { |
||||||
|
"media-typer": "0.3.0", |
||||||
|
"mime-types": "2.1.17" |
||||||
|
} |
||||||
|
}, |
||||||
|
"typedarray": { |
||||||
|
"version": "0.0.6", |
||||||
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", |
||||||
|
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" |
||||||
|
}, |
||||||
|
"unpipe": { |
||||||
|
"version": "1.0.0", |
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", |
||||||
|
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" |
||||||
|
}, |
||||||
|
"util": { |
||||||
|
"version": "0.10.3", |
||||||
|
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", |
||||||
|
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", |
||||||
|
"requires": { |
||||||
|
"inherits": "2.0.1" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"inherits": { |
||||||
|
"version": "2.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", |
||||||
|
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"util-deprecate": { |
||||||
|
"version": "1.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", |
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" |
||||||
|
}, |
||||||
|
"utils-merge": { |
||||||
|
"version": "1.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", |
||||||
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" |
||||||
|
}, |
||||||
|
"vary": { |
||||||
|
"version": "1.1.2", |
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", |
||||||
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" |
||||||
|
}, |
||||||
|
"wrappy": { |
||||||
|
"version": "1.0.2", |
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |
||||||
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" |
||||||
|
}, |
||||||
|
"xtend": { |
||||||
|
"version": "4.0.1", |
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", |
||||||
|
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
{ |
||||||
|
"name": "xmysql", |
||||||
|
"version": "0.0.2", |
||||||
|
"description": "One command to generate REST APIs for any MySql database", |
||||||
|
"main": "index.js", |
||||||
|
"scripts": { |
||||||
|
"test": "./node_modules/.bin/mocha tests/*.js --exit" |
||||||
|
}, |
||||||
|
"keywords": [ |
||||||
|
"mysql rest api generator", |
||||||
|
"mysql rest api json", |
||||||
|
"create rest api for sql database", |
||||||
|
"node mysql rest api" |
||||||
|
], |
||||||
|
"engines": { |
||||||
|
"node": ">= 7.6.0" |
||||||
|
}, |
||||||
|
"bin": { |
||||||
|
"xmysql": "bin/index.js" |
||||||
|
}, |
||||||
|
"homepage": "https://github.com/o1lab/xmysql", |
||||||
|
"author": "o1lab", |
||||||
|
"license": "MIT", |
||||||
|
"dependencies": { |
||||||
|
"assert": "^1.4.1", |
||||||
|
"body-parser": "^1.18.2", |
||||||
|
"colors": "^1.1.2", |
||||||
|
"commander": "^2.11.0", |
||||||
|
"express": "^4.16.1", |
||||||
|
"mocha": "^4.0.1", |
||||||
|
"morgan": "^1.9.0", |
||||||
|
"multer": "^1.3.0", |
||||||
|
"mysql": "^2.15.0", |
||||||
|
"serve-favicon": "^2.4.5" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"should": "^13.1.2", |
||||||
|
"sleep": "^5.1.1", |
||||||
|
"supertest": "^3.0.0" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,643 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
var bodyParser = require('body-parser') |
||||||
|
var express = require('express') |
||||||
|
var mysql = require('mysql') |
||||||
|
var Xapi = require('../lib/xapi.js') |
||||||
|
var should = require('should'); |
||||||
|
|
||||||
|
var request = require('supertest') |
||||||
|
|
||||||
|
var args = {} |
||||||
|
var app = {} |
||||||
|
var agent = {} |
||||||
|
var api = {} |
||||||
|
var mysqlPool = {} |
||||||
|
|
||||||
|
|
||||||
|
args['host'] = 'localhost' |
||||||
|
args['user'] = 'root' |
||||||
|
args['password'] = '' |
||||||
|
args['database'] = 'classicmodels' |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//desribe group of tests done
|
||||||
|
describe('xmysql : tests', function () { |
||||||
|
|
||||||
|
before(function (done) { |
||||||
|
|
||||||
|
mysqlPool = mysql.createPool(args) |
||||||
|
|
||||||
|
app = express() |
||||||
|
//app.use(morgan('tiny'))
|
||||||
|
app.use(bodyParser.json()) |
||||||
|
app.use(bodyParser.urlencoded({ |
||||||
|
extended: true |
||||||
|
})) |
||||||
|
|
||||||
|
agent = request.agent(app); |
||||||
|
|
||||||
|
api = new Xapi(args, mysqlPool, app) |
||||||
|
api.init(function (err, results) { |
||||||
|
if (err) { |
||||||
|
process.exit(1) |
||||||
|
} |
||||||
|
app.listen(3000) |
||||||
|
done(); |
||||||
|
}) |
||||||
|
}); |
||||||
|
|
||||||
|
after(function (done) { |
||||||
|
|
||||||
|
mysqlPool.end(function (err) { |
||||||
|
done(); |
||||||
|
}) |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
beforeEach(function (done) { |
||||||
|
//init common variables for each test
|
||||||
|
done(); |
||||||
|
}); |
||||||
|
|
||||||
|
afterEach(function (done) { |
||||||
|
//term common variables for each test
|
||||||
|
done(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/tables should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/tables') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/tables error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.equal(8); |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/payments/count should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/payments/count') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/tables error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body[0]['no_of_rows'].should.be.equal(273); |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/customers/describe should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/customers/describe') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/tables error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.equal(13); |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/payments/103___JM555205 should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/payments/103___JM555205')// api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
|
||||||
|
// Handle /api/tables error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response - max value here is 14571.44
|
||||||
|
res.body.length.should.be.equal(1); |
||||||
|
res.body[0]['amount'].should.be.greaterThan(14570); |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/customers should PASS', function (done) { |
||||||
|
//testcase
|
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/customers') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/customers error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
res.body.length.should.be.greaterThan(0); |
||||||
|
|
||||||
|
//validate response
|
||||||
|
return done(); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/customers/103 should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/customers/103') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/customers/103 error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.should.be.instanceOf(Object) |
||||||
|
res.body[0]['customerNumber'].should.be.equal(103) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/payments?_p=2 should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/payments?_p=2') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
res.body.length.should.be.equal(20) |
||||||
|
|
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/payments?_p=2&_size=10 should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/payments?_p=2&_size=10') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
res.body.length.should.be.equal(10) |
||||||
|
|
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/offices?_sort=city should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/offices?_sort=city') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
res.body[0]['city'].should.be.equal('Boston') |
||||||
|
|
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/offices?_fields=officeCode,city should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/offices?_fields=officeCode,city') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
Object.keys(res.body[0]).length.should.be.equal(2) |
||||||
|
|
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/offices?_fields=officeCode,ity should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/offices?_fields=officeCode,ity') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
|
||||||
|
// ity in _fields is an in valid column and it should be ignored
|
||||||
|
Object.keys(res.body[0]).length.should.be.equal(1) |
||||||
|
|
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/offices?_fields=-territory,-addressLine2,-state should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/offices?_fields=-territory,-addressLine2,-state') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
Object.keys(res.body[0]).length.should.be.equal(6) |
||||||
|
|
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/offices?_fields=-territory,-addressLine2,-state,-tate should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/offices?_fields=-territory,-addressLine2,-state') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
|
||||||
|
// tate is an invalid column but still it should query right number of columns
|
||||||
|
Object.keys(res.body[0]).length.should.be.equal(6) |
||||||
|
|
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/offices?_sort=-city should PASS', function (done) { |
||||||
|
|
||||||
|
//http get an url
|
||||||
|
agent.get('/api/offices?_sort=-city') // api url
|
||||||
|
.expect(200) // 2xx for success and 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/offices/1/employees error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate resonse
|
||||||
|
res.body.should.be.instanceOf(Array) |
||||||
|
res.body[0]['city'].should.be.equal('Tokyo') |
||||||
|
|
||||||
|
return done(); |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
// it('GET /api/offices?_sort=-city,ity,-ity should PASS', function (done) {
|
||||||
|
//
|
||||||
|
// //http get an url
|
||||||
|
// agent.get('/api/offices?_sort=-city,ity,-ity') // api url
|
||||||
|
// .expect(200) // 2xx for success and 4xx for failure
|
||||||
|
// .end(function (err, res) {
|
||||||
|
// // Handle /api/offices/1/employees error
|
||||||
|
// if (err) {
|
||||||
|
// return done(err);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //validate resonse
|
||||||
|
// res.body.should.be.instanceOf(Array)
|
||||||
|
//
|
||||||
|
// // ity is an invalid sort element and should be ignored
|
||||||
|
// res.body[0]['city'].should.be.equal('Tokyo')
|
||||||
|
//
|
||||||
|
// return done();
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
it('POST /api/productlines should PASS', function (done) { |
||||||
|
|
||||||
|
var obj = {}; |
||||||
|
|
||||||
|
obj['productLine'] = 'Hyperloop' |
||||||
|
obj['textDescription'] = 'Hyperloop is essentially a train system that Musk calls \"a cross between ' + |
||||||
|
'a Concorde, a railgun, and an air hockey table\". ' + |
||||||
|
'It\'s based on the very high-speed transit (VHST) system proposed in 1972,' + |
||||||
|
'which combines a magnetic levitation train and a low pressure transit tube.' + |
||||||
|
'It evolves some of the original ideas of VHST, but it still uses tunnels' + |
||||||
|
'and pods or capsules to move from place to place.' |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.post('/api/productlines') //enter url
|
||||||
|
.send(obj) //postdata
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
|
||||||
|
res.body['affectedRows'].should.be.equals(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('PUT /api/customers/:id should PASS', function (done) { |
||||||
|
|
||||||
|
var obj = {}; |
||||||
|
|
||||||
|
obj['textDescription'] = 'Hyperloop is essentially a train system that Elon Musk (https://twitter.com/elonmusk) calls \"a cross between ' + |
||||||
|
'a Concorde, a railgun, and an air hockey table\". ' + |
||||||
|
'It\'s based on the very high-speed transit (VHST) system proposed in 1972,' + |
||||||
|
'which combines a magnetic levitation train and a low pressure transit tube.' + |
||||||
|
'It evolves some of the original ideas of VHST, but it still uses tunnels' + |
||||||
|
'and pods or capsules to move from place to place.' |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.put('/api/productlines/Hyperloop') //enter url
|
||||||
|
.send(obj) //postdata
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body['affectedRows'].should.be.equals(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
it('DELETE /api/customers/:id should PASS', function (done) { |
||||||
|
|
||||||
|
var obj = {}; |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.del('/api/productlines/Hyperloop') //enter url
|
||||||
|
.send(obj) //postdata
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body['affectedRows'].should.be.equals(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/offices/1/employees should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/offices/1/employees') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/employees/1002/employees should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/employees/1002/employees') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/productlines/trains/products should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/productlines/trains/products') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
it('GET /api/productlines/trains/products should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/productlines/trains/products') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/employees/1165/customers should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/employees/1165/customers') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/customers/103/orders should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/customers/103/orders') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/products/S10_1678/orderdetails should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/products/S10_1678/orderdetails') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('GET /api/customers/103/payments should PASS', function (done) { |
||||||
|
|
||||||
|
//post to an url with data
|
||||||
|
agent.get('/api/customers/103/payments') //enter url
|
||||||
|
.expect(200)//200 for success 4xx for failure
|
||||||
|
.end(function (err, res) { |
||||||
|
// Handle /api/v error
|
||||||
|
if (err) { |
||||||
|
return done(err); |
||||||
|
} |
||||||
|
|
||||||
|
//validate response
|
||||||
|
res.body.length.should.be.above(1) |
||||||
|
|
||||||
|
return done(); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
}); |
Loading…
Reference in new issue