Skip to content

Commit

Permalink
refactor: pnpm workspace monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat616 committed Nov 19, 2023
1 parent da09cd0 commit f3c161f
Show file tree
Hide file tree
Showing 101 changed files with 5,916 additions and 0 deletions.
32 changes: 32 additions & 0 deletions manifest/config.example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: 'hitokoto' # 服务名称,例如:hitokoto
url: 'https://v1.hitokoto.cn' # 服务地址,例如:https://v1.hitokoto.cn
api_name: 'demo_prprpr' # 服务标识,取个好区分的标识吧,例如:cd-01-demo
server: # 配置 HTTP 服务的信息
hosts: 0.0.0.0 # 监听的地址
port: 8000 # 监听的端口
compress_body: true # 是否使用 GZIP 压缩
redis: # 配置 Redis
host: 127.0.0.1 # Redis 主机名
port: 6379 # Redis 端口
password: '' # Redis 密码
database: 0 # Redis 数据库
sentences_ab_switcher: # 本节是服务 AB 异步更新的配置,如果您不知道这个是什么意思,请保持默认
a: 1 # a 状态对应的 redis 数据库
b: 2 # b 状态对应的 redis 数据库
remote_sentences_url: https://cdn.jsdelivr.net/gh/hitokoto-osc/sentences-bundle@latest/ # 语句库地址,通常默认即可。如果您想使用您自己打包部署的语句库,您可以修改此项
workers: 0 # 启动 Worker 数目。0 表示启动和 CPU 核心数相同数量的 Worker
extensions: # 控制扩展
netease: true # 网易云音乐接口
requests:
enabled: true # 是否启用请求数目统计
hosts: # 需要单独统计的主机名
- v1.hitokoto.cn
- international.v1.hitokoto.cn
- api.a632079.me
- api.hitokoto.cn
- sslapi.hitokoto.cn
telemetry: # 遥测服务
performance: true # 性能监控
error: true # 错误报告
usage: true # 使用报告
debug: false # 是否启用调试模式(该模式会让遥测服务打印调试信息)
10 changes: 10 additions & 0 deletions packages/api/adapter/crons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Register Cron Event
module.exports = (cron) => {
// return true
return [
// Register cron
cron.countRequests,
cron.updateSentences,
// cron.checkUpdate
]
}
5 changes: 5 additions & 0 deletions packages/api/adapter/plugins.dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = [
// Dev Plugins
// ['koa-livereload', require('koa-livereload')()],
// Nodemon is better then livereload plugin
]
68 changes: 68 additions & 0 deletions packages/api/adapter/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use strict'
const path = require('path')
const nconf = require('nconf')

module.exports = [
['respond', require('@hitokoto/koa-respond')()],
// MiddleWares
['requestId', require('../src/middlewares/requestId')()],
['RequestsCounter', require('../src/middlewares/RequestsCounter')()],
['responseHandler', require('../src/middlewares/responseHandler')()],

// Recover Error
['RecoverError', require('../src/middlewares/recoverError')()],

// Basic Plugins
[
'koa-helmet',
require('koa-helmet')({
crossOriginEmbedderPolicy: false,
crossOriginResourcePolicy: {
policy: 'cross-origin',
},
}),
],
['koa-query-pretty', require('koa-query-pretty')()],
['koa-jsonp', require('@hitokoto/koa-jsonp')()],
[
'@koa/bodyparser',
require('@koa/bodyparser').bodyParser({
enableTypes: ['json', 'form'],
formLimit: '10mb',
jsonLimit: '10mb',
}),
],
[
'@koa/cors',
require('@koa/cors')({
origin: '*',
allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
exposeHeaders: ['X-Request-Id'],
}),
],
[
'koa-favicon',
require('koa-favicon')(path.join(__dirname, '../public/favicon.ico')),
],
!nconf.get('server:compress_body') || [
'koa-compress',
require('koa-compress')({
filter(contentType) {
return /text/i.test(contentType)
},
threshold: 2048,
gzip: {
flush: require('zlib').constants.Z_SYNC_FLUSH,
},
deflate: {
flush: require('zlib').constants.Z_SYNC_FLUSH,
},
}),
],
['logger', require('../src/middlewares/logger')()],
!nconf.get('telemetry:performance') ||
nconf.get('dev') || [
'performanceTracing',
require('../src/middlewares/performanceTracing'),
],
]
5 changes: 5 additions & 0 deletions packages/api/adapter/plugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Plugins } from '~/packages/@hitokoto/api/src/types'

export const DevPlugins: Plugins = []

export default [] satisfies Plugins
62 changes: 62 additions & 0 deletions packages/api/adapter/processes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// This file is a map of child processes
const path = require('path')
const chalk = require('chalk')
const AB = require('../src/extensions/sentencesABSwitcher')
const { logger } = require('../src/logger')
const { WorkersBridge } = require('../src/http/primary')
module.exports = {
processes: [
{
path: path.join(__dirname, '../src/cron.js'), // The absolute path of the process file
name: 'cronJob', // The name of the process module
messageListener: (message, { event, moduleName }) => {
// emit msg to global process route
if (message && message.key) {
message.from = moduleName
event.emit('message', message, moduleName)
}
}, // the handler of the receiving message
isDev: false, // if set true, this process will start only in Dev
isProd: false, // if set true, this process will start only in prod
// if isDev and isProd both be set false, process will both start in Dev and Prod
},
],
receivers: [
{
key: 'switchAB',
to: 'ab',
from: 'cronJob',
listener: (targetDB) => {
logger.verbose(
'[AB] received signal, switching to db: ' + chalk.yellow(targetDB),
)
AB.setDatabase(targetDB)
logger.verbose('[AB] notifying workers...')
WorkersBridge.workers.notify({
key: 'switchAB',
data: targetDB,
})
},
},
{
key: 'loaded',
to: 'core',
from: 'cronJob',
listener: (message, moduleName) => {
logger.verbose('[init] all cronJobs are loaded. ')
},
},
{
key: 'error',
to: 'core',
from: 'cronJob',
listener: (data, moduleName) => {
logger.error(chalk.red(data))
logger.error(
'[init] error was thrown while loading cron jobs, process existing.',
)
process.exit(1)
},
},
],
}
103 changes: 103 additions & 0 deletions packages/api/adapter/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
const nconf = require('nconf')

module.exports = (router, middleware, controller) => {
// Route Map
/* router.get('/', async (ctx, next) => {
ctx.body = {
message: 'Hello World',
ts: Date.now()
}
})
*/
router.get('/ping', (ctx) => {
ctx.status = 200
ctx.body = {
status: 200,
message: 'ok',
data: {},
ts: Date.now(),
}
})
if (nconf.get('dev')) {
router.get('/crash', async (ctx) => {
throw new Error('崩溃测试')
})
router.get('/test', async (ctx) => {
const nconf = require('nconf')
const os = require('os')
let memoryUsage = 0
Object.values(process.memoryUsage()).forEach((v) => {
memoryUsage += parseInt(v)
})
memoryUsage = memoryUsage / (1024 * 1024)
ctx.body = {
header: ctx.headers,
host: ctx.request.host,
server_id: nconf.get('api_name'),
server_status: {
memory: {
total: os.totalmem() / (1024 * 1024),
free: os.freemem() / (1024 * 1024),
usage: memoryUsage,
},
cpu: os.cpus(),
load: os.loadavg(),
},
hostname: ctx.request.hostname,
URL: ctx.request.URL,
url: ctx.request.url,
origin: ctx.request.origin,
originalUrl: ctx.request.originalUrl,
queryParams: ctx.query,
queryLength: ctx.query && ctx.query.c ? ctx.query.c.length : '',
now: new Date().toUTCString(),
}
})
}

router.all('/', controller.hitokoto.entry) // 兼容文档说明
// router.get('/test', controller.hello.index)
router.get('/status', controller.status.entry)

// Netease API
if (nconf.get('extensions:netease')) {
router.get('/nm/search/:keyword', controller.netease.search)
router.get('/nm/playlist/:id', controller.netease.playlist)
router.get('/nm/picture/:id/:height?', controller.netease.picture)
router.get('/nm/artist/:id', controller.netease.artist)
router.get('/nm/album/:id', controller.netease.album)
router.get('/nm/lyric/:id', controller.netease.lyric)
router.get('/nm/url/:id', controller.netease.url)
router.get('/nm/detail/:id', controller.netease.detail)
router.get('/nm/summary/:id', controller.netease.summary)
router.get('/nm/redirect/music/:id', controller.netease.redirect)
router.get('/nm/record/:uid', (ctx) => {
ctx.status = 503
ctx.body = {
status: 503,
message: '由于此接口需登录后才能使用,因此本接口已移除。',
data: null,
ts: Date.now(),
}
})
router.get('/nm/comment/music/:id', controller.netease.music_comment)
router.get('/nm/url/mv/:mvid', async (ctx) => {
ctx.redirect(301, `/nm/mv/${ctx.params.mvid}`)
})
router.get('/nm/mv/:mvid', controller.netease.mv)
router.get('/nm/mv/url/:mvid', controller.netease.mv_url)
router.get('/nm/dj/:rid', controller.netease.dj_program)
router.get('/nm/dj/program/detail/:id', controller.netease.dj_program_info)
router.get('/nm/user/dj/:uid', (ctx) => {
ctx.status = 503
ctx.body = {
status: 503,
message: '由于此接口需登录后才能使用,因此本接口已移除。',
data: null,
ts: Date.now(),
}
})
router.get('/nm/dj/detail/:rid', controller.netease.dj_detail)
}
return router
}
Loading

0 comments on commit f3c161f

Please sign in to comment.