fix: 补 .gitattributes(CRLF for .bat) + README 端口 19540 + 提交 console 锁文件
This commit is contained in:
1 parent
c121111f51
commit
b80c64a115
39 files changed
+4217
-345
No files matched your search
@@ -5,8 +5,19 @@
|
||||
* 直接断言会把服务端字段改名这类问题推迟到运行期某个深处才炸。
|
||||
*/
|
||||
|
||||
/**
|
||||
* FormData / Blob(含 File)/ URLSearchParams 不是普通对象:
|
||||
* 展开或 JSON 序列化都会丢掉内容,必须原样交给 fetch(报名表导入就是被展平才丢文件)。
|
||||
*/
|
||||
export function isRawBody(value: unknown): value is FormData | Blob | URLSearchParams {
|
||||
if (typeof FormData !== 'undefined' && value instanceof FormData) return true
|
||||
if (typeof Blob !== 'undefined' && value instanceof Blob) return true
|
||||
if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) return true
|
||||
return false
|
||||
}
|
||||
|
||||
export function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value) && !isRawBody(value)
|
||||
}
|
||||
|
||||
export function readString(source: unknown, key: string): string | null {
|
||||
@@ -14,3 +25,52 @@ export function readString(source: unknown, key: string): string | null {
|
||||
const value = source[key]
|
||||
return typeof value === 'string' ? value : null
|
||||
}
|
||||
|
||||
export function asRecord(value: unknown): Record<string, unknown> {
|
||||
return isRecord(value) ? value : {}
|
||||
}
|
||||
|
||||
/** 依次取第一个可用值:容忍服务端把数字写成字符串(settings 表存的是文本)。 */
|
||||
export function firstString(...values: unknown[]): string | null {
|
||||
for (const value of values) {
|
||||
if (typeof value === 'string') return value
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function firstNumber(def: number, ...values: unknown[]): number {
|
||||
const found = firstNumberOrNull(...values)
|
||||
return found === null ? def : found
|
||||
}
|
||||
|
||||
export function firstNumberOrNull(...values: unknown[]): number | null {
|
||||
for (const value of values) {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) return value
|
||||
if (typeof value === 'string' && value.trim() !== '') {
|
||||
const parsed = Number(value)
|
||||
if (Number.isFinite(parsed)) return parsed
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function firstBool(def: boolean, ...values: unknown[]): boolean {
|
||||
for (const value of values) {
|
||||
if (typeof value === 'boolean') return value
|
||||
if (typeof value === 'number') return value !== 0
|
||||
if (typeof value === 'string') {
|
||||
const normalized = value.trim().toLowerCase()
|
||||
if (normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on') {
|
||||
return true
|
||||
}
|
||||
if (normalized === 'false' || normalized === '0' || normalized === 'no' || normalized === 'off') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
export function emptyToNull(value: string | null): string | null {
|
||||
return value === null || value.trim() === '' ? null : value
|
||||
}
|
||||
Reference in new issue
Block a user