const select=(value,keys)=>Object.fromEntries(keys.filter(k=>value?.[k]!==undefined).map(k=>[k,value[k]])); const rows=doc=>Array.isArray(doc?.data)?doc.data:doc?.data?[doc.data]:[]; const summarize=doc=>rows(doc).map(r=>({id:r.id,type:r.type,...select(r.attributes,['name','label','color','linked_to_profile','selected_for_chore_chart','timezone','enabled','source','provider']),...(r.relationships?{relationships:r.relationships}:{})})); export async function inventory(readClient,input){ const frames=await readClient.request('GET','/frames'); const report={frames:summarize(frames),account:null,details:[],failures:[]}; try{const u=await readClient.request('GET','/user');report.account=rows(u).map(r=>({id:r.id,type:r.type,fields:Object.keys(r.attributes||{})}));}catch{report.failures.push({resource:'account'});} const start=input.date_min??new Date().toISOString().slice(0,10); const end=input.date_max??new Date(Date.now()+7*86400000).toISOString().slice(0,10); if(!/^\d{4}-\d{2}-\d{2}$/.test(start)||!/^\d{4}-\d{2}-\d{2}$/.test(end))throw new Error('Use YYYY-MM-DD dates'); for(const frame of rows(frames)){ const id=encodeURIComponent(frame.id);const detail={frameId:frame.id}; for(const resource of ['devices','users','household_config','categories','source_calendars','calendars','calendar_events']){ try{ const doc=await readClient.request('GET','/frames/'+id+'/'+resource,resource==='calendar_events'?{query:{date_min:start,date_max:end,include:'categories,calendar_account,event_notification_setting'}}:{}); detail[resource]=resource==='calendar_events'?{count:rows(doc).length,date_min:start,date_max:end,events:rows(doc).map(r=>({id:r.id,relationships:r.relationships??{},...select(r.attributes,['category_ids','calendar_id','source_calendar_id'])})),includedTypes:[...new Set((doc.included??[]).map(r=>r.type))]}:summarize(doc); }catch{report.failures.push({frameId:frame.id,resource});} } report.details.push(detail); } return report; }