44 lines
1.8 KiB
TypeScript
44 lines
1.8 KiB
TypeScript
|
|
/**
|
||
|
|
* เปลี่ยน snapshot fields ของ version (จาก GET .../versions) ให้เป็น list ที่ UI ใช้แสดงได้
|
||
|
|
* snapshot มี 2 รูปตามที่ backend เก็บ (phase 3):
|
||
|
|
* - เอกสารผูก template: { key: { value: string, missing: boolean } }
|
||
|
|
* - เอกสารไม่ผูก template: map ดิบ { key: value }
|
||
|
|
* pure function — แยกไว้ให้ unit test ได้ (Phase 7)
|
||
|
|
*/
|
||
|
|
|
||
|
|
export interface SnapshotEntry {
|
||
|
|
key: string
|
||
|
|
value: string
|
||
|
|
missing: boolean
|
||
|
|
}
|
||
|
|
|
||
|
|
export function normalizeSnapshot(fields: unknown, orderKeys?: string[]): SnapshotEntry[] {
|
||
|
|
if (fields === null || fields === undefined || typeof fields !== 'object') return []
|
||
|
|
|
||
|
|
const entries = new Map<string, SnapshotEntry>()
|
||
|
|
for (const [key, raw] of Object.entries(fields as Record<string, unknown>)) {
|
||
|
|
if (raw !== null && typeof raw === 'object' && 'value' in raw) {
|
||
|
|
const obj = raw as { value?: unknown; missing?: unknown }
|
||
|
|
entries.set(key, {
|
||
|
|
key,
|
||
|
|
value: obj.value === null || obj.value === undefined ? '' : String(obj.value),
|
||
|
|
missing: obj.missing === true,
|
||
|
|
})
|
||
|
|
} else {
|
||
|
|
entries.set(key, { key, value: raw === null || raw === undefined ? '' : String(raw), missing: false })
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const list = [...entries.values()]
|
||
|
|
if (orderKeys?.length) {
|
||
|
|
// เรียงตามลำดับ field defs ของ template — key ที่ไม่มีใน defs ต่อท้ายตามตัวอักษร
|
||
|
|
const rank = new Map(orderKeys.map((k, i) => [k, i]))
|
||
|
|
list.sort((a, b) => {
|
||
|
|
const ra = rank.get(a.key) ?? orderKeys.length
|
||
|
|
const rb = rank.get(b.key) ?? orderKeys.length
|
||
|
|
return ra === rb ? a.key.localeCompare(b.key) : ra - rb
|
||
|
|
})
|
||
|
|
}
|
||
|
|
return list
|
||
|
|
}
|