style: format all files with prettier

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
root
2026-01-22 15:05:58 +08:00
parent ac7d28f9ce
commit 24f825f60d
12 changed files with 128 additions and 52 deletions

View File

@@ -2,7 +2,8 @@ const repository =
process.env.PRICE_MIRROR_REPO || process.env.GITHUB_REPOSITORY || 'Wei-Shaw/claude-relay-service' process.env.PRICE_MIRROR_REPO || process.env.GITHUB_REPOSITORY || 'Wei-Shaw/claude-relay-service'
const branch = process.env.PRICE_MIRROR_BRANCH || 'price-mirror' const branch = process.env.PRICE_MIRROR_BRANCH || 'price-mirror'
const pricingFileName = process.env.PRICE_MIRROR_FILENAME || 'model_prices_and_context_window.json' const pricingFileName = process.env.PRICE_MIRROR_FILENAME || 'model_prices_and_context_window.json'
const hashFileName = process.env.PRICE_MIRROR_HASH_FILENAME || 'model_prices_and_context_window.sha256' const hashFileName =
process.env.PRICE_MIRROR_HASH_FILENAME || 'model_prices_and_context_window.sha256'
const baseUrl = process.env.PRICE_MIRROR_BASE_URL const baseUrl = process.env.PRICE_MIRROR_BASE_URL
? process.env.PRICE_MIRROR_BASE_URL.replace(/\/$/, '') ? process.env.PRICE_MIRROR_BASE_URL.replace(/\/$/, '')
@@ -11,7 +12,6 @@ const baseUrl = process.env.PRICE_MIRROR_BASE_URL
module.exports = { module.exports = {
pricingFileName, pricingFileName,
hashFileName, hashFileName,
pricingUrl: pricingUrl: process.env.PRICE_MIRROR_JSON_URL || `${baseUrl}/${pricingFileName}`,
process.env.PRICE_MIRROR_JSON_URL || `${baseUrl}/${pricingFileName}`,
hashUrl: process.env.PRICE_MIRROR_HASH_URL || `${baseUrl}/${hashFileName}` hashUrl: process.env.PRICE_MIRROR_HASH_URL || `${baseUrl}/${hashFileName}`
} }

View File

@@ -1193,7 +1193,9 @@ async function importData() {
pipeline.hset(`usage:global:daily:${date}`, field, value) pipeline.hset(`usage:global:daily:${date}`, field, value)
} }
} }
logger.info(`📥 Importing ${Object.keys(globalStats.globalDaily).length} global daily stats`) logger.info(
`📥 Importing ${Object.keys(globalStats.globalDaily).length} global daily stats`
)
} }
// 导入全局每月统计 // 导入全局每月统计
@@ -1203,7 +1205,9 @@ async function importData() {
pipeline.hset(`usage:global:monthly:${month}`, field, value) pipeline.hset(`usage:global:monthly:${month}`, field, value)
} }
} }
logger.info(`📥 Importing ${Object.keys(globalStats.globalMonthly).length} global monthly stats`) logger.info(
`📥 Importing ${Object.keys(globalStats.globalMonthly).length} global monthly stats`
)
} }
// 导入每日统计 // 导入每日统计

View File

@@ -1473,8 +1473,12 @@ class RedisClient {
// 多抽样检查:抽取最多 3 个 keyId 检查是否有 alltime 数据 // 多抽样检查:抽取最多 3 个 keyId 检查是否有 alltime 数据
const sampleIndices = new Set() const sampleIndices = new Set()
sampleIndices.add(0) // 始终包含第一个 sampleIndices.add(0) // 始终包含第一个
if (keyIds.length > 1) sampleIndices.add(keyIds.length - 1) // 包含最后一个 if (keyIds.length > 1) {
if (keyIds.length > 2) sampleIndices.add(Math.floor(keyIds.length / 2)) // 包含中间一个 sampleIndices.add(keyIds.length - 1)
} // 包含最后一个
if (keyIds.length > 2) {
sampleIndices.add(Math.floor(keyIds.length / 2))
} // 包含中间一个
let hasAnyAlltimeData = false let hasAnyAlltimeData = false
for (const idx of sampleIndices) { for (const idx of sampleIndices) {

View File

@@ -2673,13 +2673,14 @@ router.get('/api-keys/:keyId/usage-records', authenticateAdmin, async (req, res)
costFormatted: CostCalculator.formatCost(computedCost), costFormatted: CostCalculator.formatCost(computedCost),
realCost: Number(realCost.toFixed(6)), realCost: Number(realCost.toFixed(6)),
realCostFormatted: CostCalculator.formatCost(realCost), realCostFormatted: CostCalculator.formatCost(realCost),
costBreakdown: record.realCostBreakdown || record.costBreakdown || { costBreakdown: record.realCostBreakdown ||
input: costData?.costs?.input || 0, record.costBreakdown || {
output: costData?.costs?.output || 0, input: costData?.costs?.input || 0,
cacheCreate: costData?.costs?.cacheWrite || 0, output: costData?.costs?.output || 0,
cacheRead: costData?.costs?.cacheRead || 0, cacheCreate: costData?.costs?.cacheWrite || 0,
total: costData?.costs?.total || computedCost cacheRead: costData?.costs?.cacheRead || 0,
}, total: costData?.costs?.total || computedCost
},
responseTime: record.responseTime || null responseTime: record.responseTime || null
}) })
} }
@@ -2986,13 +2987,14 @@ router.get('/accounts/:accountId/usage-records', authenticateAdmin, async (req,
costFormatted: CostCalculator.formatCost(computedCost), costFormatted: CostCalculator.formatCost(computedCost),
realCost: Number(realCost.toFixed(6)), realCost: Number(realCost.toFixed(6)),
realCostFormatted: CostCalculator.formatCost(realCost), realCostFormatted: CostCalculator.formatCost(realCost),
costBreakdown: record.realCostBreakdown || record.costBreakdown || { costBreakdown: record.realCostBreakdown ||
input: costData?.costs?.input || 0, record.costBreakdown || {
output: costData?.costs?.output || 0, input: costData?.costs?.input || 0,
cacheCreate: costData?.costs?.cacheWrite || 0, output: costData?.costs?.output || 0,
cacheRead: costData?.costs?.cacheRead || 0, cacheCreate: costData?.costs?.cacheWrite || 0,
total: costData?.costs?.total || computedCost cacheRead: costData?.costs?.cacheRead || 0,
}, total: costData?.costs?.total || computedCost
},
responseTime: record.responseTime || null responseTime: record.responseTime || null
}) })
} }

View File

@@ -27,7 +27,14 @@ const {
} = require('../services/anthropicGeminiBridgeService') } = require('../services/anthropicGeminiBridgeService')
const router = express.Router() const router = express.Router()
function queueRateLimitUpdate(rateLimitInfo, usageSummary, model, context = '', keyId = null, accountType = null) { function queueRateLimitUpdate(
rateLimitInfo,
usageSummary,
model,
context = '',
keyId = null,
accountType = null
) {
if (!rateLimitInfo) { if (!rateLimitInfo) {
return Promise.resolve({ totalTokens: 0, totalCost: 0 }) return Promise.resolve({ totalTokens: 0, totalCost: 0 })
} }

View File

@@ -828,7 +828,7 @@ router.post('/api/batch-model-stats', async (req, res) => {
} }
// 优先使用存储的费用,否则回退到重新计算 // 优先使用存储的费用,否则回退到重新计算
const hasStoredCost = usage.hasStoredCost const { hasStoredCost } = usage
const costData = CostCalculator.calculateCost(usageData, model) const costData = CostCalculator.calculateCost(usageData, model)
// 如果有存储的费用,覆盖计算的费用 // 如果有存储的费用,覆盖计算的费用

View File

@@ -24,7 +24,14 @@ function checkPermissions(apiKeyData, requiredPermission = 'claude') {
return apiKeyService.hasPermission(apiKeyData?.permissions, requiredPermission) return apiKeyService.hasPermission(apiKeyData?.permissions, requiredPermission)
} }
function queueRateLimitUpdate(rateLimitInfo, usageSummary, model, context = '', keyId = null, accountType = null) { function queueRateLimitUpdate(
rateLimitInfo,
usageSummary,
model,
context = '',
keyId = null,
accountType = null
) {
if (!rateLimitInfo) { if (!rateLimitInfo) {
return return
} }

View File

@@ -1800,7 +1800,13 @@ function dumpToolsPayload({ vendor, model, tools, toolChoice }) {
* 更新速率限制计数器 * 更新速率限制计数器
* 跟踪 token 使用量和成本 * 跟踪 token 使用量和成本
*/ */
async function applyRateLimitTracking(rateLimitInfo, usageSummary, model, context = '', keyId = null) { async function applyRateLimitTracking(
rateLimitInfo,
usageSummary,
model,
context = '',
keyId = null
) {
if (!rateLimitInfo) { if (!rateLimitInfo) {
return return
} }

View File

@@ -162,7 +162,7 @@ class ApiKeyService {
const hashedKey = this._hashApiKey(apiKey) const hashedKey = this._hashApiKey(apiKey)
// 处理 permissions // 处理 permissions
let permissionsValue = permissions const permissionsValue = permissions
const keyData = { const keyData = {
id: keyId, id: keyId,
@@ -623,7 +623,9 @@ class ApiKeyService {
// 统计 API Key 上的标签trim 后统计) // 统计 API Key 上的标签trim 后统计)
for (const key of apiKeys) { for (const key of apiKeys) {
if (key.isDeleted === 'true') continue if (key.isDeleted === 'true') {
continue
}
let tags = [] let tags = []
try { try {
const parsed = key.tags ? JSON.parse(key.tags) : [] const parsed = key.tags ? JSON.parse(key.tags) : []
@@ -666,7 +668,9 @@ class ApiKeyService {
let affectedCount = 0 let affectedCount = 0
for (const key of apiKeys) { for (const key of apiKeys) {
if (key.isDeleted === 'true') continue if (key.isDeleted === 'true') {
continue
}
let tags = [] let tags = []
try { try {
const parsed = key.tags ? JSON.parse(key.tags) : [] const parsed = key.tags ? JSON.parse(key.tags) : []
@@ -709,7 +713,9 @@ class ApiKeyService {
let foundInKeys = false let foundInKeys = false
for (const key of apiKeys) { for (const key of apiKeys) {
if (key.isDeleted === 'true') continue if (key.isDeleted === 'true') {
continue
}
let tags = [] let tags = []
try { try {
const parsed = key.tags ? JSON.parse(key.tags) : [] const parsed = key.tags ? JSON.parse(key.tags) : []

View File

@@ -211,7 +211,9 @@ class ServiceRatesService {
* 根据账户类型获取服务类型(优先级高于模型推断) * 根据账户类型获取服务类型(优先级高于模型推断)
*/ */
getServiceFromAccountType(accountType) { getServiceFromAccountType(accountType) {
if (!accountType) return null if (!accountType) {
return null
}
const mapping = { const mapping = {
claude: 'claude', claude: 'claude',

View File

@@ -94,14 +94,23 @@ function mapToErrorCode(error, options = {}) {
// 先按 HTTP 状态码快速匹配 // 先按 HTTP 状态码快速匹配
if (statusCode) { if (statusCode) {
if (statusCode === 401) matchedCode = 'E003' if (statusCode === 401) {
else if (statusCode === 403) matchedCode = 'E009' matchedCode = 'E003'
else if (statusCode === 404) matchedCode = 'E010' } else if (statusCode === 403) {
else if (statusCode === 429) matchedCode = 'E004' matchedCode = 'E009'
else if (statusCode === 502) matchedCode = 'E007' } else if (statusCode === 404) {
else if (statusCode === 503) matchedCode = 'E001' matchedCode = 'E010'
else if (statusCode === 504) matchedCode = 'E008' } else if (statusCode === 429) {
else if (statusCode === 529) matchedCode = 'E012' matchedCode = 'E004'
} else if (statusCode === 502) {
matchedCode = 'E007'
} else if (statusCode === 503) {
matchedCode = 'E001'
} else if (statusCode === 504) {
matchedCode = 'E008'
} else if (statusCode === 529) {
matchedCode = 'E012'
}
} }
// 再按消息内容精确匹配(可能覆盖状态码匹配) // 再按消息内容精确匹配(可能覆盖状态码匹配)
@@ -117,10 +126,15 @@ function mapToErrorCode(error, options = {}) {
// 按错误 code 匹配(网络错误) // 按错误 code 匹配(网络错误)
if (errorCode) { if (errorCode) {
const codeStr = String(errorCode).toUpperCase() const codeStr = String(errorCode).toUpperCase()
if (codeStr === 'ENOTFOUND' || codeStr === 'EAI_AGAIN') matchedCode = 'E002' if (codeStr === 'ENOTFOUND' || codeStr === 'EAI_AGAIN') {
else if (codeStr === 'ECONNREFUSED' || codeStr === 'ECONNRESET') matchedCode = 'E002' matchedCode = 'E002'
else if (codeStr === 'ETIMEDOUT' || codeStr === 'ESOCKETTIMEDOUT') matchedCode = 'E008' } else if (codeStr === 'ECONNREFUSED' || codeStr === 'ECONNRESET') {
else if (codeStr === 'ECONNABORTED') matchedCode = 'E002' matchedCode = 'E002'
} else if (codeStr === 'ETIMEDOUT' || codeStr === 'ESOCKETTIMEDOUT') {
matchedCode = 'E008'
} else if (codeStr === 'ECONNABORTED') {
matchedCode = 'E002'
}
} }
const result = ERROR_CODES[matchedCode] const result = ERROR_CODES[matchedCode]
@@ -135,12 +149,24 @@ function mapToErrorCode(error, options = {}) {
* 提取原始错误消息 * 提取原始错误消息
*/ */
function extractOriginalMessage(error) { function extractOriginalMessage(error) {
if (!error) return '' if (!error) {
if (typeof error === 'string') return error return ''
if (error.message) return error.message }
if (error.response?.data?.error?.message) return error.response.data.error.message if (typeof error === 'string') {
if (error.response?.data?.error) return String(error.response.data.error) return error
if (error.response?.data?.message) return error.response.data.message }
if (error.message) {
return error.message
}
if (error.response?.data?.error?.message) {
return error.response.data.error.message
}
if (error.response?.data?.error) {
return String(error.response.data.error)
}
if (error.response?.data?.message) {
return error.response.data.message
}
return '' return ''
} }
@@ -188,7 +214,9 @@ function getSafeMessage(error, options = {}) {
// 兼容旧接口 // 兼容旧接口
function sanitizeErrorMessage(message) { function sanitizeErrorMessage(message) {
if (!message) return 'Service temporarily unavailable' if (!message) {
return 'Service temporarily unavailable'
}
return mapToErrorCode({ message }, { logOriginal: false }).message return mapToErrorCode({ message }, { logOriginal: false }).message
} }
@@ -201,9 +229,13 @@ function extractErrorMessage(body) {
} }
function isAccountDisabledError(statusCode, body) { function isAccountDisabledError(statusCode, body) {
if (statusCode !== 400) return false if (statusCode !== 400) {
return false
}
const message = extractOriginalMessage(body) const message = extractOriginalMessage(body)
if (!message) return false if (!message) {
return false
}
const lower = message.toLowerCase() const lower = message.toLowerCase()
return ( return (
lower.includes('organization has been disabled') || lower.includes('organization has been disabled') ||

View File

@@ -8,7 +8,13 @@ function toNumber(value) {
} }
// keyId 和 accountType 用于计算倍率成本 // keyId 和 accountType 用于计算倍率成本
async function updateRateLimitCounters(rateLimitInfo, usageSummary, model, keyId = null, accountType = null) { async function updateRateLimitCounters(
rateLimitInfo,
usageSummary,
model,
keyId = null,
accountType = null
) {
if (!rateLimitInfo) { if (!rateLimitInfo) {
return { totalTokens: 0, totalCost: 0, ratedCost: 0 } return { totalTokens: 0, totalCost: 0, ratedCost: 0 }
} }