chore: initial commit

This commit is contained in:
2026-07-30 17:59:42 +08:00
commit 155f06846d
62 changed files with 7852 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
export interface ApiEnvelope<T> {
code: string
message: string
data: T
requestId: string | null
traceId: string | null
timestamp: string
}
export type ApiFieldErrors = Record<string, string>
export class ApiError extends Error {
constructor(
message: string,
readonly code = 'NETWORK_ERROR',
readonly status?: number,
readonly fieldErrors?: ApiFieldErrors,
readonly traceId?: string | null,
) {
super(message)
this.name = 'ApiError'
}
}
export function isApiEnvelope(value: unknown): value is ApiEnvelope<unknown> {
if (!value || typeof value !== 'object') return false
const record = value as Record<string, unknown>
return typeof record.code === 'string' && typeof record.message === 'string' && 'data' in record
}
export function asFieldErrors(value: unknown): ApiFieldErrors | undefined {
if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined
const entries = Object.entries(value).filter((entry): entry is [string, string] => typeof entry[1] === 'string')
return entries.length > 0 ? Object.fromEntries(entries) : undefined
}