mirror of
https://github.com/purocean/yn.git
synced 2026-10-13 15:49:22 +08:00
177 lines
5.5 KiB
JavaScript
177 lines
5.5 KiB
JavaScript
const path = require('path')
|
|
const Koa = require('koa')
|
|
const bodyParser = require('koa-body')
|
|
const static = require('koa-static')
|
|
const mime = require('mime')
|
|
const request = require('request')
|
|
|
|
const file = require('./file')
|
|
const dataRepository = require('./repository')
|
|
const run = require('./run')
|
|
const convert = require('./convert')
|
|
const plantuml = require('./plantuml')
|
|
|
|
const result = (status = 'ok', message = '操作成功', data = null) => {
|
|
return { status, message, data }
|
|
}
|
|
|
|
const fileContent = async (ctx, next) => {
|
|
if (ctx.path === '/api/file') {
|
|
if (ctx.method === 'GET') {
|
|
ctx.body = result('ok', '获取成功', {
|
|
content: file.read(ctx.query.repo, ctx.query.path).toString(),
|
|
hash: file.hash(ctx.query.repo, ctx.query.path)
|
|
})
|
|
} else if (ctx.method === 'POST') {
|
|
const oldHash = ctx.request.body.old_hash
|
|
|
|
if (!oldHash) {
|
|
throw new Error('未传递文件hash')
|
|
} else if (oldHash === 'new' && file.exists(ctx.request.body.repo, ctx.request.body.path)) {
|
|
throw new Error('文件已经存在')
|
|
} else if (oldHash !== 'new' && !file.checkHash(ctx.request.body.repo, ctx.request.body.path, oldHash)) {
|
|
throw new Error('磁盘文件已经更新,请刷新文件')
|
|
}
|
|
|
|
const hash = file.write(ctx.request.body.repo, ctx.request.body.path, ctx.request.body.content)
|
|
ctx.body = result('ok', '保存成功', hash)
|
|
} else if (ctx.method === 'DELETE') {
|
|
file.rm(ctx.query.repo, ctx.query.path)
|
|
ctx.body = result()
|
|
} else if (ctx.method === 'PATCH') {
|
|
if (file.exists(ctx.request.body.repo, ctx.request.body.newPath)) {
|
|
throw new Error('文件已经存在')
|
|
}
|
|
|
|
file.mv(ctx.request.body.repo, ctx.request.body.oldPath, ctx.request.body.newPath)
|
|
ctx.body = result()
|
|
}
|
|
} else if (ctx.path === '/api/tree') {
|
|
ctx.body = result('ok', '获取成功', file.tree(ctx.query.repo))
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const attachment = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/attachment')) {
|
|
if (ctx.method === 'POST') {
|
|
const path = ctx.request.body.fields.path
|
|
const repo = ctx.request.body.fields.repo
|
|
file.upload(repo, ctx.request.body.files.attachment, path)
|
|
ctx.body = result('ok', '上传成功', path)
|
|
} else if (ctx.method === 'GET') {
|
|
ctx.type = mime.getType(ctx.query.path)
|
|
ctx.body = file.read(ctx.query.repo, ctx.query.path)
|
|
}
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const open = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/open')) {
|
|
if (ctx.method === 'GET') {
|
|
file.open(ctx.query.repo, ctx.query.path)
|
|
ctx.body = result()
|
|
}
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const searchFile = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/search')) {
|
|
const search = ctx.query.search
|
|
const repo = ctx.query.repo
|
|
|
|
ctx.body = result('ok', '操作成功', file.search(repo, search))
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const repository = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/repositories')) {
|
|
ctx.body = result('ok', '获取成功', dataRepository.list())
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const plantumlGen = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/plantuml/png')) {
|
|
ctx.set('cache-control', 'max-age=86400') // 一天过期
|
|
ctx.type = 'image/png'
|
|
ctx.body = plantuml.generate(ctx.query.data)
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const runCode = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/run')) {
|
|
const rst = run.runCode(ctx.request.body.language, ctx.request.body.code)
|
|
ctx.body = result('ok', '运行成功', rst)
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const convertFile = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/convert/')) {
|
|
const html = ctx.request.body.html
|
|
const type = ctx.request.body.type
|
|
|
|
ctx.type = mime.getType(`file.${type}`)
|
|
ctx.body = await convert(html, type)
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const proxy = async (ctx, next) => {
|
|
if (ctx.path.startsWith('/api/proxy')) {
|
|
const url = ctx.query.url
|
|
ctx.body = request(url)
|
|
} else {
|
|
await next()
|
|
}
|
|
}
|
|
|
|
const app = new Koa()
|
|
|
|
app.use(static(
|
|
path.join(__dirname, '../static')
|
|
))
|
|
|
|
app.use(bodyParser({
|
|
multipart: true,
|
|
formLimit: '20mb',
|
|
jsonLimit: '20mb',
|
|
textLimit: '20mb'
|
|
}))
|
|
|
|
const wrapper = async (ctx, next, fun) => {
|
|
try {
|
|
await fun(ctx, next)
|
|
} catch (error) {
|
|
ctx.body = result('error', error.message)
|
|
}
|
|
}
|
|
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, fileContent))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, attachment))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, open))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, plantumlGen))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, runCode))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, convertFile))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, searchFile))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, repository))
|
|
app.use(async (ctx, next) => await wrapper(ctx, next, proxy))
|
|
|
|
const port = 3000
|
|
app.listen(port)
|
|
|
|
console.log(`访问地址:http://localhost:${port}`)
|