Преглед изворни кода

新建双创api接口框架

zengyicheng пре 2 година
комит
5e1e387df4
10 измењених фајлова са 2782 додато и 0 уклоњено
  1. 24 0
      .gitignore
  2. 3 0
      .vscode/settings.json
  3. 2 0
      README.md
  4. 68 0
      app.js
  5. 85 0
      mysql.js
  6. 1395 0
      package-lock.json
  7. 434 0
      package.json
  8. 123 0
      pbl.js
  9. 98 0
      sqlserver.js
  10. 550 0
      upload.js

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/dist
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# production
+# /build
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*

+ 3 - 0
.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "compile-hero.disable-compile-files-on-did-save-code": false
+}

+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+# pbl-api
+

+ 68 - 0
app.js

@@ -0,0 +1,68 @@
+// call the packages we need
+var express = require('express');        // call express
+var app = express();                 // define our app using express
+var bodyParser = require('body-parser');
+var request = require("request");
+const edurouter = require('./pbl');
+const morgan = require('morgan');
+var path = require("path");
+var port = "7003";        // set our port
+//const cors = require('cors')
+app.use(morgan('dev'));
+// configure app to use bodyParser()
+// this will let us get the data from a POST
+app.use(bodyParser.urlencoded({ extended: true, limit: '3mb' }));
+app.use(bodyParser.json({ limit: '3mb' }));
+
+//暂时全跨域
+app.use(function (req, res, next) {
+    ///var allowedOrigins = [config.local.origin,'http://cocorobo.hk','http://www.cocorobo.hk','https://cocorobo.hk','http://cloud.cocorobo.hk','https://cloud.cocorobo.hk'];
+    var origin = req.headers.origin || "*";
+    //if(allowedOrigins.indexOf(origin) > -1){
+    res.setHeader('Access-Control-Allow-Origin', origin);
+    //}
+    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
+    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
+    res.header('Access-Control-Allow-Credentials', true);
+    //修改程序信息与版本
+    res.header('X-Powered-By', ' 3.2.1')
+    //内容类型:如果是post请求必须指定这个属性
+    res.header('Content-Type', 'application/json;charset=utf-8')
+    next();
+});
+
+/*
+app.use(cors({
+    origin:[`http:${config.local.origin}`,'http://www.cocorobo.hk','https://cocorobo.hk','http://cloud.cocorobo.hk','https://cloud.cocorobo.hk'],
+    methods:['GET','POST','PUT','DELETE'],
+    credentials: true // enable set cookie
+}));
+*/
+// all of our routes will be prefixed with /api
+app.use('/api/pbl', edurouter);
+// app.use('/game', game);
+
+app.all('/download', function (req, res, next) {
+    //req.body.url = "https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/%E4%B8%8B%E8%BD%BD%20%284%29.doc";
+    request({
+        url: req.body.url,
+        method: "GET",
+        encoding: null,
+        headers: {
+            'Accept-Encoding': 'gzip, deflate'
+        }
+    },
+        function (error, response, body) {
+            if (!error && response.statusCode == 200) {
+                res.setHeader('Content-Type', 'application/force-download');
+                res.setHeader('Content-Disposition', 'attachment; filename=' + path.basename(req.body.url));
+                res.setHeader('Content-Length', body.length);
+                res.send(body);
+            }
+        });
+});
+
+// START THE SERVER
+// =============================================================================
+app.listen(port);
+console.log('app happens on port ' + port);

+ 85 - 0
mysql.js

@@ -0,0 +1,85 @@
+//参数
+var us = {
+    mysql: require('mysql'),
+    sqle: {}
+};
+
+//连接数据库
+us.mysqlconnection = function(host, database) {
+    if (!us.sqle[host] || !us.sqle[host][database]) { //配置数据库连接 
+        us.sqle[host] = us.sqle[host] || {};
+        us.sqle[host][database] = us.mysql.createPool({
+            connectionLimit: 0,
+            host: host, //数据库地址
+            // user: "root", //用户名
+            // password: "cocorobo", //密码
+            database: database, //数据库名称
+            // port: 20007 //端口
+        }); //连接超时和错误从连
+    }
+    //connectionLimit: 1000, 
+    return us.sqle[host][database]; //返回连接对象
+}
+
+
+//连接数据库调用
+exports.usselect = function(param, callback) {
+    if (param.length > 1) {
+        var _mysqlconnection = us.mysqlconnection(param[0], param[1]); //创建连接池
+        _mysqlconnection.getConnection(function(error, connection) { //获取连接
+            if (error) { //连接错误
+                console.log("连接失败:", error);
+            } else { //连接成功
+                for (i = 0; i < param.length; i++) {
+                    param[i] = decodeURIComponent(param[i]);
+
+                } //格式化处理参数
+                var i, _sql = "CALL ";
+                var _param = new Array();
+                if (param.length > 3) { //带有参数的sql语句  如:'call test(?, ?, ?);'
+                    _param = param.slice(3) //截取有效参数
+                    _sql += (param[2] || "") + "(?"; //拼接存储过程名称 
+                    //_s += (p[2] || "") + "('" + p.slice(3).join("','") + "');";
+                    //, + ? 拼接参数 该方法拼接后比数组长度少一因此上一句代码中默认拼接了第一个参数
+                    _sql += Array(_param.length).join(",?");
+                    _sql += ");"; //拼接结果语句
+                } else { //不带参数的sql语句 如:'call test();'
+                    _sql += param[2] + "();";
+                }
+                // console.log("拼凑的MySQl语句为:", _sql);
+                connection.query(_sql, _param, function(error, results, fields) { //执行sql语句 
+                    if (results) {
+                        // if (results.pop) {
+                        //     results.pop();
+                        // }
+                        //console.log(JSON.stringify(results)); 输出结果集
+                        //执行回调函数
+                        //results.affectedRows != null 如果受影响行不等于null(空) 则返回受影响行数
+                        //results.affectedRows != null 如果受影响行不等于null(空) 则返回受影响行数
+                        //results.length > 1 ? results : results[0] 如果结果集为单行则直接返回Object对象 否则返回数组对象
+                        callback(results.affectedRows != null ? results.affectedRows : results.length > 1 ? results : results[0]);
+                    } else { //执行错误
+                        console.log("sql执行失败", error || "");
+                        callback(error);
+                    }
+                });
+
+                connection.release(function(error) { //释放资源
+                    if (error) console.log("连接释放错误", error);
+                });
+
+            }
+        });
+    }
+}
+
+
+//重新连接处理
+// us.mysqlconnet.reconnection = function (host, database, error) {
+//     if (error) {
+//         console.log("连接失败,尝试重连", error);
+//         setTimeout(function () {
+//             us.mysqlconnection(host, database)
+//         }, 2000);
+//     }
+// }

+ 1395 - 0
package-lock.json

@@ -0,0 +1,1395 @@
+{
+  "name": "cocoroboLabor",
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz",
+      "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg="
+    },
+    "accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz",
+      "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
+      "requires": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      }
+    },
+    "ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1617192427539&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.6.tgz",
+      "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz",
+      "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo="
+    },
+    "are-we-there-yet": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npm.taobao.org/are-we-there-yet/download/are-we-there-yet-1.1.5.tgz",
+      "integrity": "sha1-SzXClE8GKov82mZBB2A1D+nd/CE=",
+      "requires": {
+        "delegates": "^1.0.0",
+        "readable-stream": "^2.0.6"
+      }
+    },
+    "array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
+      "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+    },
+    "aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.11.0.tgz?cache=0&sync_timestamp=1604101166484&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.11.0.tgz",
+      "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk="
+    },
+    "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.1",
+      "resolved": "https://registry.npm.taobao.org/basic-auth/download/basic-auth-2.0.1.tgz",
+      "integrity": "sha1-uZgnm/R844NEtPPPkW1Gebv1Hjo=",
+      "requires": {
+        "safe-buffer": "5.1.2"
+      }
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "bcryptjs": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npm.taobao.org/bcryptjs/download/bcryptjs-2.4.3.tgz",
+      "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
+    },
+    "bignumber.js": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npm.taobao.org/bignumber.js/download/bignumber.js-9.0.0.tgz",
+      "integrity": "sha1-gFiA+Eoym16sbny2+CdLbYK98HU="
+    },
+    "body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz",
+      "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=",
+      "requires": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz?cache=0&sync_timestamp=1614010709807&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrace-expansion%2Fdownload%2Fbrace-expansion-1.1.11.tgz",
+      "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz?cache=0&sync_timestamp=1589682741197&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbytes%2Fdownload%2Fbytes-3.1.0.tgz",
+      "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY="
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+    },
+    "chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npm.taobao.org/chownr/download/chownr-1.1.4.tgz",
+      "integrity": "sha1-b8nXtC0ypYNZYzdmbn0ICE2izGs="
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz",
+      "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "console-control-strings": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+    },
+    "content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz",
+      "integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=",
+      "requires": {
+        "safe-buffer": "5.1.2"
+      }
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz",
+      "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js="
+    },
+    "cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz",
+      "integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo="
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+    },
+    "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="
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.2.7.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.2.7.tgz",
+      "integrity": "sha1-clgLfpFF+zm2Z2+cXl+xALk0F5o=",
+      "requires": {
+        "ms": "^2.1.1"
+      }
+    },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npm.taobao.org/deep-extend/download/deep-extend-0.6.0.tgz",
+      "integrity": "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw="
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+    },
+    "delegates": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+    },
+    "detect-libc": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+      "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "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.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+    },
+    "env-paths": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npm.taobao.org/env-paths/download/env-paths-2.2.1.tgz?cache=0&sync_timestamp=1615206693154&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fenv-paths%2Fdownload%2Fenv-paths-2.2.1.tgz",
+      "integrity": "sha1-QgOZ1BbOH76bwKB8Yvpo1n/Q+PI="
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+    },
+    "express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz?cache=0&sync_timestamp=1589682766604&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexpress%2Fdownload%2Fexpress-4.17.1.tgz",
+      "integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=",
+      "requires": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz?cache=0&sync_timestamp=1589682707348&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fextend%2Fdownload%2Fextend-3.0.2.tgz",
+      "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+    },
+    "fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU="
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM="
+    },
+    "finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz",
+      "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=",
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz",
+      "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "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-minipass": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-1.2.7.tgz",
+      "integrity": "sha1-zP+FcIQef+QmVpPaiJNsVa7X98c=",
+      "requires": {
+        "minipass": "^2.6.0"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+    },
+    "gauge": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "requires": {
+        "aproba": "^1.0.3",
+        "console-control-strings": "^1.0.0",
+        "has-unicode": "^2.0.0",
+        "object-assign": "^4.1.0",
+        "signal-exit": "^3.0.0",
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wide-align": "^1.1.0"
+      }
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz?cache=0&sync_timestamp=1589682812051&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz",
+      "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=",
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.2.6",
+      "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.6.tgz",
+      "integrity": "sha1-/wQLKwhTsjw9MQJ1I3BvGIXXa+4="
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+    },
+    "har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npm.taobao.org/har-validator/download/har-validator-5.1.5.tgz?cache=0&sync_timestamp=1596082584903&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhar-validator%2Fdownload%2Fhar-validator-5.1.5.tgz",
+      "integrity": "sha1-HwgDufjLIMD6E4It8ezds2veHv0=",
+      "requires": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has-unicode": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+    },
+    "http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz?cache=0&sync_timestamp=1593407858306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.2.tgz",
+      "integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=",
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+        }
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz",
+      "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
+    "ignore-walk": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npm.taobao.org/ignore-walk/download/ignore-walk-3.0.3.tgz",
+      "integrity": "sha1-AX4kRxhL/q3nwjjkrv3R6PlbHjc=",
+      "requires": {
+        "minimatch": "^3.0.4"
+      }
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz",
+      "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w="
+    },
+    "ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npm.taobao.org/ini/download/ini-1.3.8.tgz?cache=0&sync_timestamp=1607907834147&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fini%2Fdownload%2Fini-1.3.8.tgz",
+      "integrity": "sha1-op2kJbSIBvNHZ6Tvzjlyaa8oQyw="
+    },
+    "ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM="
+    },
+    "is-fullwidth-code-point": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+      "requires": {
+        "number-is-nan": "^1.0.0"
+      }
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisexe%2Fdownload%2Fisexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz?cache=0&sync_timestamp=1607999852153&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema-traverse%2Fdownload%2Fjson-schema-traverse-0.4.1.tgz",
+      "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA="
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "loader": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/loader/-/loader-2.1.1.tgz",
+      "integrity": "sha1-iEixKj8AVy5aQkkzPM2seXc/tAI="
+    },
+    "lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-6.0.0.tgz?cache=0&sync_timestamp=1594427582110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-6.0.0.tgz",
+      "integrity": "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ=",
+      "requires": {
+        "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz",
+          "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI="
+        }
+      }
+    },
+    "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.6.0",
+      "resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz",
+      "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE="
+    },
+    "mime-db": {
+      "version": "1.46.0",
+      "resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.46.0.tgz?cache=0&sync_timestamp=1613194712759&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.46.0.tgz",
+      "integrity": "sha1-Ymd0in95lZTePLyM3pHe80lmHO4="
+    },
+    "mime-types": {
+      "version": "2.1.29",
+      "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.29.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.29.tgz",
+      "integrity": "sha1-HUq3faZLkfX3JInfKSNlY3VLsbI=",
+      "requires": {
+        "mime-db": "1.46.0"
+      }
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz",
+      "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz?cache=0&sync_timestamp=1589682820731&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz",
+      "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI="
+    },
+    "minipass": {
+      "version": "2.9.0",
+      "resolved": "https://registry.npm.taobao.org/minipass/download/minipass-2.9.0.tgz?cache=0&sync_timestamp=1589683712023&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminipass%2Fdownload%2Fminipass-2.9.0.tgz",
+      "integrity": "sha1-5xN2Ln0+Mv7YAxFc+T4EvKn8yaY=",
+      "requires": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "minizlib": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npm.taobao.org/minizlib/download/minizlib-1.3.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminizlib%2Fdownload%2Fminizlib-1.3.3.tgz",
+      "integrity": "sha1-IpDeloGKNMKVUcio0wEha9Zahh0=",
+      "requires": {
+        "minipass": "^2.9.0"
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.5.tgz?cache=0&sync_timestamp=1589682820707&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.5.tgz",
+      "integrity": "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8=",
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "morgan": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npm.taobao.org/morgan/download/morgan-1.10.0.tgz",
+      "integrity": "sha1-CRd4q8H8R801CYJGU9rh+qtrF9c=",
+      "requires": {
+        "basic-auth": "~2.0.1",
+        "debug": "2.6.9",
+        "depd": "~2.0.0",
+        "on-finished": "~2.3.0",
+        "on-headers": "~1.0.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "depd": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/depd/download/depd-2.0.0.tgz",
+          "integrity": "sha1-tpYWPMdXVg0JzyLMj60Vcbeedt8="
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.3.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.3.tgz",
+      "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI="
+    },
+    "mysql": {
+      "version": "2.18.1",
+      "resolved": "https://registry.npm.taobao.org/mysql/download/mysql-2.18.1.tgz",
+      "integrity": "sha1-IlQUOFXFqMc4JeRSK68uoCF2Zxc=",
+      "requires": {
+        "bignumber.js": "9.0.0",
+        "readable-stream": "2.3.7",
+        "safe-buffer": "5.1.2",
+        "sqlstring": "2.3.1"
+      }
+    },
+    "needle": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npm.taobao.org/needle/download/needle-2.6.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fneedle%2Fdownload%2Fneedle-2.6.0.tgz",
+      "integrity": "sha1-JNu1XyUJ4jJLSpnWH0E5ggE8zb4=",
+      "requires": {
+        "debug": "^3.2.6",
+        "iconv-lite": "^0.4.4",
+        "sax": "^1.2.4"
+      }
+    },
+    "negotiator": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz?cache=0&sync_timestamp=1589682752355&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnegotiator%2Fdownload%2Fnegotiator-0.6.2.tgz",
+      "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs="
+    },
+    "node-gyp": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npm.taobao.org/node-gyp/download/node-gyp-7.1.2.tgz",
+      "integrity": "sha1-IagQrrsYcSAlHDvOyXmvFYexiK4=",
+      "requires": {
+        "env-paths": "^2.2.0",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.2.3",
+        "nopt": "^5.0.0",
+        "npmlog": "^4.1.2",
+        "request": "^2.88.2",
+        "rimraf": "^3.0.2",
+        "semver": "^7.3.2",
+        "tar": "^6.0.2",
+        "which": "^2.0.2"
+      },
+      "dependencies": {
+        "chownr": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/chownr/download/chownr-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchownr%2Fdownload%2Fchownr-2.0.0.tgz",
+          "integrity": "sha1-Fb++U9LqtM9w8YqM1o6+Wzyx3s4="
+        },
+        "fs-minipass": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-2.1.0.tgz?cache=0&sync_timestamp=1579628575109&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffs-minipass%2Fdownload%2Ffs-minipass-2.1.0.tgz",
+          "integrity": "sha1-f1A2/b8SxjwWkZDL5BmchSJx+fs=",
+          "requires": {
+            "minipass": "^3.0.0"
+          }
+        },
+        "minipass": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npm.taobao.org/minipass/download/minipass-3.1.3.tgz",
+          "integrity": "sha1-fUL/HzljVILhX5zbUxhN7r1YFf0=",
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "minizlib": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npm.taobao.org/minizlib/download/minizlib-2.1.2.tgz",
+          "integrity": "sha1-6Q00Zrogm5MkUVCKEc49NjIUWTE=",
+          "requires": {
+            "minipass": "^3.0.0",
+            "yallist": "^4.0.0"
+          }
+        },
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-1.0.4.tgz?cache=0&sync_timestamp=1587535418745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-1.0.4.tgz",
+          "integrity": "sha1-PrXtYmInVteaXw4qIh3+utdcL34="
+        },
+        "nopt": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npm.taobao.org/nopt/download/nopt-5.0.0.tgz",
+          "integrity": "sha1-UwlCu1ilEvzK/lP+IQ8TolNV3Ig=",
+          "requires": {
+            "abbrev": "1"
+          }
+        },
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-3.0.2.tgz?cache=0&sync_timestamp=1581229865753&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-3.0.2.tgz",
+          "integrity": "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=",
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "semver": {
+          "version": "7.3.5",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-7.3.5.tgz",
+          "integrity": "sha1-C2Ich5NI2JmOSw5L6Us/EuYBjvc=",
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "tar": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npm.taobao.org/tar/download/tar-6.1.0.tgz",
+          "integrity": "sha1-0XJOm8wEuXexjVxXOzM6IgcimoM=",
+          "requires": {
+            "chownr": "^2.0.0",
+            "fs-minipass": "^2.0.0",
+            "minipass": "^3.0.0",
+            "minizlib": "^2.1.1",
+            "mkdirp": "^1.0.3",
+            "yallist": "^4.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz",
+          "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI="
+        }
+      }
+    },
+    "node-pre-gyp": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npm.taobao.org/node-pre-gyp/download/node-pre-gyp-0.14.0.tgz?cache=0&sync_timestamp=1612890458868&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-pre-gyp%2Fdownload%2Fnode-pre-gyp-0.14.0.tgz",
+      "integrity": "sha1-mgWWUzuHcom8rU4UOYLKPZBN3IM=",
+      "requires": {
+        "detect-libc": "^1.0.2",
+        "mkdirp": "^0.5.1",
+        "needle": "^2.2.1",
+        "nopt": "^4.0.1",
+        "npm-packlist": "^1.1.6",
+        "npmlog": "^4.0.2",
+        "rc": "^1.2.7",
+        "rimraf": "^2.6.1",
+        "semver": "^5.3.0",
+        "tar": "^4.4.2"
+      }
+    },
+    "nopt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npm.taobao.org/nopt/download/nopt-4.0.3.tgz?cache=0&sync_timestamp=1597649905420&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnopt%2Fdownload%2Fnopt-4.0.3.tgz",
+      "integrity": "sha1-o3XK2dAv2SEnjZVMIlTVqlfhXkg=",
+      "requires": {
+        "abbrev": "1",
+        "osenv": "^0.1.4"
+      }
+    },
+    "npm-bundled": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/npm-bundled/download/npm-bundled-1.1.1.tgz",
+      "integrity": "sha1-Ht1XCGWpTNsbyCIHdeKUZsn7I0s=",
+      "requires": {
+        "npm-normalize-package-bin": "^1.0.1"
+      }
+    },
+    "npm-normalize-package-bin": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/npm-normalize-package-bin/download/npm-normalize-package-bin-1.0.1.tgz",
+      "integrity": "sha1-bnmkHyP9I1wGIyGCKNp9nCO49uI="
+    },
+    "npm-packlist": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npm.taobao.org/npm-packlist/download/npm-packlist-1.4.8.tgz?cache=0&sync_timestamp=1616694502609&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-packlist%2Fdownload%2Fnpm-packlist-1.4.8.tgz",
+      "integrity": "sha1-Vu5swTW5+YrT1Rwcldoiu7my7z4=",
+      "requires": {
+        "ignore-walk": "^3.0.1",
+        "npm-bundled": "^1.0.1",
+        "npm-normalize-package-bin": "^1.0.1"
+      }
+    },
+    "npmlog": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npm.taobao.org/npmlog/download/npmlog-4.1.2.tgz",
+      "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=",
+      "requires": {
+        "are-we-there-yet": "~1.1.2",
+        "console-control-strings": "~1.1.0",
+        "gauge": "~2.7.3",
+        "set-blocking": "~2.0.0"
+      }
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+    },
+    "oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz?cache=0&sync_timestamp=1589682811909&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foauth-sign%2Fdownload%2Foauth-sign-0.9.0.tgz",
+      "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU="
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+    },
+    "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.2",
+      "resolved": "https://registry.npm.taobao.org/on-headers/download/on-headers-1.0.2.tgz",
+      "integrity": "sha1-dysK5qqlJcOZ5Imt+tkMQD6zwo8="
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+    },
+    "osenv": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npm.taobao.org/osenv/download/osenv-0.1.5.tgz?cache=0&sync_timestamp=1589682762332&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fosenv%2Fdownload%2Fosenv-0.1.5.tgz",
+      "integrity": "sha1-hc36+uso6Gd/QW4odZK18/SepBA=",
+      "requires": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.0"
+      }
+    },
+    "parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz",
+      "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ="
+    },
+    "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="
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+    },
+    "process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I="
+    },
+    "proxy-addr": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.6.tgz",
+      "integrity": "sha1-/cIzZQVEfT8vLGOO0nLK9hS7sr8=",
+      "requires": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.9.1"
+      }
+    },
+    "psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npm.taobao.org/psl/download/psl-1.8.0.tgz",
+      "integrity": "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ="
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz?cache=0&sync_timestamp=1589682803838&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpunycode%2Fdownload%2Fpunycode-2.1.1.tgz",
+      "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew="
+    },
+    "qs": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz?cache=0&sync_timestamp=1616385315895&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.7.0.tgz",
+      "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw="
+    },
+    "range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz",
+      "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE="
+    },
+    "raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz",
+      "integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=",
+      "requires": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      }
+    },
+    "rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npm.taobao.org/rc/download/rc-1.2.8.tgz",
+      "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=",
+      "requires": {
+        "deep-extend": "^0.6.0",
+        "ini": "~1.3.0",
+        "minimist": "^1.2.0",
+        "strip-json-comments": "~2.0.1"
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz?cache=0&sync_timestamp=1589682741447&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.7.tgz",
+      "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=",
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npm.taobao.org/request/download/request-2.88.2.tgz?cache=0&sync_timestamp=1589682741998&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frequest%2Fdownload%2Frequest-2.88.2.tgz",
+      "integrity": "sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM=",
+      "requires": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "dependencies": {
+        "qs": {
+          "version": "6.5.2",
+          "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz?cache=0&sync_timestamp=1616385315895&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.5.2.tgz",
+          "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY="
+        }
+      }
+    },
+    "rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-2.7.1.tgz?cache=0&sync_timestamp=1589682814592&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-2.7.1.tgz",
+      "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=",
+      "requires": {
+        "glob": "^7.1.3"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz?cache=0&sync_timestamp=1589682795646&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafe-buffer%2Fdownload%2Fsafe-buffer-5.1.2.tgz",
+      "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz?cache=0&sync_timestamp=1589682784154&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafer-buffer%2Fdownload%2Fsafer-buffer-2.1.2.tgz",
+      "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo="
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz",
+      "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk="
+    },
+    "semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz",
+      "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc="
+    },
+    "send": {
+      "version": "0.17.1",
+      "resolved": "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz",
+      "integrity": "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg=",
+      "requires": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.7.2",
+        "mime": "1.6.0",
+        "ms": "2.1.1",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.1",
+        "statuses": "~1.5.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566533140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "requires": {
+            "ms": "2.0.0"
+          },
+          "dependencies": {
+            "ms": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+            }
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz?cache=0&sync_timestamp=1607433842694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.1.tgz",
+          "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo="
+        }
+      }
+    },
+    "serve-static": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz",
+      "integrity": "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk=",
+      "requires": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.17.1"
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+    },
+    "setprototypeof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz",
+      "integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM="
+    },
+    "signal-exit": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz?cache=0&sync_timestamp=1589682814780&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsignal-exit%2Fdownload%2Fsignal-exit-3.0.3.tgz",
+      "integrity": "sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw="
+    },
+    "sqlstring": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
+      "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A="
+    },
+    "sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npm.taobao.org/sshpk/download/sshpk-1.16.1.tgz",
+      "integrity": "sha1-+2YcC+8ps520B2nuOfpwCT1vaHc=",
+      "requires": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      }
+    },
+    "statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+    },
+    "string-width": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+      "requires": {
+        "code-point-at": "^1.0.0",
+        "is-fullwidth-code-point": "^1.0.0",
+        "strip-ansi": "^3.0.0"
+      }
+    },
+    "string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz",
+      "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
+      "requires": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+    },
+    "supervisor": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npm.taobao.org/supervisor/download/supervisor-0.12.0.tgz",
+      "integrity": "sha1-3n5jNwFbKRhRwQ81OMSn8EkX7ME="
+    },
+    "tar": {
+      "version": "4.4.13",
+      "resolved": "https://registry.npm.taobao.org/tar/download/tar-4.4.13.tgz",
+      "integrity": "sha1-Q7NkvFKIjVVSmGN7ENYHkCVKtSU=",
+      "requires": {
+        "chownr": "^1.1.1",
+        "fs-minipass": "^1.2.5",
+        "minipass": "^2.8.6",
+        "minizlib": "^1.2.1",
+        "mkdirp": "^0.5.0",
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.3"
+      }
+    },
+    "toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz",
+      "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM="
+    },
+    "tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.5.0.tgz?cache=0&sync_timestamp=1589682815640&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftough-cookie%2Fdownload%2Ftough-cookie-2.5.0.tgz",
+      "integrity": "sha1-zZ+yoKodWhK0c72fuW+j3P9lreI=",
+      "requires": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      }
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+    },
+    "type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz",
+      "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=",
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      }
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+    },
+    "uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npm.taobao.org/uri-js/download/uri-js-4.4.1.tgz?cache=0&sync_timestamp=1610237624359&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furi-js%2Fdownload%2Furi-js-4.4.1.tgz",
+      "integrity": "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=",
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "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="
+    },
+    "uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npm.taobao.org/uuid/download/uuid-3.4.0.tgz",
+      "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4="
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz",
+      "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=",
+      "requires": {
+        "isexe": "^2.0.0"
+      }
+    },
+    "wide-align": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npm.taobao.org/wide-align/download/wide-align-1.1.3.tgz",
+      "integrity": "sha1-rgdOa9wMFKQx6ATmJFScYzsABFc=",
+      "requires": {
+        "string-width": "^1.0.2 || 2"
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz",
+      "integrity": "sha1-27fa+b/YusmrRev2ArjLrQ1dCP0="
+    }
+  }
+}

+ 434 - 0
package.json

@@ -0,0 +1,434 @@
+{
+  "name": "cocoroboLabor",
+  "main": "app.js",
+  "scripts": {
+    "autoStart": "supervisor start app.js",
+    "autoStop": "supervisor stop app.js",
+    "restart": "supervisor restart app.js",
+    "start": "supervisor start app.js",
+    "stop": "supervisor stop app.js",
+    "dev": "supervisor app.js",
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "BSD-2-Clause",
+  "private": true,
+  "dependencies": {
+    "accepts": {
+      "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+      "requires": {
+        "mime-types": "2.1.17",
+        "negotiator": "0.6.1"
+      },
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+      "version": "1.3.4"
+    },
+    "array-flatten": {
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "version": "1.1.1"
+    },
+    "bcryptjs": "^2.4.3",
+    "bignumber.js": {
+      "integrity": "sha512-LDXpJKVzEx2/OqNbG9mXBNvHuiRL4PzHCGfnANHMJ+fv68Ads3exDVJeGDJws+AoNEuca93bU3q+S0woeUaCdg==",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.0.4.tgz",
+      "version": "4.0.4"
+    },
+    "body-parser": {
+      "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"
+      },
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+      "version": "1.18.2"
+    },
+    "bytes": {
+      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+      "version": "3.0.0"
+    },
+    "content-disposition": {
+      "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+      "version": "0.5.2"
+    },
+    "content-type": {
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "version": "1.0.4"
+    },
+    "cookie": {
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+      "version": "0.3.1"
+    },
+    "cookie-signature": {
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "version": "1.0.6"
+    },
+    "core-util-is": {
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "version": "1.0.2"
+    },
+    "debug": {
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "requires": {
+        "ms": "2.0.0"
+      },
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "version": "2.6.9"
+    },
+    "depd": {
+      "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+      "version": "1.1.1"
+    },
+    "destroy": {
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "version": "1.0.4"
+    },
+    "ee-first": {
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "version": "1.1.1"
+    },
+    "encodeurl": {
+      "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+      "version": "1.0.1"
+    },
+    "escape-html": {
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "version": "1.0.3"
+    },
+    "etag": {
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "version": "1.8.1"
+    },
+    "express": "^4.17.1",
+    "finalhandler": {
+      "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"
+      },
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+      "version": "1.1.0"
+    },
+    "forwarded": {
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "version": "0.1.2"
+    },
+    "fresh": {
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "version": "0.5.2"
+    },
+    "http-errors": {
+      "dependencies": {
+        "setprototypeof": {
+          "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+          "version": "1.0.3"
+        }
+      },
+      "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+      "requires": {
+        "depd": "1.1.1",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.0.3",
+        "statuses": "1.3.1"
+      },
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+      "version": "1.6.2"
+    },
+    "iconv-lite": {
+      "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+      "version": "0.4.19"
+    },
+    "inherits": {
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "version": "2.0.3"
+    },
+    "ipaddr.js": {
+      "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
+      "version": "1.5.2"
+    },
+    "isarray": {
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "version": "1.0.0"
+    },
+    "loader": "^2.1.1",
+    "media-typer": {
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "version": "0.3.0"
+    },
+    "merge-descriptors": {
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "version": "1.0.1"
+    },
+    "methods": {
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "version": "1.1.2"
+    },
+    "mime": {
+      "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+      "version": "1.4.1"
+    },
+    "mime-db": {
+      "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+      "version": "1.30.0"
+    },
+    "mime-types": {
+      "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+      "requires": {
+        "mime-db": "1.30.0"
+      },
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+      "version": "2.1.17"
+    },
+    "morgan": "^1.9.1",
+    "ms": {
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "version": "2.0.0"
+    },
+    "mssql": {
+      "dependencies": {
+        "generic-pool": {
+          "integrity": "sha1-rwTcLDJc/Ll1Aj+lK/zpYXp0Nf0=",
+          "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.1.1.tgz",
+          "version": "2.1.1"
+        },
+        "tedious": {
+          "dependencies": {
+            "big-number": {
+              "integrity": "sha1-4GeVx+bVy1ldysgjb7U1zYyUdyM=",
+              "resolved": "https://registry.npmjs.org/big-number/-/big-number-0.3.0.tgz",
+              "version": "0.3.0"
+            },
+            "iconv-lite": {
+              "integrity": "sha1-r1fhTCzNiyfpRde03gcazNWfALs=",
+              "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.2.tgz",
+              "version": "0.4.2"
+            },
+            "sprintf": {
+              "integrity": "sha1-6JJfyYlOGqaJnpCRx/KhITC3DeU=",
+              "resolved": "https://registry.npmjs.org/sprintf/-/sprintf-0.1.1.tgz",
+              "version": "0.1.1"
+            }
+          },
+          "integrity": "sha1-UjVmIQc5jepgusn96Rk6n7JDZrA=",
+          "requires": {
+            "big-number": "0.3.0",
+            "iconv-lite": "0.4.2",
+            "sprintf": "0.1.1"
+          },
+          "resolved": "https://registry.npmjs.org/tedious/-/tedious-1.8.0.tgz",
+          "version": "1.8.0"
+        }
+      },
+      "integrity": "sha1-kDnbuxnGTzutC2mj0RQ//BLuiho=",
+      "requires": {
+        "generic-pool": "2.1.1",
+        "tedious": "1.8.0"
+      },
+      "resolved": "https://registry.npmjs.org/mssql/-/mssql-1.3.0.tgz",
+      "version": "1.3.0"
+    },
+    "mysql": "^2.17.1",
+    "negotiator": {
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "version": "0.6.1"
+    },
+    "node-gyp": "^7.1.2",
+    "node-pre-gyp": "^0.14.0",
+    "on-finished": {
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "requires": {
+        "ee-first": "1.1.1"
+      },
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "version": "2.3.0"
+    },
+    "parseurl": {
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "version": "1.3.2"
+    },
+    "path-to-regexp": {
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "version": "0.1.7"
+    },
+    "process-nextick-args": {
+      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "version": "1.0.7"
+    },
+    "proxy-addr": {
+      "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
+      "requires": {
+        "forwarded": "0.1.2",
+        "ipaddr.js": "1.5.2"
+      },
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
+      "version": "2.0.2"
+    },
+    "qs": {
+      "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+      "version": "6.5.1"
+    },
+    "range-parser": {
+      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+      "version": "1.2.0"
+    },
+    "raw-body": {
+      "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+      "requires": {
+        "bytes": "3.0.0",
+        "http-errors": "1.6.2",
+        "iconv-lite": "0.4.19",
+        "unpipe": "1.0.0"
+      },
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+      "version": "2.3.2"
+    },
+    "readable-stream": {
+      "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"
+      },
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+      "version": "2.3.3"
+    },
+    "request": "^2.88.0",
+    "safe-buffer": {
+      "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "version": "5.1.1"
+    },
+    "send": {
+      "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"
+      },
+      "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+      "version": "0.16.1"
+    },
+    "serve-static": {
+      "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"
+      },
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+      "version": "1.13.1"
+    },
+    "setprototypeof": {
+      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+      "version": "1.1.0"
+    },
+    "sqlstring": {
+      "integrity": "sha1-UluKT9Jtb3GqYegipsr5dtMa0qg=",
+      "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.0.tgz",
+      "version": "2.3.0"
+    },
+    "statuses": {
+      "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+      "version": "1.3.1"
+    },
+    "string_decoder": {
+      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+      "requires": {
+        "safe-buffer": "5.1.1"
+      },
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+      "version": "1.0.3"
+    },
+    "supervisor": "^0.12.0",
+    "type-is": {
+      "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "2.1.17"
+      },
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
+      "version": "1.6.15"
+    },
+    "unpipe": {
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "version": "1.0.0"
+    },
+    "util-deprecate": {
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "version": "1.0.2"
+    },
+    "utils-merge": {
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "version": "1.0.1"
+    },
+    "vary": {
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "version": "1.1.2"
+    }
+  }
+}

+ 123 - 0
pbl.js

@@ -0,0 +1,123 @@
+// ROUTES FOR OUR API
+// =============================================================================
+var express = require('express');
+var bcrypt = require('bcryptjs');
+var router = express.Router(); // get an instance of the express Router
+const querystring = require('querystring');
+var mysql = require('./mysql');
+// const _mysqlLabor = ["123.58.32.151", "pbl"]; //双创數據庫信息
+// const _mysqlLabor = ["172.16.12.5", "pbl"]; //双创數據庫信息
+var crypto = require('crypto');
+var https = require('https');
+
+//統壹處理區域
+router.use(async function(req, res, next) {
+    await asynnext(req, res, next);
+    //// make sure we go to the next routes and don't stop here
+    //res.end("");
+});
+
+/**
+ * @des 參數解釋同上
+ */
+function asynnext(req, res, next) {
+    //異步處理
+    return new Promise(async(resolve, reject) => {
+        next();
+        //resolve(true);aa
+    });
+}
+/*測試*/
+router.route('/a').all((req, res, next) => {
+    var json = queryString(req.url);
+    getmysql(req, res, "a", json['ph'], json['pa']);
+});
+router.route('/b').all((req, res, next) => {
+    postmysql(req, res, "b");
+});
+
+queryString = function(url) {
+    var a = url.split("?");
+    var json = querystring.parse(a[1])
+    return json;
+}
+
+//post存儲過程處理
+postmysql = function(req, res, functionname) {
+    //mode的處理
+    if (req.body[0]) {
+        p = Object.values(req.body[0]);
+        p.unshift(_mysqlLabor[0], _mysqlLabor[1], functionname);
+        //執行存儲過程
+        mysql.usselect(p, function(ret) { res.end(JSON.stringify(ret)); });
+    }
+}
+
+//post存儲過程處理
+postmysql2 = function(req, res, functionname) {
+    //mode的處理
+    if (req.body) {
+        p = Object.values(req.body)[0].split(",");
+        p.unshift(_mysqlLabor[0], _mysqlLabor[1], functionname);
+        //執行存儲過程
+        mysql.usselect(p, function(ret) { res.end(JSON.stringify(ret)); });
+    }
+}
+
+//post存儲過程處理
+postmysql3 = function(req, res, functionname) {
+    //mode的處理
+    if (req.body) {
+        p = Object.values(req.body);
+        p.unshift(_mysqlLabor[0], _mysqlLabor[1], functionname);
+        //執行存儲過程
+        mysql.usselect(p, function(ret) { res.end(JSON.stringify(ret)); });
+    }
+}
+
+//get獲取數據庫信息
+getmysql = function(req, res, functionname, ...p) {
+    p = p || [];
+    p.unshift(_mysqlLabor[0], _mysqlLabor[1], functionname);
+    //執行存儲過程
+    mysql.usselect(p, function(ret) { res.end(JSON.stringify(ret)); }); //
+}
+
+
+//post存储过程处理
+
+userpostmysql = function(req, res, functionname) {
+
+    //mode的处理
+
+    if (req.body.mode) {
+
+        p = req.body.mode.split(",");
+
+        p.unshift(_mysqluser[0], _mysqluser[1], functionname);
+
+        //执行存储过程
+
+        mysql.usselect(p, function(ret) { res.end(JSON.stringify(ret)); });
+
+    }
+
+}
+
+
+
+//get获取数据库信息
+
+usergetmysql = function(req, res, functionname, ...p) {
+
+    p = p || [];
+
+    p.unshift(_mysqluser[0], _mysqluser[1], functionname);
+
+    //执行存储过程
+
+    mysql.usselect(p, function(ret) { res.end(JSON.stringify(ret)); }); //
+
+}
+
+module.exports = router;

+ 98 - 0
sqlserver.js

@@ -0,0 +1,98 @@
+var mssql = require('mssql'); //包含mssql模块
+//----------------------------------mssql 连接设置--------------------------------------
+function mssqlconnet(ho, db) {
+    return {
+        user: 'usestudio',
+        password: 'usestudio-1',
+        server: ho,
+        database: db,
+        port: 11302
+    };
+}
+
+//----------------------------------mssql 查询语句--------------------------------------
+exports.usselect = function (paramsarr, callback) {
+    var _params; //截取存储过程参数数组变量
+    var _sql = "EXEC " + paramsarr[2]; //拼接sqlserver语句
+    if (paramsarr[3]) { //判断是否存在参数
+        _params = paramsarr.slice(3); //截取参数
+    }
+    console.log(paramsarr[0]); //输出数据库地址
+    console.log(paramsarr[1]); //输出数据库名称
+
+    var config = mssqlconnet(paramsarr[0], paramsarr[1]); //更新设置
+    var connection = new mssql.ConnectionPool(config, function (err) { //创建连接
+        var _ps = new mssql.PreparedStatement(connection); //调用查询方法
+        var _param = {}; //定义存储过程参数对象
+        if (_params) { //判断是否存在参数
+            _params.forEach((value, key) => { //循环处理参数
+                var _key = `param${key}`; //拼接参数名称
+                _param[_key] = value; //设置的参数对象中
+                if (typeof value == "number") { //数字类型参数处理
+                    _ps.input(index, mssql.Int); //添加整形参数类型
+                } else if (typeof value == "string" && /^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$/.test(value)) { //guid参数处理
+                    _ps.input(_key, mssql.UniqueIdentifier); //添加guid参数类型
+                } else if (typeof value == "string") { //字符串参数处理
+                    _ps.input(_key, mssql.NVarChar); //添加字符串参数类型
+                }
+                _sql += ` @${_key},`; //拼接sql语句
+            });
+            _sql = _sql.slice(0, _sql.length - 1); //删除多余“,”号
+        }
+
+        _ps.prepare(_sql, function (err) { //格式化处理预执行sql语句
+            if (err) //存在错误则输出日志
+                console.log(err);
+            _ps.execute(_param, function (err, data) { //传入参数执行sql语句
+                if (err)
+                    console.log(err);
+                else
+                    callback(JSON.stringify(data.recordsets)); //输出结果
+                _ps.unprepare(function (err) { //释放连接
+                    if (err) //存在错误则输出日志
+                        console.log(err);
+                });
+            });
+        });
+    });
+}
+
+// var sql = require('mssql');//包含mssql模块
+// //----------------------------------mssql 连接设置--------------------------------------
+// function mssqlconnet(ho, db) {
+//     return {
+//         user: 'usestudio',
+//         password: 'usestudio-1',
+//         server: ho,
+//         database: db,
+//         port:11302
+//     };
+// }
+
+// exports.usselect = function (pArr, callback) {
+//     var _pro = "", i; //定义循环变量,对字符串解密
+//     //for (i = 0; i < pArr.length; i++) { pArr[i] = decodeURIComponent(pArr[i]); } //解密中文字符串。
+
+//     //如果前台没有传参数过来,则需进这里
+//     if (!pArr[3]) {
+//         _pro = "EXEC " + pArr[2];
+//     } else {  //否则有参数
+//         _pro = "EXEC " + "" + pArr[2] + " '"; //命令拼凑
+//         for (i = 3; i < pArr.length; i++) { _pro += pArr[i]; if (i < pArr.length - 1) _pro += "','"; } //拼凑参数
+//         _pro += "'"; //拼凑结束。
+//     } 
+
+//     console.log(pArr[0]);
+//  console.log(pArr[1]);
+
+
+//     var config = mssqlconnet(pArr[0], pArr[1]);//更新设置
+//     var connection = new sql.ConnectionPool(config, function (err) {//创建连接
+
+// 	var request = new sql.Request(connection);//创建连接
+//         request.query(_pro, function (err, recordsets) {//执行语句
+// 	 callback(JSON.stringify(recordsets)); //返回json数据
+//         });
+
+//     });
+// }

+ 550 - 0
upload.js

@@ -0,0 +1,550 @@
+const multer = require("multer");
+const upload = require("express").Router();
+const { exec } = require("child_process");
+const { mkdir, readdir, readFile } = require("fs");
+const { homedir } = require("os");
+const { join } = require("path");
+const aws = require("aws-sdk");
+const multerS3 = require("multer-s3");
+const config = require('./config');
+const axios = require('axios');
+
+
+const spacesEndpoint = new aws.Endpoint("sgp1.digitaloceanspaces.com");
+const s3 = new aws.S3({ endpoint: spacesEndpoint });
+const temp = `${homedir()}/temp`;
+
+const updateStatus = (urlType,courseId=null, chapterId=null, property,status,roomId=null) =>{
+  axios({
+    method:'put',
+    url:`${config.server}/${urlType}/upload`,
+    data:{
+      courseId:courseId,
+      chapterId:chapterId,
+      [property]:status,
+      roomId:roomId
+    },
+    headers:{
+      'Authorization':'yezicoco'
+    }
+  })
+  .then((res) => {
+    console.log(res.data)
+  })
+  .catch((err) => {
+    console.log(err)
+  })
+}
+const updateDBdata = (urlType,payload) => {
+    //params
+    //urlType: chapter or curriculum
+
+    axios({
+      method:'put',
+      url:`${config.server}/${urlType}/upload`,
+      data:payload,
+      headers:{
+        'Authorization':'yezicoco'
+      }
+    })
+    .then((res)=>{
+      console.log(res.data)
+    })
+    .catch((err)=>{
+      console.log(err)
+    })
+}
+const queryLastIndex = (urlType, chapterId,property) =>
+  new Promise(function(resolve, reject){
+        axios({
+          method:'get',
+          url:`${config.server}/${urlType}/pre/id/${chapterId}`,
+          headers:{
+            'Authorization':'yezicoco'
+          }
+        })
+        .then((res)=>{
+          resolve(res.data[property].length)
+        })
+        .catch((err)=>{
+          console.log(err)
+        })
+  })
+
+const queryLatestData = (urlType, chapterId, property) =>
+  new Promise ((resolve, reject) => {
+    axios({
+      method:'get',
+      url:`${config.server}/${urlType}/pre/id/${chapterId}`,
+      headers:{
+        'Authorization':'yezicoco'
+      }
+    })
+    .then((res)=>{
+      resolve(res.data[property])
+    })
+    .catch((err)=>{
+      console.log(err)
+    })
+  })
+
+
+
+const generatorMultipleArray = (courseId, chapterId, type,length,format='',filename='') =>{
+  let arr = [];
+  let baseUrl = `https://ccrb-cs.sgp1.digitaloceanspaces.com/course/${courseId}/${type}/${chapterId}/${chapterId}_`
+  for(let index = 1 ; index <= length;index++){
+    arr.push(baseUrl+index+'.'+format + filename);
+  }
+  return arr;
+};
+const generatorRoomMultipleArray = (roomId, type,length,format='',filename='') =>{
+  let arr = [];
+  let baseUrl = `https://ccrb-cs.sgp1.digitaloceanspaces.com/room/${roomId}/${type}/${roomId}_`
+  for(let index = 1 ; index <= length;index++){
+    arr.push(baseUrl+index+'.'+format + filename);
+  }
+  return arr;
+};
+
+const uploadAttachment2space = () => multer({
+  storage: multerS3({
+    s3: s3,
+    bucket: (req, file, cb) => {
+      cb(null, `ccrb-cs/course/${req.body.courseId}/attachments/${req.body.chapterId}`);
+    },
+    acl: "public-read",
+    key: function(req, file, cb) {
+      cb(null,file.originalname);
+    }
+  })
+});
+
+
+const uploadFile2Space = (type,category) =>{
+  if(category === 'course'){
+    return (course, bucket='', dir, file) => new Promise((resovle, reject) => {
+      const params = {
+        Bucket: `ccrb-cs/course/${course}/${type}${bucket?'/':''}${bucket}`,
+        Key: `${file}`,
+        ACL: "public-read"
+      };
+      readFile(`${dir}/${file}`, (err, buf) => {
+        if (err)
+          return console.error(err);
+        params.Body = buf;
+        s3.putObject(params, (err,data) => {
+          if (err) {
+            console.error(err);
+            return reject(err);
+          }else{
+            let response = {
+              status:200,
+              url:`${config.space}/course/${course}/${type}${bucket?'/':''}${bucket}/${file}`,
+            }
+            return resovle(response);
+          }
+        });
+      });
+    })
+  }else if(category === 'room'){
+    return (roomId, bucket='', dir, file) => new Promise((resovle, reject) => {
+      const params = {
+        Bucket: `ccrb-cs/room/${roomId}/${type}${bucket?'/':''}${bucket}`,
+        Key: `${file}`,
+        ACL: "public-read"
+      };
+      readFile(`${dir}/${file}`, (err, buf) => {
+        if (err)
+          return console.error(err);
+        params.Body = buf;
+        s3.putObject(params, (err,data) => {
+          if (err) {
+            console.error(err);
+            return reject(err);
+          }else{
+            let response = {
+              status:200,
+              url:`${config.space}/room/${roomId}/${type}${bucket?'/':''}${bucket}/${file}`,
+            }
+            return resovle(response);
+          }
+        });
+      });
+    })
+  }
+};
+
+//course
+const slide2SpacePromise = uploadFile2Space('slides','course');
+const clip2SpacePromise = uploadFile2Space('clips','course');
+const thumb2SpacePromise = uploadFile2Space('thumbs','course');
+const cover2SpacePromise = uploadFile2Space('covers','course');
+const demo2SpacePromise = uploadFile2Space('demos','course');
+//pdf
+const roomSlide2SpacePromise = uploadFile2Space('slides','room');
+
+
+const uploadPdf2Server = () => multer({
+  storage: multer.diskStorage({
+    destination: (req, file, cb) => {
+      const filename = req.body.roomId? req.body.roomId:req.body.chapterId;
+      const dir = `${temp}/pdf/${filename}`;
+      mkdir(dir, { recursive: true }, () => cb(null, dir));
+    },
+    filename: (req, file, cb) => {
+      const filename = req.body.roomId? req.body.roomId:req.body.chapterId;
+      return cb(null, `${filename}.pdf`)
+    }
+  })
+});
+
+const runBash = command => new Promise((resovle, reject) => {
+  exec(command, (err,stdout, stderr) => err? reject(err): resovle(stdout));
+});
+
+const uploadJpg2Space = (courseId, chapterId, dir, files, index,bashmsg,category) =>
+  {if(category === 'course'){
+    slide2SpacePromise(courseId, chapterId, dir, files[index])
+      .then((res) => {
+        delete files[index];
+        if (Object.keys(files).length === 0) {
+          console.log(bashmsg);
+          let pages = bashmsg.slice(bashmsg.indexOf('Total pages: ')+13);
+          let slides = generatorMultipleArray(courseId, chapterId, 'slides', pages, 'jpg');
+          updateDBdata('chapter',{courseId:courseId,chapterId:chapterId,slideUrl:slides})
+          exec(`rm -rf ${dir}`, err => err? console.error(err): '');
+        }
+      })
+      .catch(err => {
+        // catch the error from uploading jpg file to spaces
+        console.error(err);
+        uploadJpg2Space(courseId, chapterId, dir, files, index);
+      });
+  }else if(category === 'room'){
+    roomSlide2SpacePromise(courseId, chapterId, dir, files[index])
+      .then((res) => {
+        delete files[index];
+        if (Object.keys(files).length === 0) {
+          console.log(bashmsg);
+          let pages = bashmsg.slice(bashmsg.indexOf('Total pages: ')+13);
+          let slides = generatorRoomMultipleArray(courseId,'slides', pages, 'jpg');
+          updateDBdata('room',{roomId:courseId,slideUrl:slides})
+          exec(`rm -rf ${dir}`, err => err? console.error(err): '');
+        }
+      })
+      .catch(err => {
+        // catch the error from uploading jpg file to spaces
+        console.error(err);
+        uploadJpg2Space(courseId, chapterId, dir, files, index);
+      });
+  }
+}
+
+upload.post("/pdf", (req, res) => {
+  uploadPdf2Server().single("pdf")(req, res, err => {
+    if (err) {
+      console.error(err);
+      return res.status(401).send("upload pdf failed");
+    }
+    const { courseId, chapterId ,roomId} = req.body;
+
+    if(req.body.courseId && req.body.chapterId){
+      const raw = `${temp}/pdf/${chapterId}`;
+      const slide = `${raw}/slides`;
+      //Update status before run bash
+      //to declare property is not empty
+      updateStatus('chapter',courseId, chapterId, 'slideUrl','pending');
+
+      runBash(`./pdf2jpg.bash ${raw} ${chapterId}`)
+        .then((res) => {
+          readdir(slide, (err, files) => {
+            if (err)
+              return console.error(err);
+            const filesTree = {};
+            files.forEach((file, i) => (filesTree[i] = file));
+            files.forEach((file, i) => {
+              let bash = {
+                message:res
+              }
+              uploadJpg2Space(courseId, chapterId, slide, filesTree, i, bash.message,'course');
+            });
+          });
+        })
+        .catch(err => console.error(err));
+      res.send("OK");
+    }else if (req.body.roomId) {
+      const raw = `${temp}/pdf/${roomId}`;
+      const slide = `${raw}/slides`;
+      //Update status before run bash
+      //to declare property is not empty
+      updateStatus('room',null,null, 'slideUrl','pending',req.body.roomId);
+
+      runBash(`./pdf2jpg.bash ${raw} ${roomId}`)
+        .then((res) => {
+          readdir(slide, (err, files) => {
+            if (err)
+              return console.error(err);
+            const filesTree = {};
+            files.forEach((file, i) => (filesTree[i] = file));
+            files.forEach((file, i) => {
+              let bash = {
+                message:res
+              }
+              uploadJpg2Space(roomId, chapterId, slide, filesTree, i, bash.message,'room');
+            });
+          });
+        })
+        .catch(err => console.error(err));
+      res.send("OK");
+    }else{
+      res.status(422).send('INVALID PAYLOAD');
+    }
+  });
+});
+
+
+const uploadClip2Server = () => multer({
+  storage: multer.diskStorage({
+    destination: (req, file, cb) => {
+      const dir = `${temp}/raw-clips/`;
+      mkdir(dir, { recursive: true }, () => cb(null, dir));
+    },
+    filename: (req, file, cb) => {
+      const suffix = file.originalname.match(/\.[\w]+$/);
+      cb(null, `${req.body.uuid}${suffix ? suffix[0] : ""}`);
+    }
+  })
+});
+
+const uploadClip2Space = (courseId, chapterId, dir, filename) =>
+  clip2SpacePromise(courseId, chapterId, dir, filename)
+    .then((res) =>{
+      if(res.status === 200){
+        exec(`rm ${dir}/${filename}`,err => err? console.error(err): '');
+
+        queryLastIndex('chapter',chapterId,'clipUrl')
+          .then((lastIndex)=>{
+            console.log(lastIndex);
+            let clipUrl = generatorMultipleArray(courseId, chapterId, 'clips', lastIndex+1, 'mp4');
+            let thumbUrl = generatorMultipleArray(courseId, chapterId, 'thumbs', lastIndex+1, 'jpg');
+            updateDBdata('chapter',{chapterId:chapterId, clipUrl:clipUrl})
+            updateDBdata('chapter',{chapterId:chapterId, thumbUrl:thumbUrl})
+          })
+          .catch((err)=>{console.log(err)});
+        // updateDBdata('curriculum',{courseId:courseId,demo:res.url})
+      }else{
+        console.log('Upload clips Something Wrong.')
+      }
+    })
+    .catch(err => {
+      // catch the error from uploading jpg file to spaces
+      console.error(err);
+      uploadClip2Space(courseId, chapterId, dir, filename);
+    });
+
+const uploadThumb2Space = (courseId, chapterId, dir, filename) =>
+  thumb2SpacePromise(courseId, chapterId, dir, filename)
+    .then(() => exec(`rm ${dir}/${filename}`,
+      err => err? console.error(err): ''))
+    .catch(err => {
+      // catch the error from uploading jpg file to spaces
+      console.error(err);
+      uploadThumb2Space(courseId, chapterId, dir, filename);
+    });
+
+upload.post("/clip", (req, res) => {
+  uploadClip2Server().single("clip")(req, res, err => {
+    if (err) {
+      console.error(err);
+      return res.status(401).send("upload clip failed");
+    }
+    const { courseId, chapterId, uuid } = req.body;
+    const { filename } = req.file;
+    const raw = `${temp}/raw-clips/${filename}`;
+    runBash(`./videoProcess.bash ${raw} ${temp}`)
+      .then(() => {
+        exec(`rm ${raw}`, err => err? console.error(err): '');
+        uploadClip2Space(courseId, chapterId, `${temp}/clips`, `${uuid}.mp4`);
+        uploadThumb2Space(courseId, chapterId, `${temp}/thumbs`, `${uuid}.jpg`);
+      })
+      .catch(err => console.error(err))
+    return res.send("upload clip successfully");
+  });
+});
+
+
+upload.post("/attach", (req, res) => {
+  uploadAttachment2space().single("attachment")(req, res, err => {
+    if (err) {
+      console.error(err);
+      return res.status(401).send("upload attachment failed");
+    }else{
+      let {courseId, chapterId } = req.body;
+      const { originalname } = req.file;
+      queryLatestData('chapter',chapterId,'attachmentUrl')
+        .then((latestData) => {
+          let baseUrl = `https://ccrb-cs.sgp1.digitaloceanspaces.com/course/${courseId}/attachments/${chapterId}/${originalname}`
+          let attachmentUrl = latestData;
+          attachmentUrl.push(baseUrl);
+          updateDBdata('chapter',{courseId:courseId,chapterId:chapterId,attachmentUrl:attachmentUrl})
+          res.send("upload attachment successfully");
+        })
+        .catch(err=>{
+          console.log(err);
+        })
+
+    }
+
+  });
+});
+
+
+const uploadCover2Server = () => multer({
+  storage: multer.diskStorage({
+    destination: (req, file, cb) => {
+      const dir = `${temp}/raw-covers`;
+      mkdir(dir, { recursive: true }, () => cb(null, dir));
+    },
+    filename: (req, file, cb) => {
+      const suffix = file.originalname.match(/\.[\w]+$/);
+      cb(null, `${req.body.name}${suffix? suffix[0]: ''}`);
+    }
+  })
+});
+
+const uploadCover2Space = (courseId, dir, filename,chapterId) =>
+  cover2SpacePromise(courseId, '', dir, filename)
+    .then((res) =>{
+      if(res.status === 200){
+        exec(`rm ${dir}/${filename}`,err => err? console.error(err): '')
+        //Due to upload cover use same route path
+        //verify chapterId is exist
+        if(chapterId){
+          updateDBdata('chapter',{courseId:courseId,chapterId:chapterId,bg:res.url})
+        }else{
+          updateDBdata('curriculum',{courseId:courseId,poster:res.url})
+        }
+      }else{
+        console.log('Something Wrong.')
+      }
+    })
+    .catch(err => {
+      // catch the error from uploading jpg file to spaces
+      console.error(err);
+      uploadCover2Space(courseId, dir, filename);
+    });
+
+upload.post("/cover", (req, res) => {
+  uploadCover2Server().single("cover")(req, res, err => {
+    if (err) {
+      console.error(err);
+      return res.status(401).send("upload cover failed");
+    }
+    const { courseId, name , chapterId } = req.body;
+    const { filename } = req.file;
+    const raw = `${temp}/raw-covers/${filename}`;
+    const cover = `${temp}/covers`
+    runBash(`./coverResize.bash ${raw} ${cover}/${name}`)
+      .then(() => {
+        exec(`rm ${raw}`, err => err? console.error(err): '');
+        uploadCover2Space(courseId, cover, `${name}.jpg`,chapterId||null);
+      })
+      .catch(err => console.error(err));
+    return res.send("upload cover successfully");
+  });
+});
+
+
+const uploadDemo2Server = () => multer({
+  storage: multer.diskStorage({
+    destination: (req, file, cb) => {
+      const dir = `${temp}/raw-demos`;
+      mkdir(dir, { recursive: true }, () => cb(null, dir));
+    },
+    filename: (req, file, cb) => {
+      const suffix = file.originalname.match(/\.[\w]+$/);
+      cb(null, `${req.body.courseId}${suffix? suffix[0]: ''}`);
+    }
+  })
+});
+
+const uploadDemo2Space = (courseId, dir, filename) =>
+  demo2SpacePromise(courseId, '', dir, filename)
+    .then((res) =>{
+      if(res.status === 200){
+        exec(`rm ${dir}/${filename}`,err => err? console.error(err): '')
+        updateDBdata('curriculum',{courseId:courseId,demo:res.url})
+      }else{
+        console.log('Upload demo Something Wrong.')
+      }
+    })
+    .catch(err => {
+      // catch the error from uploading jpg file to spaces
+      console.error(err);
+      uploadDemo2Space(courseId, dir, filename);
+    });
+
+upload.post("/demo", (req, res) => {
+  uploadDemo2Server().single('demo')(req, res, err => {
+    if (err) {
+      console.error(err);
+      return res.status(401).send("upload demo failed");
+    }
+    const { courseId } = req.body;
+    const { filename } = req.file;
+    const raw = `${temp}/raw-demos/${filename}`;
+    const type = req.file.mimetype.split('/')[0];
+    let bash = '';
+    if (type === 'image') {
+      bash = './demoImageResize.bash';
+    } else if (type === 'video') {
+      bash = './demoVideoResize.bash';
+    } else {
+      return res.status(401).send("wrong file type");
+    }
+    runBash(`${bash} ${raw} ${temp}/demos/${courseId}`)
+      .then(() => {
+        exec(`rm ${raw}`, err => err? console.error(err): '');
+        const suffix = type === 'image'? '.jpg': '.mp4';
+        uploadDemo2Space(courseId, `${temp}/demos`, `${courseId}${suffix}`);
+      })
+      .catch(err => console.error(err));
+    return res.send("upload demo successfully");
+  });
+})
+
+
+
+
+// ---------------------------------------------------------------------------- //
+
+const photoDirPath = join(__dirname, "static", "images", "workshop", "3");
+const imageStorage = multer.diskStorage({
+  destination: photoDirPath,
+  filename: (req, file, cb) => {
+    const { username } = req.body;
+    const types = file.mimetype.split("/");
+    if (types[0] === "image") {
+      cb(
+        null,
+        (username ? username : "Untitled") + `-${Date.now()}.${types[1]}`
+      );
+    }
+  }
+});
+const singleImageStore = multer({ storage: imageStorage }).single("userphoto");
+
+upload.get("/all_photos", (req, res) => {
+  readdir(photoDirPath, (err, files) => {
+    if (err) return res.json({ message: "error", error: err });
+    else return res.json({ message: "ok", files: files });
+  });
+});
+
+upload.post("/images", singleImageStore, (req, res) => {
+  console.log("save photo");
+  res.json({ msg: "Upload photo successfully" });
+});
+
+module.exports = upload;