@openmdm/core 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/webhooks.ts","../src/schema.ts","../src/index.ts"],"names":["randomUUID","policy","createHmac"],"mappings":";;;;;AAolCO,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EAClC,WAAA,CACE,OAAA,EACO,IAAA,EACA,UAAA,GAAqB,KACrB,OAAA,EACP;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJN,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGP,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AAAA,EACd;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,QAAA,EAAkB;AAC5B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,QAAA,EAAkB;AAC5B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,wBAAA,GAAN,cAAuC,QAAA,CAAS;AAAA,EACrD,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,uBAAA,EAA0B,UAAU,CAAA,CAAA,EAAI,uBAAA,EAAyB,GAAG,CAAA;AAAA,EAC5E;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,SAAiB,OAAA,EAAmB;AAC9C,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,GAAA,EAAK,OAAO,CAAA;AAAA,EACjD;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,WAAA,CAAY,UAAkB,yBAAA,EAA2B;AACvD,IAAA,KAAA,CAAM,OAAA,EAAS,wBAAwB,GAAG,CAAA;AAAA,EAC5C;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC/C,WAAA,CAAY,UAAkB,eAAA,EAAiB;AAC7C,IAAA,KAAA,CAAM,OAAA,EAAS,uBAAuB,GAAG,CAAA;AAAA,EAC3C;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,SAAiB,OAAA,EAAmB;AAC9C,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,GAAA,EAAK,OAAO,CAAA;AAAA,EACjD;AACF;AClkCA,IAAM,oBAAA,GAAuB;AAAA,EAC3B,UAAA,EAAY,CAAA;AAAA,EACZ,YAAA,EAAc,GAAA;AAAA,EACd,QAAA,EAAU;AACZ,CAAA;AAKO,SAAS,qBAAqB,MAAA,EAAuC;AAC1E,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAA6B;AACnD,EAAA,MAAM,cAAc,EAAE,GAAG,oBAAA,EAAsB,GAAG,OAAO,KAAA,EAAM;AAG/D,EAAA,IAAI,OAAO,SAAA,EAAW;AACpB,IAAA,KAAA,MAAW,QAAA,IAAY,OAAO,SAAA,EAAW;AACvC,MAAA,SAAA,CAAU,GAAA,CAAI,QAAA,CAAS,EAAA,EAAI,QAAQ,CAAA;AAAA,IACrC;AAAA,EACF;AAKA,EAAA,SAAS,WAAA,CAAY,SAAiB,MAAA,EAAwB;AAC5D,IAAA,OAAO,UAAA,CAAW,UAAU,MAAM,CAAA,CAAE,OAAO,OAAO,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,EAClE;AAKA,EAAA,SAAS,gBAAgB,UAAA,EAA4B;AACnD,IAAA,MAAM,QAAQ,WAAA,CAAY,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,GAAG,UAAU,CAAA;AAC/D,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,WAAA,CAAY,QAAQ,CAAA;AAAA,EAC7C;AAKA,EAAA,SAAS,uBAAA,CACP,UACA,SAAA,EACS;AACT,IAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,MAAA,OAAO,KAAA;AAAA,IACT;AAGA,IAAA,IAAI,QAAA,CAAS,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAG;AACjC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,QAAA,CAAS,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA;AAAA,EAC3C;AAKA,EAAA,eAAe,iBAAA,CACb,UACA,OAAA,EACgC;AAChC,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AAC5C,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI,cAAA;AAEJ,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,WAAA,CAAY,YAAY,OAAA,EAAA,EAAW;AAClE,MAAA,IAAI;AAEF,QAAA,MAAM,OAAA,GAAkC;AAAA,UACtC,cAAA,EAAgB,kBAAA;AAAA,UAChB,mBAAmB,OAAA,CAAQ,KAAA;AAAA,UAC3B,sBAAsB,OAAA,CAAQ,EAAA;AAAA,UAC9B,uBAAuB,OAAA,CAAQ,SAAA;AAAA,UAC/B,GAAG,QAAA,CAAS;AAAA,SACd;AAGA,QAAA,IAAI,OAAO,aAAA,EAAe;AACxB,UAAA,MAAM,SAAA,GAAY,WAAA,CAAY,aAAA,EAAe,MAAA,CAAO,aAAa,CAAA;AACjE,UAAA,OAAA,CAAQ,qBAAqB,CAAA,GAAI,CAAA,OAAA,EAAU,SAAS,CAAA,CAAA;AAAA,QACtD;AAGA,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,QAAA,CAAS,GAAA,EAAK;AAAA,UACzC,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA;AAAA,UACA,IAAA,EAAM,aAAA;AAAA,UACN,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,GAAK;AAAA;AAAA,SAClC,CAAA;AAED,QAAA,cAAA,GAAiB,QAAA,CAAS,MAAA;AAG1B,QAAA,IAAI,SAAS,EAAA,EAAI;AACf,UAAA,OAAO;AAAA,YACL,YAAY,QAAA,CAAS,EAAA;AAAA,YACrB,OAAA,EAAS,IAAA;AAAA,YACT,YAAY,QAAA,CAAS,MAAA;AAAA,YACrB,UAAA,EAAY,OAAA;AAAA,YACZ,WAAA,sBAAiB,IAAA;AAAK,WACxB;AAAA,QACF;AAGA,QAAA,IAAI,QAAA,CAAS,UAAU,GAAA,IAAO,QAAA,CAAS,SAAS,GAAA,IAAO,QAAA,CAAS,WAAW,GAAA,EAAK;AAC9E,UAAA,OAAO;AAAA,YACL,YAAY,QAAA,CAAS,EAAA;AAAA,YACrB,OAAA,EAAS,KAAA;AAAA,YACT,YAAY,QAAA,CAAS,MAAA;AAAA,YACrB,OAAO,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA,CAAA;AAAA,YACtD,UAAA,EAAY;AAAA,WACd;AAAA,QACF;AAGA,QAAA,SAAA,GAAY,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA,CAAA;AAAA,MAC7D,SAAS,KAAA,EAAO;AACd,QAAA,SAAA,GAAY,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAAA,MACnE;AAGA,MAAA,IAAI,OAAA,GAAU,YAAY,UAAA,EAAY;AACpC,QAAA,MAAM,KAAA,GAAQ,gBAAgB,OAAO,CAAA;AACrC,QAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,KAAK,CAAC,CAAA;AAAA,MAC3D;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,YAAY,QAAA,CAAS,EAAA;AAAA,MACrB,OAAA,EAAS,KAAA;AAAA,MACT,UAAA,EAAY,cAAA;AAAA,MACZ,OAAO,SAAA,IAAa,sBAAA;AAAA,MACpB,YAAY,WAAA,CAAY;AAAA,KAC1B;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,QAAW,KAAA,EAAsD;AACrE,MAAA,MAAM,oBAAoB,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAA,QAAO,CAAC,EAAA,KAC/D,uBAAA,CAAwB,EAAA,EAAI,MAAM,IAAI;AAAA,OACxC;AAEA,MAAA,IAAI,iBAAA,CAAkB,WAAW,CAAA,EAAG;AAClC,QAAA,OAAO,EAAC;AAAA,MACV;AAGA,MAAA,MAAM,OAAA,GAA6B;AAAA,QACjC,IAAI,UAAA,EAAW;AAAA,QACf,OAAO,KAAA,CAAM,IAAA;AAAA,QACb,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAClC,MAAM,KAAA,CAAM;AAAA,OACd;AAGA,MAAA,MAAM,mBAAmB,iBAAA,CAAkB,GAAA;AAAA,QAAI,CAAC,QAAA,KAC9C,iBAAA,CAAkB,QAAA,EAAU,OAAyB;AAAA,OACvD;AAEA,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA;AAGlD,MAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,QAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,UAAA,OAAA,CAAQ,KAAA;AAAA,YACN,CAAA,8CAAA,EAAiD,OAAO,UAAU,CAAA,CAAA,CAAA;AAAA,YAClE,MAAA,CAAO;AAAA,WACT;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,YAAY,QAAA,EAAiC;AAC3C,MAAA,SAAA,CAAU,GAAA,CAAI,QAAA,CAAS,EAAA,EAAI,QAAQ,CAAA;AAAA,IACrC,CAAA;AAAA,IAEA,eAAe,UAAA,EAA0B;AACvC,MAAA,SAAA,CAAU,OAAO,UAAU,CAAA;AAAA,IAC7B,CAAA;AAAA,IAEA,cAAA,CAAe,YAAoB,OAAA,EAAyC;AAC1E,MAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,UAAU,CAAA;AACzC,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,SAAA,CAAU,IAAI,UAAA,EAAY,EAAE,GAAG,QAAA,EAAU,GAAG,SAAS,CAAA;AAAA,MACvD;AAAA,IACF,CAAA;AAAA,IAEA,YAAA,GAAkC;AAChC,MAAA,OAAO,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA;AAAA,IACtC,CAAA;AAAA,IAEA,MAAM,aAAa,UAAA,EAAoD;AACrE,MAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,UAAU,CAAA;AACzC,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,OAAO;AAAA,UACL,UAAA;AAAA,UACA,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,oBAAA;AAAA,UACP,UAAA,EAAY;AAAA,SACd;AAAA,MACF;AAEA,MAAA,MAAM,WAAA,GAA8B;AAAA,QAClC,IAAI,UAAA,EAAW;AAAA,QACf,KAAA,EAAO,kBAAA;AAAA,QACP,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAClC,IAAA,EAAM;AAAA,UACJ,IAAA,EAAM,IAAA;AAAA,UACN,OAAA,EAAS;AAAA;AACX,OACF;AAEA,MAAA,OAAO,iBAAA,CAAkB,UAAU,WAAW,CAAA;AAAA,IAChD;AAAA,GACF;AACF;AAMO,SAAS,sBAAA,CACd,OAAA,EACA,SAAA,EACA,MAAA,EACS;AACT,EAAA,MAAM,iBAAA,GAAoB,CAAA,OAAA,EAAU,UAAA,CAAW,QAAA,EAAU,MAAM,CAAA,CAC5D,MAAA,CAAO,OAAO,CAAA,CACd,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAGhB,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,iBAAA,CAAkB,MAAA,EAAQ;AACjD,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAA,IAAU,UAAU,UAAA,CAAW,CAAC,CAAA,GAAI,iBAAA,CAAkB,WAAW,CAAC,CAAA;AAAA,EACpE;AAEA,EAAA,OAAO,MAAA,KAAW,CAAA;AACpB;;;ACpPO,IAAM,SAAA,GAA8B;AAAA,EACzC,MAAA,EAAQ;AAAA;AAAA;AAAA;AAAA,IAIN,WAAA,EAAa;AAAA,MACX,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAC9C,aAAA,EAAe,EAAE,IAAA,EAAM,QAAA,EAAU,QAAQ,IAAA,EAAK;AAAA,QAC9C,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,UAAA,EAAY,CAAC,SAAA,EAAW,UAAA,EAAY,cAAc,SAAS,CAAA;AAAA,UAC3D,OAAA,EAAS;AAAA,SACX;AAAA;AAAA,QAGA,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QACxC,YAAA,EAAc,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAC7C,aAAA,EAAe,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAChD,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QACvC,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAC9C,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA;AAAA,QAG7C,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,QAAA,EAAU,IAAA;AAAA,UACV,YAAY,EAAE,KAAA,EAAO,gBAAgB,MAAA,EAAQ,IAAA,EAAM,UAAU,UAAA;AAAW,SAC1E;AAAA,QACA,cAAA,EAAgB,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA,EAAK;AAAA,QACnD,SAAA,EAAW,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA,EAAK;AAAA;AAAA,QAG9C,aAAA,EAAe,EAAE,IAAA,EAAM,SAAA,EAAW,UAAU,IAAA,EAAK;AAAA,QACjD,YAAA,EAAc,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAC/C,aAAA,EAAe,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAChD,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA;AAAA,QAC3C,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAC5C,kBAAA,EAAoB,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA,EAAK;AAAA;AAAA,QAGvD,cAAA,EAAgB,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QAC/C,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACrC,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA;AAAA,QAGzC,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,eAAe,CAAA,EAAG,QAAQ,IAAA,EAAK;AAAA,QAC3C,EAAE,OAAA,EAAS,CAAC,QAAQ,CAAA,EAAE;AAAA,QACtB,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA,EAAE;AAAA,QACzB,EAAE,OAAA,EAAS,CAAC,gBAAgB,CAAA,EAAE;AAAA,QAC9B,EAAE,OAAA,EAAS,CAAC,aAAa,CAAA,EAAE;AAAA,QAC3B,EAAE,OAAA,EAAS,CAAC,eAAe,CAAA;AAAE;AAC/B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,YAAA,EAAc;AAAA,MACZ,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACvB,WAAA,EAAa,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QAC5C,UAAA,EAAY,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,QAC9C,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,QACzB,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,MAAM,CAAA,EAAE;AAAA,QACpB,EAAE,OAAA,EAAS,CAAC,YAAY,CAAA;AAAE;AAC5B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAA,EAAkB;AAAA,MAChB,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACvB,YAAA,EAAc,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC/B,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC1B,YAAA,EAAc,EAAE,IAAA,EAAM,SAAA,EAAU;AAAA,QAChC,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACtB,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA;AAAA,QACvC,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QACvC,eAAA,EAAiB,EAAE,IAAA,EAAM,SAAA,EAAW,UAAU,IAAA,EAAK;AAAA;AAAA,QAGnD,SAAA,EAAW,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,QAC5C,iBAAA,EAAmB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,QACrD,WAAA,EAAa,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,QAC/C,SAAA,EAAW,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA;AAAA,QAG7C,SAAA,EAAW,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA;AAAA,QAG5C,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACzC,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,cAAc,CAAA,EAAE;AAAA,QAC5B,EAAE,OAAA,EAAS,CAAC,gBAAgB,SAAS,CAAA,EAAG,QAAQ,IAAA,EAAK;AAAA,QACrD,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA;AAAE;AAC3B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,YAAA,EAAc;AAAA,MACZ,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,eAAe,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SACxE;AAAA,QACA,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACvB,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACxC,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,YAAY,CAAC,SAAA,EAAW,QAAQ,cAAA,EAAgB,WAAA,EAAa,UAAU,WAAW,CAAA;AAAA,UAClF,OAAA,EAAS;AAAA,SACX;AAAA,QACA,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACvC,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACtC,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,OAAA,EAAS,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA,EAAK;AAAA,QAC5C,eAAA,EAAiB,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA,EAAK;AAAA,QACpD,YAAA,EAAc,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA;AAAK,OACnD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA,EAAE;AAAA,QACzB,EAAE,OAAA,EAAS,CAAC,QAAQ,CAAA,EAAE;AAAA,QACtB,EAAE,OAAA,EAAS,CAAC,WAAA,EAAa,QAAQ,CAAA,EAAE;AAAA,QACnC,EAAE,OAAA,EAAS,CAAC,YAAY,CAAA;AAAE;AAC5B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAA,EAAY;AAAA,MACV,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,eAAe,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SACxE;AAAA,QACA,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACvB,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,QACxB,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA,EAAE;AAAA,QACzB,EAAE,OAAA,EAAS,CAAC,MAAM,CAAA,EAAE;AAAA,QACpB,EAAE,OAAA,EAAS,CAAC,WAAA,EAAa,MAAM,CAAA,EAAE;AAAA,QACjC,EAAE,OAAA,EAAS,CAAC,YAAY,CAAA;AAAE;AAC5B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAA,EAAY;AAAA,MACV,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACvB,WAAA,EAAa,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QAC5C,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,QAAA,EAAU,IAAA;AAAA,UACV,YAAY,EAAE,KAAA,EAAO,gBAAgB,MAAA,EAAQ,IAAA,EAAM,UAAU,UAAA;AAAW,SAC1E;AAAA,QACA,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,QAAA,EAAU,IAAA;AAAA,UACV,YAAY,EAAE,KAAA,EAAO,cAAc,MAAA,EAAQ,IAAA,EAAM,UAAU,UAAA;AAAW,SACxE;AAAA,QACA,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACzC,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,MAAM,CAAA,EAAE;AAAA,QACpB,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA,EAAE;AAAA,QACzB,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA;AAAE;AAC3B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,iBAAA,EAAmB;AAAA,MACjB,OAAA,EAAS;AAAA,QACP,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,eAAe,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SACxE;AAAA,QACA,QAAA,EAAU;AAAA,UACR,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,cAAc,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SACvE;AAAA,QACA,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,aAAa,UAAU,CAAA,EAAG,QAAQ,IAAA,EAAK;AAAA,QACnD,EAAE,OAAA,EAAS,CAAC,UAAU,CAAA;AAAE;AAC1B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,eAAe,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SACxE;AAAA,QACA,QAAA,EAAU;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,UAAA,EAAY,CAAC,KAAA,EAAO,MAAA,EAAQ,WAAW;AAAA,SACzC;AAAA,QACA,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACxB,SAAA,EAAW,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,QAC5C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA,EAAE;AAAA,QACzB,EAAE,OAAA,EAAS,CAAC,YAAY,OAAO,CAAA,EAAG,QAAQ,IAAA,EAAK;AAAA,QAC/C,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA;AAAE;AAC3B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,mBAAA,EAAqB;AAAA,MACnB,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,cAAA,EAAgB;AAAA,UACd,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,oBAAoB,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SAC7E;AAAA;AAAA,QAEA,WAAA,EAAa;AAAA,UACX,IAAA,EAAM,MAAA;AAAA,UACN,UAAA,EAAY,CAAC,QAAA,EAAU,OAAO;AAAA,SAChC;AAAA,QACA,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC5B,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,UAAA,EAAY,CAAC,SAAA,EAAW,QAAA,EAAU,WAAW,CAAA;AAAA,UAC7C,OAAA,EAAS;AAAA,SACX;AAAA,QACA,WAAA,EAAa,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,gBAAgB,CAAA,EAAE;AAAA,QAC9B,EAAE,OAAA,EAAS,CAAC,aAAA,EAAe,WAAW,CAAA;AAAE;AAC1C,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,gBAAA,EAAkB;AAAA,MAChB,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,cAAA,EAAgB;AAAA,UACd,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,oBAAoB,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SAC7E;AAAA,QACA,YAAA,EAAc,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC/B,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC1B,YAAA,EAAc,EAAE,IAAA,EAAM,SAAA,EAAU;AAAA,QAChC,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACtB,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QACvC,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QACvC,aAAA,EAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QAC9C,kBAAA,EAAoB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA,EAAM;AAAA,QACtD,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,gBAAgB,CAAA,EAAE;AAAA,QAC9B,EAAE,OAAA,EAAS,CAAC,cAAc,CAAA,EAAE;AAAA,QAC5B,EAAE,OAAA,EAAS,CAAC,gBAAgB,cAAc,CAAA,EAAG,QAAQ,IAAA,EAAK;AAAA,QAC1D,EAAE,OAAA,EAAS,CAAC,oBAAoB,CAAA;AAAE;AACpC,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,aAAA,EAAe;AAAA,MACb,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,eAAe,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SACxE;AAAA,QACA,YAAA,EAAc,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC/B,YAAA,EAAc,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC/B,iBAAA,EAAmB,EAAE,IAAA,EAAM,SAAA,EAAU;AAAA,QACrC,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC7B,eAAA,EAAiB,EAAE,IAAA,EAAM,SAAA,EAAU;AAAA,QACnC,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACvC,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,UAAA,EAAY,CAAC,SAAA,EAAW,aAAA,EAAe,aAAa,QAAQ,CAAA;AAAA,UAC5D,OAAA,EAAS;AAAA,SACX;AAAA,QACA,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACtC,YAAA,EAAc,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,IAAA,EAAK;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,YAAA,EAAc,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA;AAAK,OACnD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,WAAW,CAAA,EAAE;AAAA,QACzB,EAAE,OAAA,EAAS,CAAC,cAAc,CAAA,EAAE;AAAA,QAC5B,EAAE,OAAA,EAAS,CAAC,WAAA,EAAa,cAAc,CAAA,EAAE;AAAA,QACzC,EAAE,OAAA,EAAS,CAAC,QAAQ,CAAA,EAAE;AAAA,QACtB,EAAE,OAAA,EAAS,CAAC,YAAY,CAAA;AAAE;AAC5B,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,qBAAA,EAAuB;AAAA,MACrB,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACtB,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA;AAAA,QACvB,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACxC,OAAA,EAAS,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,QAC1C,WAAA,EAAa,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QAC5C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA;AAAM,OACjD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,SAAS,CAAA;AAAE;AACzB,KACF;AAAA;AAAA;AAAA;AAAA,IAKA,sBAAA,EAAwB;AAAA,MACtB,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,YAAY,IAAA,EAAK;AAAA,QACvC,WAAA,EAAa;AAAA,UACX,IAAA,EAAM,QAAA;AAAA,UACN,YAAY,EAAE,KAAA,EAAO,yBAAyB,MAAA,EAAQ,IAAA,EAAM,UAAU,SAAA;AAAU,SAClF;AAAA,QACA,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC3B,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC7B,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,QACxB,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,MAAA;AAAA,UACN,UAAA,EAAY,CAAC,SAAA,EAAW,SAAA,EAAW,QAAQ,CAAA;AAAA,UAC3C,OAAA,EAAS;AAAA,SACX;AAAA,QACA,WAAA,EAAa,EAAE,IAAA,EAAM,SAAA,EAAW,UAAU,IAAA,EAAK;AAAA,QAC/C,KAAA,EAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,IAAA,EAAK;AAAA,QACtC,WAAA,EAAa,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,CAAA,EAAE;AAAA,QAC3C,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,SAAS,KAAA,EAAM;AAAA,QAC/C,YAAA,EAAc,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,IAAA;AAAK,OACnD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,EAAE,OAAA,EAAS,CAAC,aAAa,CAAA,EAAE;AAAA,QAC3B,EAAE,OAAA,EAAS,CAAC,YAAY,CAAA,EAAE;AAAA,QAC1B,EAAE,OAAA,EAAS,CAAC,QAAQ,CAAA,EAAE;AAAA,QACtB,EAAE,OAAA,EAAS,CAAC,YAAY,CAAA;AAAE;AAC5B;AACF;AAEJ;AASO,SAAS,aAAA,GAA0B;AACxC,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AACrC;AAKO,SAAS,eAAe,SAAA,EAA6B;AAC1D,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,MAAA,CAAO,SAAS,CAAA;AACxC,EAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,CAAA,MAAA,EAAS,SAAS,CAAA,oBAAA,CAAsB,CAAA;AACpE,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAClC;AAKO,SAAS,cAAc,SAAA,EAAkC;AAC9D,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,MAAA,CAAO,SAAS,CAAA;AACxC,EAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,CAAA,MAAA,EAAS,SAAS,CAAA,oBAAA,CAAsB,CAAA;AAEpE,EAAA,KAAA,MAAW,CAAC,MAAM,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA,EAAG;AACvD,IAAA,IAAI,GAAA,CAAI,YAAY,OAAO,IAAA;AAAA,EAC7B;AACA,EAAA,OAAO,IAAA;AACT;AAKO,SAAS,aAAa,GAAA,EAAqB;AAChD,EAAA,OAAO,GAAA,CAAI,QAAQ,WAAA,EAAa,CAAC,GAAG,MAAA,KAAW,MAAA,CAAO,aAAa,CAAA;AACrE;AAKO,SAAS,aAAa,GAAA,EAAqB;AAChD,EAAA,OAAO,GAAA,CAAI,QAAQ,QAAA,EAAU,CAAC,WAAW,CAAA,CAAA,EAAI,MAAA,CAAO,WAAA,EAAa,CAAA,CAAE,CAAA;AACrE;AAKO,SAAS,qBACd,GAAA,EACyB;AACzB,EAAA,MAAM,SAAkC,EAAC;AACzC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,IAAA,MAAA,CAAO,YAAA,CAAa,GAAG,CAAC,CAAA,GAAI,KAAA;AAAA,EAC9B;AACA,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,qBACd,GAAA,EACyB;AACzB,EAAA,MAAM,SAAkC,EAAC;AACzC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,IAAA,MAAA,CAAO,YAAA,CAAa,GAAG,CAAC,CAAA,GAAI,KAAA;AAAA,EAC9B;AACA,EAAA,OAAO,MAAA;AACT;;;ACjcO,SAAS,UAAU,MAAA,EAAgC;AACxD,EAAA,MAAM,EAAE,UAAU,IAAA,EAAM,UAAA,EAAY,UAAU,cAAA,EAAgB,OAAA,GAAU,EAAC,EAAE,GAAI,MAAA;AAG/E,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAA6C;AAGvE,EAAA,MAAM,cAA2B,IAAA,GAC7B,iBAAA,CAAkB,IAAA,EAAM,QAAQ,IAChC,qBAAA,EAAsB;AAG1B,EAAA,MAAM,cAAA,GAA6C,cAAA,GAC/C,oBAAA,CAAqB,cAAc,CAAA,GACnC,MAAA;AAGJ,EAAA,MAAM,EAAA,GAAK,CACT,KAAA,EACA,OAAA,KACiB;AACjB,IAAA,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,MAAA,aAAA,CAAc,GAAA,CAAI,KAAA,kBAAO,IAAI,GAAA,EAAK,CAAA;AAAA,IACpC;AACA,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AACxC,IAAA,QAAA,CAAS,IAAI,OAAkC,CAAA;AAG/C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,OAAO,OAAkC,CAAA;AAAA,IACpD,CAAA;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,IAAA,GAAO,OACX,KAAA,EACA,IAAA,KACkB;AAClB,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,KAAK,CAAA;AAGxC,IAAA,MAAM,WAAA,GAA4C;AAAA,MAChD,IAAIA,UAAAA,EAAW;AAAA,MACf,QAAA,EAAW,IAAA,CAAa,MAAA,EAAQ,EAAA,IAAO,KAAa,QAAA,IAAY,EAAA;AAAA,MAChE,IAAA,EAAM,KAAA;AAAA,MACN,OAAA,EAAS,IAAA;AAAA,MACT,SAAA,sBAAe,IAAA;AAAK,KACtB;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,WAAA,CAAY;AAAA,QACzB,UAAU,WAAA,CAAY,QAAA;AAAA,QACtB,MAAM,WAAA,CAAY,IAAA;AAAA,QAClB,SAAS,WAAA,CAAY;AAAA,OACtB,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AAAA,IAC3D;AAGA,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,cAAA,CAAe,OAAA,CAAQ,WAAW,CAAA,CAAE,KAAA,CAAM,CAAC,KAAA,KAAU;AACnD,QAAA,OAAA,CAAQ,KAAA,CAAM,qCAAqC,KAAK,CAAA;AAAA,MAC1D,CAAC,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,IAAI;AACF,UAAA,MAAM,QAAQ,WAAW,CAAA;AAAA,QAC3B,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,kCAAA,EAAqC,KAAK,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,CAAO,QAAQ,WAAW,CAAA;AAAA,MAClC,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,iCAAiC,KAAK,CAAA;AAAA,MACtD;AAAA,IACF;AAAA,EACF,CAAA;AAMA,EAAA,MAAM,OAAA,GAAyB;AAAA,IAC7B,MAAM,IAAI,EAAA,EAAoC;AAC5C,MAAA,OAAO,QAAA,CAAS,WAAW,EAAE,CAAA;AAAA,IAC/B,CAAA;AAAA,IAEA,MAAM,kBAAkB,YAAA,EAA8C;AACpE,MAAA,OAAO,QAAA,CAAS,yBAAyB,YAAY,CAAA;AAAA,IACvD,CAAA;AAAA,IAEA,MAAM,KAAK,MAAA,EAAkD;AAC3D,MAAA,OAAO,QAAA,CAAS,YAAY,MAAM,CAAA;AAAA,IACpC,CAAA;AAAA,IAEA,MAAM,OAAO,IAAA,EAA0C;AACrD,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,YAAA,CAAa,IAAI,CAAA;AAE/C,MAAA,MAAM,IAAA,CAAK,iBAAA,EAAmB,EAAE,MAAA,EAAQ,CAAA;AAExC,MAAA,IAAI,OAAO,gBAAA,EAAkB;AAC3B,QAAA,MAAM,MAAA,CAAO,iBAAiB,MAAM,CAAA;AAAA,MACtC;AAEA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,EAAA,EAAY,IAAA,EAA0C;AACjE,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,UAAA,CAAW,EAAE,CAAA;AAC9C,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,IAAI,oBAAoB,EAAE,CAAA;AAAA,MAClC;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,YAAA,CAAa,IAAI,IAAI,CAAA;AAGnD,MAAA,IAAI,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,MAAA,KAAW,UAAU,MAAA,EAAQ;AACnD,QAAA,MAAM,KAAK,sBAAA,EAAwB;AAAA,UACjC,MAAA;AAAA,UACA,WAAW,SAAA,CAAU,MAAA;AAAA,UACrB,WAAW,IAAA,CAAK;AAAA,SACjB,CAAA;AAAA,MACH;AAGA,MAAA,IAAI,KAAK,QAAA,KAAa,MAAA,IAAa,IAAA,CAAK,QAAA,KAAa,UAAU,QAAA,EAAU;AACvE,QAAA,MAAM,KAAK,sBAAA,EAAwB;AAAA,UACjC,MAAA;AAAA,UACA,WAAA,EAAa,UAAU,QAAA,IAAY,MAAA;AAAA,UACnC,WAAA,EAAa,KAAK,QAAA,IAAY;AAAA,SAC/B,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,OAAO,EAAA,EAA2B;AACtC,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,UAAA,CAAW,EAAE,CAAA;AAC3C,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAM,QAAA,CAAS,aAAa,EAAE,CAAA;AAC9B,QAAA,MAAM,IAAA,CAAK,mBAAA,EAAqB,EAAE,MAAA,EAAQ,CAAA;AAE1C,QAAA,IAAI,OAAO,kBAAA,EAAoB;AAC7B,UAAA,MAAM,MAAA,CAAO,mBAAmB,MAAM,CAAA;AAAA,QACxC;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,YAAA,CACJ,QAAA,EACA,QAAA,EACiB;AACjB,MAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAO,QAAA,EAAU,EAAE,UAAU,CAAA;AAGvD,MAAA,MAAM,WAAA,CAAY,KAAK,QAAA,EAAU;AAAA,QAC/B,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,EAAE,QAAA,EAAS;AAAA,QACpB,QAAA,EAAU;AAAA,OACX,CAAA;AAED,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,UAAA,CAAW,QAAA,EAAkB,OAAA,EAAgC;AACjE,MAAA,MAAM,QAAA,CAAS,gBAAA,CAAiB,QAAA,EAAU,OAAO,CAAA;AAAA,IACnD,CAAA;AAAA,IAEA,MAAM,eAAA,CAAgB,QAAA,EAAkB,OAAA,EAAgC;AACtE,MAAA,MAAM,QAAA,CAAS,qBAAA,CAAsB,QAAA,EAAU,OAAO,CAAA;AAAA,IACxD,CAAA;AAAA,IAEA,MAAM,UAAU,QAAA,EAAoC;AAClD,MAAA,OAAO,QAAA,CAAS,gBAAgB,QAAQ,CAAA;AAAA,IAC1C,CAAA;AAAA,IAEA,MAAM,WAAA,CACJ,QAAA,EACA,KAAA,EACkB;AAClB,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,aAAA,CAAc;AAAA,QAC3C,GAAG,KAAA;AAAA,QACH;AAAA,OACD,CAAA;AAGD,MAAA,MAAM,UAAA,GAAa,MAAM,WAAA,CAAY,IAAA,CAAK,QAAA,EAAU;AAAA,QAClD,IAAA,EAAM,CAAA,QAAA,EAAW,KAAA,CAAM,IAAI,CAAA,CAAA;AAAA,QAC3B,OAAA,EAAS;AAAA,UACP,WAAW,OAAA,CAAQ,EAAA;AAAA,UACnB,MAAM,KAAA,CAAM,IAAA;AAAA,UACZ,GAAG,KAAA,CAAM;AAAA,SACX;AAAA,QACA,QAAA,EAAU;AAAA,OACX,CAAA;AAGD,MAAA,IAAI,WAAW,OAAA,EAAS;AACtB,QAAA,MAAM,QAAA,CAAS,aAAA,CAAc,OAAA,CAAQ,EAAA,EAAI;AAAA,UACvC,MAAA,EAAQ,MAAA;AAAA,UACR,MAAA,sBAAY,IAAA;AAAK,SAClB,CAAA;AAAA,MACH;AAEA,MAAA,IAAI,OAAO,SAAA,EAAW;AACpB,QAAA,MAAM,MAAA,CAAO,UAAU,OAAO,CAAA;AAAA,MAChC;AAEA,MAAA,OAAO,QAAA,CAAS,WAAA,CAAY,OAAA,CAAQ,EAAE,CAAA;AAAA,IACxC,CAAA;AAAA,IAEA,MAAM,KAAK,QAAA,EAAoC;AAC7C,MAAA,OAAO,KAAK,WAAA,CAAY,QAAA,EAAU,EAAE,IAAA,EAAM,QAAQ,CAAA;AAAA,IACpD,CAAA;AAAA,IAEA,MAAM,OAAO,QAAA,EAAoC;AAC/C,MAAA,OAAO,KAAK,WAAA,CAAY,QAAA,EAAU,EAAE,IAAA,EAAM,UAAU,CAAA;AAAA,IACtD,CAAA;AAAA,IAEA,MAAM,IAAA,CAAK,QAAA,EAAkB,OAAA,EAAoC;AAC/D,MAAA,OAAO,IAAA,CAAK,YAAY,QAAA,EAAU;AAAA,QAChC,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAS,OAAA,GAAU,EAAE,OAAA,EAAQ,GAAI;AAAA,OAClC,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,IAAA,CAAK,QAAA,EAAkB,YAAA,EAA0C;AACrE,MAAA,OAAO,IAAA,CAAK,YAAY,QAAA,EAAU;AAAA,QAChC,IAAA,EAAM,eAAe,MAAA,GAAS,cAAA;AAAA,QAC9B,OAAA,EAAS,EAAE,YAAA;AAAa,OACzB,CAAA;AAAA,IACH;AAAA,GACF;AAMA,EAAA,MAAM,QAAA,GAA0B;AAAA,IAC9B,MAAM,IAAI,EAAA,EAAoC;AAC5C,MAAA,OAAO,QAAA,CAAS,WAAW,EAAE,CAAA;AAAA,IAC/B,CAAA;AAAA,IAEA,MAAM,UAAA,GAAqC;AACzC,MAAA,OAAO,SAAS,iBAAA,EAAkB;AAAA,IACpC,CAAA;AAAA,IAEA,MAAM,IAAA,GAA0B;AAC9B,MAAA,OAAO,SAAS,YAAA,EAAa;AAAA,IAC/B,CAAA;AAAA,IAEA,MAAM,OAAO,IAAA,EAA0C;AAErD,MAAA,IAAI,KAAK,SAAA,EAAW;AAClB,QAAA,MAAM,gBAAA,GAAmB,MAAM,QAAA,CAAS,YAAA,EAAa;AACrD,QAAA,KAAA,MAAW,UAAU,gBAAA,EAAkB;AACrC,UAAA,IAAI,OAAO,SAAA,EAAW;AACpB,YAAA,MAAM,SAAS,YAAA,CAAa,MAAA,CAAO,IAAI,EAAE,SAAA,EAAW,OAAO,CAAA;AAAA,UAC7D;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAO,QAAA,CAAS,aAAa,IAAI,CAAA;AAAA,IACnC,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,EAAA,EAAY,IAAA,EAA0C;AAEjE,MAAA,IAAI,KAAK,SAAA,EAAW;AAClB,QAAA,MAAM,gBAAA,GAAmB,MAAM,QAAA,CAAS,YAAA,EAAa;AACrD,QAAA,KAAA,MAAWC,WAAU,gBAAA,EAAkB;AACrC,UAAA,IAAIA,OAAAA,CAAO,SAAA,IAAaA,OAAAA,CAAO,EAAA,KAAO,EAAA,EAAI;AACxC,YAAA,MAAM,SAAS,YAAA,CAAaA,OAAAA,CAAO,IAAI,EAAE,SAAA,EAAW,OAAO,CAAA;AAAA,UAC7D;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,YAAA,CAAa,IAAI,IAAI,CAAA;AAGnD,MAAA,MAAM,gBAAgB,MAAM,QAAA,CAAS,YAAY,EAAE,QAAA,EAAU,IAAI,CAAA;AACjE,MAAA,IAAI,aAAA,CAAc,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AACpC,QAAA,MAAM,YAAY,aAAA,CAAc,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AACvD,QAAA,MAAM,WAAA,CAAY,UAAU,SAAA,EAAW;AAAA,UACrC,IAAA,EAAM,gBAAA;AAAA,UACN,OAAA,EAAS,EAAE,QAAA,EAAU,EAAA,EAAG;AAAA,UACxB,QAAA,EAAU;AAAA,SACX,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,OAAO,EAAA,EAA2B;AAEtC,MAAA,MAAM,gBAAgB,MAAM,QAAA,CAAS,YAAY,EAAE,QAAA,EAAU,IAAI,CAAA;AACjE,MAAA,IAAI,aAAA,CAAc,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAEpC,QAAA,KAAA,MAAW,MAAA,IAAU,cAAc,OAAA,EAAS;AAC1C,UAAA,MAAM,SAAS,YAAA,CAAa,MAAA,CAAO,IAAI,EAAE,QAAA,EAAU,MAAM,CAAA;AAAA,QAC3D;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,CAAS,aAAa,EAAE,CAAA;AAAA,IAChC,CAAA;AAAA,IAEA,MAAM,WAAW,EAAA,EAA6B;AAC5C,MAAA,OAAO,KAAK,MAAA,CAAO,EAAA,EAAI,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IAC5C,CAAA;AAAA,IAEA,MAAM,WAAW,QAAA,EAAqC;AACpD,MAAA,MAAM,SAAS,MAAM,QAAA,CAAS,WAAA,CAAY,EAAE,UAAU,CAAA;AACtD,MAAA,OAAO,MAAA,CAAO,OAAA;AAAA,IAChB,CAAA;AAAA,IAEA,MAAM,aAAA,CAAc,QAAA,EAAkB,QAAA,EAAiC;AACrE,MAAA,MAAM,OAAA,CAAQ,YAAA,CAAa,QAAA,EAAU,QAAQ,CAAA;AAAA,IAC/C;AAAA,GACF;AAMA,EAAA,MAAM,IAAA,GAA2B;AAAA,IAC/B,MAAM,IAAI,EAAA,EAAyC;AACjD,MAAA,OAAO,QAAA,CAAS,gBAAgB,EAAE,CAAA;AAAA,IACpC,CAAA;AAAA,IAEA,MAAM,YAAA,CACJ,WAAA,EACA,OAAA,EAC6B;AAC7B,MAAA,OAAO,QAAA,CAAS,wBAAA,CAAyB,WAAA,EAAa,OAAO,CAAA;AAAA,IAC/D,CAAA;AAAA,IAEA,MAAM,KAAK,UAAA,EAA8C;AACvD,MAAA,OAAO,QAAA,CAAS,iBAAiB,UAAU,CAAA;AAAA,IAC7C,CAAA;AAAA,IAEA,MAAM,SAAS,IAAA,EAAoD;AACjE,MAAA,OAAO,QAAA,CAAS,kBAAkB,IAAI,CAAA;AAAA,IACxC,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,EAAA,EAAY,IAAA,EAAoD;AAC3E,MAAA,OAAO,QAAA,CAAS,iBAAA,CAAkB,EAAA,EAAI,IAAI,CAAA;AAAA,IAC5C,CAAA;AAAA,IAEA,MAAM,OAAO,EAAA,EAA2B;AACtC,MAAA,MAAM,QAAA,CAAS,kBAAkB,EAAE,CAAA;AAAA,IACrC,CAAA;AAAA,IAEA,MAAM,SAAS,EAAA,EAAkC;AAC/C,MAAA,OAAO,SAAS,iBAAA,CAAkB,EAAA,EAAI,EAAE,QAAA,EAAU,MAAM,CAAA;AAAA,IAC1D,CAAA;AAAA,IAEA,MAAM,WAAW,EAAA,EAAkC;AACjD,MAAA,OAAO,SAAS,iBAAA,CAAkB,EAAA,EAAI,EAAE,QAAA,EAAU,OAAO,CAAA;AAAA,IAC3D,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,WAAA,EAAqB,MAAA,EAAqC;AACrE,MAAA,MAAM,GAAA,GAAM,MAAM,QAAA,CAAS,wBAAA,CAAyB,WAAW,CAAA;AAC/D,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,yBAAyB,WAAW,CAAA;AAAA,MAChD;AAEA,MAAA,MAAM,YAAsB,EAAC;AAG7B,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,SAAA,CAAU,IAAA,CAAK,GAAG,MAAA,CAAO,OAAO,CAAA;AAAA,MAClC;AAEA,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,KAAA,MAAW,OAAA,IAAW,OAAO,MAAA,EAAQ;AACnC,UAAA,MAAM,YAAA,GAAe,MAAM,QAAA,CAAS,kBAAA,CAAmB,OAAO,CAAA;AAC9D,UAAA,SAAA,CAAU,IAAA,CAAK,GAAG,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,QACjD;AAAA,MACF;AAEA,MAAA,IAAI,OAAO,QAAA,EAAU;AACnB,QAAA,KAAA,MAAW,QAAA,IAAY,OAAO,QAAA,EAAU;AACtC,UAAA,MAAM,SAAS,MAAM,QAAA,CAAS,WAAA,CAAY,EAAE,UAAU,CAAA;AACtD,UAAA,SAAA,CAAU,IAAA,CAAK,GAAG,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,QACnD;AAAA,MACF;AAGA,MAAA,MAAM,kBAAkB,CAAC,GAAG,IAAI,GAAA,CAAI,SAAS,CAAC,CAAA;AAG9C,MAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC9B,QAAA,MAAM,WAAA,CAAY,UAAU,eAAA,EAAiB;AAAA,UAC3C,IAAA,EAAM,oBAAA;AAAA,UACN,OAAA,EAAS;AAAA,YACP,aAAa,GAAA,CAAI,WAAA;AAAA,YACjB,SAAS,GAAA,CAAI,OAAA;AAAA,YACb,aAAa,GAAA,CAAI,WAAA;AAAA,YACjB,KAAK,GAAA,CAAI,GAAA;AAAA,YACT,MAAM,GAAA,CAAI;AAAA,WACZ;AAAA,UACA,QAAA,EAAU;AAAA,SACX,CAAA;AAGD,QAAA,KAAA,MAAW,YAAY,eAAA,EAAiB;AACtC,UAAA,MAAM,SAAS,aAAA,CAAc;AAAA,YAC3B,QAAA;AAAA,YACA,IAAA,EAAM,YAAA;AAAA,YACN,OAAA,EAAS;AAAA,cACP,aAAa,GAAA,CAAI,WAAA;AAAA,cACjB,SAAS,GAAA,CAAI,OAAA;AAAA,cACb,KAAK,GAAA,CAAI;AAAA;AACX,WACD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,eAAA,CACJ,WAAA,EACA,QAAA,EACA,OAAA,EACkB;AAClB,MAAA,MAAM,GAAA,GAAM,MAAM,QAAA,CAAS,wBAAA,CAAyB,aAAa,OAAO,CAAA;AACxE,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,yBAAyB,WAAW,CAAA;AAAA,MAChD;AAEA,MAAA,OAAO,OAAA,CAAQ,YAAY,QAAA,EAAU;AAAA,QACnC,IAAA,EAAM,YAAA;AAAA,QACN,OAAA,EAAS;AAAA,UACP,aAAa,GAAA,CAAI,WAAA;AAAA,UACjB,SAAS,GAAA,CAAI,OAAA;AAAA,UACb,aAAa,GAAA,CAAI,WAAA;AAAA,UACjB,KAAK,GAAA,CAAI,GAAA;AAAA,UACT,MAAM,GAAA,CAAI;AAAA;AACZ,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,mBAAA,CACJ,WAAA,EACA,QAAA,EACkB;AAClB,MAAA,OAAO,OAAA,CAAQ,YAAY,QAAA,EAAU;AAAA,QACnC,IAAA,EAAM,cAAA;AAAA,QACN,OAAA,EAAS,EAAE,WAAA;AAAY,OACxB,CAAA;AAAA,IACH;AAAA,GACF;AAMA,EAAA,MAAM,QAAA,GAA2B;AAAA,IAC/B,MAAM,IAAI,EAAA,EAAqC;AAC7C,MAAA,OAAO,QAAA,CAAS,YAAY,EAAE,CAAA;AAAA,IAChC,CAAA;AAAA,IAEA,MAAM,KAAK,MAAA,EAA4C;AACrD,MAAA,OAAO,QAAA,CAAS,aAAa,MAAM,CAAA;AAAA,IACrC,CAAA;AAAA,IAEA,MAAM,KAAK,KAAA,EAA2C;AACpD,MAAA,OAAO,OAAA,CAAQ,WAAA,CAAY,KAAA,CAAM,QAAA,EAAU;AAAA,QACzC,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,SAAS,KAAA,CAAM;AAAA,OAChB,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,OAAO,EAAA,EAA8B;AACzC,MAAA,OAAO,SAAS,aAAA,CAAc,EAAA,EAAI,EAAE,MAAA,EAAQ,aAAa,CAAA;AAAA,IAC3D,CAAA;AAAA,IAEA,MAAM,YAAY,EAAA,EAA8B;AAC9C,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,aAAA,CAAc,EAAA,EAAI;AAAA,QAC/C,MAAA,EAAQ,cAAA;AAAA,QACR,cAAA,sBAAoB,IAAA;AAAK,OAC1B,CAAA;AAED,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,UAAA,CAAW,QAAQ,QAAQ,CAAA;AACzD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAM,IAAA,CAAK,sBAAA,EAAwB,EAAE,MAAA,EAAQ,SAAS,CAAA;AAAA,MACxD;AAEA,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,QAAA,CAAS,EAAA,EAAY,MAAA,EAAyC;AAClE,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,aAAA,CAAc,EAAA,EAAI;AAAA,QAC/C,MAAA,EAAQ,WAAA;AAAA,QACR,MAAA;AAAA,QACA,WAAA,sBAAiB,IAAA;AAAK,OACvB,CAAA;AAED,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,UAAA,CAAW,QAAQ,QAAQ,CAAA;AACzD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAM,KAAK,mBAAA,EAAqB,EAAE,MAAA,EAAQ,OAAA,EAAS,QAAQ,CAAA;AAAA,MAC7D;AAEA,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,IAAA,CAAK,EAAA,EAAY,KAAA,EAAiC;AACtD,MAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,aAAA,CAAc,EAAA,EAAI;AAAA,QAC/C,MAAA,EAAQ,QAAA;AAAA,QACR,KAAA;AAAA,QACA,WAAA,sBAAiB,IAAA;AAAK,OACvB,CAAA;AAED,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,UAAA,CAAW,QAAQ,QAAQ,CAAA;AACzD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAM,KAAK,gBAAA,EAAkB,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAA;AAAA,MACzD;AAEA,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,WAAW,QAAA,EAAsC;AACrD,MAAA,OAAO,QAAA,CAAS,mBAAmB,QAAQ,CAAA;AAAA,IAC7C;AAAA,GACF;AAMA,EAAA,MAAM,MAAA,GAAuB;AAAA,IAC3B,MAAM,IAAI,EAAA,EAAmC;AAC3C,MAAA,OAAO,QAAA,CAAS,UAAU,EAAE,CAAA;AAAA,IAC9B,CAAA;AAAA,IAEA,MAAM,IAAA,GAAyB;AAC7B,MAAA,OAAO,SAAS,UAAA,EAAW;AAAA,IAC7B,CAAA;AAAA,IAEA,MAAM,OAAO,IAAA,EAAwC;AACnD,MAAA,OAAO,QAAA,CAAS,YAAY,IAAI,CAAA;AAAA,IAClC,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,EAAA,EAAY,IAAA,EAAwC;AAC/D,MAAA,OAAO,QAAA,CAAS,WAAA,CAAY,EAAA,EAAI,IAAI,CAAA;AAAA,IACtC,CAAA;AAAA,IAEA,MAAM,OAAO,EAAA,EAA2B;AACtC,MAAA,MAAM,QAAA,CAAS,YAAY,EAAE,CAAA;AAAA,IAC/B,CAAA;AAAA,IAEA,MAAM,WAAW,OAAA,EAAoC;AACnD,MAAA,OAAO,QAAA,CAAS,mBAAmB,OAAO,CAAA;AAAA,IAC5C,CAAA;AAAA,IAEA,MAAM,SAAA,CAAU,OAAA,EAAiB,QAAA,EAAiC;AAChE,MAAA,MAAM,QAAA,CAAS,gBAAA,CAAiB,QAAA,EAAU,OAAO,CAAA;AAAA,IACnD,CAAA;AAAA,IAEA,MAAM,YAAA,CAAa,OAAA,EAAiB,QAAA,EAAiC;AACnE,MAAA,MAAM,QAAA,CAAS,qBAAA,CAAsB,QAAA,EAAU,OAAO,CAAA;AAAA,IACxD,CAAA;AAAA,IAEA,MAAM,YAAY,OAAA,EAAmC;AACnD,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,UAAA,EAAW;AAC5C,MAAA,OAAO,UAAU,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,aAAa,OAAO,CAAA;AAAA,IACvD;AAAA,GACF;AAMA,EAAA,MAAM,MAAA,GAAS,OACb,OAAA,KACgC;AAEhC,IAAA,IACE,UAAA,EAAY,kBACZ,CAAC,UAAA,CAAW,eAAe,QAAA,CAAS,OAAA,CAAQ,MAAM,CAAA,EAClD;AACA,MAAA,MAAM,IAAI,eAAA;AAAA,QACR,CAAA,mBAAA,EAAsB,QAAQ,MAAM,CAAA,gBAAA;AAAA,OACtC;AAAA,IACF;AAGA,IAAA,IAAI,YAAY,YAAA,EAAc;AAC5B,MAAA,MAAM,OAAA,GAAU,yBAAA;AAAA,QACd,OAAA;AAAA,QACA,UAAA,CAAW;AAAA,OACb;AACA,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,IAAI,gBAAgB,8BAA8B,CAAA;AAAA,MAC1D;AAAA,IACF;AAGA,IAAA,IAAI,YAAY,QAAA,EAAU;AACxB,MAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,QAAA,CAAS,OAAO,CAAA;AACjD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,IAAI,gBAAgB,8BAA8B,CAAA;AAAA,MAC1D;AAAA,IACF;AAGA,IAAA,MAAM,eACJ,OAAA,CAAQ,UAAA,IACR,QAAQ,YAAA,IACR,OAAA,CAAQ,QACR,OAAA,CAAQ,SAAA;AAEV,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAI,eAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAGA,IAAA,IAAI,MAAA,GAAS,MAAM,QAAA,CAAS,wBAAA,CAAyB,YAAY,CAAA;AAEjE,IAAA,IAAI,MAAA,EAAQ;AAEV,MAAA,MAAA,GAAS,MAAM,QAAA,CAAS,YAAA,CAAa,MAAA,CAAO,EAAA,EAAI;AAAA,QAC9C,MAAA,EAAQ,UAAA;AAAA,QACR,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,cAAc,OAAA,CAAQ,YAAA;AAAA,QACtB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,QAAA,sBAAc,IAAA;AAAK,OACpB,CAAA;AAAA,IACH,CAAA,MAAA,IAAW,YAAY,UAAA,EAAY;AAEjC,MAAA,MAAA,GAAS,MAAM,SAAS,YAAA,CAAa;AAAA,QACnC,YAAA;AAAA,QACA,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,cAAc,OAAA,CAAQ,YAAA;AAAA,QACtB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,cAAc,OAAA,CAAQ,YAAA;AAAA,QACtB,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,YAAY,OAAA,CAAQ,UAAA;AAAA,QACpB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,QAAA,EAAU,OAAA,CAAQ,QAAA,IAAY,UAAA,CAAW;AAAA,OAC1C,CAAA;AAGD,MAAA,IAAI,WAAW,cAAA,EAAgB;AAC7B,QAAA,MAAM,QAAA,CAAS,gBAAA,CAAiB,MAAA,CAAO,EAAA,EAAI,WAAW,cAAc,CAAA;AAAA,MACtE;AAAA,IACF,CAAA,MAAA,IAAW,YAAY,eAAA,EAAiB;AAEtC,MAAA,MAAA,GAAS,MAAM,SAAS,YAAA,CAAa;AAAA,QACnC,YAAA;AAAA,QACA,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,cAAc,OAAA,CAAQ,YAAA;AAAA,QACtB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,cAAc,OAAA,CAAQ,YAAA;AAAA,QACtB,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,YAAY,OAAA,CAAQ,UAAA;AAAA,QACpB,WAAW,OAAA,CAAQ;AAAA,OACpB,CAAA;AAAA,IAEH,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,eAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAGA,IAAA,IAAI,MAAA,GAAwB,IAAA;AAC5B,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,MAAA,GAAS,MAAM,QAAA,CAAS,UAAA,CAAW,MAAA,CAAO,QAAQ,CAAA;AAAA,IACpD;AACA,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAA,GAAS,MAAM,SAAS,iBAAA,EAAkB;AAAA,IAC5C;AAGA,IAAA,MAAM,WAAA,GACJ,MAAA,CAAO,IAAA,EAAM,iBAAA,IAAqB,YAAY,YAAA,IAAgB,EAAA;AAChE,IAAA,MAAM,kBAAkB,MAAA,CAAO,IAAA,EAAM,qBAAA,IAAyB,GAAA,GAAM,KAAK,EAAA,GAAK,EAAA;AAC9E,IAAA,MAAM,KAAA,GAAQ,mBAAA,CAAoB,MAAA,CAAO,EAAA,EAAI,aAAa,eAAe,CAAA;AAGzE,IAAA,MAAM,IAAA,CAAK,iBAAA,EAAmB,EAAE,MAAA,EAAQ,CAAA;AAGxC,IAAA,IAAI,OAAO,gBAAA,EAAkB;AAC3B,MAAA,MAAM,MAAA,CAAO,iBAAiB,MAAM,CAAA;AAAA,IACtC;AAGA,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,OAAO,QAAA,EAAU;AACnB,QAAA,MAAM,MAAA,CAAO,QAAA,CAAS,MAAA,EAAQ,OAAO,CAAA;AAAA,MACvC;AACA,MAAA,IAAI,OAAO,gBAAA,EAAkB;AAC3B,QAAA,MAAM,MAAA,CAAO,iBAAiB,MAAM,CAAA;AAAA,MACtC;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,UAAU,MAAA,CAAO,EAAA;AAAA,MACjB,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,UAAU,MAAA,EAAQ,EAAA;AAAA,MAClB,QAAQ,MAAA,IAAU,MAAA;AAAA,MAClB,SAAA,EAAW,OAAO,SAAA,IAAa,EAAA;AAAA,MAC/B,UAAA,EAAY;AAAA,QACV,QAAA,EAAU,MAAM,QAAA,IAAY,SAAA;AAAA,QAC5B,WAAA,EAAc,MAAM,cAAA,EAAwB,UAAA;AAAA,QAC5C,SAAS,IAAA,EAAM,OAAA;AAAA,QACf,SAAA,EAAW,IAAA,EAAM,eAAA,GACb,CAAA,EAAG,IAAA,CAAK,eAAe,CAAA,CAAA,EAAI,MAAA,CAAO,EAAE,CAAA,CAAA,GACpC,CAAA,gBAAA,EAAmB,MAAA,CAAO,EAAE,CAAA,CAAA;AAAA,QAChC,eAAA,EAAiB,MAAM,eAAA,IAAmB;AAAA,OAC5C;AAAA,MACA,KAAA;AAAA,MACA,gBAAgB,IAAI,IAAA,CAAK,KAAK,GAAA,EAAI,GAAI,kBAAkB,GAAI;AAAA,KAC9D;AAAA,EACF,CAAA;AAMA,EAAA,MAAM,gBAAA,GAAmB,OACvB,QAAA,EACA,SAAA,KACkB;AAClB,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,UAAA,CAAW,QAAQ,CAAA;AACjD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,oBAAoB,QAAQ,CAAA;AAAA,IACxC;AAGA,IAAA,MAAM,UAAA,GAAgC;AAAA,MACpC,eAAe,SAAA,CAAU,SAAA;AAAA,MACzB,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,aAAa,SAAA,CAAU,WAAA;AAAA,MACvB,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,eAAe,SAAA,CAAU;AAAA,KAC3B;AAEA,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,UAAA,CAAW,WAAW,SAAA,CAAU,QAAA;AAAA,IAClC;AAEA,IAAA,MAAM,aAAA,GAAgB,MAAM,QAAA,CAAS,YAAA,CAAa,UAAU,UAAU,CAAA;AAGtE,IAAA,MAAM,KAAK,kBAAA,EAAoB,EAAE,MAAA,EAAQ,aAAA,EAAe,WAAW,CAAA;AAGnE,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,MAAM,KAAK,wBAAA,EAA0B;AAAA,QACnC,MAAA,EAAQ,aAAA;AAAA,QACR,UAAU,SAAA,CAAU;AAAA,OACrB,CAAA;AAAA,IACH;AAGA,IAAA,IAAI,MAAA,CAAO,aAAA,IAAiB,SAAA,CAAU,aAAA,EAAe;AACnD,MAAA,MAAM,UAAU,IAAI,GAAA;AAAA,QAClB,MAAA,CAAO,cAAc,GAAA,CAAI,CAAC,MAAM,CAAC,CAAA,CAAE,WAAA,EAAa,CAAC,CAAC;AAAA,OACpD;AACA,MAAA,MAAM,UAAU,IAAI,GAAA;AAAA,QAClB,SAAA,CAAU,cAAc,GAAA,CAAI,CAAC,MAAM,CAAC,CAAA,CAAE,WAAA,EAAa,CAAC,CAAC;AAAA,OACvD;AAGA,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,CAAA,IAAK,OAAA,EAAS;AAChC,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAC9B,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,MAAM,KAAK,eAAA,EAAiB,EAAE,MAAA,EAAQ,aAAA,EAAe,KAAK,CAAA;AAAA,QAC5D,CAAA,MAAA,IAAW,MAAA,CAAO,OAAA,KAAY,GAAA,CAAI,OAAA,EAAS;AACzC,UAAA,MAAM,KAAK,aAAA,EAAe;AAAA,YACxB,MAAA,EAAQ,aAAA;AAAA,YACR,GAAA;AAAA,YACA,YAAY,MAAA,CAAO;AAAA,WACpB,CAAA;AAAA,QACH;AAAA,MACF;AAGA,MAAA,KAAA,MAAW,CAAC,GAAG,CAAA,IAAK,OAAA,EAAS;AAC3B,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,EAAG;AACrB,UAAA,MAAM,KAAK,iBAAA,EAAmB;AAAA,YAC5B,MAAA,EAAQ,aAAA;AAAA,YACR,WAAA,EAAa;AAAA,WACd,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,WAAA,EAAa;AACtB,MAAA,MAAM,MAAA,CAAO,WAAA,CAAY,aAAA,EAAe,SAAS,CAAA;AAAA,IACnD;AAGA,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,OAAO,WAAA,EAAa;AACtB,QAAA,MAAM,MAAA,CAAO,WAAA,CAAY,aAAA,EAAe,SAAS,CAAA;AAAA,MACnD;AAAA,IACF;AAAA,EACF,CAAA;AAMA,EAAA,MAAM,iBAAA,GAAoB,OACxB,KAAA,KACyC;AACzC,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GACJ,MAAA,CAAO,IAAA,EAAM,iBAAA,IAAqB,YAAY,YAAA,IAAgB,EAAA;AAEhE,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,CAAC,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA,GAAI,KAAA;AAGrC,MAAA,MAAM,iBAAA,GAAoBC,UAAAA,CAAW,QAAA,EAAU,WAAW,CAAA,CACvD,MAAA,CAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA,CAC7B,OAAO,WAAW,CAAA;AAErB,MAAA,IAAI,cAAc,iBAAA,EAAmB;AACnC,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,MAAM,UAAU,IAAA,CAAK,KAAA;AAAA,QACnB,OAAO,IAAA,CAAK,OAAA,EAAS,WAAW,CAAA,CAAE,SAAS,OAAO;AAAA,OACpD;AAGA,MAAA,IAAI,OAAA,CAAQ,GAAA,IAAO,OAAA,CAAQ,GAAA,GAAM,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA,EAAI,GAAI,GAAI,CAAA,EAAG;AAC9D,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,OAAO,EAAE,QAAA,EAAU,OAAA,CAAQ,GAAA,EAAI;AAAA,IACjC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA;AAMA,EAAA,MAAM,aAAa,MAAmB,OAAA;AAEtC,EAAA,MAAM,SAAA,GAAY,CAAC,IAAA,KAAwC;AACzD,IAAA,OAAO,QAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AAAA,EAC5C,CAAA;AAMA,EAAA,MAAM,QAAA,GAAwB;AAAA,IAC5B,OAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA,EAAM,WAAA;AAAA,IACN,QAAA,EAAU,cAAA;AAAA,IACV,EAAA,EAAI,QAAA;AAAA,IACJ,MAAA;AAAA,IACA,EAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,gBAAA;AAAA,IACA,iBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAA,CAAC,YAAY;AACX,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,CAAO,OAAO,QAAQ,CAAA;AAC5B,UAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,8BAAA,EAAiC,MAAA,CAAO,IAAI,CAAA,CAAE,CAAA;AAAA,QAC5D,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAA;AAAA,YACN,CAAA,sCAAA,EAAyC,OAAO,IAAI,CAAA,CAAA,CAAA;AAAA,YACpD;AAAA,WACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAA,GAAG;AAEH,EAAA,OAAO,QAAA;AACT;AAMA,SAAS,iBAAA,CACP,QACA,QAAA,EACa;AACb,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,qBAAA,EAAsB;AAAA,EAC/B;AAIA,EAAA,OAAO;AAAA,IACL,MAAM,IAAA,CAAK,QAAA,EAAkB,OAAA,EAA2C;AACtE,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,kBAAA,EAAqB,QAAQ,CAAA,EAAA,EAAK,OAAA,CAAQ,IAAI,CAAA,CAAA;AAAA,QAC9C,OAAA,CAAQ;AAAA,OACV;AAGA,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAWF,YAAW,EAAE;AAAA,IAClD,CAAA;AAAA,IAEA,MAAM,SAAA,CACJ,SAAA,EACA,OAAA,EAC0B;AAC1B,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,kBAAA,EAAqB,SAAA,CAAU,MAAM,CAAA,UAAA,EAAa,QAAQ,IAAI,CAAA;AAAA,OAChE;AAEA,MAAA,MAAM,OAAA,GAAU,SAAA,CAAU,GAAA,CAAI,CAAC,QAAA,MAAc;AAAA,QAC3C,QAAA;AAAA,QACA,QAAQ,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAWA,YAAW;AAAE,OACnD,CAAE,CAAA;AAEF,MAAA,OAAO;AAAA,QACL,cAAc,SAAA,CAAU,MAAA;AAAA,QACxB,YAAA,EAAc,CAAA;AAAA,QACd;AAAA,OACF;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,aAAA,CAAc,QAAA,EAAkB,KAAA,EAA8B;AAElE,MAAA,IAAI,MAAA,CAAO,aAAa,SAAA,EAAW;AACjC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,SAAS,eAAA,CAAgB;AAAA,QAC7B,QAAA;AAAA,QACA,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,gBAAgB,QAAA,EAAiC;AAErD,MAAA,IAAI,MAAA,CAAO,aAAa,SAAA,EAAW;AACjC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,QAAA,CAAS,eAAA,CAAgB,QAAA,EAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACF;AACF;AAEA,SAAS,qBAAA,GAAqC;AAC5C,EAAA,OAAO;AAAA,IACL,MAAM,IAAA,CAAK,QAAA,EAAkB,OAAA,EAA2C;AACtE,MAAA,OAAA,CAAQ,IAAI,CAAA,uBAAA,EAA0B,QAAQ,CAAA,IAAA,EAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AACnE,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,MAAA,EAAO;AAAA,IAC5C,CAAA;AAAA,IAEA,MAAM,SAAA,CACJ,SAAA,EACA,OAAA,EAC0B;AAC1B,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,uBAAA,EAA0B,SAAA,CAAU,MAAM,CAAA,YAAA,EAAe,QAAQ,IAAI,CAAA;AAAA,OACvE;AACA,MAAA,OAAO;AAAA,QACL,cAAc,SAAA,CAAU,MAAA;AAAA,QACxB,YAAA,EAAc,CAAA;AAAA,QACd,OAAA,EAAS,SAAA,CAAU,GAAA,CAAI,CAAC,QAAA,MAAc;AAAA,UACpC,QAAA;AAAA,UACA,MAAA,EAAQ,EAAE,OAAA,EAAS,IAAA,EAAM,WAAW,MAAA;AAAO,SAC7C,CAAE;AAAA,OACJ;AAAA,IACF;AAAA,GACF;AACF;AAMA,SAAS,yBAAA,CACP,SACA,MAAA,EACS;AACT,EAAA,MAAM,EAAE,SAAA,EAAW,GAAG,IAAA,EAAK,GAAI,OAAA;AAE/B,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AAIA,EAAA,MAAM,UAAA,GACJ,KAAK,UAAA,IAAc,IAAA,CAAK,gBAAgB,IAAA,CAAK,IAAA,IAAQ,KAAK,SAAA,IAAa,EAAA;AACzE,EAAA,MAAM,OAAA,GAAU,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,KAAK,SAAS,CAAA,CAAA;AAE/C,EAAA,MAAM,iBAAA,GAAoBE,WAAW,QAAA,EAAU,MAAM,EAClD,MAAA,CAAO,OAAO,CAAA,CACd,MAAA,CAAO,KAAK,CAAA;AAEf,EAAA,IAAI;AACF,IAAA,OAAO,eAAA;AAAA,MACL,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,KAAK,CAAA;AAAA,MAC5B,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,KAAK;AAAA,KACtC;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,SAAS,mBAAA,CACP,QAAA,EACA,MAAA,EACA,iBAAA,EACQ;AACR,EAAA,MAAM,SAAS,MAAA,CAAO,IAAA;AAAA,IACpB,KAAK,SAAA,CAAU,EAAE,KAAK,OAAA,EAAS,GAAA,EAAK,OAAO;AAAA,GAC7C,CAAE,SAAS,WAAW,CAAA;AAEtB,EAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,EAAA,MAAM,UAAU,MAAA,CAAO,IAAA;AAAA,IACrB,KAAK,SAAA,CAAU;AAAA,MACb,GAAA,EAAK,QAAA;AAAA,MACL,GAAA,EAAK,GAAA;AAAA,MACL,KAAK,GAAA,GAAM,iBAAA;AAAA,MACX,GAAA,EAAK;AAAA,KACN;AAAA,GACH,CAAE,SAAS,WAAW,CAAA;AAEtB,EAAA,MAAM,SAAA,GAAYA,UAAAA,CAAW,QAAA,EAAU,MAAM,CAAA,CAC1C,MAAA,CAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA,CAC7B,OAAO,WAAW,CAAA;AAErB,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,OAAO,IAAI,SAAS,CAAA,CAAA;AAC1C","file":"index.js","sourcesContent":["/**\n * OpenMDM Core Types\n *\n * These types define the core data structures for the MDM system.\n * Designed to be database-agnostic and framework-agnostic.\n */\n\n// ============================================\n// Device Types\n// ============================================\n\nexport type DeviceStatus = 'pending' | 'enrolled' | 'unenrolled' | 'blocked';\n\nexport interface Device {\n id: string;\n externalId?: string | null;\n enrollmentId: string;\n status: DeviceStatus;\n\n // Device Info\n model?: string | null;\n manufacturer?: string | null;\n osVersion?: string | null;\n serialNumber?: string | null;\n imei?: string | null;\n macAddress?: string | null;\n androidId?: string | null;\n\n // MDM State\n policyId?: string | null;\n lastHeartbeat?: Date | null;\n lastSync?: Date | null;\n\n // Telemetry\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n location?: DeviceLocation | null;\n installedApps?: InstalledApp[] | null;\n\n // Metadata\n tags?: Record<string, string> | null;\n metadata?: Record<string, unknown> | null;\n\n // Timestamps\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DeviceLocation {\n latitude: number;\n longitude: number;\n accuracy?: number;\n timestamp: Date;\n}\n\nexport interface InstalledApp {\n packageName: string;\n version: string;\n versionCode?: number;\n installedAt?: Date;\n}\n\nexport interface CreateDeviceInput {\n enrollmentId: string;\n externalId?: string;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n serialNumber?: string;\n imei?: string;\n macAddress?: string;\n androidId?: string;\n policyId?: string;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateDeviceInput {\n externalId?: string | null;\n status?: DeviceStatus;\n policyId?: string | null;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n lastHeartbeat?: Date;\n lastSync?: Date;\n installedApps?: InstalledApp[];\n location?: DeviceLocation;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DeviceFilter {\n status?: DeviceStatus | DeviceStatus[];\n policyId?: string;\n groupId?: string;\n search?: string;\n tags?: Record<string, string>;\n limit?: number;\n offset?: number;\n}\n\nexport interface DeviceListResult {\n devices: Device[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Policy Types\n// ============================================\n\nexport interface Policy {\n id: string;\n name: string;\n description?: string | null;\n isDefault: boolean;\n settings: PolicySettings;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface PolicySettings {\n // Kiosk Mode\n kioskMode?: boolean;\n mainApp?: string;\n allowedApps?: string[];\n kioskExitPassword?: string;\n\n // Lock Features\n lockStatusBar?: boolean;\n lockNavigationBar?: boolean;\n lockSettings?: boolean;\n lockPowerButton?: boolean;\n blockInstall?: boolean;\n blockUninstall?: boolean;\n\n // Hardware Controls\n bluetooth?: HardwareControl;\n wifi?: HardwareControl;\n gps?: HardwareControl;\n mobileData?: HardwareControl;\n camera?: HardwareControl;\n microphone?: HardwareControl;\n usb?: HardwareControl;\n nfc?: HardwareControl;\n\n // Update Settings\n systemUpdatePolicy?: SystemUpdatePolicy;\n updateWindow?: TimeWindow;\n\n // Security\n passwordPolicy?: PasswordPolicy;\n encryptionRequired?: boolean;\n factoryResetProtection?: boolean;\n safeBootDisabled?: boolean;\n\n // Telemetry\n heartbeatInterval?: number;\n locationReportInterval?: number;\n locationEnabled?: boolean;\n\n // Network\n wifiConfigs?: WifiConfig[];\n vpnConfig?: VpnConfig;\n\n // Applications\n applications?: PolicyApplication[];\n\n // Custom settings (for plugins)\n custom?: Record<string, unknown>;\n}\n\nexport type HardwareControl = 'on' | 'off' | 'user';\nexport type SystemUpdatePolicy = 'auto' | 'windowed' | 'postpone' | 'manual';\n\nexport interface TimeWindow {\n start: string; // \"HH:MM\"\n end: string; // \"HH:MM\"\n}\n\nexport interface PasswordPolicy {\n required: boolean;\n minLength?: number;\n complexity?: 'none' | 'numeric' | 'alphanumeric' | 'complex';\n maxFailedAttempts?: number;\n expirationDays?: number;\n historyLength?: number;\n}\n\nexport interface WifiConfig {\n ssid: string;\n securityType: 'none' | 'wep' | 'wpa' | 'wpa2' | 'wpa3';\n password?: string;\n hidden?: boolean;\n autoConnect?: boolean;\n}\n\nexport interface VpnConfig {\n type: 'pptp' | 'l2tp' | 'ipsec' | 'openvpn' | 'wireguard';\n server: string;\n username?: string;\n password?: string;\n certificate?: string;\n config?: Record<string, unknown>;\n}\n\nexport interface PolicyApplication {\n packageName: string;\n action: 'install' | 'update' | 'uninstall';\n version?: string;\n required?: boolean;\n autoUpdate?: boolean;\n}\n\nexport interface CreatePolicyInput {\n name: string;\n description?: string;\n isDefault?: boolean;\n settings: PolicySettings;\n}\n\nexport interface UpdatePolicyInput {\n name?: string;\n description?: string | null;\n isDefault?: boolean;\n settings?: PolicySettings;\n}\n\n// ============================================\n// Application Types\n// ============================================\n\nexport interface Application {\n id: string;\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n\n // Deployment settings\n showIcon: boolean;\n runAfterInstall: boolean;\n runAtBoot: boolean;\n isSystem: boolean;\n\n // State\n isActive: boolean;\n\n // Metadata\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateApplicationInput {\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string;\n size?: number;\n minSdkVersion?: number;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isSystem?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateApplicationInput {\n name?: string;\n version?: string;\n versionCode?: number;\n url?: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isActive?: boolean;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface DeployTarget {\n devices?: string[];\n policies?: string[];\n groups?: string[];\n}\n\n// ============================================\n// App Version & Rollback Types\n// ============================================\n\nexport interface AppVersion {\n id: string;\n applicationId: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n releaseNotes?: string | null;\n isMinimumVersion: boolean;\n createdAt: Date;\n}\n\nexport interface AppRollback {\n id: string;\n deviceId: string;\n packageName: string;\n fromVersion: string;\n fromVersionCode: number;\n toVersion: string;\n toVersionCode: number;\n reason?: string | null;\n status: 'pending' | 'in_progress' | 'completed' | 'failed';\n error?: string | null;\n initiatedBy?: string | null;\n createdAt: Date;\n completedAt?: Date | null;\n}\n\nexport interface CreateAppRollbackInput {\n deviceId: string;\n packageName: string;\n toVersionCode: number;\n reason?: string;\n initiatedBy?: string;\n}\n\n// ============================================\n// Command Types\n// ============================================\n\nexport type CommandType =\n | 'reboot'\n | 'shutdown'\n | 'sync'\n | 'lock'\n | 'unlock'\n | 'wipe'\n | 'factoryReset'\n | 'installApp'\n | 'uninstallApp'\n | 'updateApp'\n | 'runApp'\n | 'clearAppData'\n | 'clearAppCache'\n | 'shell'\n | 'setPolicy'\n | 'grantPermissions'\n | 'exitKiosk'\n | 'enterKiosk'\n | 'setWifi'\n | 'screenshot'\n | 'getLocation'\n | 'setVolume'\n | 'sendNotification'\n | 'whitelistBattery' // Whitelist app from battery optimization (Doze)\n | 'enablePermissiveMode' // Enable permissive mode for debugging\n | 'setTimeZone' // Set device timezone\n | 'enableAdb' // Enable/disable ADB debugging\n | 'rollbackApp' // Rollback to previous app version\n | 'custom';\n\nexport type CommandStatus =\n | 'pending'\n | 'sent'\n | 'acknowledged'\n | 'completed'\n | 'failed'\n | 'cancelled';\n\nexport interface Command {\n id: string;\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown> | null;\n status: CommandStatus;\n result?: CommandResult | null;\n error?: string | null;\n createdAt: Date;\n sentAt?: Date | null;\n acknowledgedAt?: Date | null;\n completedAt?: Date | null;\n}\n\nexport interface CommandResult {\n success: boolean;\n message?: string;\n data?: unknown;\n}\n\nexport interface SendCommandInput {\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown>;\n}\n\nexport interface CommandFilter {\n deviceId?: string;\n status?: CommandStatus | CommandStatus[];\n type?: CommandType | CommandType[];\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Event Types\n// ============================================\n\nexport type EventType =\n | 'device.enrolled'\n | 'device.unenrolled'\n | 'device.blocked'\n | 'device.heartbeat'\n | 'device.locationUpdated'\n | 'device.statusChanged'\n | 'device.policyChanged'\n | 'app.installed'\n | 'app.uninstalled'\n | 'app.updated'\n | 'app.crashed'\n | 'app.started'\n | 'app.stopped'\n | 'policy.applied'\n | 'policy.failed'\n | 'command.received'\n | 'command.acknowledged'\n | 'command.completed'\n | 'command.failed'\n | 'security.tamper'\n | 'security.rootDetected'\n | 'security.screenLocked'\n | 'security.screenUnlocked'\n | 'custom';\n\nexport interface MDMEvent<T = unknown> {\n id: string;\n deviceId: string;\n type: EventType;\n payload: T;\n createdAt: Date;\n}\n\nexport interface EventFilter {\n deviceId?: string;\n type?: EventType | EventType[];\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Group Types\n// ============================================\n\nexport interface Group {\n id: string;\n name: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateGroupInput {\n name: string;\n description?: string;\n policyId?: string;\n parentId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateGroupInput {\n name?: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Enrollment Types\n// ============================================\n\nexport type EnrollmentMethod =\n | 'qr'\n | 'nfc'\n | 'zero-touch'\n | 'knox'\n | 'manual'\n | 'app-only'\n | 'adb';\n\nexport interface EnrollmentRequest {\n // Device identifiers (at least one required)\n macAddress?: string;\n serialNumber?: string;\n imei?: string;\n androidId?: string;\n\n // Device info\n model: string;\n manufacturer: string;\n osVersion: string;\n sdkVersion?: number;\n\n // Agent info\n agentVersion?: string;\n agentPackage?: string;\n\n // Enrollment details\n method: EnrollmentMethod;\n timestamp: string;\n signature: string;\n\n // Optional pre-assigned policy/group\n policyId?: string;\n groupId?: string;\n}\n\nexport interface EnrollmentResponse {\n deviceId: string;\n enrollmentId: string;\n policyId?: string;\n policy?: Policy;\n serverUrl: string;\n pushConfig: PushConfig;\n token: string;\n refreshToken?: string;\n tokenExpiresAt?: Date;\n}\n\nexport interface PushConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n fcmSenderId?: string;\n mqttUrl?: string;\n mqttTopic?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n wsUrl?: string;\n pollingInterval?: number;\n}\n\n// ============================================\n// Telemetry Types\n// ============================================\n\nexport interface Heartbeat {\n deviceId: string;\n timestamp: Date;\n\n // Battery\n batteryLevel: number;\n isCharging: boolean;\n batteryHealth?: 'good' | 'overheat' | 'dead' | 'cold' | 'unknown';\n\n // Storage\n storageUsed: number;\n storageTotal: number;\n\n // Memory\n memoryUsed: number;\n memoryTotal: number;\n\n // Network\n networkType?: 'wifi' | 'cellular' | 'ethernet' | 'none';\n networkName?: string; // SSID or carrier\n signalStrength?: number;\n ipAddress?: string;\n\n // Location\n location?: DeviceLocation;\n\n // Apps\n installedApps: InstalledApp[];\n runningApps?: string[];\n\n // Security\n isRooted?: boolean;\n isEncrypted?: boolean;\n screenLockEnabled?: boolean;\n\n // Agent status\n agentVersion?: string;\n policyVersion?: string;\n lastPolicySync?: Date;\n}\n\n// ============================================\n// Push Token Types\n// ============================================\n\nexport interface PushToken {\n id: string;\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n isActive: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface RegisterPushTokenInput {\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n}\n\n// ============================================\n// Configuration Types\n// ============================================\n\nexport interface MDMConfig {\n /** Database adapter for persistence */\n database: DatabaseAdapter;\n\n /** Authentication/authorization configuration */\n auth?: AuthConfig;\n\n /** Push notification provider configuration */\n push?: PushProviderConfig;\n\n /** Device enrollment configuration */\n enrollment?: EnrollmentConfig;\n\n /** Server URL (used in enrollment responses) */\n serverUrl?: string;\n\n /** APK/file storage configuration */\n storage?: StorageConfig;\n\n /** Outbound webhook configuration */\n webhooks?: WebhookConfig;\n\n /** Plugins to extend functionality */\n plugins?: MDMPlugin[];\n\n /** Event handlers */\n onDeviceEnrolled?: (device: Device) => Promise<void>;\n onDeviceUnenrolled?: (device: Device) => Promise<void>;\n onDeviceBlocked?: (device: Device) => Promise<void>;\n onHeartbeat?: (device: Device, heartbeat: Heartbeat) => Promise<void>;\n onCommand?: (command: Command) => Promise<void>;\n onEvent?: (event: MDMEvent) => Promise<void>;\n}\n\nexport interface StorageConfig {\n /** Storage provider (s3, local, custom) */\n provider: 's3' | 'local' | 'custom';\n\n /** S3 configuration */\n s3?: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string; // For S3-compatible services\n presignedUrlExpiry?: number; // Seconds, default 3600\n };\n\n /** Local storage path */\n localPath?: string;\n\n /** Custom storage adapter */\n customAdapter?: {\n upload: (file: Buffer, key: string) => Promise<string>;\n getUrl: (key: string) => Promise<string>;\n delete: (key: string) => Promise<void>;\n };\n}\n\nexport interface WebhookConfig {\n /** Webhook endpoints to notify */\n endpoints?: WebhookEndpoint[];\n\n /** Retry configuration */\n retry?: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n };\n\n /** Sign webhooks with HMAC secret */\n signingSecret?: string;\n}\n\nexport interface WebhookEndpoint {\n /** Unique identifier */\n id: string;\n /** Webhook URL */\n url: string;\n /** Events to trigger this webhook */\n events: (EventType | '*')[];\n /** Custom headers */\n headers?: Record<string, string>;\n /** Whether endpoint is active */\n enabled: boolean;\n}\n\nexport interface AuthConfig {\n /** Get current user from request context */\n getUser: <T = unknown>(context: unknown) => Promise<T | null>;\n /** Check if user has admin privileges */\n isAdmin?: (user: unknown) => Promise<boolean>;\n /** Check if user can access specific device */\n canAccessDevice?: (user: unknown, deviceId: string) => Promise<boolean>;\n /** Device JWT secret (for device auth tokens) */\n deviceTokenSecret?: string;\n /** Device token expiration in seconds (default: 365 days) */\n deviceTokenExpiration?: number;\n}\n\nexport interface PushProviderConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n\n // FCM configuration\n fcmCredentials?: string | Record<string, unknown>;\n fcmProjectId?: string;\n\n // MQTT configuration\n mqttUrl?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n mqttTopicPrefix?: string;\n\n // WebSocket configuration\n wsPath?: string;\n wsPingInterval?: number;\n\n // Polling fallback\n pollingInterval?: number;\n}\n\nexport interface EnrollmentConfig {\n /** Auto-enroll devices with valid signature */\n autoEnroll?: boolean;\n /** HMAC secret for device signature verification */\n deviceSecret: string;\n /** Allowed enrollment methods */\n allowedMethods?: EnrollmentMethod[];\n /** Default policy for new devices */\n defaultPolicyId?: string;\n /** Default group for new devices */\n defaultGroupId?: string;\n /** Require manual approval for enrollment */\n requireApproval?: boolean;\n /** Custom enrollment validation */\n validate?: (request: EnrollmentRequest) => Promise<boolean>;\n}\n\n// ============================================\n// Adapter Interfaces\n// ============================================\n\nexport interface DatabaseAdapter {\n // Devices\n findDevice(id: string): Promise<Device | null>;\n findDeviceByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n listDevices(filter?: DeviceFilter): Promise<DeviceListResult>;\n createDevice(data: CreateDeviceInput): Promise<Device>;\n updateDevice(id: string, data: UpdateDeviceInput): Promise<Device>;\n deleteDevice(id: string): Promise<void>;\n countDevices(filter?: DeviceFilter): Promise<number>;\n\n // Policies\n findPolicy(id: string): Promise<Policy | null>;\n findDefaultPolicy(): Promise<Policy | null>;\n listPolicies(): Promise<Policy[]>;\n createPolicy(data: CreatePolicyInput): Promise<Policy>;\n updatePolicy(id: string, data: UpdatePolicyInput): Promise<Policy>;\n deletePolicy(id: string): Promise<void>;\n\n // Applications\n findApplication(id: string): Promise<Application | null>;\n findApplicationByPackage(packageName: string, version?: string): Promise<Application | null>;\n listApplications(activeOnly?: boolean): Promise<Application[]>;\n createApplication(data: CreateApplicationInput): Promise<Application>;\n updateApplication(id: string, data: UpdateApplicationInput): Promise<Application>;\n deleteApplication(id: string): Promise<void>;\n\n // Commands\n findCommand(id: string): Promise<Command | null>;\n listCommands(filter?: CommandFilter): Promise<Command[]>;\n createCommand(data: SendCommandInput): Promise<Command>;\n updateCommand(id: string, data: Partial<Command>): Promise<Command>;\n getPendingCommands(deviceId: string): Promise<Command[]>;\n\n // Events\n createEvent(event: Omit<MDMEvent, 'id' | 'createdAt'>): Promise<MDMEvent>;\n listEvents(filter?: EventFilter): Promise<MDMEvent[]>;\n\n // Groups\n findGroup(id: string): Promise<Group | null>;\n listGroups(): Promise<Group[]>;\n createGroup(data: CreateGroupInput): Promise<Group>;\n updateGroup(id: string, data: UpdateGroupInput): Promise<Group>;\n deleteGroup(id: string): Promise<void>;\n listDevicesInGroup(groupId: string): Promise<Device[]>;\n addDeviceToGroup(deviceId: string, groupId: string): Promise<void>;\n removeDeviceFromGroup(deviceId: string, groupId: string): Promise<void>;\n getDeviceGroups(deviceId: string): Promise<Group[]>;\n\n // Push Tokens\n findPushToken(deviceId: string, provider: string): Promise<PushToken | null>;\n upsertPushToken(data: RegisterPushTokenInput): Promise<PushToken>;\n deletePushToken(deviceId: string, provider?: string): Promise<void>;\n\n // App Versions (optional - for version tracking)\n listAppVersions?(packageName: string): Promise<AppVersion[]>;\n createAppVersion?(data: Omit<AppVersion, 'id' | 'createdAt'>): Promise<AppVersion>;\n setMinimumVersion?(packageName: string, versionCode: number): Promise<void>;\n getMinimumVersion?(packageName: string): Promise<AppVersion | null>;\n\n // Rollback History (optional)\n createRollback?(data: CreateAppRollbackInput): Promise<AppRollback>;\n updateRollback?(id: string, data: Partial<AppRollback>): Promise<AppRollback>;\n listRollbacks?(filter?: { deviceId?: string; packageName?: string }): Promise<AppRollback[]>;\n\n // Transactions (optional)\n transaction?<T>(fn: () => Promise<T>): Promise<T>;\n}\n\nexport interface PushAdapter {\n /** Send push message to a device */\n send(deviceId: string, message: PushMessage): Promise<PushResult>;\n /** Send push message to multiple devices */\n sendBatch(deviceIds: string[], message: PushMessage): Promise<PushBatchResult>;\n /** Register device push token */\n registerToken?(deviceId: string, token: string): Promise<void>;\n /** Unregister device push token */\n unregisterToken?(deviceId: string): Promise<void>;\n /** Subscribe device to topic */\n subscribe?(deviceId: string, topic: string): Promise<void>;\n /** Unsubscribe device from topic */\n unsubscribe?(deviceId: string, topic: string): Promise<void>;\n}\n\nexport interface PushMessage {\n type: string;\n payload?: Record<string, unknown>;\n priority?: 'high' | 'normal';\n ttl?: number;\n collapseKey?: string;\n}\n\nexport interface PushResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n\nexport interface PushBatchResult {\n successCount: number;\n failureCount: number;\n results: Array<{ deviceId: string; result: PushResult }>;\n}\n\n// ============================================\n// Plugin Interface\n// ============================================\n\nexport interface MDMPlugin {\n /** Unique plugin name */\n name: string;\n /** Plugin version */\n version: string;\n\n /** Called when MDM is initialized */\n onInit?(mdm: MDMInstance): Promise<void>;\n\n /** Called when MDM is destroyed */\n onDestroy?(): Promise<void>;\n\n /** Additional routes to mount */\n routes?: PluginRoute[];\n\n /** Middleware to apply to all routes */\n middleware?: PluginMiddleware[];\n\n /** Extend enrollment process */\n onEnroll?(device: Device, request: EnrollmentRequest): Promise<void>;\n\n /** Extend device processing */\n onDeviceEnrolled?(device: Device): Promise<void>;\n onDeviceUnenrolled?(device: Device): Promise<void>;\n onHeartbeat?(device: Device, heartbeat: Heartbeat): Promise<void>;\n\n /** Extend policy processing */\n policySchema?: Record<string, unknown>;\n validatePolicy?(settings: PolicySettings): Promise<{ valid: boolean; errors?: string[] }>;\n applyPolicy?(device: Device, policy: Policy): Promise<void>;\n\n /** Extend command processing */\n commandTypes?: CommandType[];\n executeCommand?(device: Device, command: Command): Promise<CommandResult>;\n}\n\nexport interface PluginRoute {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n handler: (context: unknown) => Promise<unknown>;\n auth?: boolean;\n admin?: boolean;\n}\n\nexport type PluginMiddleware = (\n context: unknown,\n next: () => Promise<unknown>\n) => Promise<unknown>;\n\n// ============================================\n// MDM Instance Interface\n// ============================================\n\nexport interface WebhookManager {\n /** Deliver an event to all matching webhook endpoints */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n /** Add a webhook endpoint at runtime */\n addEndpoint(endpoint: WebhookEndpoint): void;\n /** Remove a webhook endpoint */\n removeEndpoint(endpointId: string): void;\n /** Update a webhook endpoint */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n /** Get all configured endpoints */\n getEndpoints(): WebhookEndpoint[];\n /** Test a webhook endpoint with a test payload */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface MDMInstance {\n /** Device management */\n devices: DeviceManager;\n /** Policy management */\n policies: PolicyManager;\n /** Application management */\n apps: ApplicationManager;\n /** Command management */\n commands: CommandManager;\n /** Group management */\n groups: GroupManager;\n\n /** Push notification service */\n push: PushAdapter;\n\n /** Webhook delivery (if configured) */\n webhooks?: WebhookManager;\n\n /** Database adapter */\n db: DatabaseAdapter;\n\n /** Configuration */\n config: MDMConfig;\n\n /** Subscribe to events */\n on<T extends EventType>(event: T, handler: EventHandler<T>): () => void;\n /** Emit an event */\n emit<T extends EventType>(event: T, data: EventPayloadMap[T]): Promise<void>;\n\n /** Process device enrollment */\n enroll(request: EnrollmentRequest): Promise<EnrollmentResponse>;\n /** Process device heartbeat */\n processHeartbeat(deviceId: string, heartbeat: Heartbeat): Promise<void>;\n /** Verify device token */\n verifyDeviceToken(token: string): Promise<{ deviceId: string } | null>;\n\n /** Get loaded plugins */\n getPlugins(): MDMPlugin[];\n /** Get plugin by name */\n getPlugin(name: string): MDMPlugin | undefined;\n}\n\n// ============================================\n// Manager Interfaces\n// ============================================\n\nexport interface DeviceManager {\n get(id: string): Promise<Device | null>;\n getByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n list(filter?: DeviceFilter): Promise<DeviceListResult>;\n create(data: CreateDeviceInput): Promise<Device>;\n update(id: string, data: UpdateDeviceInput): Promise<Device>;\n delete(id: string): Promise<void>;\n assignPolicy(deviceId: string, policyId: string | null): Promise<Device>;\n addToGroup(deviceId: string, groupId: string): Promise<void>;\n removeFromGroup(deviceId: string, groupId: string): Promise<void>;\n getGroups(deviceId: string): Promise<Group[]>;\n sendCommand(deviceId: string, input: Omit<SendCommandInput, 'deviceId'>): Promise<Command>;\n sync(deviceId: string): Promise<Command>;\n reboot(deviceId: string): Promise<Command>;\n lock(deviceId: string, message?: string): Promise<Command>;\n wipe(deviceId: string, preserveData?: boolean): Promise<Command>;\n}\n\nexport interface PolicyManager {\n get(id: string): Promise<Policy | null>;\n getDefault(): Promise<Policy | null>;\n list(): Promise<Policy[]>;\n create(data: CreatePolicyInput): Promise<Policy>;\n update(id: string, data: UpdatePolicyInput): Promise<Policy>;\n delete(id: string): Promise<void>;\n setDefault(id: string): Promise<Policy>;\n getDevices(policyId: string): Promise<Device[]>;\n applyToDevice(policyId: string, deviceId: string): Promise<void>;\n}\n\nexport interface ApplicationManager {\n get(id: string): Promise<Application | null>;\n getByPackage(packageName: string, version?: string): Promise<Application | null>;\n list(activeOnly?: boolean): Promise<Application[]>;\n register(data: CreateApplicationInput): Promise<Application>;\n update(id: string, data: UpdateApplicationInput): Promise<Application>;\n delete(id: string): Promise<void>;\n activate(id: string): Promise<Application>;\n deactivate(id: string): Promise<Application>;\n deploy(packageName: string, target: DeployTarget): Promise<void>;\n installOnDevice(packageName: string, deviceId: string, version?: string): Promise<Command>;\n uninstallFromDevice(packageName: string, deviceId: string): Promise<Command>;\n}\n\nexport interface CommandManager {\n get(id: string): Promise<Command | null>;\n list(filter?: CommandFilter): Promise<Command[]>;\n send(input: SendCommandInput): Promise<Command>;\n cancel(id: string): Promise<Command>;\n acknowledge(id: string): Promise<Command>;\n complete(id: string, result: CommandResult): Promise<Command>;\n fail(id: string, error: string): Promise<Command>;\n getPending(deviceId: string): Promise<Command[]>;\n}\n\nexport interface GroupManager {\n get(id: string): Promise<Group | null>;\n list(): Promise<Group[]>;\n create(data: CreateGroupInput): Promise<Group>;\n update(id: string, data: UpdateGroupInput): Promise<Group>;\n delete(id: string): Promise<void>;\n getDevices(groupId: string): Promise<Device[]>;\n addDevice(groupId: string, deviceId: string): Promise<void>;\n removeDevice(groupId: string, deviceId: string): Promise<void>;\n getChildren(groupId: string): Promise<Group[]>;\n}\n\n// ============================================\n// Event Handler Types\n// ============================================\n\nexport type EventHandler<T extends EventType> = (\n event: MDMEvent<EventPayloadMap[T]>\n) => Promise<void> | void;\n\nexport interface EventPayloadMap {\n 'device.enrolled': { device: Device };\n 'device.unenrolled': { device: Device; reason?: string };\n 'device.blocked': { device: Device; reason: string };\n 'device.heartbeat': { device: Device; heartbeat: Heartbeat };\n 'device.locationUpdated': { device: Device; location: DeviceLocation };\n 'device.statusChanged': { device: Device; oldStatus: DeviceStatus; newStatus: DeviceStatus };\n 'device.policyChanged': { device: Device; oldPolicyId?: string; newPolicyId?: string };\n 'app.installed': { device: Device; app: InstalledApp };\n 'app.uninstalled': { device: Device; packageName: string };\n 'app.updated': { device: Device; app: InstalledApp; oldVersion: string };\n 'app.crashed': { device: Device; packageName: string; error?: string };\n 'app.started': { device: Device; packageName: string };\n 'app.stopped': { device: Device; packageName: string };\n 'policy.applied': { device: Device; policy: Policy };\n 'policy.failed': { device: Device; policy: Policy; error: string };\n 'command.received': { device: Device; command: Command };\n 'command.acknowledged': { device: Device; command: Command };\n 'command.completed': { device: Device; command: Command; result: CommandResult };\n 'command.failed': { device: Device; command: Command; error: string };\n 'security.tamper': { device: Device; type: string; details?: unknown };\n 'security.rootDetected': { device: Device };\n 'security.screenLocked': { device: Device };\n 'security.screenUnlocked': { device: Device };\n custom: Record<string, unknown>;\n}\n\n// ============================================\n// Error Types\n// ============================================\n\nexport class MDMError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: unknown\n ) {\n super(message);\n this.name = 'MDMError';\n }\n}\n\nexport class DeviceNotFoundError extends MDMError {\n constructor(deviceId: string) {\n super(`Device not found: ${deviceId}`, 'DEVICE_NOT_FOUND', 404);\n }\n}\n\nexport class PolicyNotFoundError extends MDMError {\n constructor(policyId: string) {\n super(`Policy not found: ${policyId}`, 'POLICY_NOT_FOUND', 404);\n }\n}\n\nexport class ApplicationNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Application not found: ${identifier}`, 'APPLICATION_NOT_FOUND', 404);\n }\n}\n\nexport class EnrollmentError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'ENROLLMENT_ERROR', 400, details);\n }\n}\n\nexport class AuthenticationError extends MDMError {\n constructor(message: string = 'Authentication required') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n }\n}\n\nexport class AuthorizationError extends MDMError {\n constructor(message: string = 'Access denied') {\n super(message, 'AUTHORIZATION_ERROR', 403);\n }\n}\n\nexport class ValidationError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'VALIDATION_ERROR', 400, details);\n }\n}\n","/**\n * OpenMDM Webhook Delivery System\n *\n * Handles outbound webhook delivery with HMAC signing and retry logic.\n */\n\nimport { createHmac, randomUUID } from 'crypto';\nimport type {\n WebhookConfig,\n WebhookEndpoint,\n EventType,\n MDMEvent,\n} from './types';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface WebhookPayload<T = unknown> {\n id: string;\n event: EventType;\n timestamp: string;\n data: T;\n}\n\nexport interface WebhookManager {\n /**\n * Deliver an event to all matching webhook endpoints\n */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n\n /**\n * Add a webhook endpoint at runtime\n */\n addEndpoint(endpoint: WebhookEndpoint): void;\n\n /**\n * Remove a webhook endpoint\n */\n removeEndpoint(endpointId: string): void;\n\n /**\n * Update a webhook endpoint\n */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n\n /**\n * Get all configured endpoints\n */\n getEndpoints(): WebhookEndpoint[];\n\n /**\n * Test a webhook endpoint with a test payload\n */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\n// ============================================\n// Implementation\n// ============================================\n\nconst DEFAULT_RETRY_CONFIG = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n};\n\n/**\n * Create a webhook manager instance\n */\nexport function createWebhookManager(config: WebhookConfig): WebhookManager {\n const endpoints = new Map<string, WebhookEndpoint>();\n const retryConfig = { ...DEFAULT_RETRY_CONFIG, ...config.retry };\n\n // Initialize with configured endpoints\n if (config.endpoints) {\n for (const endpoint of config.endpoints) {\n endpoints.set(endpoint.id, endpoint);\n }\n }\n\n /**\n * Sign a webhook payload with HMAC-SHA256\n */\n function signPayload(payload: string, secret: string): string {\n return createHmac('sha256', secret).update(payload).digest('hex');\n }\n\n /**\n * Calculate exponential backoff delay\n */\n function getBackoffDelay(retryCount: number): number {\n const delay = retryConfig.initialDelay * Math.pow(2, retryCount);\n return Math.min(delay, retryConfig.maxDelay);\n }\n\n /**\n * Check if an endpoint should receive this event\n */\n function shouldDeliverToEndpoint(\n endpoint: WebhookEndpoint,\n eventType: EventType\n ): boolean {\n if (!endpoint.enabled) {\n return false;\n }\n\n // Wildcard matches all events\n if (endpoint.events.includes('*')) {\n return true;\n }\n\n return endpoint.events.includes(eventType);\n }\n\n /**\n * Deliver payload to a single endpoint with retry logic\n */\n async function deliverToEndpoint(\n endpoint: WebhookEndpoint,\n payload: WebhookPayload\n ): Promise<WebhookDeliveryResult> {\n const payloadString = JSON.stringify(payload);\n let lastError: string | undefined;\n let lastStatusCode: number | undefined;\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n // Prepare headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-OpenMDM-Event': payload.event,\n 'X-OpenMDM-Delivery': payload.id,\n 'X-OpenMDM-Timestamp': payload.timestamp,\n ...endpoint.headers,\n };\n\n // Add signature if signing secret is configured\n if (config.signingSecret) {\n const signature = signPayload(payloadString, config.signingSecret);\n headers['X-OpenMDM-Signature'] = `sha256=${signature}`;\n }\n\n // Make the request\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers,\n body: payloadString,\n signal: AbortSignal.timeout(30000), // 30 second timeout\n });\n\n lastStatusCode = response.status;\n\n // 2xx is success\n if (response.ok) {\n return {\n endpointId: endpoint.id,\n success: true,\n statusCode: response.status,\n retryCount: attempt,\n deliveredAt: new Date(),\n };\n }\n\n // 4xx errors (except 429) should not be retried\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return {\n endpointId: endpoint.id,\n success: false,\n statusCode: response.status,\n error: `HTTP ${response.status}: ${response.statusText}`,\n retryCount: attempt,\n };\n }\n\n // 5xx and 429 should be retried\n lastError = `HTTP ${response.status}: ${response.statusText}`;\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n }\n\n // Wait before retry (unless this was the last attempt)\n if (attempt < retryConfig.maxRetries) {\n const delay = getBackoffDelay(attempt);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n return {\n endpointId: endpoint.id,\n success: false,\n statusCode: lastStatusCode,\n error: lastError || 'Max retries exceeded',\n retryCount: retryConfig.maxRetries,\n };\n }\n\n return {\n async deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]> {\n const matchingEndpoints = Array.from(endpoints.values()).filter((ep) =>\n shouldDeliverToEndpoint(ep, event.type)\n );\n\n if (matchingEndpoints.length === 0) {\n return [];\n }\n\n // Prepare webhook payload\n const payload: WebhookPayload<T> = {\n id: randomUUID(),\n event: event.type,\n timestamp: new Date().toISOString(),\n data: event.payload,\n };\n\n // Deliver to all matching endpoints in parallel\n const deliveryPromises = matchingEndpoints.map((endpoint) =>\n deliverToEndpoint(endpoint, payload as WebhookPayload)\n );\n\n const results = await Promise.all(deliveryPromises);\n\n // Log failures\n for (const result of results) {\n if (!result.success) {\n console.error(\n `[OpenMDM] Webhook delivery failed to endpoint ${result.endpointId}:`,\n result.error\n );\n }\n }\n\n return results;\n },\n\n addEndpoint(endpoint: WebhookEndpoint): void {\n endpoints.set(endpoint.id, endpoint);\n },\n\n removeEndpoint(endpointId: string): void {\n endpoints.delete(endpointId);\n },\n\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void {\n const existing = endpoints.get(endpointId);\n if (existing) {\n endpoints.set(endpointId, { ...existing, ...updates });\n }\n },\n\n getEndpoints(): WebhookEndpoint[] {\n return Array.from(endpoints.values());\n },\n\n async testEndpoint(endpointId: string): Promise<WebhookDeliveryResult> {\n const endpoint = endpoints.get(endpointId);\n if (!endpoint) {\n return {\n endpointId,\n success: false,\n error: 'Endpoint not found',\n retryCount: 0,\n };\n }\n\n const testPayload: WebhookPayload = {\n id: randomUUID(),\n event: 'device.heartbeat',\n timestamp: new Date().toISOString(),\n data: {\n test: true,\n message: 'OpenMDM webhook test',\n },\n };\n\n return deliverToEndpoint(endpoint, testPayload);\n },\n };\n}\n\n/**\n * Verify a webhook signature from incoming requests\n * (Utility for consumers to verify our webhooks)\n */\nexport function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string\n): boolean {\n const expectedSignature = `sha256=${createHmac('sha256', secret)\n .update(payload)\n .digest('hex')}`;\n\n // Constant-time comparison\n if (signature.length !== expectedSignature.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < signature.length; i++) {\n result |= signature.charCodeAt(i) ^ expectedSignature.charCodeAt(i);\n }\n\n return result === 0;\n}\n","/**\n * OpenMDM Database Schema Definition\n *\n * This schema defines the structure for MDM data storage.\n * Database adapters implement this schema for their specific ORM/database.\n *\n * Tables:\n * - mdm_devices: Enrolled devices and their state\n * - mdm_policies: Device policies and configurations\n * - mdm_applications: Registered applications for deployment\n * - mdm_commands: Command queue for device operations\n * - mdm_events: Event log for device activities\n * - mdm_groups: Device grouping for bulk operations\n * - mdm_device_groups: Many-to-many device-group relationships\n * - mdm_push_tokens: FCM/MQTT push notification tokens\n * - mdm_app_deployments: App-to-policy/group deployment mappings\n * - mdm_app_versions: App version history for rollback support\n * - mdm_rollbacks: Rollback operation history and status\n * - mdm_webhook_endpoints: Outbound webhook configuration\n * - mdm_webhook_deliveries: Webhook delivery history\n */\n\n// ============================================\n// Schema Column Types\n// ============================================\n\nexport type ColumnType =\n | 'string'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'boolean'\n | 'datetime'\n | 'json'\n | 'enum';\n\nexport interface ColumnDefinition {\n type: ColumnType;\n nullable?: boolean;\n primaryKey?: boolean;\n unique?: boolean;\n default?: unknown;\n enumValues?: string[];\n references?: {\n table: string;\n column: string;\n onDelete?: 'cascade' | 'set null' | 'restrict';\n };\n}\n\nexport interface IndexDefinition {\n columns: string[];\n unique?: boolean;\n name?: string;\n}\n\nexport interface TableDefinition {\n columns: Record<string, ColumnDefinition>;\n indexes?: IndexDefinition[];\n}\n\nexport interface SchemaDefinition {\n tables: Record<string, TableDefinition>;\n}\n\n// ============================================\n// OpenMDM Schema\n// ============================================\n\nexport const mdmSchema: SchemaDefinition = {\n tables: {\n // ----------------------------------------\n // Devices Table\n // ----------------------------------------\n mdm_devices: {\n columns: {\n id: { type: 'string', primaryKey: true },\n external_id: { type: 'string', nullable: true },\n enrollment_id: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'enrolled', 'unenrolled', 'blocked'],\n default: 'pending',\n },\n\n // Device Info\n model: { type: 'string', nullable: true },\n manufacturer: { type: 'string', nullable: true },\n os_version: { type: 'string', nullable: true },\n serial_number: { type: 'string', nullable: true },\n imei: { type: 'string', nullable: true },\n mac_address: { type: 'string', nullable: true },\n android_id: { type: 'string', nullable: true },\n\n // MDM State\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n last_heartbeat: { type: 'datetime', nullable: true },\n last_sync: { type: 'datetime', nullable: true },\n\n // Telemetry (denormalized for quick access)\n battery_level: { type: 'integer', nullable: true },\n storage_used: { type: 'bigint', nullable: true },\n storage_total: { type: 'bigint', nullable: true },\n latitude: { type: 'string', nullable: true }, // Stored as string for precision\n longitude: { type: 'string', nullable: true },\n location_timestamp: { type: 'datetime', nullable: true },\n\n // JSON fields\n installed_apps: { type: 'json', nullable: true },\n tags: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n\n // Timestamps\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enrollment_id'], unique: true },\n { columns: ['status'] },\n { columns: ['policy_id'] },\n { columns: ['last_heartbeat'] },\n { columns: ['mac_address'] },\n { columns: ['serial_number'] },\n ],\n },\n\n // ----------------------------------------\n // Policies Table\n // ----------------------------------------\n mdm_policies: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n is_default: { type: 'boolean', default: false },\n settings: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['is_default'] },\n ],\n },\n\n // ----------------------------------------\n // Applications Table\n // ----------------------------------------\n mdm_applications: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true }, // SHA-256\n size: { type: 'bigint', nullable: true },\n min_sdk_version: { type: 'integer', nullable: true },\n\n // Deployment settings\n show_icon: { type: 'boolean', default: true },\n run_after_install: { type: 'boolean', default: false },\n run_at_boot: { type: 'boolean', default: false },\n is_system: { type: 'boolean', default: false },\n\n // State\n is_active: { type: 'boolean', default: true },\n\n // Metadata\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['package_name'] },\n { columns: ['package_name', 'version'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Commands Table\n // ----------------------------------------\n mdm_commands: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'sent', 'acknowledged', 'completed', 'failed', 'cancelled'],\n default: 'pending',\n },\n result: { type: 'json', nullable: true },\n error: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n sent_at: { type: 'datetime', nullable: true },\n acknowledged_at: { type: 'datetime', nullable: true },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['device_id', 'status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Events Table\n // ----------------------------------------\n mdm_events: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['type'] },\n { columns: ['device_id', 'type'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Groups Table\n // ----------------------------------------\n mdm_groups: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n parent_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_groups', column: 'id', onDelete: 'set null' },\n },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['policy_id'] },\n { columns: ['parent_id'] },\n ],\n },\n\n // ----------------------------------------\n // Device Groups (Many-to-Many)\n // ----------------------------------------\n mdm_device_groups: {\n columns: {\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n group_id: {\n type: 'string',\n references: { table: 'mdm_groups', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id', 'group_id'], unique: true },\n { columns: ['group_id'] },\n ],\n },\n\n // ----------------------------------------\n // Push Tokens (for FCM/MQTT registration)\n // ----------------------------------------\n mdm_push_tokens: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n provider: {\n type: 'enum',\n enumValues: ['fcm', 'mqtt', 'websocket'],\n },\n token: { type: 'string' },\n is_active: { type: 'boolean', default: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['provider', 'token'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Application Deployments (Which apps go to which policies/groups)\n // ----------------------------------------\n mdm_app_deployments: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n // Target can be policy or group\n target_type: {\n type: 'enum',\n enumValues: ['policy', 'group'],\n },\n target_id: { type: 'string' },\n action: {\n type: 'enum',\n enumValues: ['install', 'update', 'uninstall'],\n default: 'install',\n },\n is_required: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['target_type', 'target_id'] },\n ],\n },\n\n // ----------------------------------------\n // App Versions (Version history for rollback support)\n // ----------------------------------------\n mdm_app_versions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true },\n size: { type: 'bigint', nullable: true },\n release_notes: { type: 'text', nullable: true },\n is_minimum_version: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['package_name'] },\n { columns: ['package_name', 'version_code'], unique: true },\n { columns: ['is_minimum_version'] },\n ],\n },\n\n // ----------------------------------------\n // App Rollbacks (Rollback history and status)\n // ----------------------------------------\n mdm_rollbacks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n from_version: { type: 'string' },\n from_version_code: { type: 'integer' },\n to_version: { type: 'string' },\n to_version_code: { type: 'integer' },\n reason: { type: 'text', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'in_progress', 'completed', 'failed'],\n default: 'pending',\n },\n error: { type: 'text', nullable: true },\n initiated_by: { type: 'string', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['package_name'] },\n { columns: ['device_id', 'package_name'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Endpoints (For outbound webhook configuration storage)\n // ----------------------------------------\n mdm_webhook_endpoints: {\n columns: {\n id: { type: 'string', primaryKey: true },\n url: { type: 'string' },\n events: { type: 'json' }, // Array of event types or ['*']\n headers: { type: 'json', nullable: true },\n enabled: { type: 'boolean', default: true },\n description: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enabled'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Deliveries (Delivery history and status)\n // ----------------------------------------\n mdm_webhook_deliveries: {\n columns: {\n id: { type: 'string', primaryKey: true },\n endpoint_id: {\n type: 'string',\n references: { table: 'mdm_webhook_endpoints', column: 'id', onDelete: 'cascade' },\n },\n event_id: { type: 'string' },\n event_type: { type: 'string' },\n payload: { type: 'json' },\n status: {\n type: 'enum',\n enumValues: ['pending', 'success', 'failed'],\n default: 'pending',\n },\n status_code: { type: 'integer', nullable: true },\n error: { type: 'text', nullable: true },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n delivered_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['endpoint_id'] },\n { columns: ['event_type'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n },\n};\n\n// ============================================\n// Schema Helper Functions\n// ============================================\n\n/**\n * Get all table names from the schema\n */\nexport function getTableNames(): string[] {\n return Object.keys(mdmSchema.tables);\n}\n\n/**\n * Get column names for a table\n */\nexport function getColumnNames(tableName: string): string[] {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n return Object.keys(table.columns);\n}\n\n/**\n * Get the primary key column for a table\n */\nexport function getPrimaryKey(tableName: string): string | null {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n\n for (const [name, def] of Object.entries(table.columns)) {\n if (def.primaryKey) return name;\n }\n return null;\n}\n\n/**\n * Convert snake_case column name to camelCase\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Convert camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Transform object keys from snake_case to camelCase\n */\nexport function transformToCamelCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[snakeToCamel(key)] = value;\n }\n return result;\n}\n\n/**\n * Transform object keys from camelCase to snake_case\n */\nexport function transformToSnakeCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[camelToSnake(key)] = value;\n }\n return result;\n}\n","/**\n * OpenMDM Core\n *\n * A flexible, embeddable MDM (Mobile Device Management) SDK.\n * Inspired by better-auth's design philosophy.\n *\n * @example\n * ```typescript\n * import { createMDM } from '@openmdm/core';\n * import { drizzleAdapter } from '@openmdm/drizzle-adapter';\n *\n * const mdm = createMDM({\n * database: drizzleAdapter(db),\n * enrollment: {\n * deviceSecret: process.env.DEVICE_HMAC_SECRET!,\n * autoEnroll: true,\n * },\n * });\n *\n * // Use in your routes\n * const devices = await mdm.devices.list();\n * ```\n */\n\nimport { createHmac, timingSafeEqual, randomUUID } from 'crypto';\nimport type {\n MDMConfig,\n MDMInstance,\n Device,\n Policy,\n Application,\n Command,\n Group,\n Heartbeat,\n EnrollmentRequest,\n EnrollmentResponse,\n DeviceFilter,\n DeviceListResult,\n CreateDeviceInput,\n UpdateDeviceInput,\n CreatePolicyInput,\n UpdatePolicyInput,\n CreateApplicationInput,\n UpdateApplicationInput,\n SendCommandInput,\n CommandFilter,\n CreateGroupInput,\n UpdateGroupInput,\n DeployTarget,\n DeviceManager,\n PolicyManager,\n ApplicationManager,\n CommandManager,\n GroupManager,\n PushAdapter,\n PushResult,\n PushBatchResult,\n PushMessage,\n EventType,\n EventHandler,\n EventPayloadMap,\n MDMEvent,\n MDMPlugin,\n CommandResult,\n InstalledApp,\n WebhookManager,\n} from './types';\nimport {\n DeviceNotFoundError,\n ApplicationNotFoundError,\n EnrollmentError,\n} from './types';\nimport { createWebhookManager } from './webhooks';\n\n// Re-export all types\nexport * from './types';\nexport * from './schema';\nexport { createWebhookManager, verifyWebhookSignature } from './webhooks';\nexport type { WebhookPayload } from './webhooks';\n\n/**\n * Create an MDM instance with the given configuration.\n */\nexport function createMDM(config: MDMConfig): MDMInstance {\n const { database, push, enrollment, webhooks: webhooksConfig, plugins = [] } = config;\n\n // Event handlers registry\n const eventHandlers = new Map<EventType, Set<EventHandler<EventType>>>();\n\n // Create push adapter\n const pushAdapter: PushAdapter = push\n ? createPushAdapter(push, database)\n : createStubPushAdapter();\n\n // Create webhook manager if configured\n const webhookManager: WebhookManager | undefined = webhooksConfig\n ? createWebhookManager(webhooksConfig)\n : undefined;\n\n // Event subscription\n const on = <T extends EventType>(\n event: T,\n handler: EventHandler<T>\n ): (() => void) => {\n if (!eventHandlers.has(event)) {\n eventHandlers.set(event, new Set());\n }\n const handlers = eventHandlers.get(event)!;\n handlers.add(handler as EventHandler<EventType>);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler as EventHandler<EventType>);\n };\n };\n\n // Event emission\n const emit = async <T extends EventType>(\n event: T,\n data: EventPayloadMap[T]\n ): Promise<void> => {\n const handlers = eventHandlers.get(event);\n\n // Create event record\n const eventRecord: MDMEvent<EventPayloadMap[T]> = {\n id: randomUUID(),\n deviceId: (data as any).device?.id || (data as any).deviceId || '',\n type: event,\n payload: data,\n createdAt: new Date(),\n };\n\n // Persist event\n try {\n await database.createEvent({\n deviceId: eventRecord.deviceId,\n type: eventRecord.type,\n payload: eventRecord.payload as Record<string, unknown>,\n });\n } catch (error) {\n console.error('[OpenMDM] Failed to persist event:', error);\n }\n\n // Deliver webhooks (async, don't wait)\n if (webhookManager) {\n webhookManager.deliver(eventRecord).catch((error) => {\n console.error('[OpenMDM] Webhook delivery error:', error);\n });\n }\n\n // Call handlers\n if (handlers) {\n for (const handler of handlers) {\n try {\n await handler(eventRecord);\n } catch (error) {\n console.error(`[OpenMDM] Event handler error for ${event}:`, error);\n }\n }\n }\n\n // Call config hook if defined\n if (config.onEvent) {\n try {\n await config.onEvent(eventRecord);\n } catch (error) {\n console.error('[OpenMDM] onEvent hook error:', error);\n }\n }\n };\n\n // ============================================\n // Device Manager\n // ============================================\n\n const devices: DeviceManager = {\n async get(id: string): Promise<Device | null> {\n return database.findDevice(id);\n },\n\n async getByEnrollmentId(enrollmentId: string): Promise<Device | null> {\n return database.findDeviceByEnrollmentId(enrollmentId);\n },\n\n async list(filter?: DeviceFilter): Promise<DeviceListResult> {\n return database.listDevices(filter);\n },\n\n async create(data: CreateDeviceInput): Promise<Device> {\n const device = await database.createDevice(data);\n\n await emit('device.enrolled', { device });\n\n if (config.onDeviceEnrolled) {\n await config.onDeviceEnrolled(device);\n }\n\n return device;\n },\n\n async update(id: string, data: UpdateDeviceInput): Promise<Device> {\n const oldDevice = await database.findDevice(id);\n if (!oldDevice) {\n throw new DeviceNotFoundError(id);\n }\n\n const device = await database.updateDevice(id, data);\n\n // Emit status change event if status changed\n if (data.status && data.status !== oldDevice.status) {\n await emit('device.statusChanged', {\n device,\n oldStatus: oldDevice.status,\n newStatus: data.status,\n });\n }\n\n // Emit policy change event if policy changed\n if (data.policyId !== undefined && data.policyId !== oldDevice.policyId) {\n await emit('device.policyChanged', {\n device,\n oldPolicyId: oldDevice.policyId || undefined,\n newPolicyId: data.policyId || undefined,\n });\n }\n\n return device;\n },\n\n async delete(id: string): Promise<void> {\n const device = await database.findDevice(id);\n if (device) {\n await database.deleteDevice(id);\n await emit('device.unenrolled', { device });\n\n if (config.onDeviceUnenrolled) {\n await config.onDeviceUnenrolled(device);\n }\n }\n },\n\n async assignPolicy(\n deviceId: string,\n policyId: string | null\n ): Promise<Device> {\n const device = await this.update(deviceId, { policyId });\n\n // Notify device of policy change\n await pushAdapter.send(deviceId, {\n type: 'policy.updated',\n payload: { policyId },\n priority: 'high',\n });\n\n return device;\n },\n\n async addToGroup(deviceId: string, groupId: string): Promise<void> {\n await database.addDeviceToGroup(deviceId, groupId);\n },\n\n async removeFromGroup(deviceId: string, groupId: string): Promise<void> {\n await database.removeDeviceFromGroup(deviceId, groupId);\n },\n\n async getGroups(deviceId: string): Promise<Group[]> {\n return database.getDeviceGroups(deviceId);\n },\n\n async sendCommand(\n deviceId: string,\n input: Omit<SendCommandInput, 'deviceId'>\n ): Promise<Command> {\n const command = await database.createCommand({\n ...input,\n deviceId,\n });\n\n // Send via push\n const pushResult = await pushAdapter.send(deviceId, {\n type: `command.${input.type}`,\n payload: {\n commandId: command.id,\n type: input.type,\n ...input.payload,\n },\n priority: 'high',\n });\n\n // Update command status\n if (pushResult.success) {\n await database.updateCommand(command.id, {\n status: 'sent',\n sentAt: new Date(),\n });\n }\n\n if (config.onCommand) {\n await config.onCommand(command);\n }\n\n return database.findCommand(command.id) as Promise<Command>;\n },\n\n async sync(deviceId: string): Promise<Command> {\n return this.sendCommand(deviceId, { type: 'sync' });\n },\n\n async reboot(deviceId: string): Promise<Command> {\n return this.sendCommand(deviceId, { type: 'reboot' });\n },\n\n async lock(deviceId: string, message?: string): Promise<Command> {\n return this.sendCommand(deviceId, {\n type: 'lock',\n payload: message ? { message } : undefined,\n });\n },\n\n async wipe(deviceId: string, preserveData?: boolean): Promise<Command> {\n return this.sendCommand(deviceId, {\n type: preserveData ? 'wipe' : 'factoryReset',\n payload: { preserveData },\n });\n },\n };\n\n // ============================================\n // Policy Manager\n // ============================================\n\n const policies: PolicyManager = {\n async get(id: string): Promise<Policy | null> {\n return database.findPolicy(id);\n },\n\n async getDefault(): Promise<Policy | null> {\n return database.findDefaultPolicy();\n },\n\n async list(): Promise<Policy[]> {\n return database.listPolicies();\n },\n\n async create(data: CreatePolicyInput): Promise<Policy> {\n // If this is being set as default, clear other defaults first\n if (data.isDefault) {\n const existingPolicies = await database.listPolicies();\n for (const policy of existingPolicies) {\n if (policy.isDefault) {\n await database.updatePolicy(policy.id, { isDefault: false });\n }\n }\n }\n\n return database.createPolicy(data);\n },\n\n async update(id: string, data: UpdatePolicyInput): Promise<Policy> {\n // If setting as default, clear other defaults first\n if (data.isDefault) {\n const existingPolicies = await database.listPolicies();\n for (const policy of existingPolicies) {\n if (policy.isDefault && policy.id !== id) {\n await database.updatePolicy(policy.id, { isDefault: false });\n }\n }\n }\n\n const policy = await database.updatePolicy(id, data);\n\n // Notify all devices with this policy\n const devicesResult = await database.listDevices({ policyId: id });\n if (devicesResult.devices.length > 0) {\n const deviceIds = devicesResult.devices.map((d) => d.id);\n await pushAdapter.sendBatch(deviceIds, {\n type: 'policy.updated',\n payload: { policyId: id },\n priority: 'high',\n });\n }\n\n return policy;\n },\n\n async delete(id: string): Promise<void> {\n // Check if any devices use this policy\n const devicesResult = await database.listDevices({ policyId: id });\n if (devicesResult.devices.length > 0) {\n // Remove policy from devices first\n for (const device of devicesResult.devices) {\n await database.updateDevice(device.id, { policyId: null });\n }\n }\n\n await database.deletePolicy(id);\n },\n\n async setDefault(id: string): Promise<Policy> {\n return this.update(id, { isDefault: true });\n },\n\n async getDevices(policyId: string): Promise<Device[]> {\n const result = await database.listDevices({ policyId });\n return result.devices;\n },\n\n async applyToDevice(policyId: string, deviceId: string): Promise<void> {\n await devices.assignPolicy(deviceId, policyId);\n },\n };\n\n // ============================================\n // Application Manager\n // ============================================\n\n const apps: ApplicationManager = {\n async get(id: string): Promise<Application | null> {\n return database.findApplication(id);\n },\n\n async getByPackage(\n packageName: string,\n version?: string\n ): Promise<Application | null> {\n return database.findApplicationByPackage(packageName, version);\n },\n\n async list(activeOnly?: boolean): Promise<Application[]> {\n return database.listApplications(activeOnly);\n },\n\n async register(data: CreateApplicationInput): Promise<Application> {\n return database.createApplication(data);\n },\n\n async update(id: string, data: UpdateApplicationInput): Promise<Application> {\n return database.updateApplication(id, data);\n },\n\n async delete(id: string): Promise<void> {\n await database.deleteApplication(id);\n },\n\n async activate(id: string): Promise<Application> {\n return database.updateApplication(id, { isActive: true });\n },\n\n async deactivate(id: string): Promise<Application> {\n return database.updateApplication(id, { isActive: false });\n },\n\n async deploy(packageName: string, target: DeployTarget): Promise<void> {\n const app = await database.findApplicationByPackage(packageName);\n if (!app) {\n throw new ApplicationNotFoundError(packageName);\n }\n\n const deviceIds: string[] = [];\n\n // Collect target devices\n if (target.devices) {\n deviceIds.push(...target.devices);\n }\n\n if (target.groups) {\n for (const groupId of target.groups) {\n const groupDevices = await database.listDevicesInGroup(groupId);\n deviceIds.push(...groupDevices.map((d) => d.id));\n }\n }\n\n if (target.policies) {\n for (const policyId of target.policies) {\n const result = await database.listDevices({ policyId });\n deviceIds.push(...result.devices.map((d) => d.id));\n }\n }\n\n // Deduplicate\n const uniqueDeviceIds = [...new Set(deviceIds)];\n\n // Send install command to all devices\n if (uniqueDeviceIds.length > 0) {\n await pushAdapter.sendBatch(uniqueDeviceIds, {\n type: 'command.installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n versionCode: app.versionCode,\n url: app.url,\n hash: app.hash,\n },\n priority: 'high',\n });\n\n // Create command records for each device\n for (const deviceId of uniqueDeviceIds) {\n await database.createCommand({\n deviceId,\n type: 'installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n url: app.url,\n },\n });\n }\n }\n },\n\n async installOnDevice(\n packageName: string,\n deviceId: string,\n version?: string\n ): Promise<Command> {\n const app = await database.findApplicationByPackage(packageName, version);\n if (!app) {\n throw new ApplicationNotFoundError(packageName);\n }\n\n return devices.sendCommand(deviceId, {\n type: 'installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n versionCode: app.versionCode,\n url: app.url,\n hash: app.hash,\n },\n });\n },\n\n async uninstallFromDevice(\n packageName: string,\n deviceId: string\n ): Promise<Command> {\n return devices.sendCommand(deviceId, {\n type: 'uninstallApp',\n payload: { packageName },\n });\n },\n };\n\n // ============================================\n // Command Manager\n // ============================================\n\n const commands: CommandManager = {\n async get(id: string): Promise<Command | null> {\n return database.findCommand(id);\n },\n\n async list(filter?: CommandFilter): Promise<Command[]> {\n return database.listCommands(filter);\n },\n\n async send(input: SendCommandInput): Promise<Command> {\n return devices.sendCommand(input.deviceId, {\n type: input.type,\n payload: input.payload,\n });\n },\n\n async cancel(id: string): Promise<Command> {\n return database.updateCommand(id, { status: 'cancelled' });\n },\n\n async acknowledge(id: string): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'acknowledged',\n acknowledgedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.acknowledged', { device, command });\n }\n\n return command;\n },\n\n async complete(id: string, result: CommandResult): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'completed',\n result,\n completedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.completed', { device, command, result });\n }\n\n return command;\n },\n\n async fail(id: string, error: string): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'failed',\n error,\n completedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.failed', { device, command, error });\n }\n\n return command;\n },\n\n async getPending(deviceId: string): Promise<Command[]> {\n return database.getPendingCommands(deviceId);\n },\n };\n\n // ============================================\n // Group Manager\n // ============================================\n\n const groups: GroupManager = {\n async get(id: string): Promise<Group | null> {\n return database.findGroup(id);\n },\n\n async list(): Promise<Group[]> {\n return database.listGroups();\n },\n\n async create(data: CreateGroupInput): Promise<Group> {\n return database.createGroup(data);\n },\n\n async update(id: string, data: UpdateGroupInput): Promise<Group> {\n return database.updateGroup(id, data);\n },\n\n async delete(id: string): Promise<void> {\n await database.deleteGroup(id);\n },\n\n async getDevices(groupId: string): Promise<Device[]> {\n return database.listDevicesInGroup(groupId);\n },\n\n async addDevice(groupId: string, deviceId: string): Promise<void> {\n await database.addDeviceToGroup(deviceId, groupId);\n },\n\n async removeDevice(groupId: string, deviceId: string): Promise<void> {\n await database.removeDeviceFromGroup(deviceId, groupId);\n },\n\n async getChildren(groupId: string): Promise<Group[]> {\n const allGroups = await database.listGroups();\n return allGroups.filter((g) => g.parentId === groupId);\n },\n };\n\n // ============================================\n // Enrollment\n // ============================================\n\n const enroll = async (\n request: EnrollmentRequest\n ): Promise<EnrollmentResponse> => {\n // Validate method if restricted\n if (\n enrollment?.allowedMethods &&\n !enrollment.allowedMethods.includes(request.method)\n ) {\n throw new EnrollmentError(\n `Enrollment method '${request.method}' is not allowed`\n );\n }\n\n // Verify signature if secret is configured\n if (enrollment?.deviceSecret) {\n const isValid = verifyEnrollmentSignature(\n request,\n enrollment.deviceSecret\n );\n if (!isValid) {\n throw new EnrollmentError('Invalid enrollment signature');\n }\n }\n\n // Custom validation\n if (enrollment?.validate) {\n const isValid = await enrollment.validate(request);\n if (!isValid) {\n throw new EnrollmentError('Enrollment validation failed');\n }\n }\n\n // Determine enrollment ID\n const enrollmentId =\n request.macAddress ||\n request.serialNumber ||\n request.imei ||\n request.androidId;\n\n if (!enrollmentId) {\n throw new EnrollmentError(\n 'Device must provide at least one identifier (macAddress, serialNumber, imei, or androidId)'\n );\n }\n\n // Check if device already exists\n let device = await database.findDeviceByEnrollmentId(enrollmentId);\n\n if (device) {\n // Device re-enrolling\n device = await database.updateDevice(device.id, {\n status: 'enrolled',\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n lastSync: new Date(),\n });\n } else if (enrollment?.autoEnroll) {\n // Auto-create device\n device = await database.createDevice({\n enrollmentId,\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n serialNumber: request.serialNumber,\n imei: request.imei,\n macAddress: request.macAddress,\n androidId: request.androidId,\n policyId: request.policyId || enrollment.defaultPolicyId,\n });\n\n // Add to default group if configured\n if (enrollment.defaultGroupId) {\n await database.addDeviceToGroup(device.id, enrollment.defaultGroupId);\n }\n } else if (enrollment?.requireApproval) {\n // Create pending device\n device = await database.createDevice({\n enrollmentId,\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n serialNumber: request.serialNumber,\n imei: request.imei,\n macAddress: request.macAddress,\n androidId: request.androidId,\n });\n // Status remains 'pending'\n } else {\n throw new EnrollmentError(\n 'Device not registered and auto-enroll is disabled'\n );\n }\n\n // Get policy\n let policy: Policy | null = null;\n if (device.policyId) {\n policy = await database.findPolicy(device.policyId);\n }\n if (!policy) {\n policy = await database.findDefaultPolicy();\n }\n\n // Generate JWT token for device auth\n const tokenSecret =\n config.auth?.deviceTokenSecret || enrollment?.deviceSecret || '';\n const tokenExpiration = config.auth?.deviceTokenExpiration || 365 * 24 * 60 * 60;\n const token = generateDeviceToken(device.id, tokenSecret, tokenExpiration);\n\n // Emit enrollment event\n await emit('device.enrolled', { device });\n\n // Call config hook if defined\n if (config.onDeviceEnrolled) {\n await config.onDeviceEnrolled(device);\n }\n\n // Call plugin hooks\n for (const plugin of plugins) {\n if (plugin.onEnroll) {\n await plugin.onEnroll(device, request);\n }\n if (plugin.onDeviceEnrolled) {\n await plugin.onDeviceEnrolled(device);\n }\n }\n\n return {\n deviceId: device.id,\n enrollmentId: device.enrollmentId,\n policyId: policy?.id,\n policy: policy || undefined,\n serverUrl: config.serverUrl || '',\n pushConfig: {\n provider: push?.provider || 'polling',\n fcmSenderId: (push?.fcmCredentials as any)?.project_id,\n mqttUrl: push?.mqttUrl,\n mqttTopic: push?.mqttTopicPrefix\n ? `${push.mqttTopicPrefix}/${device.id}`\n : `openmdm/devices/${device.id}`,\n pollingInterval: push?.pollingInterval || 60,\n },\n token,\n tokenExpiresAt: new Date(Date.now() + tokenExpiration * 1000),\n };\n };\n\n // ============================================\n // Heartbeat Processing\n // ============================================\n\n const processHeartbeat = async (\n deviceId: string,\n heartbeat: Heartbeat\n ): Promise<void> => {\n const device = await database.findDevice(deviceId);\n if (!device) {\n throw new DeviceNotFoundError(deviceId);\n }\n\n // Update device with heartbeat data\n const updateData: UpdateDeviceInput = {\n lastHeartbeat: heartbeat.timestamp,\n batteryLevel: heartbeat.batteryLevel,\n storageUsed: heartbeat.storageUsed,\n storageTotal: heartbeat.storageTotal,\n installedApps: heartbeat.installedApps,\n };\n\n if (heartbeat.location) {\n updateData.location = heartbeat.location;\n }\n\n const updatedDevice = await database.updateDevice(deviceId, updateData);\n\n // Emit heartbeat event\n await emit('device.heartbeat', { device: updatedDevice, heartbeat });\n\n // Emit location event if location changed\n if (heartbeat.location) {\n await emit('device.locationUpdated', {\n device: updatedDevice,\n location: heartbeat.location,\n });\n }\n\n // Check for app changes\n if (device.installedApps && heartbeat.installedApps) {\n const oldApps = new Map(\n device.installedApps.map((a) => [a.packageName, a])\n );\n const newApps = new Map(\n heartbeat.installedApps.map((a) => [a.packageName, a])\n );\n\n // Check for new installs\n for (const [pkg, app] of newApps) {\n const oldApp = oldApps.get(pkg);\n if (!oldApp) {\n await emit('app.installed', { device: updatedDevice, app });\n } else if (oldApp.version !== app.version) {\n await emit('app.updated', {\n device: updatedDevice,\n app,\n oldVersion: oldApp.version,\n });\n }\n }\n\n // Check for uninstalls\n for (const [pkg] of oldApps) {\n if (!newApps.has(pkg)) {\n await emit('app.uninstalled', {\n device: updatedDevice,\n packageName: pkg,\n });\n }\n }\n }\n\n // Call config hook if defined\n if (config.onHeartbeat) {\n await config.onHeartbeat(updatedDevice, heartbeat);\n }\n\n // Call plugin hooks\n for (const plugin of plugins) {\n if (plugin.onHeartbeat) {\n await plugin.onHeartbeat(updatedDevice, heartbeat);\n }\n }\n };\n\n // ============================================\n // Token Verification\n // ============================================\n\n const verifyDeviceToken = async (\n token: string\n ): Promise<{ deviceId: string } | null> => {\n try {\n const tokenSecret =\n config.auth?.deviceTokenSecret || enrollment?.deviceSecret || '';\n\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const [header, payload, signature] = parts;\n\n // Verify signature\n const expectedSignature = createHmac('sha256', tokenSecret)\n .update(`${header}.${payload}`)\n .digest('base64url');\n\n if (signature !== expectedSignature) {\n return null;\n }\n\n // Decode payload\n const decoded = JSON.parse(\n Buffer.from(payload, 'base64url').toString('utf-8')\n );\n\n // Check expiration\n if (decoded.exp && decoded.exp < Math.floor(Date.now() / 1000)) {\n return null;\n }\n\n return { deviceId: decoded.sub };\n } catch {\n return null;\n }\n };\n\n // ============================================\n // Plugin Management\n // ============================================\n\n const getPlugins = (): MDMPlugin[] => plugins;\n\n const getPlugin = (name: string): MDMPlugin | undefined => {\n return plugins.find((p) => p.name === name);\n };\n\n // ============================================\n // Create Instance\n // ============================================\n\n const instance: MDMInstance = {\n devices,\n policies,\n apps,\n commands,\n groups,\n push: pushAdapter,\n webhooks: webhookManager,\n db: database,\n config,\n on,\n emit,\n enroll,\n processHeartbeat,\n verifyDeviceToken,\n getPlugins,\n getPlugin,\n };\n\n // Initialize plugins\n (async () => {\n for (const plugin of plugins) {\n if (plugin.onInit) {\n try {\n await plugin.onInit(instance);\n console.log(`[OpenMDM] Plugin initialized: ${plugin.name}`);\n } catch (error) {\n console.error(\n `[OpenMDM] Failed to initialize plugin ${plugin.name}:`,\n error\n );\n }\n }\n }\n })();\n\n return instance;\n}\n\n// ============================================\n// Push Adapter Factory\n// ============================================\n\nfunction createPushAdapter(\n config: MDMConfig['push'],\n database: MDMConfig['database']\n): PushAdapter {\n if (!config) {\n return createStubPushAdapter();\n }\n\n // The actual implementations will be provided by separate packages\n // This is a base implementation that logs and stores tokens\n return {\n async send(deviceId: string, message: PushMessage): Promise<PushResult> {\n console.log(\n `[OpenMDM] Push to ${deviceId}: ${message.type}`,\n message.payload\n );\n\n // In production, this would be replaced by FCM/MQTT adapter\n return { success: true, messageId: randomUUID() };\n },\n\n async sendBatch(\n deviceIds: string[],\n message: PushMessage\n ): Promise<PushBatchResult> {\n console.log(\n `[OpenMDM] Push to ${deviceIds.length} devices: ${message.type}`\n );\n\n const results = deviceIds.map((deviceId) => ({\n deviceId,\n result: { success: true, messageId: randomUUID() },\n }));\n\n return {\n successCount: deviceIds.length,\n failureCount: 0,\n results,\n };\n },\n\n async registerToken(deviceId: string, token: string): Promise<void> {\n // Polling doesn't use push tokens\n if (config.provider === 'polling') {\n return;\n }\n await database.upsertPushToken({\n deviceId,\n provider: config.provider,\n token,\n });\n },\n\n async unregisterToken(deviceId: string): Promise<void> {\n // Polling doesn't use push tokens\n if (config.provider === 'polling') {\n return;\n }\n await database.deletePushToken(deviceId, config.provider);\n },\n };\n}\n\nfunction createStubPushAdapter(): PushAdapter {\n return {\n async send(deviceId: string, message: PushMessage): Promise<PushResult> {\n console.log(`[OpenMDM] Push (stub): ${deviceId} <- ${message.type}`);\n return { success: true, messageId: 'stub' };\n },\n\n async sendBatch(\n deviceIds: string[],\n message: PushMessage\n ): Promise<PushBatchResult> {\n console.log(\n `[OpenMDM] Push (stub): ${deviceIds.length} devices <- ${message.type}`\n );\n return {\n successCount: deviceIds.length,\n failureCount: 0,\n results: deviceIds.map((deviceId) => ({\n deviceId,\n result: { success: true, messageId: 'stub' },\n })),\n };\n },\n };\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\nfunction verifyEnrollmentSignature(\n request: EnrollmentRequest,\n secret: string\n): boolean {\n const { signature, ...data } = request;\n\n if (!signature) {\n return false;\n }\n\n // Reconstruct the message that was signed\n // Format: identifier:timestamp\n const identifier =\n data.macAddress || data.serialNumber || data.imei || data.androidId || '';\n const message = `${identifier}:${data.timestamp}`;\n\n const expectedSignature = createHmac('sha256', secret)\n .update(message)\n .digest('hex');\n\n try {\n return timingSafeEqual(\n Buffer.from(signature, 'hex'),\n Buffer.from(expectedSignature, 'hex')\n );\n } catch {\n return false;\n }\n}\n\nfunction generateDeviceToken(\n deviceId: string,\n secret: string,\n expirationSeconds: number\n): string {\n const header = Buffer.from(\n JSON.stringify({ alg: 'HS256', typ: 'JWT' })\n ).toString('base64url');\n\n const now = Math.floor(Date.now() / 1000);\n const payload = Buffer.from(\n JSON.stringify({\n sub: deviceId,\n iat: now,\n exp: now + expirationSeconds,\n iss: 'openmdm',\n })\n ).toString('base64url');\n\n const signature = createHmac('sha256', secret)\n .update(`${header}.${payload}`)\n .digest('base64url');\n\n return `${header}.${payload}.${signature}`;\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/webhooks.ts","../src/tenant.ts","../src/authorization.ts","../src/audit.ts","../src/schedule.ts","../src/queue.ts","../src/dashboard.ts","../src/plugin-storage.ts","../src/schema.ts","../src/index.ts"],"names":["randomUUID","policy","devices","createHmac"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * OpenMDM Core Types\n *\n * These types define the core data structures for the MDM system.\n * Designed to be database-agnostic and framework-agnostic.\n */\n\n// ============================================\n// Device Types\n// ============================================\n\nexport type DeviceStatus = 'pending' | 'enrolled' | 'unenrolled' | 'blocked';\n\nexport interface Device {\n id: string;\n externalId?: string | null;\n enrollmentId: string;\n status: DeviceStatus;\n\n // Device Info\n model?: string | null;\n manufacturer?: string | null;\n osVersion?: string | null;\n serialNumber?: string | null;\n imei?: string | null;\n macAddress?: string | null;\n androidId?: string | null;\n\n // MDM State\n policyId?: string | null;\n lastHeartbeat?: Date | null;\n lastSync?: Date | null;\n\n // Telemetry\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n location?: DeviceLocation | null;\n installedApps?: InstalledApp[] | null;\n\n // Metadata\n tags?: Record<string, string> | null;\n metadata?: Record<string, unknown> | null;\n\n // Timestamps\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DeviceLocation {\n latitude: number;\n longitude: number;\n accuracy?: number;\n timestamp: Date;\n}\n\nexport interface InstalledApp {\n packageName: string;\n version: string;\n versionCode?: number;\n installedAt?: Date;\n}\n\nexport interface CreateDeviceInput {\n enrollmentId: string;\n externalId?: string;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n serialNumber?: string;\n imei?: string;\n macAddress?: string;\n androidId?: string;\n policyId?: string;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateDeviceInput {\n externalId?: string | null;\n status?: DeviceStatus;\n policyId?: string | null;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n lastHeartbeat?: Date;\n lastSync?: Date;\n installedApps?: InstalledApp[];\n location?: DeviceLocation;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DeviceFilter {\n status?: DeviceStatus | DeviceStatus[];\n policyId?: string;\n groupId?: string;\n search?: string;\n tags?: Record<string, string>;\n limit?: number;\n offset?: number;\n}\n\nexport interface DeviceListResult {\n devices: Device[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Policy Types\n// ============================================\n\nexport interface Policy {\n id: string;\n name: string;\n description?: string | null;\n isDefault: boolean;\n settings: PolicySettings;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface PolicySettings {\n // Kiosk Mode\n kioskMode?: boolean;\n mainApp?: string;\n allowedApps?: string[];\n kioskExitPassword?: string;\n\n // Lock Features\n lockStatusBar?: boolean;\n lockNavigationBar?: boolean;\n lockSettings?: boolean;\n lockPowerButton?: boolean;\n blockInstall?: boolean;\n blockUninstall?: boolean;\n\n // Hardware Controls\n bluetooth?: HardwareControl;\n wifi?: HardwareControl;\n gps?: HardwareControl;\n mobileData?: HardwareControl;\n camera?: HardwareControl;\n microphone?: HardwareControl;\n usb?: HardwareControl;\n nfc?: HardwareControl;\n\n // Update Settings\n systemUpdatePolicy?: SystemUpdatePolicy;\n updateWindow?: TimeWindow;\n\n // Security\n passwordPolicy?: PasswordPolicy;\n encryptionRequired?: boolean;\n factoryResetProtection?: boolean;\n safeBootDisabled?: boolean;\n\n // Telemetry\n heartbeatInterval?: number;\n locationReportInterval?: number;\n locationEnabled?: boolean;\n\n // Network\n wifiConfigs?: WifiConfig[];\n vpnConfig?: VpnConfig;\n\n // Applications\n applications?: PolicyApplication[];\n\n // Custom settings (for plugins)\n custom?: Record<string, unknown>;\n}\n\nexport type HardwareControl = 'on' | 'off' | 'user';\nexport type SystemUpdatePolicy = 'auto' | 'windowed' | 'postpone' | 'manual';\n\nexport interface TimeWindow {\n start: string; // \"HH:MM\"\n end: string; // \"HH:MM\"\n}\n\nexport interface PasswordPolicy {\n required: boolean;\n minLength?: number;\n complexity?: 'none' | 'numeric' | 'alphanumeric' | 'complex';\n maxFailedAttempts?: number;\n expirationDays?: number;\n historyLength?: number;\n}\n\nexport interface WifiConfig {\n ssid: string;\n securityType: 'none' | 'wep' | 'wpa' | 'wpa2' | 'wpa3';\n password?: string;\n hidden?: boolean;\n autoConnect?: boolean;\n}\n\nexport interface VpnConfig {\n type: 'pptp' | 'l2tp' | 'ipsec' | 'openvpn' | 'wireguard';\n server: string;\n username?: string;\n password?: string;\n certificate?: string;\n config?: Record<string, unknown>;\n}\n\nexport interface PolicyApplication {\n packageName: string;\n action: 'install' | 'update' | 'uninstall';\n version?: string;\n required?: boolean;\n autoUpdate?: boolean;\n}\n\nexport interface CreatePolicyInput {\n name: string;\n description?: string;\n isDefault?: boolean;\n settings: PolicySettings;\n}\n\nexport interface UpdatePolicyInput {\n name?: string;\n description?: string | null;\n isDefault?: boolean;\n settings?: PolicySettings;\n}\n\n// ============================================\n// Application Types\n// ============================================\n\nexport interface Application {\n id: string;\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n\n // Deployment settings\n showIcon: boolean;\n runAfterInstall: boolean;\n runAtBoot: boolean;\n isSystem: boolean;\n\n // State\n isActive: boolean;\n\n // Metadata\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateApplicationInput {\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string;\n size?: number;\n minSdkVersion?: number;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isSystem?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateApplicationInput {\n name?: string;\n version?: string;\n versionCode?: number;\n url?: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isActive?: boolean;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface DeployTarget {\n devices?: string[];\n policies?: string[];\n groups?: string[];\n}\n\n// ============================================\n// App Version & Rollback Types\n// ============================================\n\nexport interface AppVersion {\n id: string;\n applicationId: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n releaseNotes?: string | null;\n isMinimumVersion: boolean;\n createdAt: Date;\n}\n\nexport interface AppRollback {\n id: string;\n deviceId: string;\n packageName: string;\n fromVersion: string;\n fromVersionCode: number;\n toVersion: string;\n toVersionCode: number;\n reason?: string | null;\n status: 'pending' | 'in_progress' | 'completed' | 'failed';\n error?: string | null;\n initiatedBy?: string | null;\n createdAt: Date;\n completedAt?: Date | null;\n}\n\nexport interface CreateAppRollbackInput {\n deviceId: string;\n packageName: string;\n toVersionCode: number;\n reason?: string;\n initiatedBy?: string;\n}\n\n// ============================================\n// Command Types\n// ============================================\n\nexport type CommandType =\n | 'reboot'\n | 'shutdown'\n | 'sync'\n | 'lock'\n | 'unlock'\n | 'wipe'\n | 'factoryReset'\n | 'installApp'\n | 'uninstallApp'\n | 'updateApp'\n | 'runApp'\n | 'clearAppData'\n | 'clearAppCache'\n | 'shell'\n | 'setPolicy'\n | 'grantPermissions'\n | 'exitKiosk'\n | 'enterKiosk'\n | 'setWifi'\n | 'screenshot'\n | 'getLocation'\n | 'setVolume'\n | 'sendNotification'\n | 'whitelistBattery' // Whitelist app from battery optimization (Doze)\n | 'enablePermissiveMode' // Enable permissive mode for debugging\n | 'setTimeZone' // Set device timezone\n | 'enableAdb' // Enable/disable ADB debugging\n | 'rollbackApp' // Rollback to previous app version\n | 'custom';\n\nexport type CommandStatus =\n | 'pending'\n | 'sent'\n | 'acknowledged'\n | 'completed'\n | 'failed'\n | 'cancelled';\n\nexport interface Command {\n id: string;\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown> | null;\n status: CommandStatus;\n result?: CommandResult | null;\n error?: string | null;\n createdAt: Date;\n sentAt?: Date | null;\n acknowledgedAt?: Date | null;\n completedAt?: Date | null;\n}\n\nexport interface CommandResult {\n success: boolean;\n message?: string;\n data?: unknown;\n}\n\nexport interface SendCommandInput {\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown>;\n}\n\nexport interface CommandFilter {\n deviceId?: string;\n status?: CommandStatus | CommandStatus[];\n type?: CommandType | CommandType[];\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Event Types\n// ============================================\n\nexport type EventType =\n | 'device.enrolled'\n | 'device.unenrolled'\n | 'device.blocked'\n | 'device.heartbeat'\n | 'device.locationUpdated'\n | 'device.statusChanged'\n | 'device.policyChanged'\n | 'app.installed'\n | 'app.uninstalled'\n | 'app.updated'\n | 'app.crashed'\n | 'app.started'\n | 'app.stopped'\n | 'policy.applied'\n | 'policy.failed'\n | 'command.received'\n | 'command.acknowledged'\n | 'command.completed'\n | 'command.failed'\n | 'security.tamper'\n | 'security.rootDetected'\n | 'security.screenLocked'\n | 'security.screenUnlocked'\n | 'custom';\n\nexport interface MDMEvent<T = unknown> {\n id: string;\n deviceId: string;\n type: EventType;\n payload: T;\n createdAt: Date;\n}\n\nexport interface EventFilter {\n deviceId?: string;\n type?: EventType | EventType[];\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Group Types\n// ============================================\n\nexport interface Group {\n id: string;\n name: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateGroupInput {\n name: string;\n description?: string;\n policyId?: string;\n parentId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateGroupInput {\n name?: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Enrollment Types\n// ============================================\n\nexport type EnrollmentMethod =\n | 'qr'\n | 'nfc'\n | 'zero-touch'\n | 'knox'\n | 'manual'\n | 'app-only'\n | 'adb';\n\nexport interface EnrollmentRequest {\n // Device identifiers (at least one required)\n macAddress?: string;\n serialNumber?: string;\n imei?: string;\n androidId?: string;\n\n // Device info\n model: string;\n manufacturer: string;\n osVersion: string;\n sdkVersion?: number;\n\n // Agent info\n agentVersion?: string;\n agentPackage?: string;\n\n // Enrollment details\n method: EnrollmentMethod;\n timestamp: string;\n signature: string;\n\n // Optional pre-assigned policy/group\n policyId?: string;\n groupId?: string;\n}\n\nexport interface EnrollmentResponse {\n deviceId: string;\n enrollmentId: string;\n policyId?: string;\n policy?: Policy;\n serverUrl: string;\n pushConfig: PushConfig;\n token: string;\n refreshToken?: string;\n tokenExpiresAt?: Date;\n}\n\nexport interface PushConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n fcmSenderId?: string;\n mqttUrl?: string;\n mqttTopic?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n wsUrl?: string;\n pollingInterval?: number;\n}\n\n// ============================================\n// Telemetry Types\n// ============================================\n\nexport interface Heartbeat {\n deviceId: string;\n timestamp: Date;\n\n // Battery\n batteryLevel: number;\n isCharging: boolean;\n batteryHealth?: 'good' | 'overheat' | 'dead' | 'cold' | 'unknown';\n\n // Storage\n storageUsed: number;\n storageTotal: number;\n\n // Memory\n memoryUsed: number;\n memoryTotal: number;\n\n // Network\n networkType?: 'wifi' | 'cellular' | 'ethernet' | 'none';\n networkName?: string; // SSID or carrier\n signalStrength?: number;\n ipAddress?: string;\n\n // Location\n location?: DeviceLocation;\n\n // Apps\n installedApps: InstalledApp[];\n runningApps?: string[];\n\n // Security\n isRooted?: boolean;\n isEncrypted?: boolean;\n screenLockEnabled?: boolean;\n\n // Agent status\n agentVersion?: string;\n policyVersion?: string;\n lastPolicySync?: Date;\n}\n\n// ============================================\n// Push Token Types\n// ============================================\n\nexport interface PushToken {\n id: string;\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n isActive: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface RegisterPushTokenInput {\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n}\n\n// ============================================\n// Configuration Types\n// ============================================\n\nexport interface MDMConfig {\n /** Database adapter for persistence */\n database: DatabaseAdapter;\n\n /** Authentication/authorization configuration */\n auth?: AuthConfig;\n\n /** Push notification provider configuration */\n push?: PushProviderConfig;\n\n /** Device enrollment configuration */\n enrollment?: EnrollmentConfig;\n\n /** Server URL (used in enrollment responses) */\n serverUrl?: string;\n\n /** APK/file storage configuration */\n storage?: StorageConfig;\n\n /** Outbound webhook configuration */\n webhooks?: WebhookConfig;\n\n /** Plugins to extend functionality */\n plugins?: MDMPlugin[];\n\n /** Event handlers */\n onDeviceEnrolled?: (device: Device) => Promise<void>;\n onDeviceUnenrolled?: (device: Device) => Promise<void>;\n onDeviceBlocked?: (device: Device) => Promise<void>;\n onHeartbeat?: (device: Device, heartbeat: Heartbeat) => Promise<void>;\n onCommand?: (command: Command) => Promise<void>;\n onEvent?: (event: MDMEvent) => Promise<void>;\n\n // Enterprise features\n /** Multi-tenancy configuration */\n multiTenancy?: {\n enabled: boolean;\n defaultTenantId?: string;\n tenantResolver?: (context: unknown) => Promise<string | null>;\n };\n\n /** Authorization (RBAC) configuration */\n authorization?: {\n enabled: boolean;\n defaultRole?: string;\n };\n\n /** Audit logging configuration */\n audit?: {\n enabled: boolean;\n retentionDays?: number;\n };\n\n /** Scheduling configuration */\n scheduling?: {\n enabled: boolean;\n timezone?: string;\n };\n\n /** Plugin storage configuration */\n pluginStorage?: {\n adapter: 'database' | 'memory';\n };\n}\n\nexport interface StorageConfig {\n /** Storage provider (s3, local, custom) */\n provider: 's3' | 'local' | 'custom';\n\n /** S3 configuration */\n s3?: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string; // For S3-compatible services\n presignedUrlExpiry?: number; // Seconds, default 3600\n };\n\n /** Local storage path */\n localPath?: string;\n\n /** Custom storage adapter */\n customAdapter?: {\n upload: (file: Buffer, key: string) => Promise<string>;\n getUrl: (key: string) => Promise<string>;\n delete: (key: string) => Promise<void>;\n };\n}\n\nexport interface WebhookConfig {\n /** Webhook endpoints to notify */\n endpoints?: WebhookEndpoint[];\n\n /** Retry configuration */\n retry?: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n };\n\n /** Sign webhooks with HMAC secret */\n signingSecret?: string;\n}\n\nexport interface WebhookEndpoint {\n /** Unique identifier */\n id: string;\n /** Webhook URL */\n url: string;\n /** Events to trigger this webhook */\n events: (EventType | '*')[];\n /** Custom headers */\n headers?: Record<string, string>;\n /** Whether endpoint is active */\n enabled: boolean;\n}\n\nexport interface AuthConfig {\n /** Get current user from request context */\n getUser: <T = unknown>(context: unknown) => Promise<T | null>;\n /** Check if user has admin privileges */\n isAdmin?: (user: unknown) => Promise<boolean>;\n /** Check if user can access specific device */\n canAccessDevice?: (user: unknown, deviceId: string) => Promise<boolean>;\n /** Device JWT secret (for device auth tokens) */\n deviceTokenSecret?: string;\n /** Device token expiration in seconds (default: 365 days) */\n deviceTokenExpiration?: number;\n}\n\nexport interface PushProviderConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n\n // FCM configuration\n fcmCredentials?: string | Record<string, unknown>;\n fcmProjectId?: string;\n\n // MQTT configuration\n mqttUrl?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n mqttTopicPrefix?: string;\n\n // WebSocket configuration\n wsPath?: string;\n wsPingInterval?: number;\n\n // Polling fallback\n pollingInterval?: number;\n}\n\nexport interface EnrollmentConfig {\n /** Auto-enroll devices with valid signature */\n autoEnroll?: boolean;\n /** HMAC secret for device signature verification */\n deviceSecret: string;\n /** Allowed enrollment methods */\n allowedMethods?: EnrollmentMethod[];\n /** Default policy for new devices */\n defaultPolicyId?: string;\n /** Default group for new devices */\n defaultGroupId?: string;\n /** Require manual approval for enrollment */\n requireApproval?: boolean;\n /** Custom enrollment validation */\n validate?: (request: EnrollmentRequest) => Promise<boolean>;\n}\n\n// ============================================\n// Adapter Interfaces\n// ============================================\n\nexport interface DatabaseAdapter {\n // Devices\n findDevice(id: string): Promise<Device | null>;\n findDeviceByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n listDevices(filter?: DeviceFilter): Promise<DeviceListResult>;\n createDevice(data: CreateDeviceInput): Promise<Device>;\n updateDevice(id: string, data: UpdateDeviceInput): Promise<Device>;\n deleteDevice(id: string): Promise<void>;\n countDevices(filter?: DeviceFilter): Promise<number>;\n\n // Policies\n findPolicy(id: string): Promise<Policy | null>;\n findDefaultPolicy(): Promise<Policy | null>;\n listPolicies(): Promise<Policy[]>;\n createPolicy(data: CreatePolicyInput): Promise<Policy>;\n updatePolicy(id: string, data: UpdatePolicyInput): Promise<Policy>;\n deletePolicy(id: string): Promise<void>;\n\n // Applications\n findApplication(id: string): Promise<Application | null>;\n findApplicationByPackage(packageName: string, version?: string): Promise<Application | null>;\n listApplications(activeOnly?: boolean): Promise<Application[]>;\n createApplication(data: CreateApplicationInput): Promise<Application>;\n updateApplication(id: string, data: UpdateApplicationInput): Promise<Application>;\n deleteApplication(id: string): Promise<void>;\n\n // Commands\n findCommand(id: string): Promise<Command | null>;\n listCommands(filter?: CommandFilter): Promise<Command[]>;\n createCommand(data: SendCommandInput): Promise<Command>;\n updateCommand(id: string, data: Partial<Command>): Promise<Command>;\n getPendingCommands(deviceId: string): Promise<Command[]>;\n\n // Events\n createEvent(event: Omit<MDMEvent, 'id' | 'createdAt'>): Promise<MDMEvent>;\n listEvents(filter?: EventFilter): Promise<MDMEvent[]>;\n\n // Groups\n findGroup(id: string): Promise<Group | null>;\n listGroups(): Promise<Group[]>;\n createGroup(data: CreateGroupInput): Promise<Group>;\n updateGroup(id: string, data: UpdateGroupInput): Promise<Group>;\n deleteGroup(id: string): Promise<void>;\n listDevicesInGroup(groupId: string): Promise<Device[]>;\n addDeviceToGroup(deviceId: string, groupId: string): Promise<void>;\n removeDeviceFromGroup(deviceId: string, groupId: string): Promise<void>;\n getDeviceGroups(deviceId: string): Promise<Group[]>;\n\n // Push Tokens\n findPushToken(deviceId: string, provider: string): Promise<PushToken | null>;\n upsertPushToken(data: RegisterPushTokenInput): Promise<PushToken>;\n deletePushToken(deviceId: string, provider?: string): Promise<void>;\n\n // App Versions (optional - for version tracking)\n listAppVersions?(packageName: string): Promise<AppVersion[]>;\n createAppVersion?(data: Omit<AppVersion, 'id' | 'createdAt'>): Promise<AppVersion>;\n setMinimumVersion?(packageName: string, versionCode: number): Promise<void>;\n getMinimumVersion?(packageName: string): Promise<AppVersion | null>;\n\n // Rollback History (optional)\n createRollback?(data: CreateAppRollbackInput): Promise<AppRollback>;\n updateRollback?(id: string, data: Partial<AppRollback>): Promise<AppRollback>;\n listRollbacks?(filter?: { deviceId?: string; packageName?: string }): Promise<AppRollback[]>;\n\n // Group Hierarchy (optional)\n getGroupChildren?(parentId: string | null): Promise<Group[]>;\n getGroupAncestors?(groupId: string): Promise<Group[]>;\n getGroupDescendants?(groupId: string): Promise<Group[]>;\n getGroupTree?(rootId?: string): Promise<GroupTreeNode[]>;\n getGroupEffectivePolicy?(groupId: string): Promise<Policy | null>;\n moveGroup?(groupId: string, newParentId: string | null): Promise<Group>;\n getGroupHierarchyStats?(): Promise<GroupHierarchyStats>;\n\n // Tenants (optional - for multi-tenancy)\n findTenant?(id: string): Promise<Tenant | null>;\n findTenantBySlug?(slug: string): Promise<Tenant | null>;\n listTenants?(filter?: TenantFilter): Promise<TenantListResult>;\n createTenant?(data: CreateTenantInput): Promise<Tenant>;\n updateTenant?(id: string, data: UpdateTenantInput): Promise<Tenant>;\n deleteTenant?(id: string): Promise<void>;\n getTenantStats?(tenantId: string): Promise<TenantStats>;\n\n // Users (optional - for RBAC)\n findUser?(id: string): Promise<User | null>;\n findUserByEmail?(email: string, tenantId?: string): Promise<User | null>;\n listUsers?(filter?: UserFilter): Promise<UserListResult>;\n createUser?(data: CreateUserInput): Promise<User>;\n updateUser?(id: string, data: UpdateUserInput): Promise<User>;\n deleteUser?(id: string): Promise<void>;\n\n // Roles (optional - for RBAC)\n findRole?(id: string): Promise<Role | null>;\n listRoles?(tenantId?: string): Promise<Role[]>;\n createRole?(data: CreateRoleInput): Promise<Role>;\n updateRole?(id: string, data: UpdateRoleInput): Promise<Role>;\n deleteRole?(id: string): Promise<void>;\n assignRoleToUser?(userId: string, roleId: string): Promise<void>;\n removeRoleFromUser?(userId: string, roleId: string): Promise<void>;\n getUserRoles?(userId: string): Promise<Role[]>;\n\n // Audit Logs (optional - for compliance)\n createAuditLog?(data: CreateAuditLogInput): Promise<AuditLog>;\n listAuditLogs?(filter?: AuditLogFilter): Promise<AuditLogListResult>;\n deleteAuditLogs?(filter: { olderThan?: Date; tenantId?: string }): Promise<number>;\n\n // Scheduled Tasks (optional - for scheduling)\n findScheduledTask?(id: string): Promise<ScheduledTask | null>;\n listScheduledTasks?(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;\n createScheduledTask?(data: CreateScheduledTaskInput): Promise<ScheduledTask>;\n updateScheduledTask?(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;\n deleteScheduledTask?(id: string): Promise<void>;\n getUpcomingTasks?(hours: number): Promise<ScheduledTask[]>;\n createTaskExecution?(data: { taskId: string }): Promise<TaskExecution>;\n updateTaskExecution?(id: string, data: Partial<TaskExecution>): Promise<TaskExecution>;\n listTaskExecutions?(taskId: string, limit?: number): Promise<TaskExecution[]>;\n\n // Message Queue (optional - for persistent messaging)\n enqueueMessage?(data: EnqueueMessageInput): Promise<QueuedMessage>;\n dequeueMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n peekMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n acknowledgeMessage?(messageId: string): Promise<void>;\n failMessage?(messageId: string, error: string): Promise<void>;\n retryFailedMessages?(maxAttempts?: number): Promise<number>;\n purgeExpiredMessages?(): Promise<number>;\n getQueueStats?(tenantId?: string): Promise<QueueStats>;\n\n // Plugin Storage (optional)\n getPluginValue?(pluginName: string, key: string): Promise<unknown | null>;\n setPluginValue?(pluginName: string, key: string, value: unknown): Promise<void>;\n deletePluginValue?(pluginName: string, key: string): Promise<void>;\n listPluginKeys?(pluginName: string, prefix?: string): Promise<string[]>;\n clearPluginData?(pluginName: string): Promise<void>;\n\n // Dashboard (optional - for analytics)\n getDashboardStats?(tenantId?: string): Promise<DashboardStats>;\n getDeviceStatusBreakdown?(tenantId?: string): Promise<DeviceStatusBreakdown>;\n getEnrollmentTrend?(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;\n getCommandSuccessRates?(tenantId?: string): Promise<CommandSuccessRates>;\n getAppInstallationSummary?(tenantId?: string): Promise<AppInstallationSummary>;\n\n // Transactions (optional)\n transaction?<T>(fn: () => Promise<T>): Promise<T>;\n}\n\nexport interface PushAdapter {\n /** Send push message to a device */\n send(deviceId: string, message: PushMessage): Promise<PushResult>;\n /** Send push message to multiple devices */\n sendBatch(deviceIds: string[], message: PushMessage): Promise<PushBatchResult>;\n /** Register device push token */\n registerToken?(deviceId: string, token: string): Promise<void>;\n /** Unregister device push token */\n unregisterToken?(deviceId: string): Promise<void>;\n /** Subscribe device to topic */\n subscribe?(deviceId: string, topic: string): Promise<void>;\n /** Unsubscribe device from topic */\n unsubscribe?(deviceId: string, topic: string): Promise<void>;\n}\n\nexport interface PushMessage {\n type: string;\n payload?: Record<string, unknown>;\n priority?: 'high' | 'normal';\n ttl?: number;\n collapseKey?: string;\n}\n\nexport interface PushResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n\nexport interface PushBatchResult {\n successCount: number;\n failureCount: number;\n results: Array<{ deviceId: string; result: PushResult }>;\n}\n\n// ============================================\n// Plugin Interface\n// ============================================\n\nexport interface MDMPlugin {\n /** Unique plugin name */\n name: string;\n /** Plugin version */\n version: string;\n\n /** Called when MDM is initialized */\n onInit?(mdm: MDMInstance): Promise<void>;\n\n /** Called when MDM is destroyed */\n onDestroy?(): Promise<void>;\n\n /** Additional routes to mount */\n routes?: PluginRoute[];\n\n /** Middleware to apply to all routes */\n middleware?: PluginMiddleware[];\n\n /** Extend enrollment process */\n onEnroll?(device: Device, request: EnrollmentRequest): Promise<void>;\n\n /** Extend device processing */\n onDeviceEnrolled?(device: Device): Promise<void>;\n onDeviceUnenrolled?(device: Device): Promise<void>;\n onHeartbeat?(device: Device, heartbeat: Heartbeat): Promise<void>;\n\n /** Extend policy processing */\n policySchema?: Record<string, unknown>;\n validatePolicy?(settings: PolicySettings): Promise<{ valid: boolean; errors?: string[] }>;\n applyPolicy?(device: Device, policy: Policy): Promise<void>;\n\n /** Extend command processing */\n commandTypes?: CommandType[];\n executeCommand?(device: Device, command: Command): Promise<CommandResult>;\n}\n\nexport interface PluginRoute {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n handler: (context: unknown) => Promise<unknown>;\n auth?: boolean;\n admin?: boolean;\n}\n\nexport type PluginMiddleware = (\n context: unknown,\n next: () => Promise<unknown>\n) => Promise<unknown>;\n\n// ============================================\n// MDM Instance Interface\n// ============================================\n\nexport interface WebhookManager {\n /** Deliver an event to all matching webhook endpoints */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n /** Add a webhook endpoint at runtime */\n addEndpoint(endpoint: WebhookEndpoint): void;\n /** Remove a webhook endpoint */\n removeEndpoint(endpointId: string): void;\n /** Update a webhook endpoint */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n /** Get all configured endpoints */\n getEndpoints(): WebhookEndpoint[];\n /** Test a webhook endpoint with a test payload */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface MDMInstance {\n /** Device management */\n devices: DeviceManager;\n /** Policy management */\n policies: PolicyManager;\n /** Application management */\n apps: ApplicationManager;\n /** Command management */\n commands: CommandManager;\n /** Group management */\n groups: GroupManager;\n\n /** Tenant management (if multi-tenancy enabled) */\n tenants?: TenantManager;\n /** Authorization management (RBAC) */\n authorization?: AuthorizationManager;\n /** Audit logging */\n audit?: AuditManager;\n /** Scheduled task management */\n schedules?: ScheduleManager;\n /** Persistent message queue */\n messageQueue?: MessageQueueManager;\n /** Dashboard analytics */\n dashboard?: DashboardManager;\n /** Plugin storage */\n pluginStorage?: PluginStorageAdapter;\n\n /** Push notification service */\n push: PushAdapter;\n\n /** Webhook delivery (if configured) */\n webhooks?: WebhookManager;\n\n /** Database adapter */\n db: DatabaseAdapter;\n\n /** Configuration */\n config: MDMConfig;\n\n /** Subscribe to events */\n on<T extends EventType>(event: T, handler: EventHandler<T>): () => void;\n /** Emit an event */\n emit<T extends EventType>(event: T, data: EventPayloadMap[T]): Promise<void>;\n\n /** Process device enrollment */\n enroll(request: EnrollmentRequest): Promise<EnrollmentResponse>;\n /** Process device heartbeat */\n processHeartbeat(deviceId: string, heartbeat: Heartbeat): Promise<void>;\n /** Verify device token */\n verifyDeviceToken(token: string): Promise<{ deviceId: string } | null>;\n\n /** Get loaded plugins */\n getPlugins(): MDMPlugin[];\n /** Get plugin by name */\n getPlugin(name: string): MDMPlugin | undefined;\n}\n\n// ============================================\n// Manager Interfaces\n// ============================================\n\nexport interface DeviceManager {\n get(id: string): Promise<Device | null>;\n getByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n list(filter?: DeviceFilter): Promise<DeviceListResult>;\n create(data: CreateDeviceInput): Promise<Device>;\n update(id: string, data: UpdateDeviceInput): Promise<Device>;\n delete(id: string): Promise<void>;\n assignPolicy(deviceId: string, policyId: string | null): Promise<Device>;\n addToGroup(deviceId: string, groupId: string): Promise<void>;\n removeFromGroup(deviceId: string, groupId: string): Promise<void>;\n getGroups(deviceId: string): Promise<Group[]>;\n sendCommand(deviceId: string, input: Omit<SendCommandInput, 'deviceId'>): Promise<Command>;\n sync(deviceId: string): Promise<Command>;\n reboot(deviceId: string): Promise<Command>;\n lock(deviceId: string, message?: string): Promise<Command>;\n wipe(deviceId: string, preserveData?: boolean): Promise<Command>;\n}\n\nexport interface PolicyManager {\n get(id: string): Promise<Policy | null>;\n getDefault(): Promise<Policy | null>;\n list(): Promise<Policy[]>;\n create(data: CreatePolicyInput): Promise<Policy>;\n update(id: string, data: UpdatePolicyInput): Promise<Policy>;\n delete(id: string): Promise<void>;\n setDefault(id: string): Promise<Policy>;\n getDevices(policyId: string): Promise<Device[]>;\n applyToDevice(policyId: string, deviceId: string): Promise<void>;\n}\n\nexport interface ApplicationManager {\n get(id: string): Promise<Application | null>;\n getByPackage(packageName: string, version?: string): Promise<Application | null>;\n list(activeOnly?: boolean): Promise<Application[]>;\n register(data: CreateApplicationInput): Promise<Application>;\n update(id: string, data: UpdateApplicationInput): Promise<Application>;\n delete(id: string): Promise<void>;\n activate(id: string): Promise<Application>;\n deactivate(id: string): Promise<Application>;\n deploy(packageName: string, target: DeployTarget): Promise<void>;\n installOnDevice(packageName: string, deviceId: string, version?: string): Promise<Command>;\n uninstallFromDevice(packageName: string, deviceId: string): Promise<Command>;\n}\n\nexport interface CommandManager {\n get(id: string): Promise<Command | null>;\n list(filter?: CommandFilter): Promise<Command[]>;\n send(input: SendCommandInput): Promise<Command>;\n cancel(id: string): Promise<Command>;\n acknowledge(id: string): Promise<Command>;\n complete(id: string, result: CommandResult): Promise<Command>;\n fail(id: string, error: string): Promise<Command>;\n getPending(deviceId: string): Promise<Command[]>;\n}\n\nexport interface GroupManager {\n // Basic CRUD operations\n get(id: string): Promise<Group | null>;\n list(): Promise<Group[]>;\n create(data: CreateGroupInput): Promise<Group>;\n update(id: string, data: UpdateGroupInput): Promise<Group>;\n delete(id: string): Promise<void>;\n\n // Device management\n getDevices(groupId: string): Promise<Device[]>;\n addDevice(groupId: string, deviceId: string): Promise<void>;\n removeDevice(groupId: string, deviceId: string): Promise<void>;\n\n // Hierarchy operations\n getChildren(groupId: string): Promise<Group[]>;\n getTree(rootId?: string): Promise<GroupTreeNode[]>;\n getAncestors(groupId: string): Promise<Group[]>;\n getDescendants(groupId: string): Promise<Group[]>;\n move(groupId: string, newParentId: string | null): Promise<Group>;\n getEffectivePolicy(groupId: string): Promise<Policy | null>;\n getHierarchyStats(): Promise<GroupHierarchyStats>;\n}\n\n// ============================================\n// Group Hierarchy Types\n// ============================================\n\nexport interface GroupTreeNode extends Group {\n children: GroupTreeNode[];\n depth: number;\n path: string[];\n effectivePolicyId?: string | null;\n}\n\nexport interface GroupHierarchyStats {\n totalGroups: number;\n maxDepth: number;\n groupsWithDevices: number;\n groupsWithPolicies: number;\n}\n\n// ============================================\n// Tenant Types (Multi-tenancy)\n// ============================================\n\nexport type TenantStatus = 'active' | 'suspended' | 'pending';\n\nexport interface Tenant {\n id: string;\n name: string;\n slug: string;\n status: TenantStatus;\n settings?: TenantSettings | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface TenantSettings {\n maxDevices?: number;\n maxUsers?: number;\n features?: string[];\n branding?: {\n logo?: string;\n primaryColor?: string;\n };\n}\n\nexport interface CreateTenantInput {\n name: string;\n slug: string;\n settings?: TenantSettings;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateTenantInput {\n name?: string;\n slug?: string;\n status?: TenantStatus;\n settings?: TenantSettings;\n metadata?: Record<string, unknown>;\n}\n\nexport interface TenantFilter {\n status?: TenantStatus;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface TenantListResult {\n tenants: Tenant[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface TenantStats {\n deviceCount: number;\n userCount: number;\n policyCount: number;\n appCount: number;\n}\n\n// ============================================\n// RBAC Types (Role-Based Access Control)\n// ============================================\n\nexport type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'manage' | '*';\nexport type PermissionResource = 'devices' | 'policies' | 'apps' | 'groups' | 'commands' | 'users' | 'roles' | 'tenants' | 'audit' | '*';\n\nexport interface Permission {\n action: PermissionAction;\n resource: PermissionResource;\n resourceId?: string;\n}\n\nexport interface Role {\n id: string;\n tenantId?: string | null;\n name: string;\n description?: string | null;\n permissions: Permission[];\n isSystem: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateRoleInput {\n tenantId?: string;\n name: string;\n description?: string;\n permissions: Permission[];\n}\n\nexport interface UpdateRoleInput {\n name?: string;\n description?: string;\n permissions?: Permission[];\n}\n\nexport interface User {\n id: string;\n tenantId?: string | null;\n email: string;\n name?: string | null;\n status: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown> | null;\n lastLoginAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UserWithRoles extends User {\n roles: Role[];\n}\n\nexport interface CreateUserInput {\n tenantId?: string;\n email: string;\n name?: string;\n status?: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateUserInput {\n email?: string;\n name?: string;\n status?: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown>;\n}\n\nexport interface UserFilter {\n tenantId?: string;\n status?: 'active' | 'inactive' | 'pending';\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface UserListResult {\n users: User[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Audit Types\n// ============================================\n\nexport type AuditAction = 'create' | 'read' | 'update' | 'delete' | 'login' | 'logout' | 'enroll' | 'unenroll' | 'command' | 'export' | 'import' | 'custom';\n\nexport interface AuditLog {\n id: string;\n tenantId?: string | null;\n userId?: string | null;\n action: AuditAction;\n resource: string;\n resourceId?: string | null;\n status: 'success' | 'failure';\n error?: string | null;\n details?: Record<string, unknown> | null;\n ipAddress?: string | null;\n userAgent?: string | null;\n createdAt: Date;\n}\n\nexport interface CreateAuditLogInput {\n tenantId?: string;\n userId?: string;\n action: AuditAction;\n resource: string;\n resourceId?: string;\n status?: 'success' | 'failure';\n error?: string;\n details?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n}\n\nexport interface AuditConfig {\n enabled: boolean;\n retentionDays?: number;\n skipReadOperations?: boolean;\n logActions?: AuditAction[];\n logResources?: string[];\n}\n\nexport interface AuditSummary {\n totalLogs: number;\n byAction: Record<AuditAction, number>;\n byResource: Record<string, number>;\n byStatus: { success: number; failure: number };\n topUsers: Array<{ userId: string; count: number }>;\n recentFailures: AuditLog[];\n}\n\nexport interface AuditLogFilter {\n tenantId?: string;\n userId?: string;\n action?: string;\n resource?: string;\n resourceId?: string;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\nexport interface AuditLogListResult {\n logs: AuditLog[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Schedule Types\n// ============================================\n\nexport type TaskType = 'command' | 'policy_update' | 'app_install' | 'maintenance' | 'custom';\nexport type ScheduledTaskStatus = 'active' | 'paused' | 'completed' | 'failed';\n\nexport interface MaintenanceWindow {\n daysOfWeek: number[];\n startTime: string;\n endTime: string;\n timezone: string;\n}\n\nexport interface TaskSchedule {\n type: 'once' | 'recurring' | 'window';\n executeAt?: Date;\n cron?: string;\n window?: MaintenanceWindow;\n}\n\nexport interface ScheduledTask {\n id: string;\n tenantId?: string | null;\n name: string;\n description?: string | null;\n taskType: TaskType;\n schedule: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown> | null;\n status: ScheduledTaskStatus;\n nextRunAt?: Date | null;\n lastRunAt?: Date | null;\n maxRetries: number;\n retryCount: number;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateScheduledTaskInput {\n tenantId?: string;\n name: string;\n description?: string;\n taskType: TaskType;\n schedule: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown>;\n maxRetries?: number;\n}\n\nexport interface UpdateScheduledTaskInput {\n name?: string;\n description?: string;\n schedule?: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown>;\n status?: ScheduledTaskStatus;\n maxRetries?: number;\n}\n\nexport interface ScheduledTaskFilter {\n tenantId?: string;\n taskType?: TaskType | TaskType[];\n status?: ScheduledTaskStatus | ScheduledTaskStatus[];\n limit?: number;\n offset?: number;\n}\n\nexport interface ScheduledTaskListResult {\n tasks: ScheduledTask[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface TaskExecution {\n id: string;\n taskId: string;\n status: 'running' | 'completed' | 'failed';\n startedAt: Date;\n completedAt?: Date | null;\n devicesProcessed: number;\n devicesSucceeded: number;\n devicesFailed: number;\n error?: string | null;\n details?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Message Queue Types\n// ============================================\n\nexport type QueueMessageStatus = 'pending' | 'processing' | 'delivered' | 'failed' | 'expired';\n\nexport interface QueuedMessage {\n id: string;\n tenantId?: string | null;\n deviceId: string;\n messageType: string;\n payload: Record<string, unknown>;\n priority: 'high' | 'normal' | 'low';\n status: QueueMessageStatus;\n attempts: number;\n maxAttempts: number;\n lastAttemptAt?: Date | null;\n lastError?: string | null;\n expiresAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface EnqueueMessageInput {\n tenantId?: string;\n deviceId: string;\n messageType: string;\n payload: Record<string, unknown>;\n priority?: 'high' | 'normal' | 'low';\n maxAttempts?: number;\n ttlSeconds?: number;\n}\n\nexport interface QueueStats {\n pending: number;\n processing: number;\n delivered: number;\n failed: number;\n expired: number;\n byDevice: Record<string, number>;\n oldestPending?: Date;\n}\n\n// ============================================\n// Dashboard Types\n// ============================================\n\nexport interface DashboardStats {\n devices: {\n total: number;\n enrolled: number;\n active: number;\n blocked: number;\n pending: number;\n };\n policies: {\n total: number;\n deployed: number;\n };\n applications: {\n total: number;\n deployed: number;\n };\n commands: {\n pendingCount: number;\n last24hTotal: number;\n last24hSuccess: number;\n last24hFailed: number;\n };\n groups: {\n total: number;\n withDevices: number;\n };\n}\n\nexport interface DeviceStatusBreakdown {\n byStatus: Record<DeviceStatus, number>;\n byOs: Record<string, number>;\n byManufacturer: Record<string, number>;\n byModel: Record<string, number>;\n}\n\nexport interface EnrollmentTrendPoint {\n date: Date;\n enrolled: number;\n unenrolled: number;\n netChange: number;\n totalDevices: number;\n}\n\nexport interface CommandSuccessRates {\n overall: {\n total: number;\n completed: number;\n failed: number;\n successRate: number;\n };\n byType: Record<string, {\n total: number;\n completed: number;\n failed: number;\n successRate: number;\n avgExecutionTimeMs?: number;\n }>;\n last24h: {\n total: number;\n completed: number;\n failed: number;\n pending: number;\n };\n}\n\nexport interface AppInstallationSummary {\n total: number;\n byStatus: Record<string, number>;\n recentFailures: Array<{\n packageName: string;\n deviceId: string;\n error: string;\n timestamp: Date;\n }>;\n topInstalled: Array<{\n packageName: string;\n name: string;\n installedCount: number;\n }>;\n}\n\n// ============================================\n// Plugin Storage Types\n// ============================================\n\nexport interface PluginStorageAdapter {\n get<T>(pluginName: string, key: string): Promise<T | null>;\n set<T>(pluginName: string, key: string, value: T): Promise<void>;\n delete(pluginName: string, key: string): Promise<void>;\n list(pluginName: string, prefix?: string): Promise<string[]>;\n clear(pluginName: string): Promise<void>;\n}\n\nexport interface PluginStorageEntry {\n pluginName: string;\n key: string;\n value: unknown;\n createdAt: Date;\n updatedAt: Date;\n}\n\n// ============================================\n// Enterprise Manager Interfaces\n// ============================================\n\nexport interface TenantManager {\n get(id: string): Promise<Tenant | null>;\n getBySlug(slug: string): Promise<Tenant | null>;\n list(filter?: TenantFilter): Promise<TenantListResult>;\n create(data: CreateTenantInput): Promise<Tenant>;\n update(id: string, data: UpdateTenantInput): Promise<Tenant>;\n delete(id: string, cascade?: boolean): Promise<void>;\n getStats(tenantId: string): Promise<TenantStats>;\n activate(id: string): Promise<Tenant>;\n deactivate(id: string): Promise<Tenant>;\n}\n\nexport interface AuthorizationManager {\n createRole(data: CreateRoleInput): Promise<Role>;\n getRole(id: string): Promise<Role | null>;\n listRoles(tenantId?: string): Promise<Role[]>;\n updateRole(id: string, data: UpdateRoleInput): Promise<Role>;\n deleteRole(id: string): Promise<void>;\n createUser(data: CreateUserInput): Promise<User>;\n getUser(id: string): Promise<UserWithRoles | null>;\n getUserByEmail(email: string, tenantId?: string): Promise<UserWithRoles | null>;\n listUsers(filter?: UserFilter): Promise<UserListResult>;\n updateUser(id: string, data: UpdateUserInput): Promise<User>;\n deleteUser(id: string): Promise<void>;\n assignRole(userId: string, roleId: string): Promise<void>;\n removeRole(userId: string, roleId: string): Promise<void>;\n getUserRoles(userId: string): Promise<Role[]>;\n can(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<boolean>;\n canAny(userId: string, permissions: Array<{ action: PermissionAction; resource: PermissionResource }>): Promise<boolean>;\n requirePermission(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<void>;\n isAdmin(userId: string): Promise<boolean>;\n}\n\nexport interface AuditManager {\n log(entry: CreateAuditLogInput): Promise<AuditLog>;\n list(filter?: AuditLogFilter): Promise<AuditLogListResult>;\n getByResource(resource: string, resourceId: string): Promise<AuditLog[]>;\n getByUser(userId: string, filter?: AuditLogFilter): Promise<AuditLogListResult>;\n export(filter: AuditLogFilter, format: 'json' | 'csv'): Promise<string>;\n purge(olderThanDays?: number): Promise<number>;\n getSummary(tenantId?: string, days?: number): Promise<AuditSummary>;\n}\n\nexport interface ScheduleManager {\n get(id: string): Promise<ScheduledTask | null>;\n list(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;\n create(data: CreateScheduledTaskInput): Promise<ScheduledTask>;\n update(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;\n delete(id: string): Promise<void>;\n pause(id: string): Promise<ScheduledTask>;\n resume(id: string): Promise<ScheduledTask>;\n runNow(id: string): Promise<TaskExecution>;\n getUpcoming(hours: number): Promise<ScheduledTask[]>;\n getExecutions(taskId: string, limit?: number): Promise<TaskExecution[]>;\n calculateNextRun(schedule: TaskSchedule): Date | null;\n}\n\nexport interface MessageQueueManager {\n enqueue(message: EnqueueMessageInput): Promise<QueuedMessage>;\n enqueueBatch(messages: EnqueueMessageInput[]): Promise<QueuedMessage[]>;\n dequeue(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n acknowledge(messageId: string): Promise<void>;\n fail(messageId: string, error: string): Promise<void>;\n retryFailed(maxAttempts?: number): Promise<number>;\n purgeExpired(): Promise<number>;\n getStats(tenantId?: string): Promise<QueueStats>;\n peek(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n}\n\nexport interface DashboardManager {\n getStats(tenantId?: string): Promise<DashboardStats>;\n getDeviceStatusBreakdown(tenantId?: string): Promise<DeviceStatusBreakdown>;\n getEnrollmentTrend(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;\n getCommandSuccessRates(tenantId?: string): Promise<CommandSuccessRates>;\n getAppInstallationSummary(tenantId?: string): Promise<AppInstallationSummary>;\n}\n\n// ============================================\n// Event Handler Types\n// ============================================\n\nexport type EventHandler<T extends EventType> = (\n event: MDMEvent<EventPayloadMap[T]>\n) => Promise<void> | void;\n\nexport interface EventPayloadMap {\n 'device.enrolled': { device: Device };\n 'device.unenrolled': { device: Device; reason?: string };\n 'device.blocked': { device: Device; reason: string };\n 'device.heartbeat': { device: Device; heartbeat: Heartbeat };\n 'device.locationUpdated': { device: Device; location: DeviceLocation };\n 'device.statusChanged': { device: Device; oldStatus: DeviceStatus; newStatus: DeviceStatus };\n 'device.policyChanged': { device: Device; oldPolicyId?: string; newPolicyId?: string };\n 'app.installed': { device: Device; app: InstalledApp };\n 'app.uninstalled': { device: Device; packageName: string };\n 'app.updated': { device: Device; app: InstalledApp; oldVersion: string };\n 'app.crashed': { device: Device; packageName: string; error?: string };\n 'app.started': { device: Device; packageName: string };\n 'app.stopped': { device: Device; packageName: string };\n 'policy.applied': { device: Device; policy: Policy };\n 'policy.failed': { device: Device; policy: Policy; error: string };\n 'command.received': { device: Device; command: Command };\n 'command.acknowledged': { device: Device; command: Command };\n 'command.completed': { device: Device; command: Command; result: CommandResult };\n 'command.failed': { device: Device; command: Command; error: string };\n 'security.tamper': { device: Device; type: string; details?: unknown };\n 'security.rootDetected': { device: Device };\n 'security.screenLocked': { device: Device };\n 'security.screenUnlocked': { device: Device };\n custom: Record<string, unknown>;\n}\n\n// ============================================\n// Error Types\n// ============================================\n\nexport class MDMError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: unknown\n ) {\n super(message);\n this.name = 'MDMError';\n }\n}\n\nexport class DeviceNotFoundError extends MDMError {\n constructor(deviceId: string) {\n super(`Device not found: ${deviceId}`, 'DEVICE_NOT_FOUND', 404);\n }\n}\n\nexport class PolicyNotFoundError extends MDMError {\n constructor(policyId: string) {\n super(`Policy not found: ${policyId}`, 'POLICY_NOT_FOUND', 404);\n }\n}\n\nexport class ApplicationNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Application not found: ${identifier}`, 'APPLICATION_NOT_FOUND', 404);\n }\n}\n\nexport class TenantNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Tenant not found: ${identifier}`, 'TENANT_NOT_FOUND', 404);\n }\n}\n\nexport class RoleNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Role not found: ${identifier}`, 'ROLE_NOT_FOUND', 404);\n }\n}\n\nexport class GroupNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Group not found: ${identifier}`, 'GROUP_NOT_FOUND', 404);\n }\n}\n\nexport class UserNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`User not found: ${identifier}`, 'USER_NOT_FOUND', 404);\n }\n}\n\nexport class EnrollmentError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'ENROLLMENT_ERROR', 400, details);\n }\n}\n\nexport class AuthenticationError extends MDMError {\n constructor(message: string = 'Authentication required') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n }\n}\n\nexport class AuthorizationError extends MDMError {\n constructor(message: string = 'Access denied') {\n super(message, 'AUTHORIZATION_ERROR', 403);\n }\n}\n\nexport class ValidationError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'VALIDATION_ERROR', 400, details);\n }\n}\n","/**\n * OpenMDM Webhook Delivery System\n *\n * Handles outbound webhook delivery with HMAC signing and retry logic.\n */\n\nimport { createHmac, randomUUID } from 'crypto';\nimport type {\n WebhookConfig,\n WebhookEndpoint,\n EventType,\n MDMEvent,\n} from './types';\n\n// ============================================\n// Types\n// ============================================\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface WebhookPayload<T = unknown> {\n id: string;\n event: EventType;\n timestamp: string;\n data: T;\n}\n\nexport interface WebhookManager {\n /**\n * Deliver an event to all matching webhook endpoints\n */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n\n /**\n * Add a webhook endpoint at runtime\n */\n addEndpoint(endpoint: WebhookEndpoint): void;\n\n /**\n * Remove a webhook endpoint\n */\n removeEndpoint(endpointId: string): void;\n\n /**\n * Update a webhook endpoint\n */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n\n /**\n * Get all configured endpoints\n */\n getEndpoints(): WebhookEndpoint[];\n\n /**\n * Test a webhook endpoint with a test payload\n */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\n// ============================================\n// Implementation\n// ============================================\n\nconst DEFAULT_RETRY_CONFIG = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n};\n\n/**\n * Create a webhook manager instance\n */\nexport function createWebhookManager(config: WebhookConfig): WebhookManager {\n const endpoints = new Map<string, WebhookEndpoint>();\n const retryConfig = { ...DEFAULT_RETRY_CONFIG, ...config.retry };\n\n // Initialize with configured endpoints\n if (config.endpoints) {\n for (const endpoint of config.endpoints) {\n endpoints.set(endpoint.id, endpoint);\n }\n }\n\n /**\n * Sign a webhook payload with HMAC-SHA256\n */\n function signPayload(payload: string, secret: string): string {\n return createHmac('sha256', secret).update(payload).digest('hex');\n }\n\n /**\n * Calculate exponential backoff delay\n */\n function getBackoffDelay(retryCount: number): number {\n const delay = retryConfig.initialDelay * Math.pow(2, retryCount);\n return Math.min(delay, retryConfig.maxDelay);\n }\n\n /**\n * Check if an endpoint should receive this event\n */\n function shouldDeliverToEndpoint(\n endpoint: WebhookEndpoint,\n eventType: EventType\n ): boolean {\n if (!endpoint.enabled) {\n return false;\n }\n\n // Wildcard matches all events\n if (endpoint.events.includes('*')) {\n return true;\n }\n\n return endpoint.events.includes(eventType);\n }\n\n /**\n * Deliver payload to a single endpoint with retry logic\n */\n async function deliverToEndpoint(\n endpoint: WebhookEndpoint,\n payload: WebhookPayload\n ): Promise<WebhookDeliveryResult> {\n const payloadString = JSON.stringify(payload);\n let lastError: string | undefined;\n let lastStatusCode: number | undefined;\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n // Prepare headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-OpenMDM-Event': payload.event,\n 'X-OpenMDM-Delivery': payload.id,\n 'X-OpenMDM-Timestamp': payload.timestamp,\n ...endpoint.headers,\n };\n\n // Add signature if signing secret is configured\n if (config.signingSecret) {\n const signature = signPayload(payloadString, config.signingSecret);\n headers['X-OpenMDM-Signature'] = `sha256=${signature}`;\n }\n\n // Make the request\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers,\n body: payloadString,\n signal: AbortSignal.timeout(30000), // 30 second timeout\n });\n\n lastStatusCode = response.status;\n\n // 2xx is success\n if (response.ok) {\n return {\n endpointId: endpoint.id,\n success: true,\n statusCode: response.status,\n retryCount: attempt,\n deliveredAt: new Date(),\n };\n }\n\n // 4xx errors (except 429) should not be retried\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n return {\n endpointId: endpoint.id,\n success: false,\n statusCode: response.status,\n error: `HTTP ${response.status}: ${response.statusText}`,\n retryCount: attempt,\n };\n }\n\n // 5xx and 429 should be retried\n lastError = `HTTP ${response.status}: ${response.statusText}`;\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n }\n\n // Wait before retry (unless this was the last attempt)\n if (attempt < retryConfig.maxRetries) {\n const delay = getBackoffDelay(attempt);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n return {\n endpointId: endpoint.id,\n success: false,\n statusCode: lastStatusCode,\n error: lastError || 'Max retries exceeded',\n retryCount: retryConfig.maxRetries,\n };\n }\n\n return {\n async deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]> {\n const matchingEndpoints = Array.from(endpoints.values()).filter((ep) =>\n shouldDeliverToEndpoint(ep, event.type)\n );\n\n if (matchingEndpoints.length === 0) {\n return [];\n }\n\n // Prepare webhook payload\n const payload: WebhookPayload<T> = {\n id: randomUUID(),\n event: event.type,\n timestamp: new Date().toISOString(),\n data: event.payload,\n };\n\n // Deliver to all matching endpoints in parallel\n const deliveryPromises = matchingEndpoints.map((endpoint) =>\n deliverToEndpoint(endpoint, payload as WebhookPayload)\n );\n\n const results = await Promise.all(deliveryPromises);\n\n // Log failures\n for (const result of results) {\n if (!result.success) {\n console.error(\n `[OpenMDM] Webhook delivery failed to endpoint ${result.endpointId}:`,\n result.error\n );\n }\n }\n\n return results;\n },\n\n addEndpoint(endpoint: WebhookEndpoint): void {\n endpoints.set(endpoint.id, endpoint);\n },\n\n removeEndpoint(endpointId: string): void {\n endpoints.delete(endpointId);\n },\n\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void {\n const existing = endpoints.get(endpointId);\n if (existing) {\n endpoints.set(endpointId, { ...existing, ...updates });\n }\n },\n\n getEndpoints(): WebhookEndpoint[] {\n return Array.from(endpoints.values());\n },\n\n async testEndpoint(endpointId: string): Promise<WebhookDeliveryResult> {\n const endpoint = endpoints.get(endpointId);\n if (!endpoint) {\n return {\n endpointId,\n success: false,\n error: 'Endpoint not found',\n retryCount: 0,\n };\n }\n\n const testPayload: WebhookPayload = {\n id: randomUUID(),\n event: 'device.heartbeat',\n timestamp: new Date().toISOString(),\n data: {\n test: true,\n message: 'OpenMDM webhook test',\n },\n };\n\n return deliverToEndpoint(endpoint, testPayload);\n },\n };\n}\n\n/**\n * Verify a webhook signature from incoming requests\n * (Utility for consumers to verify our webhooks)\n */\nexport function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string\n): boolean {\n const expectedSignature = `sha256=${createHmac('sha256', secret)\n .update(payload)\n .digest('hex')}`;\n\n // Constant-time comparison\n if (signature.length !== expectedSignature.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < signature.length; i++) {\n result |= signature.charCodeAt(i) ^ expectedSignature.charCodeAt(i);\n }\n\n return result === 0;\n}\n","/**\n * OpenMDM Tenant Manager\n *\n * Provides multi-tenancy support for the MDM system.\n * Enables organization isolation, tenant management, and resource quotas.\n */\n\nimport type {\n Tenant,\n TenantManager,\n TenantFilter,\n TenantListResult,\n TenantStats,\n CreateTenantInput,\n UpdateTenantInput,\n DatabaseAdapter,\n} from './types';\nimport { TenantNotFoundError, ValidationError } from './types';\n\n/**\n * Generate a unique ID for entities\n */\nfunction generateId(): string {\n return crypto.randomUUID();\n}\n\n/**\n * Validate tenant slug format\n */\nfunction validateSlug(slug: string): boolean {\n // Slug must be lowercase alphanumeric with hyphens, 3-50 chars\n const slugRegex = /^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$/;\n return slugRegex.test(slug);\n}\n\n/**\n * Create a TenantManager instance\n */\nexport function createTenantManager(db: DatabaseAdapter): TenantManager {\n return {\n async get(id: string): Promise<Tenant | null> {\n if (!db.findTenant) {\n throw new Error('Database adapter does not support tenant operations');\n }\n return db.findTenant(id);\n },\n\n async getBySlug(slug: string): Promise<Tenant | null> {\n if (!db.findTenantBySlug) {\n throw new Error('Database adapter does not support tenant operations');\n }\n return db.findTenantBySlug(slug);\n },\n\n async list(filter?: TenantFilter): Promise<TenantListResult> {\n if (!db.listTenants) {\n throw new Error('Database adapter does not support tenant operations');\n }\n return db.listTenants(filter);\n },\n\n async create(data: CreateTenantInput): Promise<Tenant> {\n if (!db.createTenant || !db.findTenantBySlug) {\n throw new Error('Database adapter does not support tenant operations');\n }\n\n // Validate slug format\n if (!validateSlug(data.slug)) {\n throw new ValidationError(\n 'Invalid slug format. Must be 3-50 lowercase alphanumeric characters with hyphens.',\n { slug: data.slug }\n );\n }\n\n // Check for duplicate slug\n const existing = await db.findTenantBySlug(data.slug);\n if (existing) {\n throw new ValidationError(`Tenant with slug '${data.slug}' already exists`, {\n slug: data.slug,\n });\n }\n\n return db.createTenant({\n ...data,\n slug: data.slug.toLowerCase(),\n });\n },\n\n async update(id: string, data: UpdateTenantInput): Promise<Tenant> {\n if (!db.updateTenant || !db.findTenant || !db.findTenantBySlug) {\n throw new Error('Database adapter does not support tenant operations');\n }\n\n const tenant = await db.findTenant(id);\n if (!tenant) {\n throw new TenantNotFoundError(id);\n }\n\n // Validate new slug if provided\n if (data.slug) {\n if (!validateSlug(data.slug)) {\n throw new ValidationError(\n 'Invalid slug format. Must be 3-50 lowercase alphanumeric characters with hyphens.',\n { slug: data.slug }\n );\n }\n\n // Check for duplicate slug\n const existing = await db.findTenantBySlug(data.slug);\n if (existing && existing.id !== id) {\n throw new ValidationError(`Tenant with slug '${data.slug}' already exists`, {\n slug: data.slug,\n });\n }\n\n data.slug = data.slug.toLowerCase();\n }\n\n return db.updateTenant(id, data);\n },\n\n async delete(id: string, cascade: boolean = false): Promise<void> {\n if (!db.deleteTenant || !db.findTenant) {\n throw new Error('Database adapter does not support tenant operations');\n }\n\n const tenant = await db.findTenant(id);\n if (!tenant) {\n throw new TenantNotFoundError(id);\n }\n\n // If cascade is true, the database adapter should handle\n // deletion of all related resources (devices, policies, etc.)\n // This is typically done via ON DELETE CASCADE in the schema\n\n await db.deleteTenant(id);\n },\n\n async getStats(tenantId: string): Promise<TenantStats> {\n if (!db.getTenantStats || !db.findTenant) {\n throw new Error('Database adapter does not support tenant operations');\n }\n\n const tenant = await db.findTenant(tenantId);\n if (!tenant) {\n throw new TenantNotFoundError(tenantId);\n }\n\n return db.getTenantStats(tenantId);\n },\n\n async activate(id: string): Promise<Tenant> {\n if (!db.updateTenant || !db.findTenant) {\n throw new Error('Database adapter does not support tenant operations');\n }\n\n const tenant = await db.findTenant(id);\n if (!tenant) {\n throw new TenantNotFoundError(id);\n }\n\n if (tenant.status === 'active') {\n return tenant;\n }\n\n return db.updateTenant(id, { status: 'active' });\n },\n\n async deactivate(id: string): Promise<Tenant> {\n if (!db.updateTenant || !db.findTenant) {\n throw new Error('Database adapter does not support tenant operations');\n }\n\n const tenant = await db.findTenant(id);\n if (!tenant) {\n throw new TenantNotFoundError(id);\n }\n\n if (tenant.status === 'suspended') {\n return tenant;\n }\n\n return db.updateTenant(id, { status: 'suspended' });\n },\n };\n}\n\n/**\n * Default system roles that can be used across tenants\n */\nexport const DEFAULT_SYSTEM_ROLES = {\n SUPER_ADMIN: {\n name: 'Super Admin',\n description: 'Full system access across all tenants',\n permissions: [{ action: '*' as const, resource: '*' as const }],\n isSystem: true,\n },\n TENANT_ADMIN: {\n name: 'Tenant Admin',\n description: 'Full access within the tenant',\n permissions: [\n { action: 'manage' as const, resource: 'devices' as const },\n { action: 'manage' as const, resource: 'policies' as const },\n { action: 'manage' as const, resource: 'applications' as const },\n { action: 'manage' as const, resource: 'commands' as const },\n { action: 'manage' as const, resource: 'groups' as const },\n { action: 'manage' as const, resource: 'users' as const },\n { action: 'read' as const, resource: 'audit' as const },\n ],\n isSystem: true,\n },\n DEVICE_MANAGER: {\n name: 'Device Manager',\n description: 'Manage devices and send commands',\n permissions: [\n { action: 'manage' as const, resource: 'devices' as const },\n { action: 'manage' as const, resource: 'commands' as const },\n { action: 'read' as const, resource: 'policies' as const },\n { action: 'read' as const, resource: 'groups' as const },\n ],\n isSystem: true,\n },\n VIEWER: {\n name: 'Viewer',\n description: 'Read-only access to all resources',\n permissions: [\n { action: 'read' as const, resource: 'devices' as const },\n { action: 'read' as const, resource: 'policies' as const },\n { action: 'read' as const, resource: 'applications' as const },\n { action: 'read' as const, resource: 'commands' as const },\n { action: 'read' as const, resource: 'groups' as const },\n ],\n isSystem: true,\n },\n};\n\nexport type SystemRoleName = keyof typeof DEFAULT_SYSTEM_ROLES;\n","/**\n * OpenMDM Authorization Manager\n *\n * Provides Role-Based Access Control (RBAC) for the MDM system.\n * Enables fine-grained permission management for users and resources.\n */\n\nimport type {\n Role,\n User,\n UserWithRoles,\n Permission,\n PermissionAction,\n PermissionResource,\n AuthorizationManager,\n CreateRoleInput,\n UpdateRoleInput,\n CreateUserInput,\n UpdateUserInput,\n UserFilter,\n UserListResult,\n DatabaseAdapter,\n} from './types';\nimport {\n UserNotFoundError,\n RoleNotFoundError,\n AuthorizationError,\n ValidationError,\n} from './types';\n\n/**\n * Check if an action matches the required action\n */\nfunction actionMatches(required: PermissionAction, granted: PermissionAction): boolean {\n if (granted === '*') return true;\n if (granted === 'manage') {\n // 'manage' implies all CRUD operations\n return ['create', 'read', 'update', 'delete', 'manage'].includes(required);\n }\n return required === granted;\n}\n\n/**\n * Check if a resource matches the required resource\n */\nfunction resourceMatches(required: PermissionResource, granted: PermissionResource): boolean {\n if (granted === '*') return true;\n return required === granted;\n}\n\n/**\n * Check if a permission matches the required permission\n */\nfunction permissionMatches(\n required: { action: PermissionAction; resource: PermissionResource },\n granted: Permission\n): boolean {\n return (\n actionMatches(required.action, granted.action) &&\n resourceMatches(required.resource, granted.resource)\n );\n}\n\n/**\n * Check if any permission in the list grants the required access\n */\nfunction hasPermission(\n permissions: Permission[],\n action: PermissionAction,\n resource: PermissionResource\n): boolean {\n return permissions.some((p) => permissionMatches({ action, resource }, p));\n}\n\n/**\n * Check if user has admin permissions (full access)\n */\nfunction isAdminPermission(permissions: Permission[]): boolean {\n return permissions.some(\n (p) => p.action === '*' && p.resource === '*'\n );\n}\n\n/**\n * Validate email format\n */\nfunction validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n\n/**\n * Create an AuthorizationManager instance\n */\nexport function createAuthorizationManager(db: DatabaseAdapter): AuthorizationManager {\n /**\n * Get all permissions for a user from all their roles\n */\n async function getAllUserPermissions(userId: string): Promise<Permission[]> {\n if (!db.getUserRoles) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const roles = await db.getUserRoles(userId);\n const permissions: Permission[] = [];\n\n for (const role of roles) {\n permissions.push(...role.permissions);\n }\n\n return permissions;\n }\n\n return {\n // ========================================\n // Role Management\n // ========================================\n\n async createRole(data: CreateRoleInput): Promise<Role> {\n if (!db.createRole) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n // Validate permissions array\n if (!data.permissions || !Array.isArray(data.permissions)) {\n throw new ValidationError('Permissions must be an array');\n }\n\n for (const permission of data.permissions) {\n if (!permission.action || !permission.resource) {\n throw new ValidationError('Each permission must have action and resource');\n }\n }\n\n return db.createRole(data);\n },\n\n async getRole(id: string): Promise<Role | null> {\n if (!db.findRole) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n return db.findRole(id);\n },\n\n async listRoles(tenantId?: string): Promise<Role[]> {\n if (!db.listRoles) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n return db.listRoles(tenantId);\n },\n\n async updateRole(id: string, data: UpdateRoleInput): Promise<Role> {\n if (!db.updateRole || !db.findRole) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const role = await db.findRole(id);\n if (!role) {\n throw new RoleNotFoundError(id);\n }\n\n // Cannot update system roles\n if (role.isSystem) {\n throw new AuthorizationError('Cannot modify system roles');\n }\n\n // Validate permissions if provided\n if (data.permissions) {\n if (!Array.isArray(data.permissions)) {\n throw new ValidationError('Permissions must be an array');\n }\n\n for (const permission of data.permissions) {\n if (!permission.action || !permission.resource) {\n throw new ValidationError('Each permission must have action and resource');\n }\n }\n }\n\n return db.updateRole(id, data);\n },\n\n async deleteRole(id: string): Promise<void> {\n if (!db.deleteRole || !db.findRole) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const role = await db.findRole(id);\n if (!role) {\n throw new RoleNotFoundError(id);\n }\n\n // Cannot delete system roles\n if (role.isSystem) {\n throw new AuthorizationError('Cannot delete system roles');\n }\n\n await db.deleteRole(id);\n },\n\n // ========================================\n // User Management\n // ========================================\n\n async createUser(data: CreateUserInput): Promise<User> {\n if (!db.createUser || !db.findUserByEmail) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n // Validate email\n if (!validateEmail(data.email)) {\n throw new ValidationError('Invalid email format', { email: data.email });\n }\n\n // Check for duplicate email within tenant\n const existing = await db.findUserByEmail(data.email, data.tenantId);\n if (existing) {\n throw new ValidationError(`User with email '${data.email}' already exists`, {\n email: data.email,\n });\n }\n\n return db.createUser({\n ...data,\n email: data.email.toLowerCase(),\n });\n },\n\n async getUser(id: string): Promise<UserWithRoles | null> {\n if (!db.findUser || !db.getUserRoles) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(id);\n if (!user) return null;\n\n const roles = await db.getUserRoles(id);\n return { ...user, roles };\n },\n\n async getUserByEmail(email: string, tenantId?: string): Promise<UserWithRoles | null> {\n if (!db.findUserByEmail || !db.getUserRoles) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUserByEmail(email.toLowerCase(), tenantId);\n if (!user) return null;\n\n const roles = await db.getUserRoles(user.id);\n return { ...user, roles };\n },\n\n async listUsers(filter?: UserFilter): Promise<UserListResult> {\n if (!db.listUsers) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n return db.listUsers(filter);\n },\n\n async updateUser(id: string, data: UpdateUserInput): Promise<User> {\n if (!db.updateUser || !db.findUser) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(id);\n if (!user) {\n throw new UserNotFoundError(id);\n }\n\n // Validate email if provided\n if (data.email) {\n if (!validateEmail(data.email)) {\n throw new ValidationError('Invalid email format', { email: data.email });\n }\n data.email = data.email.toLowerCase();\n }\n\n return db.updateUser(id, data);\n },\n\n async deleteUser(id: string): Promise<void> {\n if (!db.deleteUser || !db.findUser) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(id);\n if (!user) {\n throw new UserNotFoundError(id);\n }\n\n await db.deleteUser(id);\n },\n\n // ========================================\n // Role Assignment\n // ========================================\n\n async assignRole(userId: string, roleId: string): Promise<void> {\n if (!db.assignRoleToUser || !db.findUser || !db.findRole) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(userId);\n if (!user) {\n throw new UserNotFoundError(userId);\n }\n\n const role = await db.findRole(roleId);\n if (!role) {\n throw new RoleNotFoundError(roleId);\n }\n\n // Verify tenant compatibility\n if (role.tenantId && user.tenantId && role.tenantId !== user.tenantId) {\n throw new AuthorizationError('Role belongs to a different tenant');\n }\n\n await db.assignRoleToUser(userId, roleId);\n },\n\n async removeRole(userId: string, roleId: string): Promise<void> {\n if (!db.removeRoleFromUser || !db.findUser) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(userId);\n if (!user) {\n throw new UserNotFoundError(userId);\n }\n\n await db.removeRoleFromUser(userId, roleId);\n },\n\n async getUserRoles(userId: string): Promise<Role[]> {\n if (!db.getUserRoles || !db.findUser) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(userId);\n if (!user) {\n throw new UserNotFoundError(userId);\n }\n\n return db.getUserRoles(userId);\n },\n\n // ========================================\n // Permission Checking\n // ========================================\n\n async can(\n userId: string,\n action: PermissionAction,\n resource: PermissionResource,\n _resourceId?: string\n ): Promise<boolean> {\n if (!db.findUser) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(userId);\n if (!user) return false;\n\n // Inactive users have no permissions\n if (user.status !== 'active') return false;\n\n const permissions = await getAllUserPermissions(userId);\n return hasPermission(permissions, action, resource);\n },\n\n async requirePermission(\n userId: string,\n action: PermissionAction,\n resource: PermissionResource,\n resourceId?: string\n ): Promise<void> {\n const allowed = await this.can(userId, action, resource, resourceId);\n if (!allowed) {\n throw new AuthorizationError(\n `Permission denied: ${action} on ${resource}${resourceId ? ` (${resourceId})` : ''}`\n );\n }\n },\n\n async canAny(\n userId: string,\n permissions: Array<{ action: PermissionAction; resource: PermissionResource }>\n ): Promise<boolean> {\n if (!db.findUser) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(userId);\n if (!user) return false;\n\n // Inactive users have no permissions\n if (user.status !== 'active') return false;\n\n const userPermissions = await getAllUserPermissions(userId);\n\n return permissions.some((required) =>\n hasPermission(userPermissions, required.action, required.resource)\n );\n },\n\n async isAdmin(userId: string): Promise<boolean> {\n if (!db.findUser) {\n throw new Error('Database adapter does not support RBAC operations');\n }\n\n const user = await db.findUser(userId);\n if (!user || user.status !== 'active') return false;\n\n const permissions = await getAllUserPermissions(userId);\n return isAdminPermission(permissions);\n },\n };\n}\n","/**\n * OpenMDM Audit Manager\n *\n * Provides audit logging for compliance and tracking.\n * Records all significant operations for security auditing.\n */\n\nimport type {\n AuditLog,\n AuditAction,\n AuditManager,\n AuditSummary,\n CreateAuditLogInput,\n AuditLogFilter,\n AuditLogListResult,\n DatabaseAdapter,\n AuditConfig,\n} from './types';\n\n/**\n * Default audit retention in days\n */\nconst DEFAULT_RETENTION_DAYS = 90;\n\n/**\n * Convert audit log to CSV row\n */\nfunction auditLogToCsvRow(log: AuditLog): string {\n const fields = [\n log.id,\n log.tenantId || '',\n log.userId || '',\n log.action,\n log.resource,\n log.resourceId || '',\n log.status,\n log.ipAddress || '',\n log.userAgent || '',\n log.error || '',\n log.createdAt.toISOString(),\n JSON.stringify(log.details || {}),\n ];\n return fields.map((f) => `\"${String(f).replace(/\"/g, '\"\"')}\"`).join(',');\n}\n\n/**\n * CSV header for audit log export\n */\nconst CSV_HEADER =\n 'id,tenant_id,user_id,action,resource,resource_id,status,ip_address,user_agent,error,created_at,details';\n\n/**\n * Create an AuditManager instance\n */\nexport function createAuditManager(\n db: DatabaseAdapter,\n config?: AuditConfig\n): AuditManager {\n const retentionDays = config?.retentionDays ?? DEFAULT_RETENTION_DAYS;\n\n /**\n * Check if an action should be logged based on configuration\n */\n function shouldLog(action: AuditAction, resource: string): boolean {\n if (!config?.enabled) return false;\n\n // Skip read operations if configured\n if (config.skipReadOperations && action === 'read') {\n return false;\n }\n\n // Check action filter\n if (config.logActions && config.logActions.length > 0) {\n if (!config.logActions.includes(action)) {\n return false;\n }\n }\n\n // Check resource filter\n if (config.logResources && config.logResources.length > 0) {\n if (!config.logResources.includes(resource)) {\n return false;\n }\n }\n\n return true;\n }\n\n return {\n async log(entry: CreateAuditLogInput): Promise<AuditLog> {\n if (!db.createAuditLog) {\n throw new Error('Database adapter does not support audit operations');\n }\n\n // Check if we should log this action\n if (config && !shouldLog(entry.action, entry.resource)) {\n // Return a stub audit log without persisting\n return {\n id: 'skipped',\n ...entry,\n createdAt: new Date(),\n } as AuditLog;\n }\n\n return db.createAuditLog(entry);\n },\n\n async list(filter?: AuditLogFilter): Promise<AuditLogListResult> {\n if (!db.listAuditLogs) {\n throw new Error('Database adapter does not support audit operations');\n }\n return db.listAuditLogs(filter);\n },\n\n async getByResource(resource: string, resourceId: string): Promise<AuditLog[]> {\n if (!db.listAuditLogs) {\n throw new Error('Database adapter does not support audit operations');\n }\n\n const result = await db.listAuditLogs({\n resource,\n resourceId,\n limit: 1000, // Reasonable limit for resource-specific queries\n });\n\n return result.logs;\n },\n\n async getByUser(\n userId: string,\n filter?: Omit<AuditLogFilter, 'userId'>\n ): Promise<AuditLogListResult> {\n if (!db.listAuditLogs) {\n throw new Error('Database adapter does not support audit operations');\n }\n\n return db.listAuditLogs({\n ...filter,\n userId,\n });\n },\n\n async export(filter: AuditLogFilter, format: 'csv' | 'json'): Promise<string> {\n if (!db.listAuditLogs) {\n throw new Error('Database adapter does not support audit operations');\n }\n\n // Fetch all matching logs (with a reasonable limit)\n const allLogs: AuditLog[] = [];\n let offset = 0;\n const batchSize = 1000;\n\n while (true) {\n const result = await db.listAuditLogs({\n ...filter,\n limit: batchSize,\n offset,\n });\n\n allLogs.push(...result.logs);\n\n if (result.logs.length < batchSize || allLogs.length >= 100000) {\n break;\n }\n\n offset += batchSize;\n }\n\n if (format === 'json') {\n return JSON.stringify(allLogs, null, 2);\n }\n\n // CSV format\n const rows = allLogs.map(auditLogToCsvRow);\n return [CSV_HEADER, ...rows].join('\\n');\n },\n\n async purge(olderThanDays?: number): Promise<number> {\n if (!db.deleteAuditLogs) {\n throw new Error('Database adapter does not support audit operations');\n }\n\n const days = olderThanDays ?? retentionDays;\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n\n return db.deleteAuditLogs({ olderThan: cutoffDate });\n },\n\n async getSummary(tenantId?: string, days: number = 30): Promise<AuditSummary> {\n if (!db.listAuditLogs) {\n throw new Error('Database adapter does not support audit operations');\n }\n\n const startDate = new Date();\n startDate.setDate(startDate.getDate() - days);\n\n // Fetch logs for the period\n const result = await db.listAuditLogs({\n tenantId,\n startDate,\n limit: 10000, // Reasonable limit for summary\n });\n\n const logs = result.logs;\n\n // Calculate summary statistics\n const byAction: Record<AuditAction, number> = {} as Record<AuditAction, number>;\n const byResource: Record<string, number> = {};\n const byStatus = { success: 0, failure: 0 };\n const userCounts: Record<string, number> = {};\n const recentFailures: AuditLog[] = [];\n\n for (const log of logs) {\n // By action\n byAction[log.action] = (byAction[log.action] || 0) + 1;\n\n // By resource\n byResource[log.resource] = (byResource[log.resource] || 0) + 1;\n\n // By status\n byStatus[log.status]++;\n\n // By user\n if (log.userId) {\n userCounts[log.userId] = (userCounts[log.userId] || 0) + 1;\n }\n\n // Collect failures\n if (log.status === 'failure' && recentFailures.length < 10) {\n recentFailures.push(log);\n }\n }\n\n // Get top users\n const topUsers = Object.entries(userCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([userId, count]) => ({ userId, count }));\n\n return {\n totalLogs: result.total,\n byAction,\n byResource,\n byStatus,\n topUsers,\n recentFailures,\n };\n },\n };\n}\n\n/**\n * Helper function to create audit log entries with common fields\n */\nexport function createAuditEntry(\n action: AuditAction,\n resource: string,\n options: {\n resourceId?: string;\n tenantId?: string;\n userId?: string;\n details?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n status?: 'success' | 'failure';\n error?: string;\n } = {}\n): CreateAuditLogInput {\n return {\n action,\n resource,\n resourceId: options.resourceId,\n tenantId: options.tenantId,\n userId: options.userId,\n details: options.details,\n ipAddress: options.ipAddress,\n userAgent: options.userAgent,\n status: options.status ?? 'success',\n error: options.error,\n };\n}\n\n/**\n * Audit decorator for wrapping async functions with audit logging\n */\nexport function withAudit<T extends (...args: unknown[]) => Promise<unknown>>(\n manager: AuditManager,\n action: AuditAction,\n resource: string,\n getContext: (...args: Parameters<T>) => Partial<CreateAuditLogInput>\n) {\n return function decorator(target: T): T {\n return (async (...args: Parameters<T>) => {\n const context = getContext(...args);\n try {\n const result = await target(...args);\n await manager.log({\n action,\n resource,\n status: 'success',\n ...context,\n });\n return result;\n } catch (error) {\n await manager.log({\n action,\n resource,\n status: 'failure',\n error: error instanceof Error ? error.message : String(error),\n ...context,\n });\n throw error;\n }\n }) as T;\n };\n}\n","/**\n * OpenMDM Schedule Manager\n *\n * Provides scheduled task management for the MDM system.\n * Enables scheduling of recurring operations, maintenance windows, and one-time tasks.\n */\n\nimport type {\n ScheduleManager,\n ScheduledTask,\n ScheduledTaskFilter,\n ScheduledTaskListResult,\n CreateScheduledTaskInput,\n UpdateScheduledTaskInput,\n TaskSchedule,\n TaskExecution,\n DatabaseAdapter,\n} from './types';\n\n/**\n * Parse cron expression and calculate next run time\n * Supports: minute hour dayOfMonth month dayOfWeek\n */\nfunction parseCronNextRun(cron: string, from: Date = new Date()): Date | null {\n try {\n const parts = cron.trim().split(/\\s+/);\n if (parts.length !== 5) return null;\n\n const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;\n\n // Simple cron parsing - handles basic patterns\n const now = new Date(from);\n const next = new Date(now);\n\n // Start from the next minute\n next.setSeconds(0);\n next.setMilliseconds(0);\n next.setMinutes(next.getMinutes() + 1);\n\n // Try to find next valid time (up to 1 year)\n const maxIterations = 365 * 24 * 60; // 1 year in minutes\n for (let i = 0; i < maxIterations; i++) {\n const matches =\n matchesCronField(minute, next.getMinutes()) &&\n matchesCronField(hour, next.getHours()) &&\n matchesCronField(dayOfMonth, next.getDate()) &&\n matchesCronField(month, next.getMonth() + 1) &&\n matchesCronField(dayOfWeek, next.getDay());\n\n if (matches) {\n return next;\n }\n\n next.setMinutes(next.getMinutes() + 1);\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a value matches a cron field pattern\n */\nfunction matchesCronField(pattern: string, value: number): boolean {\n if (pattern === '*') return true;\n\n // Handle step values: */5, */15, etc.\n if (pattern.startsWith('*/')) {\n const step = parseInt(pattern.slice(2), 10);\n return value % step === 0;\n }\n\n // Handle ranges: 1-5\n if (pattern.includes('-')) {\n const [start, end] = pattern.split('-').map((n) => parseInt(n, 10));\n return value >= start && value <= end;\n }\n\n // Handle lists: 1,3,5\n if (pattern.includes(',')) {\n const values = pattern.split(',').map((n) => parseInt(n, 10));\n return values.includes(value);\n }\n\n // Simple number\n return parseInt(pattern, 10) === value;\n}\n\n/**\n * Check if current time is within a maintenance window\n */\nfunction isInMaintenanceWindow(\n window: TaskSchedule['window'],\n now: Date = new Date()\n): boolean {\n if (!window) return false;\n\n const dayOfWeek = now.getDay();\n if (!window.daysOfWeek.includes(dayOfWeek)) return false;\n\n // Parse times\n const [startHour, startMin] = window.startTime.split(':').map(Number);\n const [endHour, endMin] = window.endTime.split(':').map(Number);\n\n const currentMinutes = now.getHours() * 60 + now.getMinutes();\n const startMinutes = startHour * 60 + startMin;\n const endMinutes = endHour * 60 + endMin;\n\n // Handle overnight windows\n if (endMinutes < startMinutes) {\n return currentMinutes >= startMinutes || currentMinutes < endMinutes;\n }\n\n return currentMinutes >= startMinutes && currentMinutes < endMinutes;\n}\n\n/**\n * Calculate next run time for a maintenance window\n */\nfunction calculateNextWindowRun(\n window: TaskSchedule['window'],\n from: Date = new Date()\n): Date | null {\n if (!window) return null;\n\n const [startHour, startMin] = window.startTime.split(':').map(Number);\n\n // Try each day for the next 7 days\n for (let dayOffset = 0; dayOffset <= 7; dayOffset++) {\n const candidate = new Date(from);\n candidate.setDate(candidate.getDate() + dayOffset);\n candidate.setHours(startHour, startMin, 0, 0);\n\n // Skip if in the past\n if (candidate <= from) continue;\n\n // Check if day matches\n if (window.daysOfWeek.includes(candidate.getDay())) {\n return candidate;\n }\n }\n\n return null;\n}\n\n/**\n * Create a ScheduleManager instance\n */\nexport function createScheduleManager(db: DatabaseAdapter): ScheduleManager {\n /**\n * Calculate the next run time for a schedule\n */\n function calculateNextRun(schedule: TaskSchedule): Date | null {\n const now = new Date();\n\n switch (schedule.type) {\n case 'once':\n // For one-time tasks, return the scheduled time if it's in the future\n if (schedule.executeAt && new Date(schedule.executeAt) > now) {\n return new Date(schedule.executeAt);\n }\n return null;\n\n case 'recurring':\n // Parse cron expression\n if (schedule.cron) {\n return parseCronNextRun(schedule.cron, now);\n }\n return null;\n\n case 'window':\n // Calculate next maintenance window start\n if (schedule.window) {\n return calculateNextWindowRun(schedule.window, now);\n }\n return null;\n\n default:\n return null;\n }\n }\n\n return {\n async get(id: string): Promise<ScheduledTask | null> {\n if (!db.findScheduledTask) {\n throw new Error('Database adapter does not support task scheduling');\n }\n return db.findScheduledTask(id);\n },\n\n async list(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult> {\n if (!db.listScheduledTasks) {\n throw new Error('Database adapter does not support task scheduling');\n }\n return db.listScheduledTasks(filter);\n },\n\n async create(data: CreateScheduledTaskInput): Promise<ScheduledTask> {\n if (!db.createScheduledTask) {\n throw new Error('Database adapter does not support task scheduling');\n }\n\n // Calculate initial next run time\n const nextRunAt = calculateNextRun(data.schedule);\n\n // Create task with calculated next run\n const task = await db.createScheduledTask({\n ...data,\n // Note: nextRunAt is set by the database adapter based on schedule\n });\n\n // Update next run time if needed\n if (nextRunAt && db.updateScheduledTask) {\n return db.updateScheduledTask(task.id, {\n ...data,\n });\n }\n\n return task;\n },\n\n async update(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask> {\n if (!db.updateScheduledTask || !db.findScheduledTask) {\n throw new Error('Database adapter does not support task scheduling');\n }\n\n const existing = await db.findScheduledTask(id);\n if (!existing) {\n throw new Error(`Scheduled task not found: ${id}`);\n }\n\n return db.updateScheduledTask(id, data);\n },\n\n async delete(id: string): Promise<void> {\n if (!db.deleteScheduledTask) {\n throw new Error('Database adapter does not support task scheduling');\n }\n await db.deleteScheduledTask(id);\n },\n\n async pause(id: string): Promise<ScheduledTask> {\n if (!db.updateScheduledTask || !db.findScheduledTask) {\n throw new Error('Database adapter does not support task scheduling');\n }\n\n const task = await db.findScheduledTask(id);\n if (!task) {\n throw new Error(`Scheduled task not found: ${id}`);\n }\n\n if (task.status === 'paused') {\n return task;\n }\n\n return db.updateScheduledTask(id, { status: 'paused' });\n },\n\n async resume(id: string): Promise<ScheduledTask> {\n if (!db.updateScheduledTask || !db.findScheduledTask) {\n throw new Error('Database adapter does not support task scheduling');\n }\n\n const task = await db.findScheduledTask(id);\n if (!task) {\n throw new Error(`Scheduled task not found: ${id}`);\n }\n\n if (task.status !== 'paused') {\n return task;\n }\n\n // Recalculate next run time\n const nextRunAt = calculateNextRun(task.schedule);\n\n return db.updateScheduledTask(id, { status: 'active' });\n },\n\n async runNow(id: string): Promise<TaskExecution> {\n if (\n !db.findScheduledTask ||\n !db.createTaskExecution ||\n !db.updateScheduledTask\n ) {\n throw new Error('Database adapter does not support task scheduling');\n }\n\n const task = await db.findScheduledTask(id);\n if (!task) {\n throw new Error(`Scheduled task not found: ${id}`);\n }\n\n // Create execution record\n const execution = await db.createTaskExecution({ taskId: id });\n\n // Update task last run time\n await db.updateScheduledTask(id, {});\n\n return execution;\n },\n\n async getUpcoming(hours: number): Promise<ScheduledTask[]> {\n if (!db.getUpcomingTasks) {\n throw new Error('Database adapter does not support task scheduling');\n }\n return db.getUpcomingTasks(hours);\n },\n\n async getExecutions(taskId: string, limit: number = 10): Promise<TaskExecution[]> {\n if (!db.listTaskExecutions) {\n throw new Error('Database adapter does not support task scheduling');\n }\n return db.listTaskExecutions(taskId, limit);\n },\n\n calculateNextRun,\n };\n}\n\n/**\n * Export utility functions\n */\nexport { parseCronNextRun, isInMaintenanceWindow, calculateNextWindowRun };\n","/**\n * OpenMDM Message Queue Manager\n *\n * Provides persistent message queue management for the MDM system.\n * Ensures reliable message delivery with retry and expiration handling.\n */\n\nimport type {\n MessageQueueManager,\n QueuedMessage,\n EnqueueMessageInput,\n QueueStats,\n DatabaseAdapter,\n} from './types';\n\n/**\n * Default maximum attempts for message delivery\n */\nconst DEFAULT_MAX_ATTEMPTS = 3;\n\n/**\n * Default TTL in seconds (24 hours)\n */\nconst DEFAULT_TTL_SECONDS = 86400;\n\n/**\n * Create a MessageQueueManager instance\n */\nexport function createMessageQueueManager(db: DatabaseAdapter): MessageQueueManager {\n return {\n async enqueue(message: EnqueueMessageInput): Promise<QueuedMessage> {\n if (!db.enqueueMessage) {\n throw new Error('Database adapter does not support message queue');\n }\n\n // Set defaults\n const enrichedMessage: EnqueueMessageInput = {\n ...message,\n priority: message.priority ?? 'normal',\n maxAttempts: message.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,\n ttlSeconds: message.ttlSeconds ?? DEFAULT_TTL_SECONDS,\n };\n\n return db.enqueueMessage(enrichedMessage);\n },\n\n async enqueueBatch(messages: EnqueueMessageInput[]): Promise<QueuedMessage[]> {\n if (!db.enqueueMessage) {\n throw new Error('Database adapter does not support message queue');\n }\n\n const results: QueuedMessage[] = [];\n\n for (const message of messages) {\n const enrichedMessage: EnqueueMessageInput = {\n ...message,\n priority: message.priority ?? 'normal',\n maxAttempts: message.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,\n ttlSeconds: message.ttlSeconds ?? DEFAULT_TTL_SECONDS,\n };\n\n const queued = await db.enqueueMessage(enrichedMessage);\n results.push(queued);\n }\n\n return results;\n },\n\n async dequeue(deviceId: string, limit: number = 10): Promise<QueuedMessage[]> {\n if (!db.dequeueMessages) {\n throw new Error('Database adapter does not support message queue');\n }\n return db.dequeueMessages(deviceId, limit);\n },\n\n async acknowledge(messageId: string): Promise<void> {\n if (!db.acknowledgeMessage) {\n throw new Error('Database adapter does not support message queue');\n }\n await db.acknowledgeMessage(messageId);\n },\n\n async fail(messageId: string, error: string): Promise<void> {\n if (!db.failMessage) {\n throw new Error('Database adapter does not support message queue');\n }\n await db.failMessage(messageId, error);\n },\n\n async retryFailed(maxAttempts: number = DEFAULT_MAX_ATTEMPTS): Promise<number> {\n if (!db.retryFailedMessages) {\n throw new Error('Database adapter does not support message queue');\n }\n return db.retryFailedMessages(maxAttempts);\n },\n\n async purgeExpired(): Promise<number> {\n if (!db.purgeExpiredMessages) {\n throw new Error('Database adapter does not support message queue');\n }\n return db.purgeExpiredMessages();\n },\n\n async getStats(tenantId?: string): Promise<QueueStats> {\n if (!db.getQueueStats) {\n throw new Error('Database adapter does not support message queue');\n }\n return db.getQueueStats(tenantId);\n },\n\n async peek(deviceId: string, limit: number = 10): Promise<QueuedMessage[]> {\n if (!db.peekMessages) {\n throw new Error('Database adapter does not support message queue');\n }\n return db.peekMessages(deviceId, limit);\n },\n };\n}\n\n/**\n * Message priority weights for sorting\n */\nexport const PRIORITY_WEIGHTS = {\n high: 3,\n normal: 2,\n low: 1,\n} as const;\n\n/**\n * Compare messages by priority (higher priority first)\n */\nexport function compareByPriority(a: QueuedMessage, b: QueuedMessage): number {\n return PRIORITY_WEIGHTS[b.priority] - PRIORITY_WEIGHTS[a.priority];\n}\n\n/**\n * Check if a message has expired\n */\nexport function isMessageExpired(message: QueuedMessage): boolean {\n if (!message.expiresAt) return false;\n return new Date(message.expiresAt) < new Date();\n}\n\n/**\n * Check if a message can be retried\n */\nexport function canRetryMessage(message: QueuedMessage): boolean {\n return message.status === 'failed' && message.attempts < message.maxAttempts;\n}\n\n/**\n * Calculate exponential backoff delay for retries\n */\nexport function calculateBackoffDelay(\n attempts: number,\n baseDelayMs: number = 1000,\n maxDelayMs: number = 300000 // 5 minutes\n): number {\n const delay = baseDelayMs * Math.pow(2, attempts - 1);\n return Math.min(delay, maxDelayMs);\n}\n","/**\n * OpenMDM Dashboard Manager\n *\n * Provides analytics and statistics for the MDM dashboard.\n * Aggregates data from devices, commands, and applications.\n */\n\nimport type {\n DashboardManager,\n DashboardStats,\n DeviceStatusBreakdown,\n EnrollmentTrendPoint,\n CommandSuccessRates,\n AppInstallationSummary,\n DatabaseAdapter,\n DeviceStatus,\n} from './types';\n\n/**\n * Create a DashboardManager instance\n */\nexport function createDashboardManager(db: DatabaseAdapter): DashboardManager {\n return {\n async getStats(_tenantId?: string): Promise<DashboardStats> {\n // Use database method if available\n if (db.getDashboardStats) {\n return db.getDashboardStats(_tenantId);\n }\n\n // Fallback: compute from individual queries\n const devices = await db.listDevices({\n limit: 10000, // Get all for counting\n });\n\n const deviceStats = {\n total: devices.total,\n enrolled: devices.devices.filter((d) => d.status === 'enrolled').length,\n active: devices.devices.filter((d) => d.status === 'enrolled').length, // 'active' = 'enrolled' for dashboard\n blocked: devices.devices.filter((d) => d.status === 'blocked').length,\n pending: devices.devices.filter((d) => d.status === 'pending').length,\n };\n\n const allPolicies = await db.listPolicies();\n const policyStats = {\n total: allPolicies.length,\n deployed: allPolicies.filter((p) => p.isDefault).length,\n };\n\n const allApps = await db.listApplications();\n const appStats = {\n total: allApps.length,\n deployed: allApps.length, // All apps in db are considered deployed\n };\n\n // Command stats - get recent commands\n const now = new Date();\n const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);\n const allCommands = await db.listCommands({ limit: 10000 });\n\n const pendingCommands = allCommands.filter((c) => c.status === 'pending');\n const last24hCommands = allCommands.filter(\n (c) => new Date(c.createdAt) >= yesterday\n );\n\n const commandStats = {\n pendingCount: pendingCommands.length,\n last24hTotal: last24hCommands.length,\n last24hSuccess: last24hCommands.filter((c) => c.status === 'completed').length,\n last24hFailed: last24hCommands.filter((c) => c.status === 'failed').length,\n };\n\n // Group stats\n const allGroups = await db.listGroups();\n let groupsWithDevices = 0;\n for (const group of allGroups) {\n const groupDevices = await db.listDevicesInGroup(group.id);\n if (groupDevices.length > 0) groupsWithDevices++;\n }\n\n return {\n devices: deviceStats,\n policies: policyStats,\n applications: appStats,\n commands: commandStats,\n groups: {\n total: allGroups.length,\n withDevices: groupsWithDevices,\n },\n };\n },\n\n async getDeviceStatusBreakdown(_tenantId?: string): Promise<DeviceStatusBreakdown> {\n if (db.getDeviceStatusBreakdown) {\n return db.getDeviceStatusBreakdown(_tenantId);\n }\n\n const devices = await db.listDevices({\n limit: 10000,\n });\n\n const byStatus: Record<DeviceStatus, number> = {\n pending: 0,\n enrolled: 0,\n blocked: 0,\n unenrolled: 0,\n };\n\n const byOs: Record<string, number> = {};\n const byManufacturer: Record<string, number> = {};\n const byModel: Record<string, number> = {};\n\n for (const device of devices.devices) {\n // By status\n byStatus[device.status]++;\n\n // By OS version\n const osKey = device.osVersion || 'Unknown';\n byOs[osKey] = (byOs[osKey] || 0) + 1;\n\n // By manufacturer\n const mfr = device.manufacturer || 'Unknown';\n byManufacturer[mfr] = (byManufacturer[mfr] || 0) + 1;\n\n // By model\n const model = device.model || 'Unknown';\n byModel[model] = (byModel[model] || 0) + 1;\n }\n\n return {\n byStatus,\n byOs,\n byManufacturer,\n byModel,\n };\n },\n\n async getEnrollmentTrend(days: number, _tenantId?: string): Promise<EnrollmentTrendPoint[]> {\n if (db.getEnrollmentTrend) {\n return db.getEnrollmentTrend(days, _tenantId);\n }\n\n // Generate trend data from event history\n const now = new Date();\n const startDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);\n\n // Get enrollment events\n const events = await db.listEvents({\n type: 'device.enrolled',\n startDate,\n limit: 10000,\n });\n\n const unenrollEvents = await db.listEvents({\n type: 'device.unenrolled',\n startDate,\n limit: 10000,\n });\n\n // Group by date\n const trendByDate = new Map<string, { enrolled: number; unenrolled: number }>();\n\n // Initialize all dates\n for (let i = 0; i < days; i++) {\n const date = new Date(startDate.getTime() + i * 24 * 60 * 60 * 1000);\n const dateKey = date.toISOString().split('T')[0];\n trendByDate.set(dateKey, { enrolled: 0, unenrolled: 0 });\n }\n\n // Count events\n for (const event of events) {\n const dateKey = new Date(event.createdAt).toISOString().split('T')[0];\n const entry = trendByDate.get(dateKey);\n if (entry) {\n entry.enrolled++;\n }\n }\n\n for (const event of unenrollEvents) {\n const dateKey = new Date(event.createdAt).toISOString().split('T')[0];\n const entry = trendByDate.get(dateKey);\n if (entry) {\n entry.unenrolled++;\n }\n }\n\n // Get initial device count\n const initialDevices = await db.listDevices({\n limit: 10000,\n });\n let runningTotal = initialDevices.total;\n\n // Build trend points\n const result: EnrollmentTrendPoint[] = [];\n const sortedDates = Array.from(trendByDate.keys()).sort();\n\n for (const dateKey of sortedDates) {\n const entry = trendByDate.get(dateKey)!;\n const netChange = entry.enrolled - entry.unenrolled;\n runningTotal += netChange;\n\n result.push({\n date: new Date(dateKey),\n enrolled: entry.enrolled,\n unenrolled: entry.unenrolled,\n netChange,\n totalDevices: runningTotal,\n });\n }\n\n return result;\n },\n\n async getCommandSuccessRates(_tenantId?: string): Promise<CommandSuccessRates> {\n if (db.getCommandSuccessRates) {\n return db.getCommandSuccessRates(_tenantId);\n }\n\n const now = new Date();\n const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);\n\n const commands = await db.listCommands({ limit: 10000 });\n\n // Overall stats\n const completed = commands.filter((c) => c.status === 'completed').length;\n const failed = commands.filter((c) => c.status === 'failed').length;\n const total = commands.length;\n\n // By type\n const byType: CommandSuccessRates['byType'] = {};\n for (const cmd of commands) {\n if (!byType[cmd.type]) {\n byType[cmd.type] = {\n total: 0,\n completed: 0,\n failed: 0,\n successRate: 0,\n };\n }\n byType[cmd.type].total++;\n if (cmd.status === 'completed') byType[cmd.type].completed++;\n if (cmd.status === 'failed') byType[cmd.type].failed++;\n }\n\n // Calculate success rates\n for (const type of Object.keys(byType)) {\n const stats = byType[type];\n const finishedCount = stats.completed + stats.failed;\n stats.successRate = finishedCount > 0 ? (stats.completed / finishedCount) * 100 : 0;\n }\n\n // Last 24h\n const last24hCommands = commands.filter(\n (c) => new Date(c.createdAt) >= yesterday\n );\n\n return {\n overall: {\n total,\n completed,\n failed,\n successRate:\n completed + failed > 0 ? (completed / (completed + failed)) * 100 : 0,\n },\n byType,\n last24h: {\n total: last24hCommands.length,\n completed: last24hCommands.filter((c) => c.status === 'completed').length,\n failed: last24hCommands.filter((c) => c.status === 'failed').length,\n pending: last24hCommands.filter((c) => c.status === 'pending').length,\n },\n };\n },\n\n async getAppInstallationSummary(_tenantId?: string): Promise<AppInstallationSummary> {\n if (db.getAppInstallationSummary) {\n return db.getAppInstallationSummary(_tenantId);\n }\n\n // Get all apps\n const apps = await db.listApplications();\n const appMap = new Map(apps.map((a) => [a.packageName, a]));\n\n // Get installation statuses if available\n const byStatus: Record<string, number> = {\n installed: 0,\n installing: 0,\n failed: 0,\n pending: 0,\n };\n\n // Count installed apps per device\n const installCounts: Record<string, number> = {};\n\n // Get devices to count installations\n const devices = await db.listDevices({\n limit: 10000,\n });\n\n for (const device of devices.devices) {\n if (device.installedApps) {\n for (const app of device.installedApps) {\n const key = app.packageName;\n installCounts[key] = (installCounts[key] || 0) + 1;\n byStatus['installed']++;\n }\n }\n }\n\n // Top installed apps\n const topInstalled = Object.entries(installCounts)\n .sort(([, a], [, b]) => b - a)\n .slice(0, 10)\n .map(([packageName, count]) => ({\n packageName,\n name: appMap.get(packageName)?.name || packageName,\n installedCount: count,\n }));\n\n return {\n total: Object.values(byStatus).reduce((a, b) => a + b, 0),\n byStatus,\n recentFailures: [], // Would need installation status tracking\n topInstalled,\n };\n },\n };\n}\n","/**\n * OpenMDM Plugin Storage Manager\n *\n * Provides persistent storage for plugin state.\n * Supports both database-backed and in-memory storage.\n */\n\nimport type { PluginStorageAdapter, DatabaseAdapter } from './types';\n\n/**\n * Create a PluginStorageAdapter backed by the database\n */\nexport function createPluginStorageAdapter(db: DatabaseAdapter): PluginStorageAdapter {\n return {\n async get<T>(pluginName: string, key: string): Promise<T | null> {\n if (db.getPluginValue) {\n const value = await db.getPluginValue(pluginName, key);\n return value as T | null;\n }\n\n // Fallback: not supported\n console.warn('Plugin storage not supported by database adapter');\n return null;\n },\n\n async set<T>(pluginName: string, key: string, value: T): Promise<void> {\n if (db.setPluginValue) {\n await db.setPluginValue(pluginName, key, value);\n return;\n }\n\n console.warn('Plugin storage not supported by database adapter');\n },\n\n async delete(pluginName: string, key: string): Promise<void> {\n if (db.deletePluginValue) {\n await db.deletePluginValue(pluginName, key);\n return;\n }\n\n console.warn('Plugin storage not supported by database adapter');\n },\n\n async list(pluginName: string, prefix?: string): Promise<string[]> {\n if (db.listPluginKeys) {\n return db.listPluginKeys(pluginName, prefix);\n }\n\n console.warn('Plugin storage not supported by database adapter');\n return [];\n },\n\n async clear(pluginName: string): Promise<void> {\n if (db.clearPluginData) {\n await db.clearPluginData(pluginName);\n return;\n }\n\n console.warn('Plugin storage not supported by database adapter');\n },\n };\n}\n\n/**\n * Create an in-memory PluginStorageAdapter for testing\n */\nexport function createMemoryPluginStorageAdapter(): PluginStorageAdapter {\n const store = new Map<string, Map<string, unknown>>();\n\n function getPluginStore(pluginName: string): Map<string, unknown> {\n if (!store.has(pluginName)) {\n store.set(pluginName, new Map());\n }\n return store.get(pluginName)!;\n }\n\n return {\n async get<T>(pluginName: string, key: string): Promise<T | null> {\n const pluginStore = getPluginStore(pluginName);\n const value = pluginStore.get(key);\n return value === undefined ? null : (value as T);\n },\n\n async set<T>(pluginName: string, key: string, value: T): Promise<void> {\n const pluginStore = getPluginStore(pluginName);\n pluginStore.set(key, value);\n },\n\n async delete(pluginName: string, key: string): Promise<void> {\n const pluginStore = getPluginStore(pluginName);\n pluginStore.delete(key);\n },\n\n async list(pluginName: string, prefix?: string): Promise<string[]> {\n const pluginStore = getPluginStore(pluginName);\n const keys = Array.from(pluginStore.keys());\n\n if (prefix) {\n return keys.filter((k) => k.startsWith(prefix));\n }\n\n return keys;\n },\n\n async clear(pluginName: string): Promise<void> {\n store.delete(pluginName);\n },\n };\n}\n\n/**\n * Plugin storage utilities\n */\n\n/**\n * Create a namespaced key for plugin storage\n */\nexport function createPluginKey(namespace: string, ...parts: string[]): string {\n return [namespace, ...parts].join(':');\n}\n\n/**\n * Parse a namespaced key\n */\nexport function parsePluginKey(key: string): { namespace: string; parts: string[] } {\n const [namespace, ...parts] = key.split(':');\n return { namespace, parts };\n}\n","/**\n * OpenMDM Database Schema Definition\n *\n * This schema defines the structure for MDM data storage.\n * Database adapters implement this schema for their specific ORM/database.\n *\n * Tables:\n * - mdm_devices: Enrolled devices and their state\n * - mdm_policies: Device policies and configurations\n * - mdm_applications: Registered applications for deployment\n * - mdm_commands: Command queue for device operations\n * - mdm_events: Event log for device activities\n * - mdm_groups: Device grouping for bulk operations\n * - mdm_device_groups: Many-to-many device-group relationships\n * - mdm_push_tokens: FCM/MQTT push notification tokens\n * - mdm_app_deployments: App-to-policy/group deployment mappings\n * - mdm_app_versions: App version history for rollback support\n * - mdm_rollbacks: Rollback operation history and status\n * - mdm_webhook_endpoints: Outbound webhook configuration\n * - mdm_webhook_deliveries: Webhook delivery history\n * - mdm_tenants: Multi-tenant organization isolation\n * - mdm_roles: RBAC role definitions\n * - mdm_users: User accounts for authorization\n * - mdm_user_roles: User-role mapping\n * - mdm_audit_logs: Compliance and audit trail\n * - mdm_scheduled_tasks: Scheduled task definitions\n * - mdm_task_executions: Task execution history\n * - mdm_message_queue: Persistent push message queue\n * - mdm_plugin_storage: Plugin state persistence\n */\n\n// ============================================\n// Schema Column Types\n// ============================================\n\nexport type ColumnType =\n | 'string'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'boolean'\n | 'datetime'\n | 'json'\n | 'enum';\n\nexport interface ColumnDefinition {\n type: ColumnType;\n nullable?: boolean;\n primaryKey?: boolean;\n unique?: boolean;\n default?: unknown;\n enumValues?: string[];\n references?: {\n table: string;\n column: string;\n onDelete?: 'cascade' | 'set null' | 'restrict';\n };\n}\n\nexport interface IndexDefinition {\n columns: string[];\n unique?: boolean;\n name?: string;\n}\n\nexport interface TableDefinition {\n columns: Record<string, ColumnDefinition>;\n indexes?: IndexDefinition[];\n}\n\nexport interface SchemaDefinition {\n tables: Record<string, TableDefinition>;\n}\n\n// ============================================\n// OpenMDM Schema\n// ============================================\n\nexport const mdmSchema: SchemaDefinition = {\n tables: {\n // ----------------------------------------\n // Devices Table\n // ----------------------------------------\n mdm_devices: {\n columns: {\n id: { type: 'string', primaryKey: true },\n external_id: { type: 'string', nullable: true },\n enrollment_id: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'enrolled', 'unenrolled', 'blocked'],\n default: 'pending',\n },\n\n // Device Info\n model: { type: 'string', nullable: true },\n manufacturer: { type: 'string', nullable: true },\n os_version: { type: 'string', nullable: true },\n serial_number: { type: 'string', nullable: true },\n imei: { type: 'string', nullable: true },\n mac_address: { type: 'string', nullable: true },\n android_id: { type: 'string', nullable: true },\n\n // MDM State\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n last_heartbeat: { type: 'datetime', nullable: true },\n last_sync: { type: 'datetime', nullable: true },\n\n // Telemetry (denormalized for quick access)\n battery_level: { type: 'integer', nullable: true },\n storage_used: { type: 'bigint', nullable: true },\n storage_total: { type: 'bigint', nullable: true },\n latitude: { type: 'string', nullable: true }, // Stored as string for precision\n longitude: { type: 'string', nullable: true },\n location_timestamp: { type: 'datetime', nullable: true },\n\n // JSON fields\n installed_apps: { type: 'json', nullable: true },\n tags: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n\n // Timestamps\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enrollment_id'], unique: true },\n { columns: ['status'] },\n { columns: ['policy_id'] },\n { columns: ['last_heartbeat'] },\n { columns: ['mac_address'] },\n { columns: ['serial_number'] },\n ],\n },\n\n // ----------------------------------------\n // Policies Table\n // ----------------------------------------\n mdm_policies: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n is_default: { type: 'boolean', default: false },\n settings: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['is_default'] },\n ],\n },\n\n // ----------------------------------------\n // Applications Table\n // ----------------------------------------\n mdm_applications: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true }, // SHA-256\n size: { type: 'bigint', nullable: true },\n min_sdk_version: { type: 'integer', nullable: true },\n\n // Deployment settings\n show_icon: { type: 'boolean', default: true },\n run_after_install: { type: 'boolean', default: false },\n run_at_boot: { type: 'boolean', default: false },\n is_system: { type: 'boolean', default: false },\n\n // State\n is_active: { type: 'boolean', default: true },\n\n // Metadata\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['package_name'] },\n { columns: ['package_name', 'version'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Commands Table\n // ----------------------------------------\n mdm_commands: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'sent', 'acknowledged', 'completed', 'failed', 'cancelled'],\n default: 'pending',\n },\n result: { type: 'json', nullable: true },\n error: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n sent_at: { type: 'datetime', nullable: true },\n acknowledged_at: { type: 'datetime', nullable: true },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['device_id', 'status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Events Table\n // ----------------------------------------\n mdm_events: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['type'] },\n { columns: ['device_id', 'type'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Groups Table\n // ----------------------------------------\n mdm_groups: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n parent_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_groups', column: 'id', onDelete: 'set null' },\n },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['policy_id'] },\n { columns: ['parent_id'] },\n ],\n },\n\n // ----------------------------------------\n // Device Groups (Many-to-Many)\n // ----------------------------------------\n mdm_device_groups: {\n columns: {\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n group_id: {\n type: 'string',\n references: { table: 'mdm_groups', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id', 'group_id'], unique: true },\n { columns: ['group_id'] },\n ],\n },\n\n // ----------------------------------------\n // Push Tokens (for FCM/MQTT registration)\n // ----------------------------------------\n mdm_push_tokens: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n provider: {\n type: 'enum',\n enumValues: ['fcm', 'mqtt', 'websocket'],\n },\n token: { type: 'string' },\n is_active: { type: 'boolean', default: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['provider', 'token'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Application Deployments (Which apps go to which policies/groups)\n // ----------------------------------------\n mdm_app_deployments: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n // Target can be policy or group\n target_type: {\n type: 'enum',\n enumValues: ['policy', 'group'],\n },\n target_id: { type: 'string' },\n action: {\n type: 'enum',\n enumValues: ['install', 'update', 'uninstall'],\n default: 'install',\n },\n is_required: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['target_type', 'target_id'] },\n ],\n },\n\n // ----------------------------------------\n // App Versions (Version history for rollback support)\n // ----------------------------------------\n mdm_app_versions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true },\n size: { type: 'bigint', nullable: true },\n release_notes: { type: 'text', nullable: true },\n is_minimum_version: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['package_name'] },\n { columns: ['package_name', 'version_code'], unique: true },\n { columns: ['is_minimum_version'] },\n ],\n },\n\n // ----------------------------------------\n // App Rollbacks (Rollback history and status)\n // ----------------------------------------\n mdm_rollbacks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n from_version: { type: 'string' },\n from_version_code: { type: 'integer' },\n to_version: { type: 'string' },\n to_version_code: { type: 'integer' },\n reason: { type: 'text', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'in_progress', 'completed', 'failed'],\n default: 'pending',\n },\n error: { type: 'text', nullable: true },\n initiated_by: { type: 'string', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['package_name'] },\n { columns: ['device_id', 'package_name'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Endpoints (For outbound webhook configuration storage)\n // ----------------------------------------\n mdm_webhook_endpoints: {\n columns: {\n id: { type: 'string', primaryKey: true },\n url: { type: 'string' },\n events: { type: 'json' }, // Array of event types or ['*']\n headers: { type: 'json', nullable: true },\n enabled: { type: 'boolean', default: true },\n description: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enabled'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Deliveries (Delivery history and status)\n // ----------------------------------------\n mdm_webhook_deliveries: {\n columns: {\n id: { type: 'string', primaryKey: true },\n endpoint_id: {\n type: 'string',\n references: { table: 'mdm_webhook_endpoints', column: 'id', onDelete: 'cascade' },\n },\n event_id: { type: 'string' },\n event_type: { type: 'string' },\n payload: { type: 'json' },\n status: {\n type: 'enum',\n enumValues: ['pending', 'success', 'failed'],\n default: 'pending',\n },\n status_code: { type: 'integer', nullable: true },\n error: { type: 'text', nullable: true },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n delivered_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['endpoint_id'] },\n { columns: ['event_type'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Tenants Table (Multi-tenancy)\n // ----------------------------------------\n mdm_tenants: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n slug: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'suspended', 'pending'],\n default: 'pending',\n },\n settings: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['slug'], unique: true },\n { columns: ['status'] },\n ],\n },\n\n // ----------------------------------------\n // Roles Table (RBAC)\n // ----------------------------------------\n mdm_roles: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n permissions: { type: 'json' },\n is_system: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['name'] },\n { columns: ['tenant_id', 'name'], unique: true },\n ],\n },\n\n // ----------------------------------------\n // Users Table (RBAC)\n // ----------------------------------------\n mdm_users: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n email: { type: 'string' },\n name: { type: 'string', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'inactive', 'pending'],\n default: 'pending',\n },\n metadata: { type: 'json', nullable: true },\n last_login_at: { type: 'datetime', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['email'] },\n { columns: ['tenant_id', 'email'], unique: true },\n { columns: ['status'] },\n ],\n },\n\n // ----------------------------------------\n // User Roles (Many-to-Many)\n // ----------------------------------------\n mdm_user_roles: {\n columns: {\n user_id: {\n type: 'string',\n references: { table: 'mdm_users', column: 'id', onDelete: 'cascade' },\n },\n role_id: {\n type: 'string',\n references: { table: 'mdm_roles', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['user_id', 'role_id'], unique: true },\n { columns: ['user_id'] },\n { columns: ['role_id'] },\n ],\n },\n\n // ----------------------------------------\n // Audit Logs Table\n // ----------------------------------------\n mdm_audit_logs: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n user_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_users', column: 'id', onDelete: 'set null' },\n },\n action: { type: 'string' },\n resource: { type: 'string' },\n resource_id: { type: 'string', nullable: true },\n details: { type: 'json', nullable: true },\n ip_address: { type: 'string', nullable: true },\n user_agent: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['user_id'] },\n { columns: ['action'] },\n { columns: ['resource'] },\n { columns: ['resource', 'resource_id'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Scheduled Tasks Table\n // ----------------------------------------\n mdm_scheduled_tasks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n task_type: {\n type: 'enum',\n enumValues: ['command', 'policy_update', 'app_install', 'maintenance', 'custom'],\n },\n schedule: { type: 'json' },\n target: { type: 'json', nullable: true },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'paused', 'completed', 'failed'],\n default: 'active',\n },\n next_run_at: { type: 'datetime', nullable: true },\n last_run_at: { type: 'datetime', nullable: true },\n max_retries: { type: 'integer', default: 3 },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['task_type'] },\n { columns: ['status'] },\n { columns: ['next_run_at'] },\n ],\n },\n\n // ----------------------------------------\n // Task Executions Table\n // ----------------------------------------\n mdm_task_executions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n task_id: {\n type: 'string',\n references: { table: 'mdm_scheduled_tasks', column: 'id', onDelete: 'cascade' },\n },\n status: {\n type: 'enum',\n enumValues: ['running', 'completed', 'failed'],\n default: 'running',\n },\n started_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n devices_processed: { type: 'integer', default: 0 },\n devices_succeeded: { type: 'integer', default: 0 },\n devices_failed: { type: 'integer', default: 0 },\n error: { type: 'text', nullable: true },\n details: { type: 'json', nullable: true },\n },\n indexes: [\n { columns: ['task_id'] },\n { columns: ['status'] },\n { columns: ['started_at'] },\n ],\n },\n\n // ----------------------------------------\n // Message Queue Table\n // ----------------------------------------\n mdm_message_queue: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n message_type: { type: 'string' },\n payload: { type: 'json' },\n priority: {\n type: 'enum',\n enumValues: ['high', 'normal', 'low'],\n default: 'normal',\n },\n status: {\n type: 'enum',\n enumValues: ['pending', 'processing', 'delivered', 'failed', 'expired'],\n default: 'pending',\n },\n attempts: { type: 'integer', default: 0 },\n max_attempts: { type: 'integer', default: 3 },\n last_attempt_at: { type: 'datetime', nullable: true },\n last_error: { type: 'text', nullable: true },\n expires_at: { type: 'datetime', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['priority'] },\n { columns: ['expires_at'] },\n { columns: ['device_id', 'status', 'priority'] },\n ],\n },\n\n // ----------------------------------------\n // Plugin Storage Table\n // ----------------------------------------\n mdm_plugin_storage: {\n columns: {\n plugin_name: { type: 'string' },\n key: { type: 'string' },\n value: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['plugin_name', 'key'], unique: true },\n { columns: ['plugin_name'] },\n ],\n },\n },\n};\n\n// ============================================\n// Schema Helper Functions\n// ============================================\n\n/**\n * Get all table names from the schema\n */\nexport function getTableNames(): string[] {\n return Object.keys(mdmSchema.tables);\n}\n\n/**\n * Get column names for a table\n */\nexport function getColumnNames(tableName: string): string[] {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n return Object.keys(table.columns);\n}\n\n/**\n * Get the primary key column for a table\n */\nexport function getPrimaryKey(tableName: string): string | null {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n\n for (const [name, def] of Object.entries(table.columns)) {\n if (def.primaryKey) return name;\n }\n return null;\n}\n\n/**\n * Convert snake_case column name to camelCase\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Convert camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Transform object keys from snake_case to camelCase\n */\nexport function transformToCamelCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[snakeToCamel(key)] = value;\n }\n return result;\n}\n\n/**\n * Transform object keys from camelCase to snake_case\n */\nexport function transformToSnakeCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[camelToSnake(key)] = value;\n }\n return result;\n}\n","/**\n * OpenMDM Core\n *\n * A flexible, embeddable MDM (Mobile Device Management) SDK.\n * Inspired by better-auth's design philosophy.\n *\n * @example\n * ```typescript\n * import { createMDM } from '@openmdm/core';\n * import { drizzleAdapter } from '@openmdm/drizzle-adapter';\n *\n * const mdm = createMDM({\n * database: drizzleAdapter(db),\n * enrollment: {\n * deviceSecret: process.env.DEVICE_HMAC_SECRET!,\n * autoEnroll: true,\n * },\n * });\n *\n * // Use in your routes\n * const devices = await mdm.devices.list();\n * ```\n */\n\nimport { createHmac, timingSafeEqual, randomUUID } from 'crypto';\nimport type {\n MDMConfig,\n MDMInstance,\n Device,\n Policy,\n Application,\n Command,\n Group,\n Heartbeat,\n EnrollmentRequest,\n EnrollmentResponse,\n DeviceFilter,\n DeviceListResult,\n CreateDeviceInput,\n UpdateDeviceInput,\n CreatePolicyInput,\n UpdatePolicyInput,\n CreateApplicationInput,\n UpdateApplicationInput,\n SendCommandInput,\n CommandFilter,\n CreateGroupInput,\n UpdateGroupInput,\n DeployTarget,\n DeviceManager,\n PolicyManager,\n ApplicationManager,\n CommandManager,\n GroupManager,\n PushAdapter,\n PushResult,\n PushBatchResult,\n PushMessage,\n EventType,\n EventHandler,\n EventPayloadMap,\n MDMEvent,\n MDMPlugin,\n CommandResult,\n InstalledApp,\n WebhookManager,\n TenantManager,\n AuthorizationManager,\n AuditManager,\n ScheduleManager,\n MessageQueueManager,\n DashboardManager,\n PluginStorageAdapter,\n GroupTreeNode,\n GroupHierarchyStats,\n} from './types';\nimport {\n DeviceNotFoundError,\n ApplicationNotFoundError,\n EnrollmentError,\n} from './types';\nimport { createWebhookManager } from './webhooks';\nimport { createTenantManager } from './tenant';\nimport { createAuthorizationManager } from './authorization';\nimport { createAuditManager } from './audit';\nimport { createScheduleManager } from './schedule';\nimport { createMessageQueueManager } from './queue';\nimport { createDashboardManager } from './dashboard';\nimport { createPluginStorageAdapter, createMemoryPluginStorageAdapter } from './plugin-storage';\n\n// Re-export all types\nexport * from './types';\nexport * from './schema';\nexport { createWebhookManager, verifyWebhookSignature } from './webhooks';\nexport type { WebhookPayload } from './webhooks';\n\n// Re-export enterprise manager factories\nexport { createTenantManager } from './tenant';\nexport { createAuthorizationManager } from './authorization';\nexport { createAuditManager } from './audit';\nexport { createScheduleManager } from './schedule';\nexport { createMessageQueueManager } from './queue';\nexport { createDashboardManager } from './dashboard';\nexport { createPluginStorageAdapter, createMemoryPluginStorageAdapter, createPluginKey, parsePluginKey } from './plugin-storage';\n\n/**\n * Create an MDM instance with the given configuration.\n */\nexport function createMDM(config: MDMConfig): MDMInstance {\n const { database, push, enrollment, webhooks: webhooksConfig, plugins = [] } = config;\n\n // Event handlers registry\n const eventHandlers = new Map<EventType, Set<EventHandler<EventType>>>();\n\n // Create push adapter\n const pushAdapter: PushAdapter = push\n ? createPushAdapter(push, database)\n : createStubPushAdapter();\n\n // Create webhook manager if configured\n const webhookManager: WebhookManager | undefined = webhooksConfig\n ? createWebhookManager(webhooksConfig)\n : undefined;\n\n // ============================================\n // Enterprise Managers (optional)\n // ============================================\n\n // Create tenant manager if multi-tenancy is enabled\n const tenantManager: TenantManager | undefined = config.multiTenancy?.enabled\n ? createTenantManager(database)\n : undefined;\n\n // Create authorization manager if authorization is enabled\n const authorizationManager: AuthorizationManager | undefined = config.authorization?.enabled\n ? createAuthorizationManager(database)\n : undefined;\n\n // Create audit manager if audit logging is enabled\n const auditManager: AuditManager | undefined = config.audit?.enabled\n ? createAuditManager(database)\n : undefined;\n\n // Create schedule manager if scheduling is enabled\n const scheduleManager: ScheduleManager | undefined = config.scheduling?.enabled\n ? createScheduleManager(database)\n : undefined;\n\n // Create message queue manager if the database supports it\n const messageQueueManager: MessageQueueManager | undefined = database.enqueueMessage\n ? createMessageQueueManager(database)\n : undefined;\n\n // Create dashboard manager (always available, uses database fallbacks)\n const dashboardManager: DashboardManager = createDashboardManager(database);\n\n // Create plugin storage adapter\n const pluginStorageAdapter: PluginStorageAdapter | undefined =\n config.pluginStorage?.adapter === 'database'\n ? createPluginStorageAdapter(database)\n : config.pluginStorage?.adapter === 'memory'\n ? createMemoryPluginStorageAdapter()\n : undefined;\n\n // Event subscription\n const on = <T extends EventType>(\n event: T,\n handler: EventHandler<T>\n ): (() => void) => {\n if (!eventHandlers.has(event)) {\n eventHandlers.set(event, new Set());\n }\n const handlers = eventHandlers.get(event)!;\n handlers.add(handler as EventHandler<EventType>);\n\n // Return unsubscribe function\n return () => {\n handlers.delete(handler as EventHandler<EventType>);\n };\n };\n\n // Event emission\n const emit = async <T extends EventType>(\n event: T,\n data: EventPayloadMap[T]\n ): Promise<void> => {\n const handlers = eventHandlers.get(event);\n\n // Create event record\n const eventRecord: MDMEvent<EventPayloadMap[T]> = {\n id: randomUUID(),\n deviceId: (data as any).device?.id || (data as any).deviceId || '',\n type: event,\n payload: data,\n createdAt: new Date(),\n };\n\n // Persist event\n try {\n await database.createEvent({\n deviceId: eventRecord.deviceId,\n type: eventRecord.type,\n payload: eventRecord.payload as Record<string, unknown>,\n });\n } catch (error) {\n console.error('[OpenMDM] Failed to persist event:', error);\n }\n\n // Deliver webhooks (async, don't wait)\n if (webhookManager) {\n webhookManager.deliver(eventRecord).catch((error) => {\n console.error('[OpenMDM] Webhook delivery error:', error);\n });\n }\n\n // Call handlers\n if (handlers) {\n for (const handler of handlers) {\n try {\n await handler(eventRecord);\n } catch (error) {\n console.error(`[OpenMDM] Event handler error for ${event}:`, error);\n }\n }\n }\n\n // Call config hook if defined\n if (config.onEvent) {\n try {\n await config.onEvent(eventRecord);\n } catch (error) {\n console.error('[OpenMDM] onEvent hook error:', error);\n }\n }\n };\n\n // ============================================\n // Device Manager\n // ============================================\n\n const devices: DeviceManager = {\n async get(id: string): Promise<Device | null> {\n return database.findDevice(id);\n },\n\n async getByEnrollmentId(enrollmentId: string): Promise<Device | null> {\n return database.findDeviceByEnrollmentId(enrollmentId);\n },\n\n async list(filter?: DeviceFilter): Promise<DeviceListResult> {\n return database.listDevices(filter);\n },\n\n async create(data: CreateDeviceInput): Promise<Device> {\n const device = await database.createDevice(data);\n\n await emit('device.enrolled', { device });\n\n if (config.onDeviceEnrolled) {\n await config.onDeviceEnrolled(device);\n }\n\n return device;\n },\n\n async update(id: string, data: UpdateDeviceInput): Promise<Device> {\n const oldDevice = await database.findDevice(id);\n if (!oldDevice) {\n throw new DeviceNotFoundError(id);\n }\n\n const device = await database.updateDevice(id, data);\n\n // Emit status change event if status changed\n if (data.status && data.status !== oldDevice.status) {\n await emit('device.statusChanged', {\n device,\n oldStatus: oldDevice.status,\n newStatus: data.status,\n });\n }\n\n // Emit policy change event if policy changed\n if (data.policyId !== undefined && data.policyId !== oldDevice.policyId) {\n await emit('device.policyChanged', {\n device,\n oldPolicyId: oldDevice.policyId || undefined,\n newPolicyId: data.policyId || undefined,\n });\n }\n\n return device;\n },\n\n async delete(id: string): Promise<void> {\n const device = await database.findDevice(id);\n if (device) {\n await database.deleteDevice(id);\n await emit('device.unenrolled', { device });\n\n if (config.onDeviceUnenrolled) {\n await config.onDeviceUnenrolled(device);\n }\n }\n },\n\n async assignPolicy(\n deviceId: string,\n policyId: string | null\n ): Promise<Device> {\n const device = await this.update(deviceId, { policyId });\n\n // Notify device of policy change\n await pushAdapter.send(deviceId, {\n type: 'policy.updated',\n payload: { policyId },\n priority: 'high',\n });\n\n return device;\n },\n\n async addToGroup(deviceId: string, groupId: string): Promise<void> {\n await database.addDeviceToGroup(deviceId, groupId);\n },\n\n async removeFromGroup(deviceId: string, groupId: string): Promise<void> {\n await database.removeDeviceFromGroup(deviceId, groupId);\n },\n\n async getGroups(deviceId: string): Promise<Group[]> {\n return database.getDeviceGroups(deviceId);\n },\n\n async sendCommand(\n deviceId: string,\n input: Omit<SendCommandInput, 'deviceId'>\n ): Promise<Command> {\n const command = await database.createCommand({\n ...input,\n deviceId,\n });\n\n // Send via push\n const pushResult = await pushAdapter.send(deviceId, {\n type: `command.${input.type}`,\n payload: {\n commandId: command.id,\n type: input.type,\n ...input.payload,\n },\n priority: 'high',\n });\n\n // Update command status\n if (pushResult.success) {\n await database.updateCommand(command.id, {\n status: 'sent',\n sentAt: new Date(),\n });\n }\n\n if (config.onCommand) {\n await config.onCommand(command);\n }\n\n return database.findCommand(command.id) as Promise<Command>;\n },\n\n async sync(deviceId: string): Promise<Command> {\n return this.sendCommand(deviceId, { type: 'sync' });\n },\n\n async reboot(deviceId: string): Promise<Command> {\n return this.sendCommand(deviceId, { type: 'reboot' });\n },\n\n async lock(deviceId: string, message?: string): Promise<Command> {\n return this.sendCommand(deviceId, {\n type: 'lock',\n payload: message ? { message } : undefined,\n });\n },\n\n async wipe(deviceId: string, preserveData?: boolean): Promise<Command> {\n return this.sendCommand(deviceId, {\n type: preserveData ? 'wipe' : 'factoryReset',\n payload: { preserveData },\n });\n },\n };\n\n // ============================================\n // Policy Manager\n // ============================================\n\n const policies: PolicyManager = {\n async get(id: string): Promise<Policy | null> {\n return database.findPolicy(id);\n },\n\n async getDefault(): Promise<Policy | null> {\n return database.findDefaultPolicy();\n },\n\n async list(): Promise<Policy[]> {\n return database.listPolicies();\n },\n\n async create(data: CreatePolicyInput): Promise<Policy> {\n // If this is being set as default, clear other defaults first\n if (data.isDefault) {\n const existingPolicies = await database.listPolicies();\n for (const policy of existingPolicies) {\n if (policy.isDefault) {\n await database.updatePolicy(policy.id, { isDefault: false });\n }\n }\n }\n\n return database.createPolicy(data);\n },\n\n async update(id: string, data: UpdatePolicyInput): Promise<Policy> {\n // If setting as default, clear other defaults first\n if (data.isDefault) {\n const existingPolicies = await database.listPolicies();\n for (const policy of existingPolicies) {\n if (policy.isDefault && policy.id !== id) {\n await database.updatePolicy(policy.id, { isDefault: false });\n }\n }\n }\n\n const policy = await database.updatePolicy(id, data);\n\n // Notify all devices with this policy\n const devicesResult = await database.listDevices({ policyId: id });\n if (devicesResult.devices.length > 0) {\n const deviceIds = devicesResult.devices.map((d) => d.id);\n await pushAdapter.sendBatch(deviceIds, {\n type: 'policy.updated',\n payload: { policyId: id },\n priority: 'high',\n });\n }\n\n return policy;\n },\n\n async delete(id: string): Promise<void> {\n // Check if any devices use this policy\n const devicesResult = await database.listDevices({ policyId: id });\n if (devicesResult.devices.length > 0) {\n // Remove policy from devices first\n for (const device of devicesResult.devices) {\n await database.updateDevice(device.id, { policyId: null });\n }\n }\n\n await database.deletePolicy(id);\n },\n\n async setDefault(id: string): Promise<Policy> {\n return this.update(id, { isDefault: true });\n },\n\n async getDevices(policyId: string): Promise<Device[]> {\n const result = await database.listDevices({ policyId });\n return result.devices;\n },\n\n async applyToDevice(policyId: string, deviceId: string): Promise<void> {\n await devices.assignPolicy(deviceId, policyId);\n },\n };\n\n // ============================================\n // Application Manager\n // ============================================\n\n const apps: ApplicationManager = {\n async get(id: string): Promise<Application | null> {\n return database.findApplication(id);\n },\n\n async getByPackage(\n packageName: string,\n version?: string\n ): Promise<Application | null> {\n return database.findApplicationByPackage(packageName, version);\n },\n\n async list(activeOnly?: boolean): Promise<Application[]> {\n return database.listApplications(activeOnly);\n },\n\n async register(data: CreateApplicationInput): Promise<Application> {\n return database.createApplication(data);\n },\n\n async update(id: string, data: UpdateApplicationInput): Promise<Application> {\n return database.updateApplication(id, data);\n },\n\n async delete(id: string): Promise<void> {\n await database.deleteApplication(id);\n },\n\n async activate(id: string): Promise<Application> {\n return database.updateApplication(id, { isActive: true });\n },\n\n async deactivate(id: string): Promise<Application> {\n return database.updateApplication(id, { isActive: false });\n },\n\n async deploy(packageName: string, target: DeployTarget): Promise<void> {\n const app = await database.findApplicationByPackage(packageName);\n if (!app) {\n throw new ApplicationNotFoundError(packageName);\n }\n\n const deviceIds: string[] = [];\n\n // Collect target devices\n if (target.devices) {\n deviceIds.push(...target.devices);\n }\n\n if (target.groups) {\n for (const groupId of target.groups) {\n const groupDevices = await database.listDevicesInGroup(groupId);\n deviceIds.push(...groupDevices.map((d) => d.id));\n }\n }\n\n if (target.policies) {\n for (const policyId of target.policies) {\n const result = await database.listDevices({ policyId });\n deviceIds.push(...result.devices.map((d) => d.id));\n }\n }\n\n // Deduplicate\n const uniqueDeviceIds = [...new Set(deviceIds)];\n\n // Send install command to all devices\n if (uniqueDeviceIds.length > 0) {\n await pushAdapter.sendBatch(uniqueDeviceIds, {\n type: 'command.installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n versionCode: app.versionCode,\n url: app.url,\n hash: app.hash,\n },\n priority: 'high',\n });\n\n // Create command records for each device\n for (const deviceId of uniqueDeviceIds) {\n await database.createCommand({\n deviceId,\n type: 'installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n url: app.url,\n },\n });\n }\n }\n },\n\n async installOnDevice(\n packageName: string,\n deviceId: string,\n version?: string\n ): Promise<Command> {\n const app = await database.findApplicationByPackage(packageName, version);\n if (!app) {\n throw new ApplicationNotFoundError(packageName);\n }\n\n return devices.sendCommand(deviceId, {\n type: 'installApp',\n payload: {\n packageName: app.packageName,\n version: app.version,\n versionCode: app.versionCode,\n url: app.url,\n hash: app.hash,\n },\n });\n },\n\n async uninstallFromDevice(\n packageName: string,\n deviceId: string\n ): Promise<Command> {\n return devices.sendCommand(deviceId, {\n type: 'uninstallApp',\n payload: { packageName },\n });\n },\n };\n\n // ============================================\n // Command Manager\n // ============================================\n\n const commands: CommandManager = {\n async get(id: string): Promise<Command | null> {\n return database.findCommand(id);\n },\n\n async list(filter?: CommandFilter): Promise<Command[]> {\n return database.listCommands(filter);\n },\n\n async send(input: SendCommandInput): Promise<Command> {\n return devices.sendCommand(input.deviceId, {\n type: input.type,\n payload: input.payload,\n });\n },\n\n async cancel(id: string): Promise<Command> {\n return database.updateCommand(id, { status: 'cancelled' });\n },\n\n async acknowledge(id: string): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'acknowledged',\n acknowledgedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.acknowledged', { device, command });\n }\n\n return command;\n },\n\n async complete(id: string, result: CommandResult): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'completed',\n result,\n completedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.completed', { device, command, result });\n }\n\n return command;\n },\n\n async fail(id: string, error: string): Promise<Command> {\n const command = await database.updateCommand(id, {\n status: 'failed',\n error,\n completedAt: new Date(),\n });\n\n const device = await database.findDevice(command.deviceId);\n if (device) {\n await emit('command.failed', { device, command, error });\n }\n\n return command;\n },\n\n async getPending(deviceId: string): Promise<Command[]> {\n return database.getPendingCommands(deviceId);\n },\n };\n\n // ============================================\n // Group Manager\n // ============================================\n\n const groups: GroupManager = {\n async get(id: string): Promise<Group | null> {\n return database.findGroup(id);\n },\n\n async list(): Promise<Group[]> {\n return database.listGroups();\n },\n\n async create(data: CreateGroupInput): Promise<Group> {\n return database.createGroup(data);\n },\n\n async update(id: string, data: UpdateGroupInput): Promise<Group> {\n return database.updateGroup(id, data);\n },\n\n async delete(id: string): Promise<void> {\n await database.deleteGroup(id);\n },\n\n async getDevices(groupId: string): Promise<Device[]> {\n return database.listDevicesInGroup(groupId);\n },\n\n async addDevice(groupId: string, deviceId: string): Promise<void> {\n await database.addDeviceToGroup(deviceId, groupId);\n },\n\n async removeDevice(groupId: string, deviceId: string): Promise<void> {\n await database.removeDeviceFromGroup(deviceId, groupId);\n },\n\n async getChildren(groupId: string): Promise<Group[]> {\n const allGroups = await database.listGroups();\n return allGroups.filter((g) => g.parentId === groupId);\n },\n\n async getTree(rootId?: string): Promise<GroupTreeNode[]> {\n // Use database implementation if available\n if (database.getGroupTree) {\n return database.getGroupTree(rootId);\n }\n\n // Fallback: Build tree from flat list\n const allGroups = await database.listGroups();\n const groupMap = new Map(allGroups.map((g) => [g.id, g]));\n\n const buildNode = (group: Group, depth: number, path: string[]): GroupTreeNode => {\n const children = allGroups\n .filter((g) => g.parentId === group.id)\n .map((child) => buildNode(child, depth + 1, [...path, group.id]));\n\n return {\n ...group,\n children,\n depth,\n path,\n effectivePolicyId: group.policyId,\n };\n };\n\n // Find root groups (those with no parent or matching rootId)\n const roots = allGroups.filter((g) =>\n rootId ? g.id === rootId : !g.parentId\n );\n\n return roots.map((root) => buildNode(root, 0, []));\n },\n\n async getAncestors(groupId: string): Promise<Group[]> {\n // Use database implementation if available\n if (database.getGroupAncestors) {\n return database.getGroupAncestors(groupId);\n }\n\n // Fallback: Traverse up the tree\n const ancestors: Group[] = [];\n const allGroups = await database.listGroups();\n const groupMap = new Map(allGroups.map((g) => [g.id, g]));\n\n let current = groupMap.get(groupId);\n while (current?.parentId) {\n const parent = groupMap.get(current.parentId);\n if (parent) {\n ancestors.push(parent);\n current = parent;\n } else {\n break;\n }\n }\n\n return ancestors;\n },\n\n async getDescendants(groupId: string): Promise<Group[]> {\n // Use database implementation if available\n if (database.getGroupDescendants) {\n return database.getGroupDescendants(groupId);\n }\n\n // Fallback: Find all descendants recursively\n const allGroups = await database.listGroups();\n const descendants: Group[] = [];\n\n const findDescendants = (parentId: string) => {\n const children = allGroups.filter((g) => g.parentId === parentId);\n for (const child of children) {\n descendants.push(child);\n findDescendants(child.id);\n }\n };\n\n findDescendants(groupId);\n return descendants;\n },\n\n async move(groupId: string, newParentId: string | null): Promise<Group> {\n // Validate that we're not creating a cycle\n if (newParentId) {\n const ancestors = await this.getAncestors(newParentId);\n if (ancestors.some((a) => a.id === groupId)) {\n throw new Error('Cannot move group: would create circular reference');\n }\n }\n\n return database.updateGroup(groupId, { parentId: newParentId });\n },\n\n async getEffectivePolicy(groupId: string): Promise<Policy | null> {\n // Use database implementation if available\n if (database.getGroupEffectivePolicy) {\n return database.getGroupEffectivePolicy(groupId);\n }\n\n // Fallback: Walk up the tree to find first policy\n const group = await database.findGroup(groupId);\n if (!group) return null;\n\n if (group.policyId) {\n return database.findPolicy(group.policyId);\n }\n\n // Check ancestors\n const ancestors = await this.getAncestors(groupId);\n for (const ancestor of ancestors) {\n if (ancestor.policyId) {\n return database.findPolicy(ancestor.policyId);\n }\n }\n\n return null;\n },\n\n async getHierarchyStats(): Promise<GroupHierarchyStats> {\n // Use database implementation if available\n if (database.getGroupHierarchyStats) {\n return database.getGroupHierarchyStats();\n }\n\n // Fallback: Compute from flat list\n const allGroups = await database.listGroups();\n let maxDepth = 0;\n let groupsWithDevices = 0;\n let groupsWithPolicies = 0;\n\n for (const group of allGroups) {\n // Calculate depth\n const ancestors = await this.getAncestors(group.id);\n maxDepth = Math.max(maxDepth, ancestors.length);\n\n // Check for devices\n const devices = await database.listDevicesInGroup(group.id);\n if (devices.length > 0) groupsWithDevices++;\n\n // Check for policies\n if (group.policyId) groupsWithPolicies++;\n }\n\n return {\n totalGroups: allGroups.length,\n maxDepth,\n groupsWithDevices,\n groupsWithPolicies,\n };\n },\n };\n\n // ============================================\n // Enrollment\n // ============================================\n\n const enroll = async (\n request: EnrollmentRequest\n ): Promise<EnrollmentResponse> => {\n // Validate method if restricted\n if (\n enrollment?.allowedMethods &&\n !enrollment.allowedMethods.includes(request.method)\n ) {\n throw new EnrollmentError(\n `Enrollment method '${request.method}' is not allowed`\n );\n }\n\n // Verify signature if secret is configured\n if (enrollment?.deviceSecret) {\n const isValid = verifyEnrollmentSignature(\n request,\n enrollment.deviceSecret\n );\n if (!isValid) {\n throw new EnrollmentError('Invalid enrollment signature');\n }\n }\n\n // Custom validation\n if (enrollment?.validate) {\n const isValid = await enrollment.validate(request);\n if (!isValid) {\n throw new EnrollmentError('Enrollment validation failed');\n }\n }\n\n // Determine enrollment ID\n const enrollmentId =\n request.macAddress ||\n request.serialNumber ||\n request.imei ||\n request.androidId;\n\n if (!enrollmentId) {\n throw new EnrollmentError(\n 'Device must provide at least one identifier (macAddress, serialNumber, imei, or androidId)'\n );\n }\n\n // Check if device already exists\n let device = await database.findDeviceByEnrollmentId(enrollmentId);\n\n if (device) {\n // Device re-enrolling\n device = await database.updateDevice(device.id, {\n status: 'enrolled',\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n lastSync: new Date(),\n });\n } else if (enrollment?.autoEnroll) {\n // Auto-create device\n device = await database.createDevice({\n enrollmentId,\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n serialNumber: request.serialNumber,\n imei: request.imei,\n macAddress: request.macAddress,\n androidId: request.androidId,\n policyId: request.policyId || enrollment.defaultPolicyId,\n });\n\n // Add to default group if configured\n if (enrollment.defaultGroupId) {\n await database.addDeviceToGroup(device.id, enrollment.defaultGroupId);\n }\n } else if (enrollment?.requireApproval) {\n // Create pending device\n device = await database.createDevice({\n enrollmentId,\n model: request.model,\n manufacturer: request.manufacturer,\n osVersion: request.osVersion,\n serialNumber: request.serialNumber,\n imei: request.imei,\n macAddress: request.macAddress,\n androidId: request.androidId,\n });\n // Status remains 'pending'\n } else {\n throw new EnrollmentError(\n 'Device not registered and auto-enroll is disabled'\n );\n }\n\n // Get policy\n let policy: Policy | null = null;\n if (device.policyId) {\n policy = await database.findPolicy(device.policyId);\n }\n if (!policy) {\n policy = await database.findDefaultPolicy();\n }\n\n // Generate JWT token for device auth\n const tokenSecret =\n config.auth?.deviceTokenSecret || enrollment?.deviceSecret || '';\n const tokenExpiration = config.auth?.deviceTokenExpiration || 365 * 24 * 60 * 60;\n const token = generateDeviceToken(device.id, tokenSecret, tokenExpiration);\n\n // Emit enrollment event\n await emit('device.enrolled', { device });\n\n // Call config hook if defined\n if (config.onDeviceEnrolled) {\n await config.onDeviceEnrolled(device);\n }\n\n // Call plugin hooks\n for (const plugin of plugins) {\n if (plugin.onEnroll) {\n await plugin.onEnroll(device, request);\n }\n if (plugin.onDeviceEnrolled) {\n await plugin.onDeviceEnrolled(device);\n }\n }\n\n return {\n deviceId: device.id,\n enrollmentId: device.enrollmentId,\n policyId: policy?.id,\n policy: policy || undefined,\n serverUrl: config.serverUrl || '',\n pushConfig: {\n provider: push?.provider || 'polling',\n fcmSenderId: (push?.fcmCredentials as any)?.project_id,\n mqttUrl: push?.mqttUrl,\n mqttTopic: push?.mqttTopicPrefix\n ? `${push.mqttTopicPrefix}/${device.id}`\n : `openmdm/devices/${device.id}`,\n pollingInterval: push?.pollingInterval || 60,\n },\n token,\n tokenExpiresAt: new Date(Date.now() + tokenExpiration * 1000),\n };\n };\n\n // ============================================\n // Heartbeat Processing\n // ============================================\n\n const processHeartbeat = async (\n deviceId: string,\n heartbeat: Heartbeat\n ): Promise<void> => {\n const device = await database.findDevice(deviceId);\n if (!device) {\n throw new DeviceNotFoundError(deviceId);\n }\n\n // Update device with heartbeat data\n const updateData: UpdateDeviceInput = {\n lastHeartbeat: heartbeat.timestamp,\n batteryLevel: heartbeat.batteryLevel,\n storageUsed: heartbeat.storageUsed,\n storageTotal: heartbeat.storageTotal,\n installedApps: heartbeat.installedApps,\n };\n\n if (heartbeat.location) {\n updateData.location = heartbeat.location;\n }\n\n const updatedDevice = await database.updateDevice(deviceId, updateData);\n\n // Emit heartbeat event\n await emit('device.heartbeat', { device: updatedDevice, heartbeat });\n\n // Emit location event if location changed\n if (heartbeat.location) {\n await emit('device.locationUpdated', {\n device: updatedDevice,\n location: heartbeat.location,\n });\n }\n\n // Check for app changes\n if (device.installedApps && heartbeat.installedApps) {\n const oldApps = new Map(\n device.installedApps.map((a) => [a.packageName, a])\n );\n const newApps = new Map(\n heartbeat.installedApps.map((a) => [a.packageName, a])\n );\n\n // Check for new installs\n for (const [pkg, app] of newApps) {\n const oldApp = oldApps.get(pkg);\n if (!oldApp) {\n await emit('app.installed', { device: updatedDevice, app });\n } else if (oldApp.version !== app.version) {\n await emit('app.updated', {\n device: updatedDevice,\n app,\n oldVersion: oldApp.version,\n });\n }\n }\n\n // Check for uninstalls\n for (const [pkg] of oldApps) {\n if (!newApps.has(pkg)) {\n await emit('app.uninstalled', {\n device: updatedDevice,\n packageName: pkg,\n });\n }\n }\n }\n\n // Call config hook if defined\n if (config.onHeartbeat) {\n await config.onHeartbeat(updatedDevice, heartbeat);\n }\n\n // Call plugin hooks\n for (const plugin of plugins) {\n if (plugin.onHeartbeat) {\n await plugin.onHeartbeat(updatedDevice, heartbeat);\n }\n }\n };\n\n // ============================================\n // Token Verification\n // ============================================\n\n const verifyDeviceToken = async (\n token: string\n ): Promise<{ deviceId: string } | null> => {\n try {\n const tokenSecret =\n config.auth?.deviceTokenSecret || enrollment?.deviceSecret || '';\n\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const [header, payload, signature] = parts;\n\n // Verify signature\n const expectedSignature = createHmac('sha256', tokenSecret)\n .update(`${header}.${payload}`)\n .digest('base64url');\n\n if (signature !== expectedSignature) {\n return null;\n }\n\n // Decode payload\n const decoded = JSON.parse(\n Buffer.from(payload, 'base64url').toString('utf-8')\n );\n\n // Check expiration\n if (decoded.exp && decoded.exp < Math.floor(Date.now() / 1000)) {\n return null;\n }\n\n return { deviceId: decoded.sub };\n } catch {\n return null;\n }\n };\n\n // ============================================\n // Plugin Management\n // ============================================\n\n const getPlugins = (): MDMPlugin[] => plugins;\n\n const getPlugin = (name: string): MDMPlugin | undefined => {\n return plugins.find((p) => p.name === name);\n };\n\n // ============================================\n // Create Instance\n // ============================================\n\n const instance: MDMInstance = {\n devices,\n policies,\n apps,\n commands,\n groups,\n push: pushAdapter,\n webhooks: webhookManager,\n db: database,\n config,\n on,\n emit,\n enroll,\n processHeartbeat,\n verifyDeviceToken,\n getPlugins,\n getPlugin,\n // Enterprise managers (optional)\n tenants: tenantManager,\n authorization: authorizationManager,\n audit: auditManager,\n schedules: scheduleManager,\n messageQueue: messageQueueManager,\n dashboard: dashboardManager,\n pluginStorage: pluginStorageAdapter,\n };\n\n // Initialize plugins\n (async () => {\n for (const plugin of plugins) {\n if (plugin.onInit) {\n try {\n await plugin.onInit(instance);\n console.log(`[OpenMDM] Plugin initialized: ${plugin.name}`);\n } catch (error) {\n console.error(\n `[OpenMDM] Failed to initialize plugin ${plugin.name}:`,\n error\n );\n }\n }\n }\n })();\n\n return instance;\n}\n\n// ============================================\n// Push Adapter Factory\n// ============================================\n\nfunction createPushAdapter(\n config: MDMConfig['push'],\n database: MDMConfig['database']\n): PushAdapter {\n if (!config) {\n return createStubPushAdapter();\n }\n\n // The actual implementations will be provided by separate packages\n // This is a base implementation that logs and stores tokens\n return {\n async send(deviceId: string, message: PushMessage): Promise<PushResult> {\n console.log(\n `[OpenMDM] Push to ${deviceId}: ${message.type}`,\n message.payload\n );\n\n // In production, this would be replaced by FCM/MQTT adapter\n return { success: true, messageId: randomUUID() };\n },\n\n async sendBatch(\n deviceIds: string[],\n message: PushMessage\n ): Promise<PushBatchResult> {\n console.log(\n `[OpenMDM] Push to ${deviceIds.length} devices: ${message.type}`\n );\n\n const results = deviceIds.map((deviceId) => ({\n deviceId,\n result: { success: true, messageId: randomUUID() },\n }));\n\n return {\n successCount: deviceIds.length,\n failureCount: 0,\n results,\n };\n },\n\n async registerToken(deviceId: string, token: string): Promise<void> {\n // Polling doesn't use push tokens\n if (config.provider === 'polling') {\n return;\n }\n await database.upsertPushToken({\n deviceId,\n provider: config.provider,\n token,\n });\n },\n\n async unregisterToken(deviceId: string): Promise<void> {\n // Polling doesn't use push tokens\n if (config.provider === 'polling') {\n return;\n }\n await database.deletePushToken(deviceId, config.provider);\n },\n };\n}\n\nfunction createStubPushAdapter(): PushAdapter {\n return {\n async send(deviceId: string, message: PushMessage): Promise<PushResult> {\n console.log(`[OpenMDM] Push (stub): ${deviceId} <- ${message.type}`);\n return { success: true, messageId: 'stub' };\n },\n\n async sendBatch(\n deviceIds: string[],\n message: PushMessage\n ): Promise<PushBatchResult> {\n console.log(\n `[OpenMDM] Push (stub): ${deviceIds.length} devices <- ${message.type}`\n );\n return {\n successCount: deviceIds.length,\n failureCount: 0,\n results: deviceIds.map((deviceId) => ({\n deviceId,\n result: { success: true, messageId: 'stub' },\n })),\n };\n },\n };\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\nfunction verifyEnrollmentSignature(\n request: EnrollmentRequest,\n secret: string\n): boolean {\n const { signature, ...data } = request;\n\n if (!signature) {\n return false;\n }\n\n // Reconstruct the message that was signed\n // Format: identifier:timestamp\n const identifier =\n data.macAddress || data.serialNumber || data.imei || data.androidId || '';\n const message = `${identifier}:${data.timestamp}`;\n\n const expectedSignature = createHmac('sha256', secret)\n .update(message)\n .digest('hex');\n\n try {\n return timingSafeEqual(\n Buffer.from(signature, 'hex'),\n Buffer.from(expectedSignature, 'hex')\n );\n } catch {\n return false;\n }\n}\n\nfunction generateDeviceToken(\n deviceId: string,\n secret: string,\n expirationSeconds: number\n): string {\n const header = Buffer.from(\n JSON.stringify({ alg: 'HS256', typ: 'JWT' })\n ).toString('base64url');\n\n const now = Math.floor(Date.now() / 1000);\n const payload = Buffer.from(\n JSON.stringify({\n sub: deviceId,\n iat: now,\n exp: now + expirationSeconds,\n iss: 'openmdm',\n })\n ).toString('base64url');\n\n const signature = createHmac('sha256', secret)\n .update(`${header}.${payload}`)\n .digest('base64url');\n\n return `${header}.${payload}.${signature}`;\n}\n"]}