export const UV_PACK_ENUMS = { udim_source: ['CLOSEST_UDIM','ACTIVE_UDIM','ORIGINAL_AABB','CUSTOM_REGION'], rotate_method: ['ANY','CARDINAL','AXIS_ALIGNED','AXIS_ALIGNED_X','AXIS_ALIGNED_Y'], margin_method: ['SCALED','ADD','FRACTION'], pin_method: ['SCALE','ROTATION','ROTATION_SCALE','LOCKED'], shape_method: ['CONCAVE','CONVEX','AABB'], } as const; export const UV_PACK_BOOLEANS = ['rotate','scale','merge_overlap','pin'] as const; export type NativeUVPackOptions = Partial<{[K in keyof typeof UV_PACK_ENUMS]: typeof UV_PACK_ENUMS[K][number]} & Record & {margin:number}>; export function parseNativeUVPackOptions(value: unknown): NativeUVPackOptions { if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).length > 10) throw new Error('UV 打包选项无效'); const parsed: Record = {}; for (const [key,option] of Object.entries(value)) { const choices = Object.hasOwn(UV_PACK_ENUMS,key) ? UV_PACK_ENUMS[key as keyof typeof UV_PACK_ENUMS] as readonly string[] : undefined; const valid = choices ? typeof option === 'string' && choices.includes(option) : (UV_PACK_BOOLEANS as readonly string[]).includes(key) ? typeof option === 'boolean' : key === 'margin' && typeof option === 'number' && Number.isFinite(option) && option >= 0 && option <= 1; if (!valid) throw new Error(`UV 打包选项无效:${key}`); parsed[key] = option; } return parsed as NativeUVPackOptions; }