paper-burner/local-proxy/routes/utils.js

123 lines
2.8 KiB
JavaScript

/**
* 路由辅助工具
* 用于简化 HTTP 路由处理
*/
import { URL } from 'url';
/**
* JSON 响应辅助函数
*/
export function jsonResponse(res, data, status = 200, origin = '*') {
const headers = {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': origin,
'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};
res.writeHead(status, headers);
res.end(JSON.stringify(data));
}
/**
* 读取请求体
*/
export async function readBody(req) {
return new Promise((resolve, reject) => {
const chunks = [];
req.on('data', chunk => chunks.push(chunk));
req.on('end', () => resolve(Buffer.concat(chunks)));
req.on('error', reject);
});
}
/**
* 解析 JSON 请求体
*/
export async function readJsonBody(req) {
const body = await readBody(req);
if (body.length === 0) return {};
try {
return JSON.parse(body.toString());
} catch {
throw new Error('Invalid JSON');
}
}
/**
* 解析 URL 路径参数
* @param {string} pathname - 请求路径
* @param {string} pattern - 路由模式,如 '/api/documents/:id'
* @returns {Object|null} 解析出的参数或 null
*/
export function parsePathParams(pathname, pattern) {
const patternParts = pattern.split('/');
const pathnameParts = pathname.split('/');
if (patternParts.length !== pathnameParts.length) {
return null;
}
const params = {};
for (let i = 0; i < patternParts.length; i++) {
if (patternParts[i].startsWith(':')) {
params[patternParts[i].slice(1)] = pathnameParts[i];
} else if (patternParts[i] !== pathnameParts[i]) {
return null;
}
}
return params;
}
/**
* 检查路径是否匹配
* @param {string} pathname - 请求路径
* @param {string} prefix - 路径前缀
* @returns {boolean}
*/
export function pathStartsWith(pathname, prefix) {
return pathname.startsWith(prefix);
}
/**
* 获取路径剩余部分
* @param {string} pathname - 请求路径
* @param {string} prefix - 路径前缀
* @returns {string}
*/
export function getPathRemainder(pathname, prefix) {
return pathname.slice(prefix.length);
}
/**
* 解析查询参数
* @param {string} searchParams - URL 查询字符串
* @returns {Object}
*/
export function parseQuery(searchParams) {
const params = new URLSearchParams(searchParams);
const result = {};
for (const [key, value] of params) {
result[key] = value;
}
return result;
}
/**
* 验证 UUID 格式
*/
export function isValidUUID(id) {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
}
/**
* 生成 UUID
*/
export function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}