├── .gitignore ├── DB ├── config.js └── models │ ├── blogs.js │ ├── comments.js │ └── users.js ├── index.js ├── package.json ├── routers ├── blog.js ├── comments.js ├── remote-search.js └── user.js ├── token ├── checkToken.js └── createToken.js ├── utils └── axios.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /DB/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dbs: 'mongodb://127.0.0.1:27017' 3 | } -------------------------------------------------------------------------------- /DB/models/blogs.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | const Schema = mongoose.Schema 3 | const BlogSchema = new Schema({ 4 | // blog title 5 | title: { 6 | type: String, 7 | required: true 8 | }, 9 | // blog keyword (SEO) 10 | keyword: [{ 11 | type: String, 12 | default: '' 13 | }], 14 | // blog author (only me) 15 | author: { 16 | type: String, 17 | default: '' 18 | }, 19 | // blog description (display on the blog card) 20 | desc: { 21 | type: String, 22 | default: '' 23 | }, 24 | // blog content 25 | content: { 26 | type: String, 27 | required: true 28 | }, 29 | // number of words 30 | numbers: { 31 | type: Number, 32 | default: 0 33 | }, 34 | // surface plot 35 | headerPic: { 36 | type: String, 37 | required: true 38 | }, 39 | // blog tag 40 | tag: { 41 | type: Array, 42 | require: true 43 | }, 44 | // blog category 45 | category: { 46 | type: String, 47 | require: true 48 | }, 49 | pubTime: { 50 | type: Date, 51 | required: true 52 | }, 53 | upTime: { 54 | type: Date, 55 | required: true 56 | }, 57 | // some other meta data 58 | meta: { 59 | views: { 60 | type: Number, 61 | default: 0 62 | }, 63 | likes: { 64 | type: Number, 65 | default: 0 66 | }, 67 | comments: { 68 | type: Number, 69 | default: 0 70 | }, 71 | }, 72 | }) 73 | module.exports = mongoose.model('Blogs', BlogSchema) -------------------------------------------------------------------------------- /DB/models/comments.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | const Schema = mongoose.Schema 3 | 4 | // 评论模型 5 | const commentSchema = new mongoose.Schema({ 6 | // 评论所在的文章 id 7 | article_id: { 8 | type: mongoose.Schema.Types.ObjectId, 9 | required: true 10 | }, 11 | name: { 12 | type: String, 13 | required: true 14 | }, 15 | replyer: { 16 | type: String, 17 | required: true, 18 | default: 'Blogger' 19 | }, 20 | createTime: { 21 | type: Date, 22 | default: Date.now 23 | }, 24 | isRead: { 25 | type: Boolean, 26 | default: false 27 | }, 28 | avatar: { 29 | type: String, 30 | default: 'https://libra321.oss-cn-huhehaote.aliyuncs.com/avatar.jpg' 31 | }, 32 | email: { 33 | type: String 34 | }, 35 | content: { 36 | type: String, 37 | required: true, 38 | validate: /\S+/ 39 | }, 40 | // 第三者评论 41 | otherComment: [ 42 | { 43 | name: { 44 | type: String, 45 | required: true 46 | }, 47 | replyer: { 48 | type: String, 49 | required: true 50 | }, 51 | createTime: { 52 | type: Date, 53 | default: Date.now 54 | }, 55 | isRead: { 56 | type: Boolean, 57 | default: false 58 | }, 59 | email: { 60 | type: String 61 | }, 62 | content: { 63 | type: String, 64 | required: true, 65 | validate: /\S+/ 66 | }, 67 | avatar: { 68 | type: String, 69 | default: 'https://libra321.oss-cn-huhehaote.aliyuncs.com/avatar.jpg' 70 | }, 71 | }, 72 | ], 73 | }); 74 | 75 | module.exports = mongoose.model('Comments', commentSchema); -------------------------------------------------------------------------------- /DB/models/users.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | const Schema = mongoose.Schema 3 | 4 | const UserSchema = mongoose.Schema({ 5 | userName: String, 6 | password: String, 7 | token: String, 8 | create_time: Date, 9 | isAdmin: { 10 | type: Boolean, //是否是管理员 11 | default: false //默认false 管理员身份修改数据库即可 12 | }, 13 | }); 14 | 15 | module.exports = mongoose.model('Users', UserSchema) -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa') 2 | const consola = require('consola') 3 | const mongoose = require('mongoose') 4 | const dbConfig = require('./DB/config') 5 | const KoaRouter = require('koa-router'); 6 | const router = new KoaRouter(); 7 | const userRouter = require('./routers/user') 8 | const blogRouter = require('./routers/blog') 9 | const commentsRouter = require('./routers/comments') 10 | const remoteSearchRouter = require('./routers/remote-search') 11 | const path = require('path'); 12 | const cors = require('koa2-cors'); 13 | //引入json 14 | const json = require('koa-json'); 15 | //配置静态图片 否则koa-multer上传图片后在浏览器无法查看图片 16 | const staticFiles = require('koa-static'); 17 | //引入users数据表 18 | const User = require('./DB/models/users'); 19 | //bodyparser:该中间件用于post请求的数据 20 | const bodyParser = require('koa-bodyparser'); 21 | const check = require('./token/checkToken') 22 | const app = new Koa() 23 | //跨域问题解决 24 | app.use(cors({ 25 | origin: '*' 26 | })); 27 | app.use(bodyParser()); 28 | app.use(json()); 29 | app.use(check) 30 | //注意 访问时不需要增加/static前缀 31 | app.use(staticFiles(path.join(__dirname, '../static'))); 32 | //封装接口 33 | router.use('/api/users', userRouter); 34 | router.use('/api/blogs', blogRouter); 35 | router.use('/api/comments', commentsRouter); 36 | router.use('/api/remote-search', remoteSearchRouter); 37 | //配置路由模块 38 | app.use(router.routes()).use(router.allowedMethods()); 39 | mongoose.connect(dbConfig.dbs, { 40 | useNewUrlParser: true, 41 | useUnifiedTopology: true 42 | }).then(() => { 43 | console.log('数据库连接成功'); 44 | }).catch(() => { 45 | console.log('数据库连接失败'); 46 | }) 47 | const host = process.env.HOST || '0.0.0.0' 48 | const port = process.env.PORT || 3000 49 | app.listen(port, host) 50 | consola.ready({ 51 | message: `Server listening on http://${host}:${port}`, 52 | badge: true 53 | }) 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libra-blog-back-end", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "axios": "^0.19.2", 8 | "consola": "^2.12.1", 9 | "jsonwebtoken": "^8.5.1", 10 | "koa": "^2.12.0", 11 | "koa-bodyparser": "^4.3.0", 12 | "koa-json": "^2.0.2", 13 | "koa-router": "^8.0.8", 14 | "koa-static": "^5.0.0", 15 | "koa2-cors": "^2.0.6", 16 | "moment": "^2.25.3", 17 | "mongodb": "^3.5.7", 18 | "mongoose": "^5.9.15", 19 | "objectid-to-timestamp": "^1.3.0", 20 | "sha1": "^1.1.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /routers/blog.js: -------------------------------------------------------------------------------- 1 | const koaRouter = require('koa-router') 2 | const router = new koaRouter() 3 | const Blog = require('../DB/models/blogs') 4 | const ObjectID = require("mongodb").ObjectID; 5 | 6 | //获取最近Blog 7 | const getRecentBlog = async (ctx) => { 8 | return new Promise((resolve, reject) => { 9 | Blog.find({}, (err, doc) => { 10 | if (err) { 11 | reject(err); 12 | } 13 | resolve(doc); 14 | }).limit(10).sort({ pubTime: -1 }); 15 | }); 16 | }; 17 | //获取全部Blog(分页) 18 | const getAllBlogs = async (ctx) => { 19 | let { page, limit } = ctx.request.query; 20 | return new Promise((resolve, reject) => { 21 | Blog.find({}, (err, doc) => { 22 | if (err) { 23 | reject(err); 24 | } 25 | resolve(doc); 26 | }).limit(Number(limit)) 27 | .skip((page - 1) * limit) 28 | .exec(); 29 | }); 30 | }; 31 | //获取全部Blog 32 | const getAllBlog = async (ctx) => { 33 | return new Promise((resolve, reject) => { 34 | Blog.find({}, (err, doc) => { 35 | if (err) { 36 | reject(err); 37 | } 38 | resolve(doc); 39 | }).sort({ pubTime: -1 }) 40 | }); 41 | }; 42 | //获取全部Blog数量 43 | const getAllBlogsCount = async (ctx) => { 44 | let { page, limit } = ctx.request.query; 45 | return new Promise((resolve, reject) => { 46 | Blog.find({}, (err, doc) => { 47 | if (err) { 48 | reject(err); 49 | } 50 | resolve(doc); 51 | }) 52 | }); 53 | }; 54 | // 根据Id获取blog详情 55 | const getBlogById = async (ctx) => { 56 | return new Promise((resolve, reject) => { 57 | Blog.find({ _id: ObjectID(ctx.query.id) }, (err, doc) => { 58 | if (err) { 59 | reject(err); 60 | } 61 | resolve(doc); 62 | }); 63 | }) 64 | }; 65 | // 获取所有分类 66 | const getAllCategory = async (ctx) => { 67 | return new Promise((resolve, reject) => { 68 | Blog.find({}, (err, doc) => { 69 | if (err) { 70 | reject(err); 71 | } 72 | resolve(doc); 73 | }).distinct("category").exec(); 74 | }) 75 | }; 76 | // 根据分类获取博客列表 77 | const getBlogsByCategory = async (ctx) => { 78 | let pageSize = 8 79 | return new Promise((resolve, reject) => { 80 | Blog.find({ category: ctx.query.category }, (err, doc) => { 81 | if (err) { 82 | reject(err); 83 | } 84 | resolve(doc); 85 | }).limit(8).skip((ctx.query.pageNum - 1) * pageSize) 86 | }) 87 | }; 88 | // 根据标签获取博客列表 89 | const getBlogsByTag = async (ctx) => { 90 | let pageSize = 8 91 | return new Promise((resolve, reject) => { 92 | Blog.find({ tag: { $in: [ctx.query.tag] } }, (err, doc) => { 93 | if (err) { 94 | reject(err); 95 | } 96 | resolve(doc); 97 | }).limit(8).skip((ctx.query.pageNum - 1) * pageSize) 98 | }) 99 | }; 100 | router.post('/publishBlog', async ctx => { 101 | let blog = new Blog({ 102 | title: ctx.request.body.title, 103 | author: ctx.request.body.author, 104 | desc: ctx.request.body.content_short, 105 | content: ctx.request.body.content, 106 | numbers: ctx.request.body.content.length, 107 | headerPic: ctx.request.body.image_uri, 108 | tag: ctx.request.body.tag, 109 | category: ctx.request.body.category, 110 | pubTime: ctx.request.body.pubTime, 111 | upTime: ctx.request.body.upTime 112 | }) 113 | await new Promise((resolve, reject) => { 114 | blog.save((err) => { 115 | if (err) { 116 | console.log(err) 117 | reject 118 | } 119 | ctx.status = 200 120 | ctx.body = { 121 | code: 0, 122 | res: '发布成功' 123 | } 124 | resolve() 125 | }) 126 | }) 127 | }) 128 | router.get('/getRecentBlog', async ctx => { 129 | let blogs = await getRecentBlog(ctx) 130 | if (!blogs) { 131 | ctx.status = 200 132 | ctx.body = { 133 | code: -1, 134 | res: '没有查到文章' 135 | } 136 | } else { 137 | ctx.status = 200; 138 | ctx.body = { 139 | code: 0, 140 | blogs, 141 | total: blogs.length, 142 | }; 143 | } 144 | }) 145 | router.get('/getAllCategory', async ctx => { 146 | let blogs = await getAllCategory(ctx) 147 | if (!blogs) { 148 | ctx.status = 200 149 | ctx.body = { 150 | code: -1, 151 | res: '没有查到文章' 152 | } 153 | } else { 154 | ctx.status = 200; 155 | ctx.body = { 156 | code: 0, 157 | data: blogs, 158 | }; 159 | } 160 | }) 161 | router.get('/getBlogsByCategory', async ctx => { 162 | let blogs = await getBlogsByCategory(ctx) 163 | let total = await Blog.countDocuments({ category: ctx.query.category }) 164 | if (!blogs) { 165 | ctx.status = 200 166 | ctx.body = { 167 | code: -1, 168 | res: '没有查到文章' 169 | } 170 | } else { 171 | ctx.status = 200; 172 | ctx.body = { 173 | code: 0, 174 | data: blogs, 175 | total: total 176 | }; 177 | } 178 | }) 179 | router.get('/getBlogsByTag', async ctx => { 180 | let blogs = await getBlogsByTag(ctx) 181 | let total = await Blog.countDocuments({ tag: { $in: [ctx.query.tag] } }) 182 | if (!blogs) { 183 | ctx.status = 200 184 | ctx.body = { 185 | code: -1, 186 | res: '没有查到文章' 187 | } 188 | } else { 189 | ctx.status = 200; 190 | ctx.body = { 191 | code: 0, 192 | data: blogs, 193 | total: total 194 | }; 195 | } 196 | }) 197 | router.get('/getAllBlogs', async ctx => { 198 | let blogs = await getAllBlogs(ctx) 199 | if (!blogs) { 200 | ctx.status = 200 201 | ctx.body = { 202 | code: -1, 203 | res: '没有查到文章' 204 | } 205 | } else { 206 | ctx.status = 200; 207 | ctx.body = { 208 | code: 0, 209 | total: blogs.length, 210 | blogs 211 | }; 212 | } 213 | }) 214 | router.get('/getAllBlog', async ctx => { 215 | let blogs = await getAllBlog(ctx) 216 | if (!blogs) { 217 | ctx.status = 200 218 | ctx.body = { 219 | code: -1, 220 | res: '没有查到文章' 221 | } 222 | } else { 223 | ctx.status = 200; 224 | ctx.body = { 225 | code: 0, 226 | blogs 227 | }; 228 | } 229 | }) 230 | router.get('/getAllBlogsCount', async ctx => { 231 | let blogs = await getAllBlogsCount(ctx) 232 | if (!blogs) { 233 | ctx.status = 200 234 | ctx.body = { 235 | code: -1, 236 | res: '没有查到文章' 237 | } 238 | } else { 239 | ctx.status = 200; 240 | ctx.body = { 241 | code: 0, 242 | total: blogs.length, 243 | }; 244 | } 245 | }) 246 | router.get('/getBlogById', async (ctx) => { 247 | let blog = await getBlogById(ctx) 248 | if (!blog) { 249 | ctx.status = 200 250 | ctx.body = { 251 | code: -1, 252 | res: '没有查到文章内容' 253 | } 254 | } else { 255 | ctx.status = 200; 256 | ctx.body = { 257 | code: 0, 258 | blog 259 | }; 260 | } 261 | }) 262 | 263 | module.exports = router.routes() -------------------------------------------------------------------------------- /routers/comments.js: -------------------------------------------------------------------------------- 1 | const koaRouter = require('koa-router') 2 | const router = new koaRouter() 3 | const Comment = require('../DB/models/comments') 4 | const ObjectID = require("mongodb").ObjectID; 5 | 6 | 7 | //获取评论列表 8 | const getComments = async (ctx) => { 9 | return new Promise((resolve, reject) => { 10 | Comment.find({ article_id: ctx.query.id }, (err, doc) => { 11 | if (err) { 12 | reject(err); 13 | } 14 | resolve(doc); 15 | }); 16 | }); 17 | }; 18 | router.post('/replyComment', async ctx => { 19 | await new Promise((resolve, reject) => { 20 | Comment.updateOne({ _id: ObjectID(ctx.request.body.id) }, 21 | { 22 | '$push': { 23 | otherComment: { 24 | name: ctx.request.body.name, 25 | replyer: ctx.request.body.replyer, 26 | content: ctx.request.body.content, 27 | avatar: ctx.request.body.avatar, 28 | email: ctx.request.body.email 29 | } 30 | } 31 | }, (err) => { 32 | if (err) { 33 | console.log(err) 34 | reject 35 | } 36 | ctx.status = 200 37 | ctx.body = { 38 | code: 0, 39 | res: '回复成功' 40 | } 41 | resolve() 42 | }); 43 | }) 44 | }) 45 | router.post('/publishComment', async ctx => { 46 | let comment = new Comment({ 47 | article_id: ctx.request.body.article_id, 48 | name: ctx.request.body.name, 49 | replyer: ctx.request.body.replyer, 50 | content: ctx.request.body.content, 51 | avatar: ctx.request.body.avatar, 52 | email: ctx.request.body.email 53 | }) 54 | await new Promise((resolve, reject) => { 55 | comment.save((err) => { 56 | if (err) { 57 | console.log(err) 58 | reject 59 | } 60 | ctx.status = 200 61 | ctx.body = { 62 | code: 0, 63 | res: '评论成功' 64 | } 65 | resolve() 66 | }) 67 | }) 68 | }) 69 | router.get('/getComments', async (ctx) => { 70 | let comments = await getComments(ctx) 71 | if (!comments) { 72 | ctx.status = 200 73 | ctx.body = { 74 | code: -1, 75 | res: '没有评论' 76 | } 77 | } else { 78 | ctx.status = 200; 79 | ctx.body = { 80 | code: 0, 81 | comments 82 | }; 83 | } 84 | }) 85 | 86 | module.exports = router.routes() -------------------------------------------------------------------------------- /routers/remote-search.js: -------------------------------------------------------------------------------- 1 | const koaRouter = require('koa-router') 2 | const router = new koaRouter() 3 | const User = require('../DB/models/users') 4 | const Blog = require('../DB/models/blogs') 5 | 6 | //找到所有管理员用户 7 | const findAllAdminUsers = () => { 8 | return new Promise((resolve, reject) => { 9 | User.find({ isAdmin: { $in: true } }, (err, doc) => { 10 | if (err) { 11 | reject(err); 12 | } 13 | resolve(doc); 14 | }); 15 | }); 16 | }; 17 | //找到所有文章标签 18 | const getAllTags = () => { 19 | return new Promise((resolve, reject) => { 20 | Blog.find({}, { tag: 1 }, (err, doc) => { 21 | if (err) { 22 | reject(err); 23 | } 24 | resolve(doc); 25 | }); 26 | }); 27 | }; 28 | //找到所有文章分类 29 | const searchCategory = () => { 30 | return new Promise((resolve, reject) => { 31 | Blog.find({}, { category: 1 }, (err, doc) => { 32 | if (err) { 33 | reject(err); 34 | } 35 | resolve(doc); 36 | }); 37 | }); 38 | }; 39 | router.get('/getAllAdminUsers', async ctx => { 40 | let info = await findAllAdminUsers(ctx) 41 | if (!info) { 42 | ctx.status = 200 43 | ctx.body = { 44 | code: -1, 45 | res: '没有查询到管理员用户' 46 | } 47 | } else { 48 | ctx.status = 200; 49 | ctx.body = { 50 | code: 0, 51 | info 52 | }; 53 | } 54 | }) 55 | router.get('/getAllTags', async ctx => { 56 | let info = await getAllTags(ctx) 57 | if (!info) { 58 | ctx.status = 200 59 | ctx.body = { 60 | code: -1, 61 | res: '没有查询到标签' 62 | } 63 | } else { 64 | let res = [] 65 | for (const item of info) { 66 | item.tag.forEach(element => { 67 | if (!res.includes(element)) { 68 | res.push(element) 69 | } 70 | }); 71 | } 72 | ctx.status = 200; 73 | ctx.body = { 74 | code: 0, 75 | info: res 76 | }; 77 | } 78 | }) 79 | router.get('/searchCategory', async ctx => { 80 | let info = await searchCategory(ctx) 81 | if (!info) { 82 | ctx.status = 200 83 | ctx.body = { 84 | code: -1, 85 | res: '没有查询到标签' 86 | } 87 | } else { 88 | let res = [] 89 | for (const item of info) { 90 | if (!res.includes(item.category)) { 91 | res.push(item.category) 92 | } 93 | } 94 | ctx.status = 200; 95 | ctx.body = { 96 | code: 0, 97 | info: res 98 | }; 99 | } 100 | }) 101 | module.exports = router.routes() -------------------------------------------------------------------------------- /routers/user.js: -------------------------------------------------------------------------------- 1 | const koaRouter = require('koa-router') 2 | const router = new koaRouter() 3 | //下面这两个包用来生成时间 4 | const moment = require('moment'); 5 | const objectIdToTimestamp = require('objectid-to-timestamp'); 6 | //用于密码加密 7 | const sha1 = require('sha1'); 8 | const User = require('../DB/models/users') 9 | const createToken = require('../token/createToken') 10 | 11 | //数据库的操作 12 | //根据用户名查找用户 13 | const findUser = (userName) => { 14 | return new Promise((resolve, reject) => { 15 | User.findOne({ userName }, (err, doc) => { 16 | if (err) { 17 | reject(err); 18 | } 19 | resolve(doc); 20 | }); 21 | }); 22 | }; 23 | //找到所有用户 24 | const findAllUsers = () => { 25 | return new Promise((resolve, reject) => { 26 | User.find({}, (err, doc) => { 27 | if (err) { 28 | reject(err); 29 | } 30 | resolve(doc); 31 | }); 32 | }); 33 | }; 34 | //删除某个用户 35 | const delUser = function (id) { 36 | return new Promise((resolve, reject) => { 37 | User.findOneAndRemove({ _id: id }, err => { 38 | if (err) { 39 | reject(err); 40 | } 41 | console.log('删除用户成功'); 42 | resolve(); 43 | }); 44 | }); 45 | }; 46 | //获得所有用户信息 47 | const GetAllUsers = async (ctx) => { 48 | //查询所有用户信息 49 | let doc = await findAllUsers(); 50 | ctx.status = 200; 51 | ctx.body = { 52 | code: 0, 53 | res: doc 54 | }; 55 | }; 56 | 57 | //删除某个用户 58 | const DelUser = async (ctx) => { 59 | //拿到要删除的用户id 60 | let id = ctx.request.body.id; 61 | await delUser(id); 62 | ctx.status = 200; 63 | ctx.body = { 64 | code: -1, 65 | res: '删除成功' 66 | }; 67 | }; 68 | //根据token查询用户 69 | const getInfoByToken = async (ctx) => { 70 | let token = ctx.query.token; 71 | return new Promise((resolve, reject) => { 72 | User.findOne({ token }, (err, doc) => { 73 | if (err) { 74 | reject(err); 75 | } 76 | resolve(doc); 77 | }); 78 | }); 79 | }; 80 | router.get('/getInfoByToken', async ctx => { 81 | let info = await getInfoByToken(ctx) 82 | if (!info) { 83 | ctx.status = 200 84 | ctx.body = { 85 | code: -1, 86 | res: '用户不存在' 87 | } 88 | } else { 89 | ctx.status = 200; 90 | ctx.body = { 91 | code: 0, 92 | info 93 | }; 94 | } 95 | }) 96 | router.post('/login', async ctx => { 97 | let userName = ctx.request.body.userName 98 | let password = sha1(ctx.request.body.password) //解密 99 | let doc = await findUser(userName) 100 | if (!doc) { 101 | ctx.status = 200; 102 | ctx.body = { 103 | code: -1, 104 | res: '用户名不存在' 105 | } 106 | } else if (doc.password === password) { 107 | //生成一个新的token,并存到数据库 108 | let token = createToken(userName); 109 | doc.token = token; 110 | let newDoc = new User(doc) 111 | await new Promise((resolve, reject) => { 112 | newDoc.save((err) => { 113 | if (err) { 114 | reject(err); 115 | } 116 | resolve(); 117 | }); 118 | }); 119 | ctx.status = 200; 120 | ctx.body = { 121 | code: 0, 122 | userName, 123 | token, //登录成功要创建一个新的token,应该存入数据库 124 | create_time: doc.create_time 125 | }; 126 | } else { 127 | ctx.status = 200; 128 | ctx.body = { 129 | code: -1, 130 | res: '密码错误' 131 | }; 132 | } 133 | }) 134 | router.post('/register', async ctx => { 135 | console.log(ctx.request.body) 136 | let user = new User({ 137 | userName: ctx.request.body.userName, 138 | password: sha1(ctx.request.body.password), //加密 139 | token: createToken(this.userName), //创建token并存入数据库 140 | create_time: moment(new Date().getTime()).format('YYYY-MM-DD HH:mm:ss'), 141 | }); 142 | let doc = await findUser(user.userName); 143 | if (doc) { 144 | ctx.status = 200; 145 | ctx.body = { 146 | code: -1, 147 | res: '用户名已经存在' 148 | }; 149 | } else { 150 | await new Promise((resolve, reject) => { 151 | user.save((err) => { 152 | if (err) { 153 | reject(err); 154 | } 155 | resolve(); 156 | }); 157 | }); 158 | ctx.status = 200; 159 | ctx.body = { 160 | code: 0, 161 | res: '注册成功' 162 | } 163 | } 164 | }) 165 | router.post('/logout', async (ctx) => { 166 | try { 167 | // 跳转到登录页或网站首页 168 | ctx.status = 200; 169 | ctx.body = { 170 | code: 0, 171 | res: '退出成功' 172 | } 173 | } catch (err) { 174 | ctx.status = 200; 175 | ctx.body = { 176 | code: -1, 177 | res: '退出失败' 178 | } 179 | throw new Error(err) 180 | } 181 | }) 182 | module.exports = router.routes() -------------------------------------------------------------------------------- /token/checkToken.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | 3 | const avoidVerifyUrl = [ 4 | "/api/users/login", 5 | "/api/users/logout", 6 | "/api/blogs/getRecentBlog", 7 | "/api/blogs/getAllBlogsCount", 8 | "/api/blogs/getAllBlog", 9 | "/api/blogs/getAllCategory", 10 | "/api/remote-search/getAllTags", 11 | "/api/comments/publishComment", 12 | "/api/comments/replyComment", 13 | ] 14 | //检查token是否过期 15 | module.exports = async (ctx, next) => { 16 | let url = ctx.request.url; 17 | // 不用检查的接口 18 | if (!url.startsWith("/api") || 19 | avoidVerifyUrl.includes(url) || 20 | url.startsWith("/api/blogs/getBlogById") || 21 | url.startsWith("/api/comments/getComments") || 22 | url.startsWith("/api/blogs/getBlogsByCategory") || 23 | url.startsWith("/api/blogs/getBlogsByTag") 24 | ) { 25 | await next() 26 | } else { 27 | //拿到token 28 | const authorization = ctx.get('Authorization'); 29 | if (authorization === '') { 30 | ctx.throw(401, 'no token detected in http headerAuthorization'); 31 | } 32 | let tokenContent; 33 | try { 34 | tokenContent = await jwt.verify(authorization, 'Libra');//如果token过期或验证失败,将抛出错误 35 | } catch (err) { 36 | ctx.throw(401, 'invalid token'); 37 | } 38 | await next(); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /token/createToken.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | module.exports = function (user_id) { 3 | const token = jwt.sign({ user_id: user_id }, 'Libra', { 4 | expiresIn: '259220s' 5 | }); 6 | return token; 7 | }; -------------------------------------------------------------------------------- /utils/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | // create an axios instance 4 | const service = axios.create({ 5 | baseURL: 'http://127.0.0.1:3000', // url = base url + request url 6 | // withCredentials: true, // send cookies when cross-domain requests 7 | timeout: 5000 // request timeout 8 | }) 9 | 10 | export default service 11 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@^1.3.5: 6 | version "1.3.7" 7 | resolved "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" 8 | integrity sha1-UxvHJlF6OytB+FACHGzBXqq1B80= 9 | dependencies: 10 | mime-types "~2.1.24" 11 | negotiator "0.6.2" 12 | 13 | any-promise@^1.0.0, any-promise@^1.1.0: 14 | version "1.3.0" 15 | resolved "https://registry.npm.taobao.org/any-promise/download/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" 16 | integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= 17 | 18 | axios@^0.19.2: 19 | version "0.19.2" 20 | resolved "https://registry.npm.taobao.org/axios/download/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" 21 | integrity sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc= 22 | dependencies: 23 | follow-redirects "1.5.10" 24 | 25 | bl@^2.2.0: 26 | version "2.2.0" 27 | resolved "https://registry.npm.taobao.org/bl/download/bl-2.2.0.tgz#e1a574cdf528e4053019bb800b041c0ac88da493" 28 | integrity sha1-4aV0zfUo5AUwGbuACwQcCsiNpJM= 29 | dependencies: 30 | readable-stream "^2.3.5" 31 | safe-buffer "^5.1.1" 32 | 33 | bluebird@3.5.1: 34 | version "3.5.1" 35 | resolved "https://registry.npm.taobao.org/bluebird/download/bluebird-3.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbluebird%2Fdownload%2Fbluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" 36 | integrity sha1-2VUfnemPH82h5oPRfukaBgLuLrk= 37 | 38 | bson@^1.1.4: 39 | version "1.1.4" 40 | resolved "https://registry.npm.taobao.org/bson/download/bson-1.1.4.tgz#f76870d799f15b854dffb7ee32f0a874797f7e89" 41 | integrity sha1-92hw15nxW4VN/7fuMvCodHl/fok= 42 | 43 | buffer-equal-constant-time@1.0.1: 44 | version "1.0.1" 45 | resolved "https://registry.npm.taobao.org/buffer-equal-constant-time/download/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" 46 | integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= 47 | 48 | bytes@3.1.0: 49 | version "3.1.0" 50 | resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" 51 | integrity sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY= 52 | 53 | cache-content-type@^1.0.0: 54 | version "1.0.1" 55 | resolved "https://registry.npm.taobao.org/cache-content-type/download/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" 56 | integrity sha1-A1zeKwjuISn0qDFeqPAKANuhRTw= 57 | dependencies: 58 | mime-types "^2.1.18" 59 | ylru "^1.2.0" 60 | 61 | "charenc@>= 0.0.1": 62 | version "0.0.2" 63 | resolved "https://registry.npm.taobao.org/charenc/download/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" 64 | integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= 65 | 66 | co-body@^6.0.0: 67 | version "6.0.0" 68 | resolved "https://registry.npm.taobao.org/co-body/download/co-body-6.0.0.tgz#965b9337d7f5655480787471f4237664820827e3" 69 | integrity sha1-lluTN9f1ZVSAeHRx9CN2ZIIIJ+M= 70 | dependencies: 71 | inflation "^2.0.0" 72 | qs "^6.5.2" 73 | raw-body "^2.3.3" 74 | type-is "^1.6.16" 75 | 76 | co@^4.6.0: 77 | version "4.6.0" 78 | resolved "https://registry.npm.taobao.org/co/download/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 79 | integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= 80 | 81 | consola@^2.12.1: 82 | version "2.12.1" 83 | resolved "https://registry.npm.taobao.org/consola/download/consola-2.12.1.tgz#88e9311a02cb88a7f6f9488239dd30b6ba99cbb0" 84 | integrity sha1-iOkxGgLLiKf2+UiCOd0wtrqZy7A= 85 | 86 | content-disposition@~0.5.2: 87 | version "0.5.3" 88 | resolved "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" 89 | integrity sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70= 90 | dependencies: 91 | safe-buffer "5.1.2" 92 | 93 | content-type@^1.0.4: 94 | version "1.0.4" 95 | resolved "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 96 | integrity sha1-4TjMdeBAxyexlm/l5fjJruJW/js= 97 | 98 | cookies@~0.8.0: 99 | version "0.8.0" 100 | resolved "https://registry.npm.taobao.org/cookies/download/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" 101 | integrity sha1-EpPOSzkXQKhAbjyYcOgoxLVPP5A= 102 | dependencies: 103 | depd "~2.0.0" 104 | keygrip "~1.1.0" 105 | 106 | copy-to@^2.0.1: 107 | version "2.0.1" 108 | resolved "https://registry.npm.taobao.org/copy-to/download/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5" 109 | integrity sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU= 110 | 111 | core-util-is@~1.0.0: 112 | version "1.0.2" 113 | resolved "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 114 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 115 | 116 | "crypt@>= 0.0.1": 117 | version "0.0.2" 118 | resolved "https://registry.npm.taobao.org/crypt/download/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" 119 | integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= 120 | 121 | debug@3.1.0, debug@=3.1.0, debug@~3.1.0: 122 | version "3.1.0" 123 | resolved "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz?cache=0&sync_timestamp=1589881689076&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 124 | integrity sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE= 125 | dependencies: 126 | ms "2.0.0" 127 | 128 | debug@^3.1.0: 129 | version "3.2.6" 130 | resolved "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz?cache=0&sync_timestamp=1589881689076&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 131 | integrity sha1-6D0X3hbYp++3cX7b5fsQE17uYps= 132 | dependencies: 133 | ms "^2.1.1" 134 | 135 | debug@^4.1.1: 136 | version "4.1.1" 137 | resolved "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz?cache=0&sync_timestamp=1589881689076&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 138 | integrity sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E= 139 | dependencies: 140 | ms "^2.1.1" 141 | 142 | deep-equal@~1.0.1: 143 | version "1.0.1" 144 | resolved "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.0.1.tgz?cache=0&sync_timestamp=1587708810466&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeep-equal%2Fdownload%2Fdeep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 145 | integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= 146 | 147 | delegates@^1.0.0: 148 | version "1.0.0" 149 | resolved "https://registry.npm.taobao.org/delegates/download/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 150 | integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= 151 | 152 | denque@^1.4.1: 153 | version "1.4.1" 154 | resolved "https://registry.npm.taobao.org/denque/download/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" 155 | integrity sha1-Z0T/dkHBSMP4ppwwflEjXB9KN88= 156 | 157 | depd@^1.1.2, depd@~1.1.2: 158 | version "1.1.2" 159 | resolved "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 160 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 161 | 162 | depd@~2.0.0: 163 | version "2.0.0" 164 | resolved "https://registry.npm.taobao.org/depd/download/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 165 | integrity sha1-tpYWPMdXVg0JzyLMj60Vcbeedt8= 166 | 167 | destroy@^1.0.4: 168 | version "1.0.4" 169 | resolved "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 170 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 171 | 172 | ecdsa-sig-formatter@1.0.11: 173 | version "1.0.11" 174 | resolved "https://registry.npm.taobao.org/ecdsa-sig-formatter/download/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" 175 | integrity sha1-rg8PothQRe8UqBfao86azQSJ5b8= 176 | dependencies: 177 | safe-buffer "^5.0.1" 178 | 179 | ee-first@1.1.1: 180 | version "1.1.1" 181 | resolved "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 182 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 183 | 184 | encodeurl@^1.0.2: 185 | version "1.0.2" 186 | resolved "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 187 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 188 | 189 | escape-html@^1.0.3: 190 | version "1.0.3" 191 | resolved "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 192 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 193 | 194 | follow-redirects@1.5.10: 195 | version "1.5.10" 196 | resolved "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" 197 | integrity sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio= 198 | dependencies: 199 | debug "=3.1.0" 200 | 201 | fresh@~0.5.2: 202 | version "0.5.2" 203 | resolved "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 204 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 205 | 206 | http-assert@^1.3.0: 207 | version "1.4.1" 208 | resolved "https://registry.npm.taobao.org/http-assert/download/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" 209 | integrity sha1-xfcl1neqfoc+9zYZm4lobM6zeHg= 210 | dependencies: 211 | deep-equal "~1.0.1" 212 | http-errors "~1.7.2" 213 | 214 | http-errors@1.7.3, http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.7.2: 215 | version "1.7.3" 216 | resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" 217 | integrity sha1-bGGeT5xgMIw4UZSYwU+7EKrOuwY= 218 | dependencies: 219 | depd "~1.1.2" 220 | inherits "2.0.4" 221 | setprototypeof "1.1.1" 222 | statuses ">= 1.5.0 < 2" 223 | toidentifier "1.0.0" 224 | 225 | http-errors@~1.6.2: 226 | version "1.6.3" 227 | resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" 228 | integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= 229 | dependencies: 230 | depd "~1.1.2" 231 | inherits "2.0.3" 232 | setprototypeof "1.1.0" 233 | statuses ">= 1.4.0 < 2" 234 | 235 | iconv-lite@0.4.24: 236 | version "0.4.24" 237 | resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 238 | integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= 239 | dependencies: 240 | safer-buffer ">= 2.1.2 < 3" 241 | 242 | inflation@^2.0.0: 243 | version "2.0.0" 244 | resolved "https://registry.npm.taobao.org/inflation/download/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" 245 | integrity sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8= 246 | 247 | inherits@2.0.3: 248 | version "2.0.3" 249 | resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 250 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 251 | 252 | inherits@2.0.4, inherits@~2.0.3: 253 | version "2.0.4" 254 | resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 255 | integrity sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= 256 | 257 | is-generator-function@^1.0.7: 258 | version "1.0.7" 259 | resolved "https://registry.npm.taobao.org/is-generator-function/download/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" 260 | integrity sha1-0hMuUpuwAAp/gHlNS99c1eWBNSI= 261 | 262 | isarray@0.0.1: 263 | version "0.0.1" 264 | resolved "https://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 265 | integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= 266 | 267 | isarray@~1.0.0: 268 | version "1.0.0" 269 | resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 270 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 271 | 272 | json-stringify-safe@5: 273 | version "5.0.1" 274 | resolved "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 275 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 276 | 277 | jsonwebtoken@^8.5.1: 278 | version "8.5.1" 279 | resolved "https://registry.npm.taobao.org/jsonwebtoken/download/jsonwebtoken-8.5.1.tgz?cache=0&sync_timestamp=1586264928256&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsonwebtoken%2Fdownload%2Fjsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" 280 | integrity sha1-AOceC431TCEhofJhN98igGc7zA0= 281 | dependencies: 282 | jws "^3.2.2" 283 | lodash.includes "^4.3.0" 284 | lodash.isboolean "^3.0.3" 285 | lodash.isinteger "^4.0.4" 286 | lodash.isnumber "^3.0.3" 287 | lodash.isplainobject "^4.0.6" 288 | lodash.isstring "^4.0.1" 289 | lodash.once "^4.0.0" 290 | ms "^2.1.1" 291 | semver "^5.6.0" 292 | 293 | jwa@^1.4.1: 294 | version "1.4.1" 295 | resolved "https://registry.npm.taobao.org/jwa/download/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" 296 | integrity sha1-dDwymFy56YZVUw1TZBtmyGRbA5o= 297 | dependencies: 298 | buffer-equal-constant-time "1.0.1" 299 | ecdsa-sig-formatter "1.0.11" 300 | safe-buffer "^5.0.1" 301 | 302 | jws@^3.2.2: 303 | version "3.2.2" 304 | resolved "https://registry.npm.taobao.org/jws/download/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" 305 | integrity sha1-ABCZ82OUaMlBQADpmZX6UvtHgwQ= 306 | dependencies: 307 | jwa "^1.4.1" 308 | safe-buffer "^5.0.1" 309 | 310 | kareem@2.3.1: 311 | version "2.3.1" 312 | resolved "https://registry.npm.taobao.org/kareem/download/kareem-2.3.1.tgz#def12d9c941017fabfb00f873af95e9c99e1be87" 313 | integrity sha1-3vEtnJQQF/q/sA+HOvlenJnhvoc= 314 | 315 | keygrip@~1.1.0: 316 | version "1.1.0" 317 | resolved "https://registry.npm.taobao.org/keygrip/download/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" 318 | integrity sha1-hxsWgdXhWcYqRFsMdLYV4JF+ciY= 319 | dependencies: 320 | tsscmp "1.0.6" 321 | 322 | koa-bodyparser@^4.3.0: 323 | version "4.3.0" 324 | resolved "https://registry.npm.taobao.org/koa-bodyparser/download/koa-bodyparser-4.3.0.tgz#274c778555ff48fa221ee7f36a9fbdbace22759a" 325 | integrity sha1-J0x3hVX/SPoiHufzap+9us4idZo= 326 | dependencies: 327 | co-body "^6.0.0" 328 | copy-to "^2.0.1" 329 | 330 | koa-compose@^3.0.0: 331 | version "3.2.1" 332 | resolved "https://registry.npm.taobao.org/koa-compose/download/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" 333 | integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= 334 | dependencies: 335 | any-promise "^1.1.0" 336 | 337 | koa-compose@^4.1.0: 338 | version "4.1.0" 339 | resolved "https://registry.npm.taobao.org/koa-compose/download/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" 340 | integrity sha1-UHMGuTcZAdtBEhyBLpI9DWfT6Hc= 341 | 342 | koa-convert@^1.2.0: 343 | version "1.2.0" 344 | resolved "https://registry.npm.taobao.org/koa-convert/download/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" 345 | integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= 346 | dependencies: 347 | co "^4.6.0" 348 | koa-compose "^3.0.0" 349 | 350 | koa-is-json@1: 351 | version "1.0.0" 352 | resolved "https://registry.npm.taobao.org/koa-is-json/download/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14" 353 | integrity sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ= 354 | 355 | koa-json@^2.0.2: 356 | version "2.0.2" 357 | resolved "https://registry.npm.taobao.org/koa-json/download/koa-json-2.0.2.tgz#36af14e6ea1f5d646d7c44a285701c6f85a4fde4" 358 | integrity sha1-Nq8U5uofXWRtfESihXAcb4Wk/eQ= 359 | dependencies: 360 | koa-is-json "1" 361 | streaming-json-stringify "3" 362 | 363 | koa-router@^8.0.8: 364 | version "8.0.8" 365 | resolved "https://registry.npm.taobao.org/koa-router/download/koa-router-8.0.8.tgz#f0b70f90dae275db8c71a41e1efb625581fb3b5a" 366 | integrity sha1-8LcPkNridduMcaQeHvtiVYH7O1o= 367 | dependencies: 368 | debug "^4.1.1" 369 | http-errors "^1.7.3" 370 | koa-compose "^4.1.0" 371 | methods "^1.1.2" 372 | path-to-regexp "1.x" 373 | urijs "^1.19.2" 374 | 375 | koa-send@^5.0.0: 376 | version "5.0.0" 377 | resolved "https://registry.npm.taobao.org/koa-send/download/koa-send-5.0.0.tgz#5e8441e07ef55737734d7ced25b842e50646e7eb" 378 | integrity sha1-XoRB4H71VzdzTXztJbhC5QZG5+s= 379 | dependencies: 380 | debug "^3.1.0" 381 | http-errors "^1.6.3" 382 | mz "^2.7.0" 383 | resolve-path "^1.4.0" 384 | 385 | koa-static@^5.0.0: 386 | version "5.0.0" 387 | resolved "https://registry.npm.taobao.org/koa-static/download/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" 388 | integrity sha1-XpL8lrU3rVIZ9CUxnJW2R3J3aUM= 389 | dependencies: 390 | debug "^3.1.0" 391 | koa-send "^5.0.0" 392 | 393 | koa2-cors@^2.0.6: 394 | version "2.0.6" 395 | resolved "https://registry.npm.taobao.org/koa2-cors/download/koa2-cors-2.0.6.tgz#9ad23df3a0b9bb84530b46f5944f3fb576086554" 396 | integrity sha1-mtI986C5u4RTC0b1lE8/tXYIZVQ= 397 | 398 | koa@^2.12.0: 399 | version "2.12.0" 400 | resolved "https://registry.npm.taobao.org/koa/download/koa-2.12.0.tgz?cache=0&sync_timestamp=1589732495458&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fkoa%2Fdownload%2Fkoa-2.12.0.tgz#c92bfb42defd86f365c31bf63fe918db11fc5c74" 401 | integrity sha1-ySv7Qt79hvNlwxv2P+kY2xH8XHQ= 402 | dependencies: 403 | accepts "^1.3.5" 404 | cache-content-type "^1.0.0" 405 | content-disposition "~0.5.2" 406 | content-type "^1.0.4" 407 | cookies "~0.8.0" 408 | debug "~3.1.0" 409 | delegates "^1.0.0" 410 | depd "^1.1.2" 411 | destroy "^1.0.4" 412 | encodeurl "^1.0.2" 413 | escape-html "^1.0.3" 414 | fresh "~0.5.2" 415 | http-assert "^1.3.0" 416 | http-errors "^1.6.3" 417 | is-generator-function "^1.0.7" 418 | koa-compose "^4.1.0" 419 | koa-convert "^1.2.0" 420 | on-finished "^2.3.0" 421 | only "~0.0.2" 422 | parseurl "^1.3.2" 423 | statuses "^1.5.0" 424 | type-is "^1.6.16" 425 | vary "^1.1.2" 426 | 427 | lodash.includes@^4.3.0: 428 | version "4.3.0" 429 | resolved "https://registry.npm.taobao.org/lodash.includes/download/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" 430 | integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= 431 | 432 | lodash.isboolean@^3.0.3: 433 | version "3.0.3" 434 | resolved "https://registry.npm.taobao.org/lodash.isboolean/download/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" 435 | integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= 436 | 437 | lodash.isinteger@^4.0.4: 438 | version "4.0.4" 439 | resolved "https://registry.npm.taobao.org/lodash.isinteger/download/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" 440 | integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= 441 | 442 | lodash.isnumber@^3.0.3: 443 | version "3.0.3" 444 | resolved "https://registry.npm.taobao.org/lodash.isnumber/download/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" 445 | integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= 446 | 447 | lodash.isplainobject@^4.0.6: 448 | version "4.0.6" 449 | resolved "https://registry.npm.taobao.org/lodash.isplainobject/download/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 450 | integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= 451 | 452 | lodash.isstring@^4.0.1: 453 | version "4.0.1" 454 | resolved "https://registry.npm.taobao.org/lodash.isstring/download/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 455 | integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= 456 | 457 | lodash.once@^4.0.0: 458 | version "4.1.1" 459 | resolved "https://registry.npm.taobao.org/lodash.once/download/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" 460 | integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= 461 | 462 | media-typer@0.3.0: 463 | version "0.3.0" 464 | resolved "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 465 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 466 | 467 | memory-pager@^1.0.2: 468 | version "1.5.0" 469 | resolved "https://registry.npm.taobao.org/memory-pager/download/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" 470 | integrity sha1-2HUWVdItOEaCdByXLyw9bfo+ZrU= 471 | 472 | methods@^1.1.2: 473 | version "1.1.2" 474 | resolved "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 475 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 476 | 477 | mime-db@1.44.0: 478 | version "1.44.0" 479 | resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" 480 | integrity sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I= 481 | 482 | mime-types@^2.1.18, mime-types@~2.1.24: 483 | version "2.1.27" 484 | resolved "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" 485 | integrity sha1-R5SfmOJ56lMRn1ci4PNOUpvsAJ8= 486 | dependencies: 487 | mime-db "1.44.0" 488 | 489 | moment@^2.25.3: 490 | version "2.25.3" 491 | resolved "https://registry.npm.taobao.org/moment/download/moment-2.25.3.tgz#252ff41319cf41e47761a1a88cab30edfe9808c0" 492 | integrity sha1-JS/0ExnPQeR3YaGojKsw7f6YCMA= 493 | 494 | mongodb@3.5.7, mongodb@^3.5.7: 495 | version "3.5.7" 496 | resolved "https://registry.npm.taobao.org/mongodb/download/mongodb-3.5.7.tgz#6dcfff3bdbf67a53263dcca1647c265eea1d065d" 497 | integrity sha1-bc//O9v2elMmPcyhZHwmXuodBl0= 498 | dependencies: 499 | bl "^2.2.0" 500 | bson "^1.1.4" 501 | denque "^1.4.1" 502 | require_optional "^1.0.1" 503 | safe-buffer "^5.1.2" 504 | optionalDependencies: 505 | saslprep "^1.0.0" 506 | 507 | mongoose-legacy-pluralize@1.0.2: 508 | version "1.0.2" 509 | resolved "https://registry.npm.taobao.org/mongoose-legacy-pluralize/download/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4" 510 | integrity sha1-O6n5H6UHtRhtOZ+0CFS/8Y+1Y+Q= 511 | 512 | mongoose@^5.9.15: 513 | version "5.9.15" 514 | resolved "https://registry.npm.taobao.org/mongoose/download/mongoose-5.9.15.tgz?cache=0&sync_timestamp=1589851346351&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmongoose%2Fdownload%2Fmongoose-5.9.15.tgz#935e157d1429c0702b71c5ecf0e6801faa771091" 515 | integrity sha1-k14VfRQpwHArccXs8OaAH6p3EJE= 516 | dependencies: 517 | bson "^1.1.4" 518 | kareem "2.3.1" 519 | mongodb "3.5.7" 520 | mongoose-legacy-pluralize "1.0.2" 521 | mpath "0.7.0" 522 | mquery "3.2.2" 523 | ms "2.1.2" 524 | regexp-clone "1.0.0" 525 | safe-buffer "5.1.2" 526 | sift "7.0.1" 527 | sliced "1.0.1" 528 | 529 | mpath@0.7.0: 530 | version "0.7.0" 531 | resolved "https://registry.npm.taobao.org/mpath/download/mpath-0.7.0.tgz#20e8102e276b71709d6e07e9f8d4d0f641afbfb8" 532 | integrity sha1-IOgQLidrcXCdbgfp+NTQ9kGvv7g= 533 | 534 | mquery@3.2.2: 535 | version "3.2.2" 536 | resolved "https://registry.npm.taobao.org/mquery/download/mquery-3.2.2.tgz#e1383a3951852ce23e37f619a9b350f1fb3664e7" 537 | integrity sha1-4Tg6OVGFLOI+N/YZqbNQ8fs2ZOc= 538 | dependencies: 539 | bluebird "3.5.1" 540 | debug "3.1.0" 541 | regexp-clone "^1.0.0" 542 | safe-buffer "5.1.2" 543 | sliced "1.0.1" 544 | 545 | ms@2.0.0: 546 | version "2.0.0" 547 | resolved "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 548 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 549 | 550 | ms@2.1.2, ms@^2.1.1: 551 | version "2.1.2" 552 | resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 553 | integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= 554 | 555 | mz@^2.7.0: 556 | version "2.7.0" 557 | resolved "https://registry.npm.taobao.org/mz/download/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" 558 | integrity sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI= 559 | dependencies: 560 | any-promise "^1.0.0" 561 | object-assign "^4.0.1" 562 | thenify-all "^1.0.0" 563 | 564 | negotiator@0.6.2: 565 | version "0.6.2" 566 | resolved "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" 567 | integrity sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs= 568 | 569 | object-assign@^4.0.1: 570 | version "4.1.1" 571 | resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 572 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 573 | 574 | objectid-to-timestamp@^1.3.0: 575 | version "1.3.0" 576 | resolved "https://registry.npm.taobao.org/objectid-to-timestamp/download/objectid-to-timestamp-1.3.0.tgz#61ecacf6580751d2063b35446709dd8ccec2e5f1" 577 | integrity sha1-Yeys9lgHUdIGOzVEZwndjM7C5fE= 578 | 579 | on-finished@^2.3.0: 580 | version "2.3.0" 581 | resolved "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 582 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 583 | dependencies: 584 | ee-first "1.1.1" 585 | 586 | only@~0.0.2: 587 | version "0.0.2" 588 | resolved "https://registry.npm.taobao.org/only/download/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" 589 | integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= 590 | 591 | parseurl@^1.3.2: 592 | version "1.3.3" 593 | resolved "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 594 | integrity sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ= 595 | 596 | path-is-absolute@1.0.1: 597 | version "1.0.1" 598 | resolved "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 599 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 600 | 601 | path-to-regexp@1.x: 602 | version "1.8.0" 603 | resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" 604 | integrity sha1-iHs7qdhDk+h6CgufTLdWGYtTVIo= 605 | dependencies: 606 | isarray "0.0.1" 607 | 608 | process-nextick-args@~2.0.0: 609 | version "2.0.1" 610 | resolved "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 611 | integrity sha1-eCDZsWEgzFXKmud5JoCufbptf+I= 612 | 613 | qs@^6.5.2: 614 | version "6.9.4" 615 | resolved "https://registry.npm.taobao.org/qs/download/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" 616 | integrity sha1-kJCykNH5FyjTwi5UhDykSupatoc= 617 | 618 | raw-body@^2.3.3: 619 | version "2.4.1" 620 | resolved "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" 621 | integrity sha1-MKyC+Yu1rowVLmcUnayNVRU7Fow= 622 | dependencies: 623 | bytes "3.1.0" 624 | http-errors "1.7.3" 625 | iconv-lite "0.4.24" 626 | unpipe "1.0.0" 627 | 628 | readable-stream@2, readable-stream@^2.3.5: 629 | version "2.3.7" 630 | resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz?cache=0&sync_timestamp=1581623021561&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 631 | integrity sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c= 632 | dependencies: 633 | core-util-is "~1.0.0" 634 | inherits "~2.0.3" 635 | isarray "~1.0.0" 636 | process-nextick-args "~2.0.0" 637 | safe-buffer "~5.1.1" 638 | string_decoder "~1.1.1" 639 | util-deprecate "~1.0.1" 640 | 641 | regexp-clone@1.0.0, regexp-clone@^1.0.0: 642 | version "1.0.0" 643 | resolved "https://registry.npm.taobao.org/regexp-clone/download/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63" 644 | integrity sha1-Ii25Z2IydwViYLmSYmNUoEzpv2M= 645 | 646 | require_optional@^1.0.1: 647 | version "1.0.1" 648 | resolved "https://registry.npm.taobao.org/require_optional/download/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e" 649 | integrity sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4= 650 | dependencies: 651 | resolve-from "^2.0.0" 652 | semver "^5.1.0" 653 | 654 | resolve-from@^2.0.0: 655 | version "2.0.0" 656 | resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" 657 | integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c= 658 | 659 | resolve-path@^1.4.0: 660 | version "1.4.0" 661 | resolved "https://registry.npm.taobao.org/resolve-path/download/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" 662 | integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= 663 | dependencies: 664 | http-errors "~1.6.2" 665 | path-is-absolute "1.0.1" 666 | 667 | safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 668 | version "5.1.2" 669 | resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 670 | integrity sha1-mR7GnSluAxN0fVm9/St0XDX4go0= 671 | 672 | safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2: 673 | version "5.2.1" 674 | resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 675 | integrity sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY= 676 | 677 | "safer-buffer@>= 2.1.2 < 3": 678 | version "2.1.2" 679 | resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 680 | integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= 681 | 682 | saslprep@^1.0.0: 683 | version "1.0.3" 684 | resolved "https://registry.npm.taobao.org/saslprep/download/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" 685 | integrity sha1-TAL5RrVs9UKX40e6EJPnrKxM8iY= 686 | dependencies: 687 | sparse-bitfield "^3.0.3" 688 | 689 | semver@^5.1.0, semver@^5.6.0: 690 | version "5.7.1" 691 | resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1586886660126&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 692 | integrity sha1-qVT5Ma66UI0we78Gnv8MAclhFvc= 693 | 694 | setprototypeof@1.1.0: 695 | version "1.1.0" 696 | resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 697 | integrity sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY= 698 | 699 | setprototypeof@1.1.1: 700 | version "1.1.1" 701 | resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" 702 | integrity sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM= 703 | 704 | sha1@^1.1.1: 705 | version "1.1.1" 706 | resolved "https://registry.npm.taobao.org/sha1/download/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848" 707 | integrity sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg= 708 | dependencies: 709 | charenc ">= 0.0.1" 710 | crypt ">= 0.0.1" 711 | 712 | sift@7.0.1: 713 | version "7.0.1" 714 | resolved "https://registry.npm.taobao.org/sift/download/sift-7.0.1.tgz#47d62c50b159d316f1372f8b53f9c10cd21a4b08" 715 | integrity sha1-R9YsULFZ0xbxNy+LU/nBDNIaSwg= 716 | 717 | sliced@1.0.1: 718 | version "1.0.1" 719 | resolved "https://registry.npm.taobao.org/sliced/download/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41" 720 | integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E= 721 | 722 | sparse-bitfield@^3.0.3: 723 | version "3.0.3" 724 | resolved "https://registry.npm.taobao.org/sparse-bitfield/download/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" 725 | integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= 726 | dependencies: 727 | memory-pager "^1.0.2" 728 | 729 | "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: 730 | version "1.5.0" 731 | resolved "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 732 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 733 | 734 | streaming-json-stringify@3: 735 | version "3.1.0" 736 | resolved "https://registry.npm.taobao.org/streaming-json-stringify/download/streaming-json-stringify-3.1.0.tgz#80200437a993cc39c4fe00263b7b3b903ac87af5" 737 | integrity sha1-gCAEN6mTzDnE/gAmO3s7kDrIevU= 738 | dependencies: 739 | json-stringify-safe "5" 740 | readable-stream "2" 741 | 742 | string_decoder@~1.1.1: 743 | version "1.1.1" 744 | resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 745 | integrity sha1-nPFhG6YmhdcDCunkujQUnDrwP8g= 746 | dependencies: 747 | safe-buffer "~5.1.0" 748 | 749 | thenify-all@^1.0.0: 750 | version "1.6.0" 751 | resolved "https://registry.npm.taobao.org/thenify-all/download/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" 752 | integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= 753 | dependencies: 754 | thenify ">= 3.1.0 < 4" 755 | 756 | "thenify@>= 3.1.0 < 4": 757 | version "3.3.0" 758 | resolved "https://registry.npm.taobao.org/thenify/download/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" 759 | integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= 760 | dependencies: 761 | any-promise "^1.0.0" 762 | 763 | toidentifier@1.0.0: 764 | version "1.0.0" 765 | resolved "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 766 | integrity sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM= 767 | 768 | tsscmp@1.0.6: 769 | version "1.0.6" 770 | resolved "https://registry.npm.taobao.org/tsscmp/download/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" 771 | integrity sha1-hbmVg6w1iexL/vgltQAKqRHWBes= 772 | 773 | type-is@^1.6.16: 774 | version "1.6.18" 775 | resolved "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 776 | integrity sha1-TlUs0F3wlGfcvE73Od6J8s83wTE= 777 | dependencies: 778 | media-typer "0.3.0" 779 | mime-types "~2.1.24" 780 | 781 | unpipe@1.0.0: 782 | version "1.0.0" 783 | resolved "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 784 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 785 | 786 | urijs@^1.19.2: 787 | version "1.19.2" 788 | resolved "https://registry.npm.taobao.org/urijs/download/urijs-1.19.2.tgz#f9be09f00c4c5134b7cb3cf475c1dd394526265a" 789 | integrity sha1-+b4J8AxMUTS3yzz0dcHdOUUmJlo= 790 | 791 | util-deprecate@~1.0.1: 792 | version "1.0.2" 793 | resolved "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 794 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 795 | 796 | vary@^1.1.2: 797 | version "1.1.2" 798 | resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 799 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 800 | 801 | ylru@^1.2.0: 802 | version "1.2.1" 803 | resolved "https://registry.npm.taobao.org/ylru/download/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" 804 | integrity sha1-9Xa2M0FUeYnB3nuiiHYJI7J/6E8= 805 | --------------------------------------------------------------------------------