forked from Binaryify/NeteaseCloudMusicApi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
142 lines (123 loc) · 4.11 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const express = require('express')
const apicache = require('apicache')
const path = require('path')
const fs = require('fs')
const app = express()
let cache = apicache.middleware
const { exec } = require('child_process');
exec('npm info NeteaseCloudMusicApi version', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
const onlinePackageVersion = stdout.trim();
const package = require('./package.json')
if (package.version < onlinePackageVersion) {
console.log(
'最新版:Version:' +
onlinePackageVersion +
',当前版本:' +
package.version +
',请及时更新'
)
}
})
// 跨域设置
app.all('*', function(req, res, next) {
if (req.path !== '/' && !req.path.includes('.')) {
res.header('Access-Control-Allow-Credentials', true)
// 这里获取 origin 请求头 而不是用 *
res.header('Access-Control-Allow-Origin', req.headers['origin'] || '*')
res.header('Access-Control-Allow-Headers', 'X-Requested-With')
res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
res.header('Content-Type', 'application/json;charset=utf-8')
}
next()
})
const onlyStatus200 = (req, res) => res.statusCode === 200
app.use(cache('2 minutes', onlyStatus200))
app.use(express.static(path.resolve(__dirname, 'public')))
app.use(function(req, res, next) {
const proxy = req.query.proxy
if (proxy) {
req.headers.cookie += `__proxy__${proxy}`
}
next()
})
// 补全缺失的cookie
const { completeCookie } = require('./util/init')
app.use(function(req, res, next) {
let cookie = completeCookie(req.headers.cookie)
req.headers.cookie = cookie.map(x => x[0]).concat(req.headers.cookie || []).join('; ')
res.append('Set-Cookie', cookie.map(x => (x.concat('Path=/').join('; '))))
next()
})
// 因为这几个文件对外所注册的路由 和 其他文件对外注册的路由规则不一样, 所以专门写个MAP对这些文件做特殊处理
const UnusualRouteFileMap = {
// key 为文件名, value 为对外注册的路由
'daily_signin.js': '/daily_signin',
'fm_trash.js': '/fm_trash',
'personal_fm.js': '/personal_fm'
}
// 简化 路由 导出方式, 由这里统一对 router 目录中导出的路由做包装, 路由实际对应的文件只专注做它该做的事情, 不用重复写样板代码
const { createWebAPIRequest, request } = require('./util/util')
const Wrap = fn => (req, res) => fn(req, res, createWebAPIRequest, request)
// 同步读取 router 目录中的js文件, 根据命名规则, 自动注册路由
fs.readdirSync(path.resolve(__dirname, 'router'))
.reverse()
.forEach(file => {
if (/\.js$/i.test(file) === false) {
return
}
let route
if (typeof UnusualRouteFileMap[file] !== 'undefined') {
route = UnusualRouteFileMap[file]
} else {
route =
'/' +
file
.replace(/\.js$/i, '')
.replace(/_/g, '/')
}
app.use(route, Wrap(require('./router/' + file)))
})
const requestMod = require('./util/request')
let dev = express()
fs.readdirSync(path.resolve(__dirname, 'module'))
.reverse()
.forEach(file => {
if (/\.js$/i.test(file) === false) {
return
}
let route
if (typeof UnusualRouteFileMap[file] !== 'undefined') {
route = UnusualRouteFileMap[file]
} else {
route =
'/' +
file
.replace(/\.js$/i, '')
.replace(/_/g, '/')
}
dev.use(route, (req, res) => {
let question = require('./module/' + file)
let query = {...req.query, cookie: req.headers.cookie}
question(query, requestMod)
.then(answer => {
console.log('[OK]', req.originalUrl)
res.append('Set-Cookie', answer.cookie)
res.status(answer.code).send(answer.body)
})
.catch( answer => {
console.log('[ERROR]', req.originalUrl)
res.append('Set-Cookie', answer.cookie)
res.status(answer.code).send(answer.body)
})
})
})
app.use('/dev', dev)
const port = process.env.PORT || 3000
app.server = app.listen(port, () => {
console.log(`server running @ http://localhost:${port}`)
})
module.exports = app