mirror of
https://gitlab.com/Binaryify/neteasecloudmusicapi.git
synced 2025-05-23 22:37:41 +08:00
feat(server): allow passing modules manually
自行維護 require 名單以相容 Webpack。
This commit is contained in:
parent
fc9630aa39
commit
5bf53028ef
2
app.js
2
app.js
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
require('./server')({
|
require('./server').serveNcmApi({
|
||||||
checkVersion: true,
|
checkVersion: true,
|
||||||
})
|
})
|
||||||
|
76
server.js
76
server.js
@ -20,11 +20,19 @@ const VERSION_CHECK_RESULT = {
|
|||||||
LATEST: 1,
|
LATEST: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* route: string,
|
||||||
|
* module: any
|
||||||
|
* }} ModuleDefinition
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* port?: number,
|
* port?: number,
|
||||||
* host?: string,
|
* host?: string,
|
||||||
* checkVersion?: boolean,
|
* checkVersion?: boolean,
|
||||||
|
* moduleDefs?: ModuleDefinition[]
|
||||||
* }} NcmApiOptions
|
* }} NcmApiOptions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -42,6 +50,35 @@ const VERSION_CHECK_RESULT = {
|
|||||||
* }} ExpressExtension
|
* }} ExpressExtension
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the module definitions dynamically.
|
||||||
|
*
|
||||||
|
* @param {string} modulePath The path to modules (JS).
|
||||||
|
* @param {Record<string, string>} [specificRoute] The specific route of specific modules.
|
||||||
|
* @returns {Promise<ModuleDefinition[]>} The module definitions.
|
||||||
|
*
|
||||||
|
* @example getModuleDefinitions("./module", {"album_new.js": "/album/create"})
|
||||||
|
*/
|
||||||
|
async function getModulesDefinitions(modulePath, specificRoute) {
|
||||||
|
const files = await fs.promises.readdir(path.join(__dirname, 'module'))
|
||||||
|
const parseRoute = (/** @type {string} */ fileName) =>
|
||||||
|
specificRoute && fileName in specificRoute
|
||||||
|
? specificRoute[fileName]
|
||||||
|
: `/${fileName.replace(/\.js$/i, '').replace(/_/g, '/')}`
|
||||||
|
|
||||||
|
const modules = files
|
||||||
|
.reverse()
|
||||||
|
.filter((file) => file.endsWith('.js'))
|
||||||
|
.map((file) => {
|
||||||
|
const route = parseRoute(file)
|
||||||
|
const module = require(path.join(modulePath, file))
|
||||||
|
|
||||||
|
return { route, module }
|
||||||
|
})
|
||||||
|
|
||||||
|
return modules
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the version of this API is latest.
|
* Check if the version of this API is latest.
|
||||||
*
|
*
|
||||||
@ -50,8 +87,8 @@ const VERSION_CHECK_RESULT = {
|
|||||||
* need to notify users to upgrade it manually.
|
* need to notify users to upgrade it manually.
|
||||||
*/
|
*/
|
||||||
async function checkVersion() {
|
async function checkVersion() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve) => {
|
||||||
exec('npm info NeteaseCloudMusicApi version', (err, stdout, stderr) => {
|
exec('npm info NeteaseCloudMusicApi version', (err, stdout) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
let version = stdout.trim()
|
let version = stdout.trim()
|
||||||
|
|
||||||
@ -82,9 +119,10 @@ async function checkVersion() {
|
|||||||
/**
|
/**
|
||||||
* Construct the server of NCM API.
|
* Construct the server of NCM API.
|
||||||
*
|
*
|
||||||
|
* @param {ModuleDefinition[]} moduleDefs Customized module definitions [advanced]
|
||||||
* @returns {Promise<import("express").Express>} The server instance.
|
* @returns {Promise<import("express").Express>} The server instance.
|
||||||
*/
|
*/
|
||||||
async function consturctServer() {
|
async function consturctServer(moduleDefs) {
|
||||||
const app = express()
|
const app = express()
|
||||||
app.set('trust proxy', true)
|
app.set('trust proxy', true)
|
||||||
|
|
||||||
@ -107,7 +145,7 @@ async function consturctServer() {
|
|||||||
/**
|
/**
|
||||||
* Cookie Parser
|
* Cookie Parser
|
||||||
*/
|
*/
|
||||||
app.use((req, res, next) => {
|
app.use((req, _, next) => {
|
||||||
req.cookies = {}
|
req.cookies = {}
|
||||||
//;(req.headers.cookie || '').split(/\s*;\s*/).forEach((pair) => { // Polynomial regular expression //
|
//;(req.headers.cookie || '').split(/\s*;\s*/).forEach((pair) => { // Polynomial regular expression //
|
||||||
;(req.headers.cookie || '').split(/;\s+|(?<!\s)\s+$/g).forEach((pair) => {
|
;(req.headers.cookie || '').split(/;\s+|(?<!\s)\s+$/g).forEach((pair) => {
|
||||||
@ -150,24 +188,13 @@ async function consturctServer() {
|
|||||||
/**
|
/**
|
||||||
* Load every modules in this directory
|
* Load every modules in this directory
|
||||||
*/
|
*/
|
||||||
const modules = (
|
const moduleDefinitions =
|
||||||
await fs.promises.readdir(path.join(__dirname, 'module'))
|
moduleDefs ||
|
||||||
).reverse()
|
(await getModulesDefinitions(path.join(__dirname, 'module'), special))
|
||||||
for (const file of modules) {
|
|
||||||
// Check if the file is written in JS.
|
|
||||||
if (!file.endsWith('.js')) continue
|
|
||||||
|
|
||||||
// Get the route path.
|
|
||||||
const route =
|
|
||||||
file in special
|
|
||||||
? special[file]
|
|
||||||
: '/' + file.replace(/\.js$/i, '').replace(/_/g, '/')
|
|
||||||
|
|
||||||
// Get the module itself.
|
|
||||||
const module = require(path.join(__dirname, 'module', file))
|
|
||||||
|
|
||||||
|
for (const moduleDef of moduleDefinitions) {
|
||||||
// Register the route.
|
// Register the route.
|
||||||
app.use(route, async (req, res) => {
|
app.use(moduleDef.route, async (req, res) => {
|
||||||
;[req.query, req.body].forEach((item) => {
|
;[req.query, req.body].forEach((item) => {
|
||||||
if (typeof item.cookie === 'string') {
|
if (typeof item.cookie === 'string') {
|
||||||
item.cookie = cookieToJson(decode(item.cookie))
|
item.cookie = cookieToJson(decode(item.cookie))
|
||||||
@ -182,7 +209,7 @@ async function consturctServer() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const moduleResponse = await module(query, request)
|
const moduleResponse = await moduleDef.module(query, request)
|
||||||
console.log('[OK]', decode(req.originalUrl))
|
console.log('[OK]', decode(req.originalUrl))
|
||||||
|
|
||||||
const cookies = moduleResponse.cookie
|
const cookies = moduleResponse.cookie
|
||||||
@ -242,7 +269,7 @@ async function serveNcmApi(options) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const constructServerSubmission = consturctServer()
|
const constructServerSubmission = consturctServer(options.moduleDefs)
|
||||||
|
|
||||||
const [_, app] = await Promise.all([
|
const [_, app] = await Promise.all([
|
||||||
checkVersionSubmission,
|
checkVersionSubmission,
|
||||||
@ -258,4 +285,7 @@ async function serveNcmApi(options) {
|
|||||||
return appExt
|
return appExt
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = serveNcmApi
|
module.exports = {
|
||||||
|
serveNcmApi,
|
||||||
|
getModulesDefinitions,
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user