拆分打手平台参数校验
This commit is contained in:
@@ -12,12 +12,9 @@ import {
|
|||||||
type WorkOrderShareRow,
|
type WorkOrderShareRow,
|
||||||
type WorkerWalletLedgerRow,
|
type WorkerWalletLedgerRow,
|
||||||
type WorkerUserRow,
|
type WorkerUserRow,
|
||||||
type GrabWorkOrderFailureReason,
|
|
||||||
type ProblemWorkOrderResolutionAction,
|
|
||||||
} from '../../repositories/worker-platform/index.js'
|
} from '../../repositories/worker-platform/index.js'
|
||||||
import type { JsonObject } from '../../types/json.js'
|
import type { JsonObject } from '../../types/json.js'
|
||||||
import type { OrderItemRow, OrderRow } from '../../types/repository/rows.js'
|
import type { OrderItemRow, OrderRow } from '../../types/repository/rows.js'
|
||||||
import { createHttpError } from '../../utils/http.js'
|
|
||||||
import { safeParseJson } from '../admin/admin-query-utils.js'
|
import { safeParseJson } from '../admin/admin-query-utils.js'
|
||||||
import {
|
import {
|
||||||
refreshStoredFileUrl,
|
refreshStoredFileUrl,
|
||||||
@@ -46,6 +43,29 @@ import {
|
|||||||
normalizeStatuses,
|
normalizeStatuses,
|
||||||
normalizeUploadedFiles,
|
normalizeUploadedFiles,
|
||||||
} from './worker-input-normalizers.js'
|
} from './worker-input-normalizers.js'
|
||||||
|
export {
|
||||||
|
assertWithdrawChannelAllowedForAmount,
|
||||||
|
isWorkerPasswordStrong,
|
||||||
|
normalizeAdminFinanceReviewStatus,
|
||||||
|
normalizeAmountFen,
|
||||||
|
normalizeEnabledStatus,
|
||||||
|
normalizeFinanceRequestStatus,
|
||||||
|
normalizeFinanceRequestType,
|
||||||
|
normalizeMatchType,
|
||||||
|
normalizeOptionalId,
|
||||||
|
normalizePassword,
|
||||||
|
normalizeProblemResolutionAction,
|
||||||
|
normalizeProofFiles,
|
||||||
|
normalizeReviewStatus,
|
||||||
|
normalizeSlugKey,
|
||||||
|
normalizeUsername,
|
||||||
|
normalizeWalletLedgerType,
|
||||||
|
normalizeWithdrawChannel,
|
||||||
|
normalizeWorkerFreezeReason,
|
||||||
|
throwGrabWorkOrderFailure,
|
||||||
|
validateWorkerPassword,
|
||||||
|
validateWorkerUsername,
|
||||||
|
} from './worker-platform-normalizers.js'
|
||||||
export {
|
export {
|
||||||
normalizeRequirementFields,
|
normalizeRequirementFields,
|
||||||
normalizeRequirementFieldsFromPayload,
|
normalizeRequirementFieldsFromPayload,
|
||||||
@@ -1123,230 +1143,6 @@ export function resolveCollectSubmittedFieldValues(workOrder: WorkOrderRow) {
|
|||||||
return normalizeSubmittedFields(collect.fields)
|
return normalizeSubmittedFields(collect.fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeReviewStatus(value: unknown) {
|
|
||||||
const status = String(value || '').trim()
|
|
||||||
if (['active', 'rejected', 'disabled', 'pending_review'].includes(status)) return status
|
|
||||||
return 'pending_review'
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 冻结原因必须可追溯,限制长度避免异常大载荷写入账号资料。 */
|
|
||||||
export function normalizeWorkerFreezeReason(value: unknown): string {
|
|
||||||
const reason = String(value || '').trim()
|
|
||||||
if (!reason) {
|
|
||||||
throw createHttpError('请填写冻结原因或备注', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_freeze_reason_required',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (reason.length > 500) {
|
|
||||||
throw createHttpError('冻结原因不能超过 500 个字符', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_freeze_reason_too_long',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return reason
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeProblemResolutionAction(value: unknown): ProblemWorkOrderResolutionAction {
|
|
||||||
const action = String(value || '').trim()
|
|
||||||
if (['return_to_worker', 'reopen', 'cancel_release', 'cancel_deduct'].includes(action)) {
|
|
||||||
return action as ProblemWorkOrderResolutionAction
|
|
||||||
}
|
|
||||||
throw createHttpError('问题单处置方式不正确', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'work_order_problem_resolution_action_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function throwGrabWorkOrderFailure(failureReason: GrabWorkOrderFailureReason | null): never {
|
|
||||||
if (failureReason === 'worker_active_order_limit') {
|
|
||||||
throw createHttpError('已达到当前等级最大同时接单量', {
|
|
||||||
statusCode: 409,
|
|
||||||
errorCode: 'worker_active_order_limit',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (failureReason === 'worker_deposit_insufficient') {
|
|
||||||
throw createHttpError('余额不足,无法冻结所需押金', {
|
|
||||||
statusCode: 409,
|
|
||||||
errorCode: 'worker_deposit_insufficient',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
throw createHttpError('抢单失败,订单可能已被抢走', {
|
|
||||||
statusCode: 409,
|
|
||||||
errorCode: 'work_order_grab_conflict',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeEnabledStatus(value: unknown) {
|
|
||||||
return String(value || 'active').trim() === 'disabled' ? 'disabled' : 'active'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeWalletLedgerType(value: unknown) {
|
|
||||||
const ledgerType = String(value || '').trim()
|
|
||||||
if (!ledgerType) return ''
|
|
||||||
if (
|
|
||||||
[
|
|
||||||
'manual_credit',
|
|
||||||
'withdraw_paid',
|
|
||||||
'deposit_freeze',
|
|
||||||
'deposit_release',
|
|
||||||
'deposit_pending_unfreeze',
|
|
||||||
'deposit_unfreeze',
|
|
||||||
'deposit_deduction',
|
|
||||||
'reward_settlement',
|
|
||||||
'after_sales_deposit_deduction',
|
|
||||||
'after_sales_balance_deduction',
|
|
||||||
'after_sales_debt_offset',
|
|
||||||
].includes(ledgerType)
|
|
||||||
) {
|
|
||||||
return ledgerType
|
|
||||||
}
|
|
||||||
throw createHttpError('钱包流水类型不正确', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_wallet_ledger_type_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeFinanceRequestType(value: unknown) {
|
|
||||||
const requestType = String(value || '').trim()
|
|
||||||
if (!requestType) return ''
|
|
||||||
if (['recharge', 'withdraw'].includes(requestType)) {
|
|
||||||
return requestType
|
|
||||||
}
|
|
||||||
throw createHttpError('资金申请类型不正确', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_finance_request_type_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeFinanceRequestStatus(value: unknown) {
|
|
||||||
const status = String(value || '').trim()
|
|
||||||
if (!status) return ''
|
|
||||||
if (['pending', 'approved', 'rejected', 'cancelled'].includes(status)) {
|
|
||||||
return status
|
|
||||||
}
|
|
||||||
throw createHttpError('资金申请状态不正确', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_finance_request_status_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeAdminFinanceReviewStatus(value: unknown) {
|
|
||||||
const status = String(value || '').trim()
|
|
||||||
if (['approved', 'rejected', 'cancelled'].includes(status)) {
|
|
||||||
return status
|
|
||||||
}
|
|
||||||
throw createHttpError('审核状态不正确', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_finance_review_status_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeWithdrawChannel(value: unknown) {
|
|
||||||
const channel = String(value || '').trim()
|
|
||||||
if (['alipay', 'wechat'].includes(channel)) {
|
|
||||||
return channel
|
|
||||||
}
|
|
||||||
throw createHttpError('提现方式不正确', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_withdraw_channel_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 提现金额超过 100 元时,仅允许使用支付宝。 */
|
|
||||||
export function assertWithdrawChannelAllowedForAmount(amount: number, channel: string) {
|
|
||||||
if (amount > 10_000 && channel !== 'alipay') {
|
|
||||||
throw createHttpError('提现金额超过 100 元时,仅支持支付宝提现', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_withdraw_channel_amount_limited',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeMatchType(value: unknown) {
|
|
||||||
const matchType = String(value || '').trim()
|
|
||||||
if (matchType === 'exact') return 'exact'
|
|
||||||
return 'contains'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeSlugKey(value: unknown, fallback: string) {
|
|
||||||
const key = String(value || '')
|
|
||||||
.trim()
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(/[^a-z0-9._-]+/g, '-')
|
|
||||||
.replace(/^-+|-+$/g, '')
|
|
||||||
return key || fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeUsername(value: unknown): string {
|
|
||||||
return String(value || '')
|
|
||||||
.trim()
|
|
||||||
.toLowerCase()
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizePassword(value: unknown): string {
|
|
||||||
return String(value || '').trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
export function validateWorkerUsername(username: string) {
|
|
||||||
if (!/^[a-zA-Z0-9._-]{3,32}$/.test(username)) {
|
|
||||||
throw createHttpError('接单账号格式无效,需为 3-32 位字母数字或 ._-', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_username_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function validateWorkerPassword(password: string) {
|
|
||||||
if (!isWorkerPasswordStrong(password)) {
|
|
||||||
throw createHttpError('接单密码至少 8 位,且必须包含英文字母和数字', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'worker_password_invalid',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isWorkerPasswordStrong(password: string): boolean {
|
|
||||||
return password.length >= 8 && /[a-zA-Z]/.test(password) && /\d/.test(password)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeOptionalId(value: unknown): number | null {
|
|
||||||
const parsed = Number(value)
|
|
||||||
return Number.isInteger(parsed) && parsed > 0 ? parsed : null
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeAmountFen(value: unknown, fallback: number): number {
|
|
||||||
const text = String(value ?? '').trim()
|
|
||||||
if (!text) return fallback
|
|
||||||
const parsed = Number(text)
|
|
||||||
if (!Number.isFinite(parsed) || parsed < 0) return fallback
|
|
||||||
return Math.round(parsed * 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalizeProofFiles(value: unknown): Array<Record<string, unknown>> {
|
|
||||||
if (!Array.isArray(value)) return []
|
|
||||||
const files: Array<Record<string, unknown>> = []
|
|
||||||
for (const item of value) {
|
|
||||||
if (!item || typeof item !== 'object') continue
|
|
||||||
const file = item as Record<string, unknown>
|
|
||||||
const url = String(file.url || '').trim()
|
|
||||||
if (!url) continue
|
|
||||||
files.push({
|
|
||||||
url,
|
|
||||||
thumbnailUrl: String(file.thumbnailUrl || file.thumbnail_url || '').trim(),
|
|
||||||
mediumUrl: String(file.mediumUrl || file.medium_url || '').trim(),
|
|
||||||
objectKey: String(file.objectKey || file.object_key || '').trim(),
|
|
||||||
originalFilename: String(
|
|
||||||
file.originalFilename || file.original_filename || file.name || '',
|
|
||||||
).trim(),
|
|
||||||
contentType: String(file.contentType || file.content_type || '').trim(),
|
|
||||||
sizeBytes: Number(file.sizeBytes || file.size_bytes || 0),
|
|
||||||
})
|
|
||||||
if (files.length >= 10) break
|
|
||||||
}
|
|
||||||
return files
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isIgnorableWorkerAuthError(error: unknown) {
|
export function isIgnorableWorkerAuthError(error: unknown) {
|
||||||
return IGNORABLE_WORKER_AUTH_ERROR_CODES.has(
|
return IGNORABLE_WORKER_AUTH_ERROR_CODES.has(
|
||||||
String((error as { errorCode?: string })?.errorCode || '').trim(),
|
String((error as { errorCode?: string })?.errorCode || '').trim(),
|
||||||
|
|||||||
@@ -0,0 +1,219 @@
|
|||||||
|
import type {
|
||||||
|
GrabWorkOrderFailureReason,
|
||||||
|
ProblemWorkOrderResolutionAction,
|
||||||
|
} from '../../repositories/worker-platform/index.js'
|
||||||
|
import { createHttpError } from '../../utils/http.js'
|
||||||
|
|
||||||
|
export function normalizeReviewStatus(value: unknown) {
|
||||||
|
const status = String(value || '').trim()
|
||||||
|
if (['active', 'rejected', 'disabled', 'pending_review'].includes(status)) return status
|
||||||
|
return 'pending_review'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 冻结原因必须可追溯,限制长度避免异常大载荷写入账号资料。 */
|
||||||
|
export function normalizeWorkerFreezeReason(value: unknown): string {
|
||||||
|
const reason = String(value || '').trim()
|
||||||
|
if (!reason) {
|
||||||
|
throw createHttpError('请填写冻结原因或备注', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_freeze_reason_required',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (reason.length > 500) {
|
||||||
|
throw createHttpError('冻结原因不能超过 500 个字符', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_freeze_reason_too_long',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return reason
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeProblemResolutionAction(value: unknown): ProblemWorkOrderResolutionAction {
|
||||||
|
const action = String(value || '').trim()
|
||||||
|
if (['return_to_worker', 'reopen', 'cancel_release', 'cancel_deduct'].includes(action)) {
|
||||||
|
return action as ProblemWorkOrderResolutionAction
|
||||||
|
}
|
||||||
|
throw createHttpError('问题单处置方式不正确', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'work_order_problem_resolution_action_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function throwGrabWorkOrderFailure(failureReason: GrabWorkOrderFailureReason | null): never {
|
||||||
|
if (failureReason === 'worker_active_order_limit') {
|
||||||
|
throw createHttpError('已达到当前等级最大同时接单量', {
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: 'worker_active_order_limit',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (failureReason === 'worker_deposit_insufficient') {
|
||||||
|
throw createHttpError('余额不足,无法冻结所需押金', {
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: 'worker_deposit_insufficient',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
throw createHttpError('抢单失败,订单可能已被抢走', {
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: 'work_order_grab_conflict',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeEnabledStatus(value: unknown) {
|
||||||
|
return String(value || 'active').trim() === 'disabled' ? 'disabled' : 'active'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeWalletLedgerType(value: unknown) {
|
||||||
|
const ledgerType = String(value || '').trim()
|
||||||
|
if (!ledgerType) return ''
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
'manual_credit',
|
||||||
|
'withdraw_paid',
|
||||||
|
'deposit_freeze',
|
||||||
|
'deposit_release',
|
||||||
|
'deposit_pending_unfreeze',
|
||||||
|
'deposit_unfreeze',
|
||||||
|
'deposit_deduction',
|
||||||
|
'reward_settlement',
|
||||||
|
'after_sales_deposit_deduction',
|
||||||
|
'after_sales_balance_deduction',
|
||||||
|
'after_sales_debt_offset',
|
||||||
|
].includes(ledgerType)
|
||||||
|
) {
|
||||||
|
return ledgerType
|
||||||
|
}
|
||||||
|
throw createHttpError('钱包流水类型不正确', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_wallet_ledger_type_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeFinanceRequestType(value: unknown) {
|
||||||
|
const requestType = String(value || '').trim()
|
||||||
|
if (!requestType) return ''
|
||||||
|
if (['recharge', 'withdraw'].includes(requestType)) return requestType
|
||||||
|
throw createHttpError('资金申请类型不正确', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_finance_request_type_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeFinanceRequestStatus(value: unknown) {
|
||||||
|
const status = String(value || '').trim()
|
||||||
|
if (!status) return ''
|
||||||
|
if (['pending', 'approved', 'rejected', 'cancelled'].includes(status)) return status
|
||||||
|
throw createHttpError('资金申请状态不正确', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_finance_request_status_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeAdminFinanceReviewStatus(value: unknown) {
|
||||||
|
const status = String(value || '').trim()
|
||||||
|
if (['approved', 'rejected', 'cancelled'].includes(status)) return status
|
||||||
|
throw createHttpError('审核状态不正确', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_finance_review_status_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeWithdrawChannel(value: unknown) {
|
||||||
|
const channel = String(value || '').trim()
|
||||||
|
if (['alipay', 'wechat'].includes(channel)) return channel
|
||||||
|
throw createHttpError('提现方式不正确', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_withdraw_channel_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 提现金额超过 100 元时,仅允许使用支付宝。 */
|
||||||
|
export function assertWithdrawChannelAllowedForAmount(amount: number, channel: string) {
|
||||||
|
if (amount > 10_000 && channel !== 'alipay') {
|
||||||
|
throw createHttpError('提现金额超过 100 元时,仅支持支付宝提现', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_withdraw_channel_amount_limited',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeMatchType(value: unknown) {
|
||||||
|
return String(value || '').trim() === 'exact' ? 'exact' : 'contains'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeSlugKey(value: unknown, fallback: string) {
|
||||||
|
const key = String(value || '')
|
||||||
|
.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9._-]+/g, '-')
|
||||||
|
.replace(/^-+|-+$/g, '')
|
||||||
|
return key || fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeUsername(value: unknown): string {
|
||||||
|
return String(value || '')
|
||||||
|
.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizePassword(value: unknown): string {
|
||||||
|
return String(value || '').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateWorkerUsername(username: string) {
|
||||||
|
if (!/^[a-zA-Z0-9._-]{3,32}$/.test(username)) {
|
||||||
|
throw createHttpError('接单账号格式无效,需为 3-32 位字母数字或 ._-', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_username_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateWorkerPassword(password: string) {
|
||||||
|
if (!isWorkerPasswordStrong(password)) {
|
||||||
|
throw createHttpError('接单密码至少 8 位,且必须包含英文字母和数字', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'worker_password_invalid',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isWorkerPasswordStrong(password: string): boolean {
|
||||||
|
return password.length >= 8 && /[a-zA-Z]/.test(password) && /\d/.test(password)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeOptionalId(value: unknown): number | null {
|
||||||
|
const parsed = Number(value)
|
||||||
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeAmountFen(value: unknown, fallback: number): number {
|
||||||
|
const text = String(value ?? '').trim()
|
||||||
|
if (!text) return fallback
|
||||||
|
const parsed = Number(text)
|
||||||
|
if (!Number.isFinite(parsed) || parsed < 0) return fallback
|
||||||
|
return Math.round(parsed * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeProofFiles(value: unknown): Array<Record<string, unknown>> {
|
||||||
|
if (!Array.isArray(value)) return []
|
||||||
|
const files: Array<Record<string, unknown>> = []
|
||||||
|
for (const item of value) {
|
||||||
|
if (!item || typeof item !== 'object') continue
|
||||||
|
const file = item as Record<string, unknown>
|
||||||
|
const url = String(file.url || '').trim()
|
||||||
|
if (!url) continue
|
||||||
|
files.push({
|
||||||
|
url,
|
||||||
|
thumbnailUrl: String(file.thumbnailUrl || file.thumbnail_url || '').trim(),
|
||||||
|
mediumUrl: String(file.mediumUrl || file.medium_url || '').trim(),
|
||||||
|
objectKey: String(file.objectKey || file.object_key || '').trim(),
|
||||||
|
originalFilename: String(
|
||||||
|
file.originalFilename || file.original_filename || file.name || '',
|
||||||
|
).trim(),
|
||||||
|
contentType: String(file.contentType || file.content_type || '').trim(),
|
||||||
|
sizeBytes: Number(file.sizeBytes || file.size_bytes || 0),
|
||||||
|
})
|
||||||
|
if (files.length >= 10) break
|
||||||
|
}
|
||||||
|
return files
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user