Compare commits

...
5 Commits
Author SHA1 Message Date
cancerai 7a6ab45920 mod: 通用化部署脚本 2026-10-11 23:51:11 +08:00
cancerai ac53e4ed27 mod: 规范构建script 2026-10-11 23:08:21 +08:00
cancerai b26bee6f05 add: 自动部署上线脚本 2026-10-11 19:08:56 +08:00
cancerai 3ad5f0915b change: 规范响应描述 2026-10-11 18:36:38 +08:00
cancerai 33172b0968 删除了跨域,并删除一些无用库引用 2026-09-29 19:38:37 +08:00
8 changed files with 77 additions and 48 deletions

No files matched your search

+2
View File
@@ -32,3 +32,5 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# Finder (MacOS) folder config # Finder (MacOS) folder config
.DS_Store .DS_Store
build/
+4
View File
@@ -0,0 +1,4 @@
FROM debian
COPY ./app /app
EXPOSE 8080
CMD ["/app"]
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
# 上线脚本
app_name="test-api"
app_ver="v1.02"
bun run build-linux-x86
scp -P $server_port Dockerfile ${server_user}@${server_host}:${server_user_path}
scp -P $server_port build/linux_x86_app ${server_user}@${server_host}:${server_user_path}/app
ssh -p $server_port root@${server_host} "cd ${server_user_path} && docker build -t ${app_name}:${app_ver} . && docker compose down && docker compose up -d"
ssh -p $server_port ${server_user}@${server_host} "cd ${server_user_path}/ && rm -rf Dockerfile app"
+20 -20
View File
@@ -1,22 +1,22 @@
{ {
"name": "test-api", "name": "test-api",
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "bun run --hot src/index.ts", "dev": "bun run --hot src/index.ts",
"clean": "rm -rf ./build && rm -rf ./.*.bun-build", "clean": "rm -rf ./build && rm -rf ./.*.bun-build",
"build-macos": "mkdir -p build && bun build src/index.ts --compile --minify --outfile build/test-api-macos", "build-macos": "mkdir -p build && bun build src/index.ts --compile --minify --outfile build/macos_app",
"build-linux-x86": "bun build src/index.ts --compile --minify --target=bun-linux-x64 --outfile build/test-api-linux-x86", "build-linux-x86": "bun build src/index.ts --compile --minify --target=bun-linux-x64 --outfile build/linux_x86_app",
"build-linux-arm64": "bun build src/index.ts --compile --minify --target=bun-linux-arm64 --outfile build/test-api-linux-arm64" "build-linux-arm64": "bun build src/index.ts --compile --minify --target=bun-linux-arm64 --outfile build/linux_arm64_app"
}, },
"devDependencies": { "devDependencies": {
"@types/bun": "latest" "@types/bun": "latest"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^7" "typescript": "^7"
}, },
"dependencies": { "dependencies": {
"hono": "^4.13.8" "hono": "^4.13.8"
} }
} }
+17
View File
@@ -0,0 +1,17 @@
export class responseStr {
static REQ_PARAM_ERR = "请求参数错误"
static REQ_SYNTAX_ERR = "请求解析错误"
static USER_GET_SUCCESS = "用户获取成功"
static USER_ADD_SUCCESS = "用户添加成功"
static USER_DEL_SUCCESS = "用户删除成功"
static USER_MOD_SUCCESS = "用户修改成功"
static FILE_SIZE_LIMIT_5M = "文件大小应不超过5MB"
static FILE_TYPE_INVALID = "不是合法的文件"
static FILE_UPLOAD_SUCCESS = "文件上传成功"
static UNEXPECTED_ERR = "未知错误"
static API_NOTFOUND = "找不到请求路径"
}
+15 -17
View File
@@ -4,18 +4,16 @@ import { validator } from "hono/validator";
import { postUser } from "./service/postUser"; import { postUser } from "./service/postUser";
import { isEmpty } from "./utils/is_empty"; import { isEmpty } from "./utils/is_empty";
import { getUser } from "./service/getUser"; import { getUser } from "./service/getUser";
import { cors } from "hono/cors";
import { bodyLimit } from "hono/body-limit"; import { bodyLimit } from "hono/body-limit";
import { getRandom } from "./service/getRandom"; import { getRandom } from "./service/getRandom";
import { responseStr } from "./const/response_str";
const tmpApp: Hono = new Hono() const tmpApp: Hono = new Hono()
export const app = tmpApp.basePath("/test/") export const app = tmpApp.basePath("/test/")
app.use("/test/*", cors())
// routers
app.get("/user", (c) => { app.get("/user", (c) => {
const re = getUser() const re = getUser()
return c.json(ApiResponse.success(200, "Get user successfully", re)) return c.json(ApiResponse.success(200, responseStr.USER_GET_SUCCESS, re))
}) })
app.post( app.post(
@@ -23,13 +21,13 @@ app.post(
validator("json", (val, c) => { validator("json", (val, c) => {
if (isEmpty(val.name, val.passwd)) { if (isEmpty(val.name, val.passwd)) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Param is invalid")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
return val return val
}), }),
c => { c => {
const re = postUser() const re = postUser()
return c.json(ApiResponse.success(200, "Add successfully", re)) return c.json(ApiResponse.success(200, responseStr.USER_ADD_SUCCESS, re))
} }
) )
@@ -37,12 +35,12 @@ app.patch("/user",
validator("json", (val, c) => { validator("json", (val, c) => {
if (isEmpty(val.id, val.changeFields)) { if (isEmpty(val.id, val.changeFields)) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Param is invalid")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
return val return val
}), }),
c => { c => {
return c.json(ApiResponse.success(200, "Change user information successfully")) return c.json(ApiResponse.success(200, responseStr.USER_MOD_SUCCESS))
} }
) )
@@ -50,12 +48,12 @@ app.put("/user",
validator("json", (val, c) => { validator("json", (val, c) => {
if (isEmpty(val.id, val.changeFields)) { if (isEmpty(val.id, val.changeFields)) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Param is invalid")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
return val return val
}), }),
c => { c => {
return c.json(ApiResponse.success(200, "Change user information successfully")) return c.json(ApiResponse.success(200, responseStr.USER_MOD_SUCCESS))
} }
) )
@@ -63,13 +61,13 @@ app.delete("/user",
validator("json", (val, c) => { validator("json", (val, c) => {
if (isEmpty(val.id)) { if (isEmpty(val.id)) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Param is invalid")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
return val return val
}), }),
async (c) => { async (c) => {
const id = await c.req.json() const id = await c.req.json()
return c.json(ApiResponse.success(200, `Delete user successfully by id: ${id.id}`)) return c.json(ApiResponse.success(200, responseStr.USER_DEL_SUCCESS))
} }
) )
@@ -77,19 +75,19 @@ app.post("/file",
bodyLimit({ bodyLimit({
maxSize: 5 * 1024 * 1024, maxSize: 5 * 1024 * 1024,
onError: (c) => { onError: (c) => {
return c.json(ApiResponse.err(400, "File must less than 5MB")) return c.json(ApiResponse.err(400, responseStr.FILE_SIZE_LIMIT_5M))
} }
}), }),
async (c) => { async (c) => {
const body = await c.req.parseBody() const body = await c.req.parseBody()
const file = body["file"] const file = body["file"]
if (!(file instanceof File)) { if (!(file instanceof File)) {
return c.json(ApiResponse.err(400, "Not file")) return c.json(ApiResponse.err(400, responseStr.FILE_TYPE_INVALID))
} }
const fileName = file.name const fileName = file.name
const fileSize = file.size const fileSize = file.size
return c.json(ApiResponse.success(200, "Upload file successfully", { return c.json(ApiResponse.success(200, responseStr.FILE_UPLOAD_SUCCESS, {
fileName, fileName,
fileSize fileSize
})) }))
@@ -100,7 +98,7 @@ app.get("/random",
validator("query", (val, c) => { validator("query", (val, c) => {
if (isEmpty(val.typeList, val.length)) { if (isEmpty(val.typeList, val.length)) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Param is invalid")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
return val return val
}), }),
@@ -111,7 +109,7 @@ app.get("/random",
app.notFound((c) => { app.notFound((c) => {
console.log(`Not found [${c.req.method}]: ${c.req.path}`); console.log(`Not found [${c.req.method}]: ${c.req.path}`);
return c.json(ApiResponse.err(404, "Not Found")) return c.json(ApiResponse.err(404, responseStr.API_NOTFOUND))
}) })
export default { export default {
+8 -7
View File
@@ -1,6 +1,7 @@
import type { Context } from "hono" import type { Context } from "hono"
import { ApiResponse } from "../modules/api_response" import { ApiResponse } from "../modules/api_response"
import { Random } from "../utils/random" import { Random } from "../utils/random"
import { responseStr } from "../const/response_str"
export function getRandom(c: Context) { export function getRandom(c: Context) {
const typeInReq = c.req.query("typeList") const typeInReq = c.req.query("typeList")
@@ -8,28 +9,28 @@ export function getRandom(c: Context) {
let len: number let len: number
if (typeInReq == "") { if (typeInReq == "") {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Param is invalid")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
let typeList: string[] let typeList: string[]
try { try {
typeList = JSON.parse(typeInReq!.toString()) typeList = JSON.parse(typeInReq!.toString())
} catch (e) { } catch (e) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Syntax error in parameter[typeList]")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
if (typeList.length == 0) { if (typeList.length == 0) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Array is empty in parameter[typeList]")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
if (isNaN((Number(lenTmp)))) { if (isNaN((Number(lenTmp)))) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Parameter[length] must be a number")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} else { } else {
len = Number(lenTmp) len = Number(lenTmp)
if (len <= 0) { if (len <= 0) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, "Parameter[length] must > 0")) return c.json(ApiResponse.err(400, responseStr.REQ_PARAM_ERR))
} }
} }
@@ -41,13 +42,13 @@ export function getRandom(c: Context) {
c.status(400) c.status(400)
return c.json(ApiResponse.err(400, e.message)) return c.json(ApiResponse.err(400, e.message))
} else { } else {
console.log("Unexcepted error"); console.log(responseStr.UNEXPECTED_ERR);
} }
} }
if (result != undefined) { if (result != undefined) {
return c.json(ApiResponse.success(200, "ok", result)) return c.json(ApiResponse.success(200, "ok", result))
} else { } else {
return c.json(ApiResponse.err(500, "Unexcepted error")) return c.json(ApiResponse.err(500, responseStr.UNEXPECTED_ERR))
} }
} }
-4
View File
@@ -1,7 +1,3 @@
import type { Context, ContextVariableMap } from "hono"
import { updateExpressionWithTypeArguments } from "typescript/unstable/ast/factory"
import { ApiResponse } from "../modules/api_response"
enum Type { enum Type {
lcLetter = "lcLetter", lcLetter = "lcLetter",
ucLetter = "ucLetter", ucLetter = "ucLetter",