@hanzo/iam 0.9.0 → 0.9.2

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.
Files changed (74) hide show
  1. package/dist/auth.cjs +111 -0
  2. package/dist/auth.cjs.map +1 -0
  3. package/dist/auth.d.cts +19 -0
  4. package/dist/auth.d.ts +7 -4
  5. package/dist/auth.js +94 -121
  6. package/dist/auth.js.map +1 -1
  7. package/dist/betterauth.cjs +34 -0
  8. package/dist/betterauth.cjs.map +1 -0
  9. package/dist/betterauth.d.cts +64 -0
  10. package/dist/betterauth.d.ts +8 -11
  11. package/dist/betterauth.js +28 -62
  12. package/dist/betterauth.js.map +1 -1
  13. package/dist/billing.cjs +8 -0
  14. package/dist/billing.cjs.map +1 -0
  15. package/dist/billing.d.cts +2 -0
  16. package/dist/billing.d.ts +2 -16
  17. package/dist/billing.js +5 -17
  18. package/dist/billing.js.map +1 -1
  19. package/dist/browser.cjs +680 -0
  20. package/dist/browser.cjs.map +1 -0
  21. package/dist/browser.d.cts +217 -0
  22. package/dist/browser.d.ts +10 -7
  23. package/dist/browser.js +645 -663
  24. package/dist/browser.js.map +1 -1
  25. package/dist/index.cjs +1087 -0
  26. package/dist/index.cjs.map +1 -0
  27. package/dist/{client.d.ts → index.d.cts} +23 -4
  28. package/dist/index.d.ts +86 -23
  29. package/dist/index.js +1077 -29
  30. package/dist/index.js.map +1 -1
  31. package/dist/nextauth.cjs +35 -0
  32. package/dist/nextauth.cjs.map +1 -0
  33. package/dist/nextauth.d.cts +55 -0
  34. package/dist/nextauth.d.ts +5 -8
  35. package/dist/nextauth.js +30 -66
  36. package/dist/nextauth.js.map +1 -1
  37. package/dist/passport.cjs +47 -0
  38. package/dist/passport.cjs.map +1 -0
  39. package/dist/passport.d.cts +50 -0
  40. package/dist/passport.d.ts +13 -7
  41. package/dist/passport.js +39 -65
  42. package/dist/passport.js.map +1 -1
  43. package/dist/react.cjs +1434 -0
  44. package/dist/react.cjs.map +1 -0
  45. package/dist/react.d.cts +133 -0
  46. package/dist/react.d.ts +18 -50
  47. package/dist/react.js +1399 -494
  48. package/dist/react.js.map +1 -1
  49. package/dist/types.cjs +4 -0
  50. package/dist/types.cjs.map +1 -0
  51. package/dist/types.d.cts +219 -0
  52. package/dist/types.d.ts +25 -24
  53. package/dist/types.js +2 -5
  54. package/dist/types.js.map +1 -1
  55. package/package.json +28 -15
  56. package/src/betterauth.ts +1 -1
  57. package/src/nextauth.ts +1 -1
  58. package/src/passport.ts +7 -10
  59. package/dist/auth.d.ts.map +0 -1
  60. package/dist/betterauth.d.ts.map +0 -1
  61. package/dist/billing.d.ts.map +0 -1
  62. package/dist/browser.d.ts.map +0 -1
  63. package/dist/client.d.ts.map +0 -1
  64. package/dist/client.js +0 -292
  65. package/dist/client.js.map +0 -1
  66. package/dist/index.d.ts.map +0 -1
  67. package/dist/nextauth.d.ts.map +0 -1
  68. package/dist/passport.d.ts.map +0 -1
  69. package/dist/pkce.d.ts +0 -13
  70. package/dist/pkce.d.ts.map +0 -1
  71. package/dist/pkce.js +0 -36
  72. package/dist/pkce.js.map +0 -1
  73. package/dist/react.d.ts.map +0 -1
  74. package/dist/types.d.ts.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,kDAAkD;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAErD,wFAAwF;AACxF,mDAAmD;AAEnD,iBAAiB;AACjB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE1D,gEAAgE;AAChE,OAAO,EAAE,GAAG,EAAE,UAAU,EAA+C,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"sources":["../src/client.ts","../src/auth.ts","../src/pkce.ts","../src/browser.ts"],"names":["tokens"],"mappings":";;;AAcA,IAAM,kBAAA,GAAqB,GAAA;AAEpB,IAAM,YAAN,MAAgB;AAAA,EACJ,OAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACT,cAAA,GAAoE,IAAA;AAAA,EAE5E,YAAY,MAAA,EAAmB;AAC7B,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAClD,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,QAAA;AACvB,IAAA,IAAA,CAAK,eAAe,MAAA,CAAO,YAAA;AAC3B,IAAA,IAAA,CAAK,UAAU,MAAA,CAAO,OAAA;AACtB,IAAA,IAAA,CAAK,UAAU,MAAA,CAAO,OAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,OAAA,CACZ,IAAA,EACA,IAAA,EAOY;AACZ,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,EAAM,KAAK,OAAO,CAAA;AACtC,IAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,MAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,EAAG;AAChD,QAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAAA,MAC3B;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,KAAA,GAAQ,UAAA;AAAA,MACZ,MAAM,WAAW,KAAA,EAAM;AAAA,MACvB,MAAM,SAAA,IAAa;AAAA,KACrB;AAEA,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,MAAA,EAAQ;AAAA,KACV;AACA,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,IAC9C;AACA,IAAA,IAAI,MAAM,IAAA,EAAM;AACd,MAAA,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AAAA,IAC5B;AAGA,IAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,CAAC,IAAA,EAAM,KAAA,EAAO;AACrC,MAAA,MAAM,cAAc,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,KAAK,YAAY,CAAA,CAAA;AACzD,MAAA,MAAM,KAAA,GACJ,OAAO,MAAA,KAAW,WAAA,GACd,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAA,GAC1C,IAAA,CAAK,WAAW,CAAA;AACtB,MAAA,OAAA,CAAQ,aAAA,GAAgB,SAAS,KAAK,CAAA,CAAA;AAAA,IACxC;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,CAAI,UAAS,EAAG;AAAA,QACtC,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,QACxB,OAAA;AAAA,QACA,MAAM,IAAA,EAAM,IAAA,GAAO,KAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA,CAAA;AAAA,QAC/C,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAED,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,QAAA,MAAM,IAAI,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,CAAA,EAAG,GAAA,CAAI,UAAU,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA,CAAG,IAAA,EAAM,CAAA;AAAA,MACvE;AAEA,MAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,IACzB,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAA,GAAuC;AAC3C,IAAA,MAAM,YAAA,GAAe,IAAI,EAAA,GAAK,GAAA;AAC9B,IAAA,IAAI,IAAA,CAAK,kBAAkB,IAAA,CAAK,GAAA,KAAQ,IAAA,CAAK,cAAA,CAAe,YAAY,YAAA,EAAc;AACpF,MAAA,OAAO,KAAK,cAAA,CAAe,IAAA;AAAA,IAC7B;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB;AAAA,KACF;AACA,IAAA,IAAA,CAAK,iBAAiB,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,CAAK,KAAI,EAAE;AACpD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,UAAA,GAA8B;AAClC,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,OAAO,SAAA,CAAU,QAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAoB,MAAA,EAMN;AAClB,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,SAAA,CAAU,sBAAsB,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,WAAA,EAAa,IAAA,CAAK,QAAQ,CAAA;AAC/C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAC5C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,MAAA,CAAO,WAAW,CAAA;AACvD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,MAAA,CAAO,KAAK,CAAA;AAC1C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,MAAA,CAAO,SAAS,sBAAsB,CAAA;AACpE,IAAA,IAAI,OAAO,aAAA,EAAe;AACxB,MAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,MAAA,CAAO,aAAa,CAAA;AAC3D,MAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAA,CAAO,uBAAuB,MAAM,CAAA;AAAA,IACpF;AACA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAAA;AAAA,EAGA,MAAM,aAAa,MAAA,EAIQ;AACzB,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,MAC/B,UAAA,EAAY,oBAAA;AAAA,MACZ,WAAW,IAAA,CAAK,QAAA;AAAA,MAChB,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,cAAc,MAAA,CAAO;AAAA,KACtB,CAAA;AACD,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,IAAA,CAAK,YAAY,CAAA;AAAA,IAC7C;AACA,IAAA,IAAI,OAAO,YAAA,EAAc;AACvB,MAAA,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,MAAA,CAAO,YAAY,CAAA;AAAA,IAC/C;AAEA,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,kBAAkB,CAAA;AACrE,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,SAAA,CAAU,cAAA,EAAgB;AAAA,QAChD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,QAC/D,IAAA,EAAM,KAAK,QAAA,EAAS;AAAA,QACpB,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AACD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,QAAA,MAAM,IAAI,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAE,CAAA;AAAA,MACpE;AACA,MAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,IACzB,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAc,MAAA,EAIO;AACzB,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,MAC/B,UAAA,EAAY,UAAA;AAAA,MACZ,WAAW,IAAA,CAAK,QAAA;AAAA,MAChB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,KACxB,CAAA;AACD,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,IAAA,CAAK,YAAY,CAAA;AAAA,IAC7C;AAEA,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,kBAAkB,CAAA;AACrE,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,SAAA,CAAU,cAAA,EAAgB;AAAA,QAChD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,QAC/D,IAAA,EAAM,KAAK,QAAA,EAAS;AAAA,QACpB,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AACD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,QAAA,MAAM,IAAI,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAE,CAAA;AAAA,MACpE;AACA,MAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,IACzB,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,aAAa,YAAA,EAA8C;AAC/D,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,MAC/B,UAAA,EAAY,eAAA;AAAA,MACZ,WAAW,IAAA,CAAK,QAAA;AAAA,MAChB,aAAA,EAAe;AAAA,KAChB,CAAA;AACD,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,IAAA,CAAK,YAAY,CAAA;AAAA,IAC7C;AAEA,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,kBAAkB,CAAA;AACrE,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,SAAA,CAAU,cAAA,EAAgB;AAAA,QAChD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,QAC/D,IAAA,EAAM,KAAK,QAAA,EAAS;AAAA,QACpB,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AACD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,QAAA,MAAM,IAAI,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAE,CAAA;AAAA,MACnE;AACA,MAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,IACzB,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,WAAA,EAAuC;AACvD,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,kBAAkB,CAAA;AACrE,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,SAAA,CAAU,iBAAA,EAAmB;AAAA,QACnD,OAAA,EAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,WAAW,CAAA,CAAA,EAAG;AAAA,QAClD,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AACD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,IAAI,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,0BAA0B,CAAA;AAAA,MAC9D;AACA,MAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,IACzB,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,OAAA,CAAQ,MAAA,EAAgB,KAAA,EAAyC;AACrE,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA,CAAiC,eAAA,EAAiB;AAAA,MACxE,MAAA,EAAQ,EAAE,EAAA,EAAI,MAAA,EAAO;AAAA,MACrB;AAAA,KACD,CAAA;AACD,IAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAiB,KAAA,EAA4C;AACjE,IAAA,MAAM,KAAA,GAAQ,KAAK,OAAA,IAAW,OAAA;AAC9B,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,wBAAA;AAAA,MACA,EAAE,MAAA,EAAQ,EAAE,KAAA,IAAS,KAAA;AAAM,KAC7B;AACA,IAAA,OAAO,IAAA,CAAK,QAAQ,EAAC;AAAA,EACvB;AAAA;AAAA,EAGA,MAAM,eAAA,CACJ,EAAA,EACA,KAAA,EACiC;AACjC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,uBAAA;AAAA,MACA,EAAE,MAAA,EAAQ,EAAE,EAAA,IAAM,KAAA;AAAM,KAC1B;AACA,IAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,EACtB;AAAA;AAAA,EAGA,MAAM,oBAAA,CACJ,MAAA,EACA,KAAA,EAC4B;AAG5B,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAQ,KAAK,CAAA;AAC7C,IAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAC;AAEnB,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,eAAA;AAAA,MACrB,CAAA,MAAA,EAAS,KAAK,KAAK,CAAA,CAAA;AAAA,MACnB;AAAA,KACF;AACA,IAAA,OAAO,GAAA,GAAM,CAAC,GAAG,CAAA,GAAI,EAAC;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,KAAA,EAAuC;AACvD,IAAA,MAAM,KAAA,GAAQ,KAAK,OAAA,IAAW,OAAA;AAC9B,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,mBAAA;AAAA,MACA,EAAE,MAAA,EAAQ,EAAE,KAAA,IAAS,KAAA;AAAM,KAC7B;AACA,IAAA,OAAO,IAAA,CAAK,QAAQ,EAAC;AAAA,EACvB;AAAA;AAAA,EAGA,MAAM,UAAA,CAAW,EAAA,EAAY,KAAA,EAA4C;AACvE,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,kBAAA;AAAA,MACA,EAAE,MAAA,EAAQ,EAAE,EAAA,IAAM,KAAA;AAAM,KAC1B;AACA,IAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,EACtB;AAAA;AAAA,EAGA,MAAM,uBAAA,CACJ,YAAA,EACA,KAAA,EACuB;AACvB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,OAAA;AAAA,MACtB,gCAAA;AAAA,MACA,EAAE,MAAA,EAAQ,EAAE,YAAA,IAAgB,KAAA;AAAM,KACpC;AACA,IAAA,OAAO,IAAA,CAAK,QAAQ,EAAC;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAA,CACJ,IAAA,EACA,IAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,OAAA,CAAW,IAAA,EAAM,IAAI,CAAA;AAAA,EACnC;AACF;AAMO,IAAM,WAAA,GAAN,cAA0B,KAAA,CAAM;AAAA,EAC5B,MAAA;AAAA,EAET,WAAA,CAAY,QAAgB,OAAA,EAAiB;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AACF;AC1XA,IAAM,QAAA,uBAAe,GAAA,EAAmD;AAExE,SAAS,cAAc,OAAA,EAAwD;AAC7E,EAAA,IAAI,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA;AACjC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAA,GAAS,kBAAA,CAAmB,IAAI,GAAA,CAAI,OAAO,CAAC,CAAA;AAC5C,IAAA,QAAA,CAAS,GAAA,CAAI,SAAS,MAAM,CAAA;AAAA,EAC9B;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,cAAA,GAAuB;AACrC,EAAA,QAAA,CAAS,KAAA,EAAM;AACjB;AAOA,IAAM,cAAA,uBAAqB,GAAA,EAA6B;AACxD,IAAM,gBAAA,GAAmB,IAAI,EAAA,GAAK,GAAA;AAElC,eAAe,eAAe,SAAA,EAAiE;AAC7F,EAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,GAAA,CAAI,OAAO,CAAA;AACzC,EAAA,IAAI,UAAU,IAAA,CAAK,GAAA,EAAI,GAAI,MAAA,CAAO,YAAY,gBAAA,EAAkB;AAC9D,IAAA,OAAO,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,EAAS,MAAA,EAAQ,OAAO,MAAA,EAAO;AAAA,EAC1D;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,GAAK,CAAA;AACxD,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,iCAAA,CAAA,EAAqC;AAAA,MACrE,QAAQ,UAAA,CAAW,MAAA;AAAA,MACnB,OAAA,EAAS,EAAE,MAAA,EAAQ,kBAAA;AAAmB,KACvC,CAAA;AACD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IACxD;AACA,IAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,IAAA,MAAM,UAAU,IAAA,CAAK,QAAA;AACrB,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,OAAA;AAC9B,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,MAAM,0CAA0C,CAAA;AAAA,IAC5D;AACA,IAAA,cAAA,CAAe,GAAA,CAAI,SAAS,EAAE,OAAA,EAAS,QAAQ,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,EAAG,CAAA;AACtE,IAAA,OAAO,EAAE,SAAS,MAAA,EAAO;AAAA,EAC3B,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,EACpB;AACF;AAYA,eAAsB,aAAA,CACpB,OACA,MAAA,EACwB;AACxB,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,mBAAA,EAAoB;AAAA,EAClD;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAAY,MAAM,cAAA,CAAe,MAAA,CAAO,SAAS,CAAA;AACvD,IAAA,OAAA,GAAU,SAAA,CAAU,OAAA;AACpB,IAAA,MAAA,GAAS,SAAA,CAAU,MAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,sBAAA,EAAuB;AAAA,EACrD;AAEA,EAAA,MAAM,MAAA,GAAS,cAAc,OAAO,CAAA;AAEpC,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,KAAA,EAAO,MAAA,EAAQ;AAAA,MAC5C,MAAA;AAAA,MACA,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,cAAA,EAAgB;AAAA;AAAA,KACjB,CAAA;AACD,IAAA,OAAA,GAAU,MAAA,CAAO,OAAA;AAAA,EACnB,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,EAAG;AAC/B,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,mBAAA,EAAoB;AAAA,IAClD;AACA,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,UAAU,CAAA,EAAG;AAEhC,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,KAAA,EAAO,MAAA,EAAQ;AAAA,UAC5C,MAAA;AAAA,UACA,cAAA,EAAgB;AAAA,SACjB,CAAA;AACD,QAAA,OAAA,GAAU,MAAA,CAAO,OAAA;AAAA,MACnB,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,uBAAA,EAAwB;AAAA,MACtD;AAAA,IACF,CAAA,MAAO;AACL,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,uBAAA,EAAwB;AAAA,IACtD;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,OAAA;AAGf,EAAA,MAAM,MACJ,MAAA,CAAO,GAAA,KACN,OAAO,MAAA,CAAO,UAAU,QAAA,IAAY,OAAO,MAAA,CAAO,IAAA,KAAS,WACxD,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,CAAA,EAAI,MAAA,CAAO,IAAI,CAAA,CAAA,GAC9B,MAAA,CAAA;AAEN,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,qBAAA,EAAsB;AAAA,EACpD;AAGA,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,MAAM,MAAA,GAAS,CAAA,GAAI,MAAM,CAAC,CAAA,GAAI,OAAO,OAAA,IAAW,SAAA;AAE9D,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA;AAAA,IACJ,MAAA,EAAQ,GAAA;AAAA,IACR,OAAO,OAAO,MAAA,CAAO,KAAA,KAAU,QAAA,GAAW,OAAO,KAAA,GAAQ,MAAA;AAAA,IACzD,IAAA,EACE,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GACnB,MAAA,CAAO,IAAA,GACP,OAAO,MAAA,CAAO,kBAAA,KAAuB,QAAA,GACnC,MAAA,CAAO,kBAAA,GACP,MAAA;AAAA,IACR,QAAQ,OAAO,MAAA,CAAO,OAAA,KAAY,QAAA,GAAW,OAAO,OAAA,GAAU,MAAA;AAAA,IAC9D,KAAA;AAAA,IACA;AAAA,GACF;AACF;;;ACvJA,SAAS,qBAAqB,MAAA,EAAwB;AACpD,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,OAAO,MAAM,IAAA,CAAK,KAAA,EAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAC5D,IAAA,CAAK,EAAE,CAAA,CACP,KAAA,CAAM,GAAG,MAAM,CAAA;AACpB;AAEA,eAAe,OAAO,KAAA,EAAqC;AACzD,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,EAAA,OAAO,OAAO,MAAA,CAAO,MAAA,CAAO,WAAW,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAC,CAAA;AAC9D;AAEA,SAAS,gBAAgB,MAAA,EAA6B;AACpD,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,MAAM,CAAA;AACnC,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAA,IAAU,MAAA,CAAO,aAAa,IAAI,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,IAAA,CAAK,MAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC/E;AAGA,eAAsB,qBAAA,GAGnB;AACD,EAAA,MAAM,YAAA,GAAe,qBAAqB,EAAE,CAAA;AAC5C,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,YAAY,CAAA;AACtC,EAAA,MAAM,aAAA,GAAgB,gBAAgB,IAAI,CAAA;AAC1C,EAAA,OAAO,EAAE,cAAc,aAAA,EAAc;AACvC;AAGO,SAAS,aAAA,GAAwB;AACtC,EAAA,OAAO,qBAAqB,EAAE,CAAA;AAChC;;;AC1BA,IAAM,cAAA,GAAiB,YAAA;AACvB,IAAM,SAAA,GAAY,GAAG,cAAc,CAAA,KAAA,CAAA;AACnC,IAAM,iBAAA,GAAoB,GAAG,cAAc,CAAA,aAAA,CAAA;AAC3C,IAAM,gBAAA,GAAmB,GAAG,cAAc,CAAA,YAAA,CAAA;AAC1C,IAAM,iBAAA,GAAoB,GAAG,cAAc,CAAA,aAAA,CAAA;AAC3C,IAAM,YAAA,GAAe,GAAG,cAAc,CAAA,QAAA,CAAA;AACtC,IAAM,cAAA,GAAiB,GAAG,cAAc,CAAA,UAAA,CAAA;AAuBjC,IAAM,MAAN,MAAU;AAAA,EACE,MAAA;AAAA,EACA,OAAA;AAAA,EACT,cAAA,GAAuC,IAAA;AAAA,EAE/C,YAAY,MAAA,EAAmB;AAC7B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,cAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAAA,GAAuC;AACnD,IAAA,IAAI,IAAA,CAAK,cAAA,EAAgB,OAAO,IAAA,CAAK,cAAA;AAErC,IAAA,MAAM,UAAU,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAKxD,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,iCAAA,CAAA,EAAqC;AAAA,QACrE,OAAA,EAAS,EAAE,MAAA,EAAQ,kBAAA;AAAmB,OACvC,CAAA;AACD,MAAA,IAAI,IAAI,EAAA,EAAI;AACV,QAAA,IAAA,CAAK,cAAA,GAAkB,MAAM,GAAA,CAAI,IAAA,EAAK;AACtC,QAAA,OAAO,IAAA,CAAK,cAAA;AAAA,MACd;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,IAAA,CAAK,cAAA,GAAiB;AAAA,MACpB,MAAA,EAAQ,OAAA;AAAA,MACR,sBAAA,EAAwB,GAAG,OAAO,CAAA,gBAAA,CAAA;AAAA,MAClC,cAAA,EAAgB,GAAG,OAAO,CAAA,YAAA,CAAA;AAAA,MAC1B,iBAAA,EAAmB,GAAG,OAAO,CAAA,eAAA,CAAA;AAAA,MAC7B,QAAA,EAAU,GAAG,OAAO,CAAA,iBAAA,CAAA;AAAA,MACpB,wBAAA,EAA0B,CAAC,MAAA,EAAQ,OAAA,EAAS,UAAU,CAAA;AAAA,MACtD,qBAAA,EAAuB,CAAC,oBAAA,EAAsB,UAAA,EAAY,eAAe,CAAA;AAAA,MACzE,gBAAA,EAAkB,CAAC,QAAA,EAAU,OAAA,EAAS,SAAS;AAAA,KACjD;AACA,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,eAAe,MAAA,EAAuE;AAC1F,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,EAAE,YAAA,EAAc,aAAA,EAAc,GAAI,MAAM,qBAAA,EAAsB;AACpE,IAAA,MAAM,QAAQ,aAAA,EAAc;AAE5B,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,SAAA,EAAW,KAAK,CAAA;AACrC,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,YAAY,CAAA;AAEpD,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,SAAA,CAAU,sBAAsB,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,WAAA,EAAa,IAAA,CAAK,OAAO,QAAQ,CAAA;AACtD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAC5C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,IAAA,CAAK,OAAO,WAAW,CAAA;AAC5D,IAAA,GAAA,CAAI,aAAa,GAAA,CAAI,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,SAAS,sBAAsB,CAAA;AACzE,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AAEpD,IAAA,IAAI,QAAQ,gBAAA,EAAkB;AAC5B,MAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,gBAAgB,CAAA,EAAG;AAC5D,QAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAAA,MAC3B;AAAA,IACF;AAEA,IAAA,MAAA,CAAO,QAAA,CAAS,IAAA,GAAO,GAAA,CAAI,QAAA,EAAS;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,eAAe,WAAA,EAAyC;AAC5D,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,WAAA,IAAe,MAAA,CAAO,SAAS,IAAI,CAAA;AACvD,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA;AAE1C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,mBAAmB,CAAA,IAAK,KAAA;AAC1D,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,aAAA,EAAgB,IAAI,CAAA,CAAE,CAAA;AAAA,IACxC;AAEA,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA;AAC1C,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA;AACjD,IAAA,IAAI,UAAA,IAAc,UAAU,UAAA,EAAY;AACtC,MAAA,MAAM,IAAI,MAAM,kDAA6C,CAAA;AAAA,IAC/D;AAGA,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAc,CAAA;AACvD,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,SAAS,CAAA;AACjC,MAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,iBAAiB,CAAA;AAEzC,MAAA,MAAMA,OAAAA,GAAwB;AAAA,QAC5B,YAAA,EAAc,WAAA;AAAA,QACd,UAAA,EAAY,QAAA;AAAA,QACZ,aAAA,EAAe,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAe,CAAA,IAAK,MAAA;AAAA,QACxD,UAAA,EAAY;AAAA,OACd;AACA,MAAA,IAAA,CAAK,YAAYA,OAAM,CAAA;AACvB,MAAA,OAAO,WAAWA,OAAM,CAAA;AAAA,IAC1B;AAGA,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACxC,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAiB,CAAA;AAC3D,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAI,MAAM,gEAA2D,CAAA;AAAA,IAC7E;AAGA,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,SAAS,CAAA;AACjC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,iBAAiB,CAAA;AAEzC,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,MAC/B,UAAA,EAAY,oBAAA;AAAA,MACZ,SAAA,EAAW,KAAK,MAAA,CAAO,QAAA;AAAA,MACvB,IAAA;AAAA,MACA,YAAA,EAAc,KAAK,MAAA,CAAO,WAAA;AAAA,MAC1B,aAAA,EAAe;AAAA,KAChB,CAAA;AAGD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,YAAA,GACzB,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,gBAC/C,SAAA,CAAU,cAAA;AAEd,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,QAAA,EAAU;AAAA,MAChC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,MAC/D,IAAA,EAAM,KAAK,QAAA;AAAS,KACrB,CAAA;AAED,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,IAAI,MAAM,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,CAAA;AAAA,IAClE;AAEA,IAAA,MAAM,MAAA,GAAU,MAAM,GAAA,CAAI,IAAA,EAAK;AAC/B,IAAA,IAAA,CAAK,YAAY,MAAM,CAAA;AACvB,IAAA,OAAO,WAAW,MAAM,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAA,GAAwC;AAC5C,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAiB,CAAA;AAC3D,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,IAC9C;AAEA,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,MAC/B,UAAA,EAAY,eAAA;AAAA,MACZ,SAAA,EAAW,KAAK,MAAA,CAAO,QAAA;AAAA,MACvB,aAAA,EAAe;AAAA,KAChB,CAAA;AAED,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,YAAA,GACzB,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,gBAC/C,SAAA,CAAU,cAAA;AAEd,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,QAAA,EAAU;AAAA,MAChC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,MAC/D,IAAA,EAAM,KAAK,QAAA;AAAS,KACrB,CAAA;AAED,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,IAAI,MAAM,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,CAAA;AAAA,IACjE;AAEA,IAAA,MAAM,MAAA,GAAU,MAAM,GAAA,CAAI,IAAA,EAAK;AAC/B,IAAA,IAAA,CAAK,YAAY,MAAM,CAAA;AACvB,IAAA,OAAO,WAAW,MAAM,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,YAAY,MAAA,EAII;AACpB,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,EAAE,YAAA,EAAc,aAAA,EAAc,GAAI,MAAM,qBAAA,EAAsB;AACpE,IAAA,MAAM,QAAQ,aAAA,EAAc;AAE5B,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,SAAA,EAAW,KAAK,CAAA;AACrC,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,YAAY,CAAA;AAEpD,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,SAAA,CAAU,sBAAsB,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,WAAA,EAAa,IAAA,CAAK,OAAO,QAAQ,CAAA;AACtD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAC5C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,IAAA,CAAK,OAAO,WAAW,CAAA;AAC5D,IAAA,GAAA,CAAI,aAAa,GAAA,CAAI,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,SAAS,sBAAsB,CAAA;AACzE,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AAEpD,IAAA,IAAI,QAAQ,gBAAA,EAAkB;AAC5B,MAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,gBAAgB,CAAA,EAAG;AAC5D,QAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAAA,MAC3B;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,GAAA;AAC/B,IAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,GAAA;AACjC,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,GAAA,CAAW,MAAA,CAAO,aAAa,KAAA,IAAS,CAAA;AAC5D,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,GAAA,CAAW,MAAA,CAAO,cAAc,MAAA,IAAU,CAAA;AAE7D,IAAA,OAAO,IAAI,OAAA,CAAkB,CAAC,OAAA,EAAS,MAAA,KAAW;AAChD,MAAA,MAAM,QAAQ,MAAA,CAAO,IAAA;AAAA,QACnB,IAAI,QAAA,EAAS;AAAA,QACb,iBAAA;AAAA,QACA,SAAS,KAAK,CAAA,QAAA,EAAW,MAAM,CAAA,MAAA,EAAS,IAAI,QAAQ,GAAG,CAAA,sBAAA;AAAA,OACzD;AAEA,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,uDAAkD,CAAC,CAAA;AACpE,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,QAAA,IAAI;AACF,UAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,YAAA,aAAA,CAAc,QAAQ,CAAA;AACtB,YAAA,MAAA,CAAO,IAAI,KAAA,CAAM,0CAA0C,CAAC,CAAA;AAC5D,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,QAAA,GAAW,MAAM,QAAA,CAAS,IAAA;AAChC,UAAA,IAAI,QAAA,CAAS,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,WAAW,CAAA,EAAG;AAChD,YAAA,aAAA,CAAc,QAAQ,CAAA;AACtB,YAAA,KAAA,CAAM,KAAA,EAAM;AACZ,YAAA,IAAA,CAAK,cAAA,CAAe,QAAQ,CAAA,CAAE,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,UACpD;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF,GAAG,GAAG,CAAA;AAAA,IACR,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,YAAA,CAAa,SAAA,GAAY,GAAA,EAAgC;AAC7D,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,EAAE,YAAA,EAAc,aAAA,EAAc,GAAI,MAAM,qBAAA,EAAsB;AACpE,IAAA,MAAM,QAAQ,aAAA,EAAc;AAE5B,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,SAAA,EAAW,KAAK,CAAA;AACrC,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,YAAY,CAAA;AAEpD,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,SAAA,CAAU,sBAAsB,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,WAAA,EAAa,IAAA,CAAK,OAAO,QAAQ,CAAA;AACtD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAC5C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,IAAA,CAAK,OAAO,WAAW,CAAA;AAC5D,IAAA,GAAA,CAAI,aAAa,GAAA,CAAI,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,SAAS,sBAAsB,CAAA;AACzE,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,QAAA,EAAU,MAAM,CAAA;AAErC,IAAA,OAAO,IAAI,OAAA,CAAyB,CAAC,OAAA,KAAY;AAC/C,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAA,CAAO,MAAM,OAAA,GAAU,MAAA;AAEvB,MAAA,MAAM,OAAA,GAAU,WAAW,MAAM;AAC/B,QAAA,OAAA,EAAQ;AACR,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,MACd,GAAG,SAAS,CAAA;AAEZ,MAAA,MAAM,UAAU,MAAM;AACpB,QAAA,YAAA,CAAa,OAAO,CAAA;AACpB,QAAA,MAAA,CAAO,MAAA,EAAO;AACd,QAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,SAAS,CAAA;AACjC,QAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,iBAAiB,CAAA;AAAA,MAC3C,CAAA;AAEA,MAAA,MAAA,CAAO,gBAAA,CAAiB,QAAQ,MAAM;AACpC,QAAA,IAAI;AACF,UAAA,MAAM,SAAA,GAAY,MAAA,CAAO,aAAA,EAAe,QAAA,CAAS,IAAA;AACjD,UAAA,IAAI,aAAa,SAAA,CAAU,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,WAAW,CAAA,EAAG;AAC9D,YAAA,OAAA,EAAQ;AACR,YAAA,IAAA,CAAK,cAAA,CAAe,SAAS,CAAA,CAAE,IAAA;AAAA,cAC7B,CAAC,MAAA,KAAW,OAAA,CAAQ,MAAM,CAAA;AAAA,cAC1B,MAAM,QAAQ,IAAI;AAAA,aACpB;AAAA,UACF;AAAA,QACF,CAAA,CAAA,MAAQ;AAEN,UAAA,OAAA,EAAQ;AACR,UAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,QACd;AAAA,MACF,CAAC,CAAA;AAED,MAAA,MAAA,CAAO,GAAA,GAAM,IAAI,QAAA,EAAS;AAC1B,MAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA,IAClC,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAY,MAAA,EAA6B;AAC/C,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,gBAAA,EAAkB,MAAA,CAAO,YAAY,CAAA;AAC1D,IAAA,IAAI,OAAO,aAAA,EAAe;AACxB,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,MAAA,CAAO,aAAa,CAAA;AAAA,IAC9D;AACA,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,YAAA,EAAc,MAAA,CAAO,QAAQ,CAAA;AAAA,IACpD;AACA,IAAA,IAAI,OAAO,UAAA,EAAY;AACrB,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,OAAO,UAAA,GAAa,GAAA;AACnD,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,cAAA,EAAgB,MAAA,CAAO,SAAS,CAAC,CAAA;AAAA,IACxD;AAAA,EACF;AAAA;AAAA,EAGA,cAAA,GAAgC;AAC9B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,gBAAgB,CAAA;AAAA,EAC9C;AAAA;AAAA,EAGA,eAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAiB,CAAA;AAAA,EAC/C;AAAA;AAAA,EAGA,UAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,YAAY,CAAA;AAAA,EAC1C;AAAA;AAAA,EAGA,cAAA,GAA0B;AACxB,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,cAAc,CAAA;AACrD,IAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AACvB,IAAA,OAAO,IAAA,CAAK,GAAA,EAAI,IAAK,MAAA,CAAO,SAAS,CAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBAAA,GAA8C;AAClD,IAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,EAAe;AAClC,IAAA,IAAI,KAAA,IAAS,CAAC,IAAA,CAAK,cAAA,EAAe,EAAG;AACnC,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,CAAK,iBAAgB,EAAG;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,kBAAA,EAAmB;AAC7C,QAAA,OAAO,MAAA,CAAO,WAAA;AAAA,MAChB,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,WAAA,GAAoB;AAClB,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,gBAAgB,CAAA;AACxC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,iBAAiB,CAAA;AACzC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,YAAY,CAAA;AACpC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,cAAc,CAAA;AACtC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,SAAS,CAAA;AACjC,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,iBAAiB,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAA,GAAgD;AACpD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,mBAAA,EAAoB;AAC7C,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,MAAM,+CAA0C,CAAA;AAAA,IAC5D;AACA,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,MAAA,CAAO,YAAA,GAC5B,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,mBAC/C,SAAA,CAAU,iBAAA;AACd,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,WAAA,EAAa;AAAA,MACnC,OAAA,EAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAG,KAC7C,CAAA;AACD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,IACzD;AACA,IAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,MAAA,EAA+C;AAC1D,IAAA,MAAM,OAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACrD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,KAAA;AACnC,IAAY,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW;AACnC,IAAA,IAAI,GAAA,GAAM,CAAA,EAAG,IAAI,CAAA,QAAA,EAAW,GAAG,CAAA,CAAA;AAC/B,IAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,MAAA,GAAA,IAAO,sBAAA;AAAA,IACT;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA,EAGA,kBAAkB,QAAA,EAA0B;AAC1C,IAAA,MAAM,OAAO,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACrD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,UAAA;AACnC,IAAA,OAAO,CAAA,EAAG,IAAI,CAAA,OAAA,EAAU,GAAG,IAAI,QAAQ,CAAA,CAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,oBAAA,CACJ,OAAA,EACA,MAAA,GAA+D,OAAA,EACrB;AAE1C,IAAA,IAAI,MAAA,KAAW,SAAS,MAAA,GAAS,QAAA;AACjC,IAAA,MAAM,UAAU,OAAA,IAAW,OAAA;AAC3B,IAAA,MAAM,IAAA,GAAO,OAAA,GAAU,OAAA,CAAQ,KAAA,GAAQ,OAAA,CAAQ,KAAA;AAC/C,IAAA,MAAM,MAAA,GAAiC;AAAA,MACrC,aAAA,EAAe,CAAA,MAAA,EAAS,IAAA,CAAK,MAAA,CAAO,WAAW,KAAK,CAAA,CAAA;AAAA,MACpD,IAAA;AAAA,MACA,IAAA,EAAM,UAAU,OAAA,GAAU,OAAA;AAAA,MAC1B,MAAA;AAAA,MACA,WAAA,EAAa,MAAA;AAAA,MACb,YAAA,EAAc;AAAA,KAChB;AACA,IAAA,IAAI,OAAA,EAAS,MAAA,CAAO,WAAA,GAAc,OAAA,CAAQ,WAAA;AAE1C,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,MAAA,CAAO,UAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,uBAAA,CAAA;AACxD,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAC3B,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,MAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB,MAAM,EAAE,QAAA;AAAS,KAC5C,CAAA;AACD,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AAC9C,IAAA,IAAI,KAAK,MAAA,KAAW,IAAA,EAAM,OAAO,EAAE,IAAI,IAAA,EAAK;AAC5C,IAAA,MAAM,GAAA,GAAO,IAAA,CAAK,GAAA,IAAkB,CAAA,+BAAA,EAAkC,IAAI,MAAM,CAAA,CAAA,CAAA;AAGhF,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,cAAc,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,UAAU,CAAA,EAAG,OAAO,EAAE,EAAA,EAAI,IAAA,EAAK;AAChF,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,GAAA,EAAI;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eAAA,CAAgB,KAAA,EAAe,WAAA,EAAmE;AACtG,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,MAAA,CAAO,UAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,eAAA,CAAA;AACxD,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAC3B,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,WAAA,EAAa,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,KAAA;AAAA,QACpC,KAAA;AAAA,QACA;AAAA,OACD;AAAA,KACF,CAAA;AACD,IAAA,IAAI,IAAI,MAAA,KAAW,GAAA,EAAK,OAAO,EAAE,QAAQ,KAAA,EAAM;AAC/C,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAO,CAAA,wBAAA,EAA2B,GAAA,CAAI,MAAM,CAAA,CAAA,CAAA,EAAI;AACrF,IAAA,OAAO,EAAE,QAAQ,IAAA,EAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,MAAA,EAU6C;AACxD,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,IAAY,MAAA,CAAO,IAAA;AAC3C,IAAA,MAAM,WAAW,MAAA,CAAO,QAAA,IAAY,CAAA,GAAA,EAAM,IAAA,CAAK,KAAK,CAAA,CAAA,CAAA;AACpD,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,WAAA,EAAa,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,KAAA;AAAA,MACpC,YAAA,EAAc,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,UAAA;AAAA,MACrC,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,QAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA,EAAS,QAAA;AAAA,MACT,SAAA,EAAW;AAAA,KACb;AACA,IAAA,IAAI,MAAA,CAAO,WAAW,OAAA,EAAS;AAC7B,MAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA;AACpB,MAAA,IAAI,MAAA,CAAO,SAAA,EAAW,IAAA,CAAK,SAAA,GAAY,MAAA,CAAO,SAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA;AACpB,MAAA,IAAA,CAAK,cAAc,MAAA,CAAO,WAAA;AAC1B,MAAA,IAAI,MAAA,CAAO,SAAA,EAAW,IAAA,CAAK,SAAA,GAAY,MAAA,CAAO,SAAA;AAC9C,MAAA,IAAI,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,KAAA,GAAQ,MAAA,CAAO,KAAA;AACtC,MAAA,IAAI,MAAA,CAAO,SAAA,EAAW,IAAA,CAAK,SAAA,GAAY,MAAA,CAAO,SAAA;AAAA,IAChD;AACA,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,MAAA,CAAO,UAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,OAAA,CAAA;AACxD,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAC3B,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AACD,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AAC9C,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,IAAA,EAAM,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,IAAA,EAAK;AACzE,IAAA,OAAO,EAAE,IAAI,KAAA,EAAO,KAAA,EAAQ,KAAK,GAAA,IAAkB,CAAA,eAAA,EAAkB,GAAA,CAAI,MAAM,CAAA,CAAA,CAAA,EAAI;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,qBAAqB,MAAA,EAKiC;AAC1D,IAAA,MAAM,EAAE,YAAA,EAAc,aAAA,EAAc,GAAI,MAAM,qBAAA,EAAsB;AACpE,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,YAAY,CAAA;AAEpD,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,MAAA,CAAQ,CAAA;AACxE,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AAEpD,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,CAAI,UAAS,EAAG;AAAA,MACtC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,WAAA,EAAa,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,KAAA;AAAA,QACpC,YAAA,EAAc,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,UAAA;AAAA,QACrC,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,IAAA,EAAM,OAAO,IAAA,IAAQ,MAAA;AAAA,QACrB,QAAA,EAAU,KAAK,MAAA,CAAO,QAAA;AAAA,QACtB,WAAA,EAAa,MAAA,CAAO,WAAA,IAAe,IAAA,CAAK,MAAA,CAAO,WAAA;AAAA,QAC/C,aAAA;AAAA,QACA,mBAAA,EAAqB,MAAA;AAAA,QACrB,UAAA,EAAY;AAAA,OACb;AAAA,KACF,CAAA;AACD,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AAC9C,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,IAAA,IAAQ,IAAA,CAAK,IAAA,EAAM,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,IAAA,CAAK,IAAA,EAAe;AACpF,IAAA,OAAO,EAAE,IAAI,KAAA,EAAO,KAAA,EAAQ,KAAK,GAAA,IAAkB,CAAA,cAAA,EAAiB,GAAA,CAAI,MAAM,CAAA,CAAA,CAAA,EAAI;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAAA,CAAqB,IAAA,EAAc,WAAA,EAAyC;AAChF,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAiB,CAAA;AAC3D,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAI,MAAM,gEAA2D,CAAA;AAAA,IAC7E;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAW,iBAAiB,CAAA;AAEzC,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,YAAA,GACzB,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,gBAC/C,SAAA,CAAU,cAAA;AAEd,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,MAC/B,UAAA,EAAY,oBAAA;AAAA,MACZ,SAAA,EAAW,KAAK,MAAA,CAAO,QAAA;AAAA,MACvB,IAAA;AAAA,MACA,YAAA,EAAc,WAAA,IAAe,IAAA,CAAK,MAAA,CAAO,WAAA;AAAA,MACzC,aAAA,EAAe;AAAA,KAChB,CAAA;AACD,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,QAAA,EAAU;AAAA,MAChC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,MAC/D,IAAA,EAAM,KAAK,QAAA;AAAS,KACrB,CAAA;AACD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,GAAA,GAAM,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAC1E,MAAA,MAAM,IAAI,KAAA,CAAO,GAAA,CAA+B,iBAAA,IAAsB,GAAA,CAA+B,SAAS,uBAAuB,CAAA;AAAA,IACvI;AACA,IAAA,MAAM,MAAA,GAAU,MAAM,GAAA,CAAI,IAAA,EAAK;AAC/B,IAAA,IAAA,CAAK,YAAY,MAAM,CAAA;AACvB,IAAA,OAAO,WAAW,MAAM,CAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAkB,MAAA,EAKF;AACpB,IAAA,MAAM,SAAA,GAAY,CAAC,MAAA,CAAO,KAAA,EAAO,CAAA,EAAG,OAAO,WAAW,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,CAAE,CAAA;AACvE,IAAA,IAAI,SAAA,GAAY,EAAA;AAChB,IAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,oBAAA,CAAqB;AAAA,QAC7C,QAAA;AAAA,QACA,UAAU,MAAA,CAAO,IAAA;AAAA,QACjB,aAAa,MAAA,CAAO;AAAA,OACrB,CAAA;AACD,MAAA,IAAI,MAAA,CAAO,EAAA,IAAM,MAAA,CAAO,IAAA,EAAM;AAC5B,QAAA,OAAO,IAAA,CAAK,oBAAA,CAAqB,MAAA,CAAO,IAAA,EAAM,OAAO,WAAW,CAAA;AAAA,MAClE;AACA,MAAA,SAAA,GAAY,OAAO,KAAA,IAAS,SAAA;AAAA,IAC9B;AACA,IAAA,MAAM,IAAI,KAAA,CAAM,SAAA,IAAa,wBAAwB,CAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,GAAwB;AAC5B,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,gBAAgB,CAAA;AACnD,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,CAAM,GAAG,IAAA,CAAK,MAAA,CAAO,UAAU,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,aAAA,CAAA,EAAiB;AAAA,QACvE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,QAAQ,EAAE,aAAA,EAAe,UAAU,KAAK,CAAA,CAAA,KAAO;AAAC,OAC1D,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,iBAAA,CAAkB,QAAA,EAAkB,KAAA,GAAQ,sBAAA,EAAyC;AACzF,IAAA,MAAM,EAAE,YAAA,EAAc,aAAA,EAAc,GAAI,MAAM,qBAAA,EAAsB;AACpE,IAAA,MAAM,QAAQ,aAAA,EAAc;AAC5B,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,SAAA,EAAW,KAAK,CAAA;AACrC,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,iBAAA,EAAmB,YAAY,CAAA;AAEpD,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,EAAa;AAC1C,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,SAAA,CAAU,sBAAsB,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,WAAA,EAAa,IAAA,CAAK,OAAO,QAAQ,CAAA;AACtD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAC5C,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,IAAA,CAAK,OAAO,WAAW,CAAA;AAC5D,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,aAAa,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AACpD,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,QAAQ,CAAA;AACzC,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAA,GAAmC;AACvC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,mBAAA,EAAoB;AAC7C,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,WAAA,EAAY;AACjC,IAAA,OAAO;AAAA,MACL,GAAA,EAAM,EAAE,GAAA,IAAkB,EAAA;AAAA,MAC1B,OAAO,CAAA,CAAE,KAAA;AAAA,MACT,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,WAAW,CAAA,CAAE,UAAA;AAAA,MACb,YAAY,CAAA,CAAE,WAAA;AAAA,MACd,aAAa,CAAA,CAAE,YAAA;AAAA,MACf,eAAe,CAAA,CAAE,cAAA;AAAA,MACjB,SAAS,CAAA,CAAE,OAAA;AAAA,MACX,OAAO,CAAA,CAAE;AAAA,KACX;AAAA,EACF;AACF;AAgCO,SAAS,WAAW,CAAA,EAA4B;AACrD,EAAA,OAAO;AAAA,IACL,aAAa,CAAA,CAAE,YAAA;AAAA,IACf,cAAc,CAAA,CAAE,aAAA;AAAA,IAChB,SAAS,CAAA,CAAE,QAAA;AAAA,IACX,WAAW,CAAA,CAAE,UAAA;AAAA,IACb,WAAW,CAAA,CAAE,UAAA;AAAA,IACb,OAAO,CAAA,CAAE;AAAA,GACX;AACF","file":"index.js","sourcesContent":["/**\n * Core HTTP client for Hanzo IAM API.\n */\n\nimport type {\n IamConfig,\n IamApiResponse,\n IamUser,\n IamOrganization,\n IamProject,\n OidcDiscovery,\n TokenResponse,\n} from \"./types.js\";\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport class IamClient {\n private readonly baseUrl: string;\n private readonly clientId: string;\n private readonly clientSecret: string | undefined;\n private readonly orgName: string | undefined;\n private readonly appName: string | undefined;\n private discoveryCache: { data: OidcDiscovery; fetchedAt: number } | null = null;\n\n constructor(config: IamConfig) {\n this.baseUrl = config.serverUrl.replace(/\\/+$/, \"\");\n this.clientId = config.clientId;\n this.clientSecret = config.clientSecret;\n this.orgName = config.orgName;\n this.appName = config.appName;\n }\n\n // -----------------------------------------------------------------------\n // Internal HTTP helpers\n // -----------------------------------------------------------------------\n\n private async request<T>(\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n token?: string;\n params?: Record<string, string>;\n timeoutMs?: number;\n },\n ): Promise<T> {\n const url = new URL(path, this.baseUrl);\n if (opts?.params) {\n for (const [k, v] of Object.entries(opts.params)) {\n url.searchParams.set(k, v);\n }\n }\n\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n );\n\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n };\n if (opts?.token) {\n headers.Authorization = `Bearer ${opts.token}`;\n }\n if (opts?.body) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n // Server-side basic auth for confidential client operations\n if (this.clientSecret && !opts?.token) {\n const credentials = `${this.clientId}:${this.clientSecret}`;\n const basic =\n typeof Buffer !== \"undefined\"\n ? Buffer.from(credentials).toString(\"base64\")\n : btoa(credentials);\n headers.Authorization = `Basic ${basic}`;\n }\n\n try {\n const res = await fetch(url.toString(), {\n method: opts?.method ?? \"GET\",\n headers,\n body: opts?.body ? JSON.stringify(opts.body) : undefined,\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new IamApiError(res.status, `${res.statusText}: ${text}`.trim());\n }\n\n return (await res.json()) as T;\n } finally {\n clearTimeout(timer);\n }\n }\n\n // -----------------------------------------------------------------------\n // OIDC Discovery\n // -----------------------------------------------------------------------\n\n async getDiscovery(): Promise<OidcDiscovery> {\n const CACHE_TTL_MS = 5 * 60 * 1000;\n if (this.discoveryCache && Date.now() - this.discoveryCache.fetchedAt < CACHE_TTL_MS) {\n return this.discoveryCache.data;\n }\n const data = await this.request<OidcDiscovery>(\n \"/.well-known/openid-configuration\",\n );\n this.discoveryCache = { data, fetchedAt: Date.now() };\n return data;\n }\n\n /** Get JWKS URI from OIDC discovery (cached). */\n async getJwksUri(): Promise<string> {\n const discovery = await this.getDiscovery();\n return discovery.jwks_uri;\n }\n\n // -----------------------------------------------------------------------\n // OAuth2 / Token\n // -----------------------------------------------------------------------\n\n /** Build the authorization URL for user login redirect. */\n async getAuthorizationUrl(params: {\n redirectUri: string;\n state: string;\n scope?: string;\n codeChallenge?: string;\n codeChallengeMethod?: string;\n }): Promise<string> {\n const discovery = await this.getDiscovery();\n const url = new URL(discovery.authorization_endpoint);\n url.searchParams.set(\"client_id\", this.clientId);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", params.redirectUri);\n url.searchParams.set(\"state\", params.state);\n url.searchParams.set(\"scope\", params.scope ?? \"openid profile email\");\n if (params.codeChallenge) {\n url.searchParams.set(\"code_challenge\", params.codeChallenge);\n url.searchParams.set(\"code_challenge_method\", params.codeChallengeMethod ?? \"S256\");\n }\n return url.toString();\n }\n\n /** Exchange authorization code for tokens. */\n async exchangeCode(params: {\n code: string;\n redirectUri: string;\n codeVerifier?: string;\n }): Promise<TokenResponse> {\n const discovery = await this.getDiscovery();\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n client_id: this.clientId,\n code: params.code,\n redirect_uri: params.redirectUri,\n });\n if (this.clientSecret) {\n body.set(\"client_secret\", this.clientSecret);\n }\n if (params.codeVerifier) {\n body.set(\"code_verifier\", params.codeVerifier);\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n try {\n const res = await fetch(discovery.token_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: controller.signal,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new IamApiError(res.status, `Token exchange failed: ${text}`);\n }\n return (await res.json()) as TokenResponse;\n } finally {\n clearTimeout(timer);\n }\n }\n\n /**\n * Resource Owner Password Credentials grant.\n * Used for service-to-service auth, CLI login, and e2e tests.\n */\n async passwordGrant(params: {\n username: string;\n password: string;\n scope?: string;\n }): Promise<TokenResponse> {\n const discovery = await this.getDiscovery();\n const body = new URLSearchParams({\n grant_type: \"password\",\n client_id: this.clientId,\n username: params.username,\n password: params.password,\n scope: params.scope ?? \"openid profile email phone\",\n });\n if (this.clientSecret) {\n body.set(\"client_secret\", this.clientSecret);\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n try {\n const res = await fetch(discovery.token_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: controller.signal,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new IamApiError(res.status, `Password grant failed: ${text}`);\n }\n return (await res.json()) as TokenResponse;\n } finally {\n clearTimeout(timer);\n }\n }\n\n /** Refresh an access token. */\n async refreshToken(refreshToken: string): Promise<TokenResponse> {\n const discovery = await this.getDiscovery();\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: this.clientId,\n refresh_token: refreshToken,\n });\n if (this.clientSecret) {\n body.set(\"client_secret\", this.clientSecret);\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n try {\n const res = await fetch(discovery.token_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: controller.signal,\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new IamApiError(res.status, `Token refresh failed: ${text}`);\n }\n return (await res.json()) as TokenResponse;\n } finally {\n clearTimeout(timer);\n }\n }\n\n // -----------------------------------------------------------------------\n // User\n // -----------------------------------------------------------------------\n\n /** Get user info from access token (OIDC userinfo endpoint). */\n async getUserInfo(accessToken: string): Promise<IamUser> {\n const discovery = await this.getDiscovery();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n try {\n const res = await fetch(discovery.userinfo_endpoint, {\n headers: { Authorization: `Bearer ${accessToken}` },\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new IamApiError(res.status, \"Failed to fetch userinfo\");\n }\n return (await res.json()) as IamUser;\n } finally {\n clearTimeout(timer);\n }\n }\n\n /** Get a user by ID (\"org/username\" format). */\n async getUser(userId: string, token?: string): Promise<IamUser | null> {\n const resp = await this.request<IamApiResponse<IamUser>>(\"/api/get-user\", {\n params: { id: userId },\n token,\n });\n return resp.data ?? null;\n }\n\n // -----------------------------------------------------------------------\n // Organization\n // -----------------------------------------------------------------------\n\n /** List organizations (for the configured owner). */\n async getOrganizations(token?: string): Promise<IamOrganization[]> {\n const owner = this.orgName ?? \"admin\";\n const resp = await this.request<IamApiResponse<IamOrganization[]>>(\n \"/api/get-organizations\",\n { params: { owner }, token },\n );\n return resp.data ?? [];\n }\n\n /** Get a specific organization. */\n async getOrganization(\n id: string,\n token?: string,\n ): Promise<IamOrganization | null> {\n const resp = await this.request<IamApiResponse<IamOrganization>>(\n \"/api/get-organization\",\n { params: { id }, token },\n );\n return resp.data ?? null;\n }\n\n /** Get organizations a user belongs to. */\n async getUserOrganizations(\n userId: string,\n token?: string,\n ): Promise<IamOrganization[]> {\n // IAM returns orgs the user is a member of via the user's properties.\n // We can also query via get-user and read their signupApplication/org.\n const user = await this.getUser(userId, token);\n if (!user) return [];\n // The owner field on a user is their org\n const org = await this.getOrganization(\n `admin/${user.owner}`,\n token,\n );\n return org ? [org] : [];\n }\n\n // -----------------------------------------------------------------------\n // Project\n // -----------------------------------------------------------------------\n\n /** List projects (for the configured owner). */\n async getProjects(token?: string): Promise<IamProject[]> {\n const owner = this.orgName ?? \"admin\";\n const resp = await this.request<IamApiResponse<IamProject[]>>(\n \"/api/get-projects\",\n { params: { owner }, token },\n );\n return resp.data ?? [];\n }\n\n /** Get a specific project by ID (\"owner/name\" format). */\n async getProject(id: string, token?: string): Promise<IamProject | null> {\n const resp = await this.request<IamApiResponse<IamProject>>(\n \"/api/get-project\",\n { params: { id }, token },\n );\n return resp.data ?? null;\n }\n\n /** Get all projects for an organization. */\n async getOrganizationProjects(\n organization: string,\n token?: string,\n ): Promise<IamProject[]> {\n const resp = await this.request<IamApiResponse<IamProject[]>>(\n \"/api/get-organization-projects\",\n { params: { organization }, token },\n );\n return resp.data ?? [];\n }\n\n // -----------------------------------------------------------------------\n // Raw request (for extending)\n // -----------------------------------------------------------------------\n\n /** Make an arbitrary authenticated request to the IAM API. */\n async apiRequest<T = unknown>(\n path: string,\n opts?: { method?: string; body?: unknown; token?: string; params?: Record<string, string> },\n ): Promise<T> {\n return this.request<T>(path, opts);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Error\n// ---------------------------------------------------------------------------\n\nexport class IamApiError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = \"IamApiError\";\n this.status = status;\n }\n}\n","/**\n * JWT validation using jose library + OIDC JWKS discovery.\n *\n * Validates access/ID tokens issued by Hanzo IAM.\n */\n\nimport { createRemoteJWKSet, jwtVerify, type JWTPayload } from \"jose\";\nimport type { IamConfig, IamAuthResult, IamJwtClaims } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// JWKS key set cache (per issuer)\n// ---------------------------------------------------------------------------\n\nconst jwksSets = new Map<string, ReturnType<typeof createRemoteJWKSet>>();\n\nfunction getJwksKeySet(jwksUri: string): ReturnType<typeof createRemoteJWKSet> {\n let keySet = jwksSets.get(jwksUri);\n if (!keySet) {\n keySet = createRemoteJWKSet(new URL(jwksUri));\n jwksSets.set(jwksUri, keySet);\n }\n return keySet;\n}\n\n/** Clear cached JWKS key sets (useful for testing or key rotation). */\nexport function clearJwksCache(): void {\n jwksSets.clear();\n}\n\n// ---------------------------------------------------------------------------\n// OIDC discovery cache (lightweight, no full client needed)\n// ---------------------------------------------------------------------------\n\ntype CachedDiscovery = { jwksUri: string; issuer: string; fetchedAt: number };\nconst discoveryCache = new Map<string, CachedDiscovery>();\nconst DISCOVERY_TTL_MS = 5 * 60 * 1000;\n\nasync function resolveJwksUri(serverUrl: string): Promise<{ jwksUri: string; issuer: string }> {\n const baseUrl = serverUrl.replace(/\\/+$/, \"\");\n const cached = discoveryCache.get(baseUrl);\n if (cached && Date.now() - cached.fetchedAt < DISCOVERY_TTL_MS) {\n return { jwksUri: cached.jwksUri, issuer: cached.issuer };\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 8_000);\n try {\n const res = await fetch(`${baseUrl}/.well-known/openid-configuration`, {\n signal: controller.signal,\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`OIDC discovery failed: ${res.status}`);\n }\n const body = (await res.json()) as { jwks_uri?: string; issuer?: string };\n const jwksUri = body.jwks_uri;\n const issuer = body.issuer ?? baseUrl;\n if (!jwksUri) {\n throw new Error(\"OIDC discovery response missing jwks_uri\");\n }\n discoveryCache.set(baseUrl, { jwksUri, issuer, fetchedAt: Date.now() });\n return { jwksUri, issuer };\n } finally {\n clearTimeout(timer);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Token validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate a JWT access token against IAM's JWKS.\n *\n * Uses OIDC discovery to find the JWKS URI, then verifies the token\n * signature, issuer, audience, and expiry using the `jose` library.\n */\nexport async function validateToken(\n token: string,\n config: IamConfig,\n): Promise<IamAuthResult> {\n if (!token || typeof token !== \"string\") {\n return { ok: false, reason: \"iam_token_missing\" };\n }\n\n let jwksUri: string;\n let issuer: string;\n try {\n const discovery = await resolveJwksUri(config.serverUrl);\n jwksUri = discovery.jwksUri;\n issuer = discovery.issuer;\n } catch {\n return { ok: false, reason: \"iam_discovery_failed\" };\n }\n\n const keySet = getJwksKeySet(jwksUri);\n\n let payload: JWTPayload;\n try {\n const result = await jwtVerify(token, keySet, {\n issuer,\n audience: config.clientId,\n clockTolerance: 30, // 30s clock skew\n });\n payload = result.payload;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"expired\")) {\n return { ok: false, reason: \"iam_token_expired\" };\n }\n if (message.includes(\"audience\")) {\n // Retry without audience check - some IAM configs don't set aud\n try {\n const result = await jwtVerify(token, keySet, {\n issuer,\n clockTolerance: 30,\n });\n payload = result.payload;\n } catch {\n return { ok: false, reason: \"iam_signature_invalid\" };\n }\n } else {\n return { ok: false, reason: \"iam_signature_invalid\" };\n }\n }\n\n const claims = payload as unknown as IamJwtClaims;\n\n // Hanzo IAM tokens may use owner/name instead of sub claim\n const sub =\n claims.sub ||\n (typeof claims.owner === \"string\" && typeof claims.name === \"string\"\n ? `${claims.owner}/${claims.name}`\n : undefined);\n\n if (!sub) {\n return { ok: false, reason: \"iam_subject_missing\" };\n }\n\n // IAM sub format is \"org/username\" - extract owner\n const parts = sub.split(\"/\");\n const owner = parts.length > 1 ? parts[0] : config.orgName ?? \"unknown\";\n\n return {\n ok: true,\n userId: sub,\n email: typeof claims.email === \"string\" ? claims.email : undefined,\n name:\n typeof claims.name === \"string\"\n ? claims.name\n : typeof claims.preferred_username === \"string\"\n ? claims.preferred_username\n : undefined,\n avatar: typeof claims.picture === \"string\" ? claims.picture : undefined,\n owner,\n claims,\n };\n}\n","/**\n * PKCE (Proof Key for Code Exchange) utilities for browser-side OAuth2 flows.\n *\n * PKCE utilities for OAuth2 flows, using native Web Crypto API.\n */\n\nfunction generateRandomString(length: number): string {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return Array.from(array, (b) => b.toString(36).padStart(2, \"0\"))\n .join(\"\")\n .slice(0, length);\n}\n\nasync function sha256(plain: string): Promise<ArrayBuffer> {\n const encoder = new TextEncoder();\n return crypto.subtle.digest(\"SHA-256\", encoder.encode(plain));\n}\n\nfunction base64UrlEncode(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** Generate a PKCE code verifier + challenge pair. */\nexport async function generatePKCEChallenge(): Promise<{\n codeVerifier: string;\n codeChallenge: string;\n}> {\n const codeVerifier = generateRandomString(64);\n const hash = await sha256(codeVerifier);\n const codeChallenge = base64UrlEncode(hash);\n return { codeVerifier, codeChallenge };\n}\n\n/** Generate a random state parameter for CSRF protection. */\nexport function generateState(): string {\n return generateRandomString(32);\n}\n","/**\n * Browser-side OAuth2 flows for Hanzo IAM.\n *\n * Provides PKCE-based login redirect, code exchange, token refresh,\n * popup signin, and silent signin for single-page applications.\n *\n * Adapted and modernized for Hanzo IAM.\n */\n\nimport type { IamConfig, TokenResponse, OidcDiscovery } from \"./types.js\";\nimport { generatePKCEChallenge, generateState } from \"./pkce.js\";\n\n// ---------------------------------------------------------------------------\n// Storage keys\n// ---------------------------------------------------------------------------\n\nconst STORAGE_PREFIX = \"hanzo_iam_\";\nconst KEY_STATE = `${STORAGE_PREFIX}state`;\nconst KEY_CODE_VERIFIER = `${STORAGE_PREFIX}code_verifier`;\nconst KEY_ACCESS_TOKEN = `${STORAGE_PREFIX}access_token`;\nconst KEY_REFRESH_TOKEN = `${STORAGE_PREFIX}refresh_token`;\nconst KEY_ID_TOKEN = `${STORAGE_PREFIX}id_token`;\nconst KEY_EXPIRES_AT = `${STORAGE_PREFIX}expires_at`;\n\n// ---------------------------------------------------------------------------\n// Browser IAM SDK\n// ---------------------------------------------------------------------------\n\nexport type IAMConfig = IamConfig & {\n /** OAuth2 redirect URI (e.g. \"https://app.hanzo.bot/auth/callback\"). */\n redirectUri: string;\n /** OAuth2 scopes (default: \"openid profile email\"). */\n scope?: string;\n /** Storage to use for tokens (default: sessionStorage). */\n storage?: Storage;\n /**\n * Proxy base URL for token exchange and userinfo requests.\n * When set, token exchange POSTs go to `${proxyBaseUrl}/auth/token`\n * and userinfo GETs go to `${proxyBaseUrl}/auth/userinfo` instead of\n * directly to the IAM server. This avoids CORS issues when the IAM\n * server doesn't send Access-Control-Allow-Origin headers.\n */\n proxyBaseUrl?: string;\n};\n\nexport class IAM {\n private readonly config: IAMConfig;\n private readonly storage: Storage;\n private discoveryCache: OidcDiscovery | null = null;\n\n constructor(config: IAMConfig) {\n this.config = config;\n this.storage = config.storage ?? sessionStorage;\n }\n\n // -----------------------------------------------------------------------\n // OIDC Discovery\n // -----------------------------------------------------------------------\n\n private async getDiscovery(): Promise<OidcDiscovery> {\n if (this.discoveryCache) return this.discoveryCache;\n\n const baseUrl = this.config.serverUrl.replace(/\\/+$/, \"\");\n\n // Try fetching the OIDC discovery document. If it fails (e.g. due to\n // CORS when the IAM server doesn't send Access-Control-Allow-Origin),\n // construct a fallback from well-known Hanzo IAM endpoint paths.\n try {\n const res = await fetch(`${baseUrl}/.well-known/openid-configuration`, {\n headers: { Accept: \"application/json\" },\n });\n if (res.ok) {\n this.discoveryCache = (await res.json()) as OidcDiscovery;\n return this.discoveryCache;\n }\n } catch {\n // CORS or network error — fall through to constructed discovery\n }\n\n this.discoveryCache = {\n issuer: baseUrl,\n authorization_endpoint: `${baseUrl}/oauth/authorize`,\n token_endpoint: `${baseUrl}/oauth/token`,\n userinfo_endpoint: `${baseUrl}/oauth/userinfo`,\n jwks_uri: `${baseUrl}/.well-known/jwks`,\n response_types_supported: [\"code\", \"token\", \"id_token\"],\n grant_types_supported: [\"authorization_code\", \"implicit\", \"refresh_token\"],\n scopes_supported: [\"openid\", \"email\", \"profile\"],\n };\n return this.discoveryCache;\n }\n\n // -----------------------------------------------------------------------\n // Login redirect (PKCE)\n // -----------------------------------------------------------------------\n\n /**\n * Start the OAuth2 PKCE login flow by redirecting to the IAM authorize endpoint.\n *\n * Generates PKCE challenge and state, stores them in session storage,\n * then redirects the browser.\n */\n async signinRedirect(params?: { additionalParams?: Record<string, string> }): Promise<void> {\n const discovery = await this.getDiscovery();\n const { codeVerifier, codeChallenge } = await generatePKCEChallenge();\n const state = generateState();\n\n this.storage.setItem(KEY_STATE, state);\n this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);\n\n const url = new URL(discovery.authorization_endpoint);\n url.searchParams.set(\"client_id\", this.config.clientId);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", this.config.redirectUri);\n url.searchParams.set(\"scope\", this.config.scope ?? \"openid profile email\");\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n\n if (params?.additionalParams) {\n for (const [k, v] of Object.entries(params.additionalParams)) {\n url.searchParams.set(k, v);\n }\n }\n\n window.location.href = url.toString();\n }\n\n // -----------------------------------------------------------------------\n // Callback handling\n // -----------------------------------------------------------------------\n\n /**\n * Handle the OAuth2 callback after redirect. Exchanges the authorization code\n * for tokens using PKCE.\n *\n * Call this on your callback page (e.g. /auth/callback).\n * Returns the token response, or throws if the state doesn't match.\n */\n async handleCallback(callbackUrl?: string): Promise<IAMToken> {\n const url = new URL(callbackUrl ?? window.location.href);\n const error = url.searchParams.get(\"error\");\n\n if (error) {\n const desc = url.searchParams.get(\"error_description\") ?? error;\n throw new Error(`OAuth error: ${desc}`);\n }\n\n const state = url.searchParams.get(\"state\");\n const savedState = this.storage.getItem(KEY_STATE);\n if (savedState && state !== savedState) {\n throw new Error(\"OAuth state mismatch — possible CSRF attack\");\n }\n\n // Implicit flow: access_token returned directly in URL\n const accessToken = url.searchParams.get(\"access_token\");\n if (accessToken) {\n this.storage.removeItem(KEY_STATE);\n this.storage.removeItem(KEY_CODE_VERIFIER);\n\n const tokens: TokenResponse = {\n access_token: accessToken,\n token_type: \"Bearer\",\n refresh_token: url.searchParams.get(\"refresh_token\") ?? undefined,\n expires_in: 7200,\n };\n this.storeTokens(tokens);\n return toIAMToken(tokens);\n }\n\n // Authorization code flow: exchange code for tokens via PKCE\n const code = url.searchParams.get(\"code\");\n if (!code) {\n throw new Error(\"Missing authorization code in callback URL\");\n }\n\n const codeVerifier = this.storage.getItem(KEY_CODE_VERIFIER);\n if (!codeVerifier) {\n throw new Error(\"Missing PKCE code verifier — was signinRedirect() called?\");\n }\n\n // Clean up one-time state\n this.storage.removeItem(KEY_STATE);\n this.storage.removeItem(KEY_CODE_VERIFIER);\n\n const discovery = await this.getDiscovery();\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n client_id: this.config.clientId,\n code,\n redirect_uri: this.config.redirectUri,\n code_verifier: codeVerifier,\n });\n\n // Use proxy URL when configured to avoid CORS on the token endpoint.\n const tokenUrl = this.config.proxyBaseUrl\n ? `${this.config.proxyBaseUrl.replace(/\\/+$/, \"\")}/auth/token`\n : discovery.token_endpoint;\n\n const res = await fetch(tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`Token exchange failed (${res.status}): ${text}`);\n }\n\n const tokens = (await res.json()) as TokenResponse;\n this.storeTokens(tokens);\n return toIAMToken(tokens);\n }\n\n // -----------------------------------------------------------------------\n // Token refresh\n // -----------------------------------------------------------------------\n\n /** Refresh the access token using the stored refresh token. */\n async refreshAccessToken(): Promise<IAMToken> {\n const refreshToken = this.storage.getItem(KEY_REFRESH_TOKEN);\n if (!refreshToken) {\n throw new Error(\"No refresh token available\");\n }\n\n const discovery = await this.getDiscovery();\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: this.config.clientId,\n refresh_token: refreshToken,\n });\n\n const tokenUrl = this.config.proxyBaseUrl\n ? `${this.config.proxyBaseUrl.replace(/\\/+$/, \"\")}/auth/token`\n : discovery.token_endpoint;\n\n const res = await fetch(tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`Token refresh failed (${res.status}): ${text}`);\n }\n\n const tokens = (await res.json()) as TokenResponse;\n this.storeTokens(tokens);\n return toIAMToken(tokens);\n }\n\n // -----------------------------------------------------------------------\n // Popup signin\n // -----------------------------------------------------------------------\n\n /**\n * Open the IAM login page in a popup window. Resolves when the popup\n * completes the OAuth flow and returns tokens.\n */\n async signinPopup(params?: {\n width?: number;\n height?: number;\n additionalParams?: Record<string, string>;\n }): Promise<IAMToken> {\n const discovery = await this.getDiscovery();\n const { codeVerifier, codeChallenge } = await generatePKCEChallenge();\n const state = generateState();\n\n this.storage.setItem(KEY_STATE, state);\n this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);\n\n const url = new URL(discovery.authorization_endpoint);\n url.searchParams.set(\"client_id\", this.config.clientId);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", this.config.redirectUri);\n url.searchParams.set(\"scope\", this.config.scope ?? \"openid profile email\");\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n\n if (params?.additionalParams) {\n for (const [k, v] of Object.entries(params.additionalParams)) {\n url.searchParams.set(k, v);\n }\n }\n\n const width = params?.width ?? 600;\n const height = params?.height ?? 700;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n\n return new Promise<IAMToken>((resolve, reject) => {\n const popup = window.open(\n url.toString(),\n \"hanzo_iam_login\",\n `width=${width},height=${height},left=${left},top=${top},menubar=no,toolbar=no`,\n );\n\n if (!popup) {\n reject(new Error(\"Failed to open login popup — blocked by browser?\"));\n return;\n }\n\n const interval = setInterval(() => {\n try {\n if (popup.closed) {\n clearInterval(interval);\n reject(new Error(\"Login popup was closed before completing\"));\n return;\n }\n // Check if popup navigated to our redirect URI\n const popupUrl = popup.location.href;\n if (popupUrl.startsWith(this.config.redirectUri)) {\n clearInterval(interval);\n popup.close();\n this.handleCallback(popupUrl).then(resolve, reject);\n }\n } catch {\n // Cross-origin — popup is still on IAM domain, keep waiting\n }\n }, 200);\n });\n }\n\n // -----------------------------------------------------------------------\n // Silent signin (iframe)\n // -----------------------------------------------------------------------\n\n /**\n * Attempt silent authentication via a hidden iframe.\n * Useful for checking if the user has an active IAM session.\n * Returns null if silent auth fails (user needs to log in interactively).\n */\n async signinSilent(timeoutMs = 5000): Promise<IAMToken | null> {\n const discovery = await this.getDiscovery();\n const { codeVerifier, codeChallenge } = await generatePKCEChallenge();\n const state = generateState();\n\n this.storage.setItem(KEY_STATE, state);\n this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);\n\n const url = new URL(discovery.authorization_endpoint);\n url.searchParams.set(\"client_id\", this.config.clientId);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", this.config.redirectUri);\n url.searchParams.set(\"scope\", this.config.scope ?? \"openid profile email\");\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n url.searchParams.set(\"prompt\", \"none\"); // No interactive login\n\n return new Promise<IAMToken | null>((resolve) => {\n const iframe = document.createElement(\"iframe\");\n iframe.style.display = \"none\";\n\n const timeout = setTimeout(() => {\n cleanup();\n resolve(null);\n }, timeoutMs);\n\n const cleanup = () => {\n clearTimeout(timeout);\n iframe.remove();\n this.storage.removeItem(KEY_STATE);\n this.storage.removeItem(KEY_CODE_VERIFIER);\n };\n\n iframe.addEventListener(\"load\", () => {\n try {\n const iframeUrl = iframe.contentWindow?.location.href;\n if (iframeUrl && iframeUrl.startsWith(this.config.redirectUri)) {\n cleanup();\n this.handleCallback(iframeUrl).then(\n (tokens) => resolve(tokens),\n () => resolve(null),\n );\n }\n } catch {\n // Cross-origin or error — silent auth failed\n cleanup();\n resolve(null);\n }\n });\n\n iframe.src = url.toString();\n document.body.appendChild(iframe);\n });\n }\n\n // -----------------------------------------------------------------------\n // Token management\n // -----------------------------------------------------------------------\n\n private storeTokens(tokens: TokenResponse): void {\n this.storage.setItem(KEY_ACCESS_TOKEN, tokens.access_token);\n if (tokens.refresh_token) {\n this.storage.setItem(KEY_REFRESH_TOKEN, tokens.refresh_token);\n }\n if (tokens.id_token) {\n this.storage.setItem(KEY_ID_TOKEN, tokens.id_token);\n }\n if (tokens.expires_in) {\n const expiresAt = Date.now() + tokens.expires_in * 1000;\n this.storage.setItem(KEY_EXPIRES_AT, String(expiresAt));\n }\n }\n\n /** Get the stored access token (may be expired). */\n getAccessToken(): string | null {\n return this.storage.getItem(KEY_ACCESS_TOKEN);\n }\n\n /** Get the stored refresh token. */\n getRefreshToken(): string | null {\n return this.storage.getItem(KEY_REFRESH_TOKEN);\n }\n\n /** Get the stored ID token. */\n getIdToken(): string | null {\n return this.storage.getItem(KEY_ID_TOKEN);\n }\n\n /** Check if the stored access token is expired. */\n isTokenExpired(): boolean {\n const expiresAt = this.storage.getItem(KEY_EXPIRES_AT);\n if (!expiresAt) return true;\n return Date.now() >= Number(expiresAt);\n }\n\n /**\n * Get a valid access token — refreshes automatically if expired.\n * Returns null if no token and no refresh token available.\n */\n async getValidAccessToken(): Promise<string | null> {\n const token = this.getAccessToken();\n if (token && !this.isTokenExpired()) {\n return token;\n }\n if (this.getRefreshToken()) {\n try {\n const tokens = await this.refreshAccessToken();\n return tokens.accessToken;\n } catch {\n return null;\n }\n }\n return null;\n }\n\n /** Clear all stored tokens (logout). */\n clearTokens(): void {\n this.storage.removeItem(KEY_ACCESS_TOKEN);\n this.storage.removeItem(KEY_REFRESH_TOKEN);\n this.storage.removeItem(KEY_ID_TOKEN);\n this.storage.removeItem(KEY_EXPIRES_AT);\n this.storage.removeItem(KEY_STATE);\n this.storage.removeItem(KEY_CODE_VERIFIER);\n }\n\n // -----------------------------------------------------------------------\n // User info\n // -----------------------------------------------------------------------\n\n /** Fetch user info from the OIDC userinfo endpoint using the stored access token. */\n async getUserInfo(): Promise<Record<string, unknown>> {\n const token = await this.getValidAccessToken();\n if (!token) {\n throw new Error(\"No valid access token — user must log in\");\n }\n const discovery = await this.getDiscovery();\n const userinfoUrl = this.config.proxyBaseUrl\n ? `${this.config.proxyBaseUrl.replace(/\\/+$/, \"\")}/auth/userinfo`\n : discovery.userinfo_endpoint;\n const res = await fetch(userinfoUrl, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (!res.ok) {\n throw new Error(`Userinfo fetch failed (${res.status})`);\n }\n return (await res.json()) as Record<string, unknown>;\n }\n\n // -----------------------------------------------------------------------\n // URL helpers\n // -----------------------------------------------------------------------\n\n /** Build the signup URL for the IAM server. */\n getSignupUrl(params?: { enablePassword?: boolean }): string {\n const base = this.config.serverUrl.replace(/\\/+$/, \"\");\n const app = this.config.appName ?? \"app\";\n const org = this.config.orgName ?? \"built-in\";\n let url = `${base}/signup/${app}`;\n if (params?.enablePassword) {\n url += \"?enablePassword=true\";\n }\n return url;\n }\n\n /** Build the user profile URL on the IAM server. */\n getUserProfileUrl(username: string): string {\n const base = this.config.serverUrl.replace(/\\/+$/, \"\");\n const org = this.config.orgName ?? \"built-in\";\n return `${base}/users/${org}/${username}`;\n }\n\n // -----------------------------------------------------------------------\n // Casdoor REST surface (signup, OTP, REST login, phone lookup)\n //\n // The OIDC layer covers redirect/PKCE, token exchange, refresh, userinfo.\n // These methods cover the Casdoor-native endpoints that don't have an OIDC\n // analogue: phone/email OTP, custom signup with verification codes, and\n // direct REST login that returns an authorization code in one round-trip\n // (used as the bridge between OTP collection and `exchangeCode`).\n //\n // All paths are gateway-canonical (`/login`, `/signup`,\n // `/send-verification-code`, `/get-phone-user`) — point `serverUrl` at the\n // gateway prefix (e.g. `https://api.dev.satschel.com/v1/iam`) and the\n // gateway proxies to Casdoor's `/api/*` internally.\n // -----------------------------------------------------------------------\n\n /**\n * Send a verification code to a phone or email destination.\n *\n * @param contact `{ phone, countryCode }` for SMS, `{ email }` for email.\n * @param method Casdoor method: `login`, `signup`, `forget`, `mfaSetup`, etc.\n */\n async sendVerificationCode(\n contact: { phone: string; countryCode: string } | { email: string },\n method: \"login\" | \"signup\" | \"forget\" | \"reset\" | \"mfaSetup\" = \"login\",\n ): Promise<{ ok: boolean; error?: string }> {\n // 'reset' is an idiomatic alias for Casdoor's 'forget'.\n if (method === \"reset\") method = \"forget\";\n const isPhone = \"phone\" in contact;\n const dest = isPhone ? contact.phone : contact.email;\n const params: Record<string, string> = {\n applicationId: `admin/${this.config.appName ?? \"app\"}`,\n dest,\n type: isPhone ? \"phone\" : \"email\",\n method,\n captchaType: \"none\",\n captchaToken: \"\",\n };\n if (isPhone) params.countryCode = contact.countryCode;\n\n const url = `${this.config.serverUrl.replace(/\\/+$/, \"\")}/send-verification-code`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(params).toString(),\n });\n const data = await res.json().catch(() => ({}));\n if (data.status === \"ok\") return { ok: true };\n const msg = (data.msg as string) || `send-verification-code failed (${res.status})`;\n // Provider misconfig is treated as soft success in dev — Casdoor still\n // generates the code and stores it for verification.\n if (msg.includes(\"SMS provider\") || msg.includes(\"provider\")) return { ok: true };\n return { ok: false, error: msg };\n }\n\n /**\n * Look up whether a phone number is registered. Returns `{ exists: false }`\n * on 404 or unknown numbers; `{ exists: true }` when Casdoor confirms a user.\n */\n async lookupPhoneUser(phone: string, countryCode: string): Promise<{ exists: boolean; error?: string }> {\n const url = `${this.config.serverUrl.replace(/\\/+$/, \"\")}/get-phone-user`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n application: this.config.appName ?? \"app\",\n phone,\n countryCode,\n }),\n });\n if (res.status === 404) return { exists: false };\n if (!res.ok) return { exists: false, error: `lookupPhoneUser failed (${res.status})` };\n return { exists: true };\n }\n\n /**\n * Casdoor REST signup. Returns the new user's id on success.\n *\n * Phone signup flow: send phoneCode via `sendVerificationCode`, then call\n * this with the OTP in `phoneCode`. Casdoor verifies the code internally.\n * Email signup flow: same with `email` + `emailCode`.\n */\n async signup(params: {\n method: \"email\" | \"phone\";\n name: string;\n username?: string;\n email?: string;\n phone?: string;\n countryCode?: string;\n password?: string;\n emailCode?: string;\n phoneCode?: string;\n }): Promise<{ id?: string; ok: boolean; error?: string }> {\n const username = params.username ?? params.name;\n const password = params.password ?? `Liq${Date.now()}!`;\n const body: Record<string, unknown> = {\n application: this.config.appName ?? \"app\",\n organization: this.config.orgName ?? \"built-in\",\n name: params.name,\n username,\n password,\n confirm: password,\n agreement: true,\n };\n if (params.method === \"email\") {\n body.email = params.email;\n if (params.emailCode) body.emailCode = params.emailCode;\n } else {\n body.phone = params.phone;\n body.countryCode = params.countryCode;\n if (params.phoneCode) body.phoneCode = params.phoneCode;\n if (params.email) body.email = params.email;\n if (params.emailCode) body.emailCode = params.emailCode;\n }\n const url = `${this.config.serverUrl.replace(/\\/+$/, \"\")}/signup`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n const data = await res.json().catch(() => ({}));\n if (data.status === \"ok\") return { ok: true, id: data.data2 || data.data };\n return { ok: false, error: (data.msg as string) || `signup failed (${res.status})` };\n }\n\n /**\n * REST login that returns an authorization code (Casdoor `/login`).\n *\n * Use this when you want the caller to drive the PKCE flow without a\n * full redirect — collect credentials in your own UI, get a code back,\n * then call `exchangeCodeForToken` to land tokens.\n */\n async loginWithCredentials(params: {\n username: string;\n password: string;\n type?: \"code\" | \"token\";\n redirectUri?: string;\n }): Promise<{ code?: string; ok: boolean; error?: string }> {\n const { codeVerifier, codeChallenge } = await generatePKCEChallenge();\n this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);\n\n const url = new URL(`${this.config.serverUrl.replace(/\\/+$/, \"\")}/login`);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n\n const res = await fetch(url.toString(), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n application: this.config.appName ?? \"app\",\n organization: this.config.orgName ?? \"built-in\",\n username: params.username,\n password: params.password,\n type: params.type ?? \"code\",\n clientId: this.config.clientId,\n redirectUri: params.redirectUri ?? this.config.redirectUri,\n codeChallenge,\n codeChallengeMethod: \"S256\",\n autoSignin: true,\n }),\n });\n const data = await res.json().catch(() => ({}));\n if (data.status === \"ok\" && data.data) return { ok: true, code: data.data as string };\n return { ok: false, error: (data.msg as string) || `login failed (${res.status})` };\n }\n\n /**\n * Exchange an authorization code for tokens using the stored PKCE verifier.\n * Pairs with `loginWithCredentials` for a code → tokens round-trip.\n */\n async exchangeCodeForToken(code: string, redirectUri?: string): Promise<IAMToken> {\n const codeVerifier = this.storage.getItem(KEY_CODE_VERIFIER);\n if (!codeVerifier) {\n throw new Error(\"Missing PKCE verifier — call loginWithCredentials() first\");\n }\n this.storage.removeItem(KEY_CODE_VERIFIER);\n\n const discovery = await this.getDiscovery();\n const tokenUrl = this.config.proxyBaseUrl\n ? `${this.config.proxyBaseUrl.replace(/\\/+$/, \"\")}/auth/token`\n : discovery.token_endpoint;\n\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n client_id: this.config.clientId,\n code,\n redirect_uri: redirectUri ?? this.config.redirectUri,\n code_verifier: codeVerifier,\n });\n const res = await fetch(tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n throw new Error((err as Record<string, string>).error_description || (err as Record<string, string>).error || \"Token exchange failed\");\n }\n const tokens = (await res.json()) as TokenResponse;\n this.storeTokens(tokens);\n return toIAMToken(tokens);\n }\n\n /**\n * Phone OTP login: tries the numbered username variants Casdoor accepts\n * (`{phone}`, `{countryCode}{phone}`), exchanges the resulting code for\n * tokens. Returns the token response, or throws on failure.\n */\n async loginWithPhoneOTP(params: {\n phone: string;\n countryCode: string;\n code: string;\n redirectUri?: string;\n }): Promise<IAMToken> {\n const usernames = [params.phone, `${params.countryCode}${params.phone}`];\n let lastError = \"\";\n for (const username of usernames) {\n const result = await this.loginWithCredentials({\n username,\n password: params.code,\n redirectUri: params.redirectUri,\n });\n if (result.ok && result.code) {\n return this.exchangeCodeForToken(result.code, params.redirectUri);\n }\n lastError = result.error ?? lastError;\n }\n throw new Error(lastError || \"Phone OTP login failed\");\n }\n\n /**\n * Logout via Casdoor REST `/logout` (clears server-side session) and\n * the local storage.\n */\n async logout(): Promise<void> {\n const token = this.storage.getItem(KEY_ACCESS_TOKEN);\n try {\n await fetch(`${this.config.serverUrl.replace(/\\/+$/, \"\")}/oauth/logout`, {\n method: \"POST\",\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n } catch {\n // best-effort — local cleanup is what matters\n }\n this.clearTokens();\n }\n\n // -----------------------------------------------------------------------\n // High-level helpers — normalize to ergonomic types so apps don't need\n // their own adapters around the OIDC/Casdoor wire shapes.\n // -----------------------------------------------------------------------\n\n /**\n * Build a social-login authorize URL. Used to navigate the user to\n * Google/Apple/etc. — same as `signinRedirect` but returns the URL\n * instead of issuing the redirect, so apps can `<a href=\"...\">`.\n */\n async getSocialLoginUrl(provider: string, scope = \"openid profile email\"): Promise<string> {\n const { codeVerifier, codeChallenge } = await generatePKCEChallenge();\n const state = generateState();\n this.storage.setItem(KEY_STATE, state);\n this.storage.setItem(KEY_CODE_VERIFIER, codeVerifier);\n\n const discovery = await this.getDiscovery();\n const url = new URL(discovery.authorization_endpoint);\n url.searchParams.set(\"client_id\", this.config.clientId);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", this.config.redirectUri);\n url.searchParams.set(\"scope\", scope);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", codeChallenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n url.searchParams.set(\"provider\", provider);\n return url.toString();\n }\n\n /**\n * Fetch the current user, shaped into the canonical `IAMUser` form\n * (camelCase, no `_` keys). Returns null when no token is present.\n */\n async getUser(): Promise<IAMUser | null> {\n const token = await this.getValidAccessToken();\n if (!token) return null;\n const u = await this.getUserInfo() as Record<string, unknown>;\n return {\n sub: (u.sub as string) ?? \"\",\n email: u.email as string | undefined,\n name: u.name as string | undefined,\n givenName: u.given_name as string | undefined,\n familyName: u.family_name as string | undefined,\n phoneNumber: u.phone_number as string | undefined,\n emailVerified: u.email_verified as boolean | undefined,\n picture: u.picture as string | undefined,\n owner: u.owner as string | undefined,\n };\n }\n}\n\n/**\n * Canonical user shape returned by `IAM#getUser()`. Maps the OIDC userinfo\n * response (snake_case) to camelCase. Apps should consume this rather than\n * the raw `Record<string, unknown>` from `getUserInfo()`.\n */\nexport type IAMUser = {\n sub: string;\n email?: string;\n name?: string;\n givenName?: string;\n familyName?: string;\n phoneNumber?: string;\n emailVerified?: boolean;\n picture?: string;\n owner?: string;\n};\n\n/**\n * Canonical token shape (camelCase, no `_` keys) for app code.\n */\nexport type IAMToken = {\n accessToken: string;\n refreshToken?: string;\n idToken?: string;\n expiresIn?: number;\n tokenType?: string;\n scope?: string;\n};\n\n/** Convert the raw OAuth2 token response into the canonical `IAMToken`. */\nexport function toIAMToken(t: TokenResponse): IAMToken {\n return {\n accessToken: t.access_token,\n refreshToken: t.refresh_token,\n idToken: t.id_token,\n expiresIn: t.expires_in,\n tokenType: t.token_type,\n scope: t.scope,\n };\n}\n"]}
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ // src/nextauth.ts
4
+ function IamProvider(options) {
5
+ const issuer = options.serverUrl.replace(/\/$/, "");
6
+ const checks = options.checks ?? ["state"];
7
+ return {
8
+ id: "iam",
9
+ name: "IAM",
10
+ type: "oauth",
11
+ wellKnown: `${issuer}/.well-known/openid-configuration`,
12
+ idToken: true,
13
+ checks,
14
+ authorization: { params: { scope: "openid profile email" } },
15
+ profile(profile) {
16
+ return {
17
+ id: profile.sub,
18
+ name: profile.displayName || profile.name || profile.preferred_username || profile.email || "",
19
+ email: profile.email,
20
+ image: profile.avatar || profile.picture || null
21
+ };
22
+ },
23
+ style: {
24
+ bg: "#050508",
25
+ text: "#fff",
26
+ logo: ""
27
+ },
28
+ options
29
+ };
30
+ }
31
+
32
+ exports.HanzoIamProvider = IamProvider;
33
+ exports.IamProvider = IamProvider;
34
+ //# sourceMappingURL=nextauth.cjs.map
35
+ //# sourceMappingURL=nextauth.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/nextauth.ts"],"names":[],"mappings":";;;AA6CO,SAAS,YACd,OAAA,EAUyB;AACzB,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,CAAU,OAAA,CAAQ,OAAO,EAAE,CAAA;AAClD,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,CAAC,OAAO,CAAA;AAEzC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,KAAA;AAAA,IACJ,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAM,OAAA;AAAA,IACN,SAAA,EAAW,GAAG,MAAM,CAAA,iCAAA,CAAA;AAAA,IACpB,OAAA,EAAS,IAAA;AAAA,IACT,MAAA;AAAA,IACA,eAAe,EAAE,MAAA,EAAQ,EAAE,KAAA,EAAO,wBAAuB,EAAE;AAAA,IAC3D,QAAQ,OAAA,EAAY;AAClB,MAAA,OAAO;AAAA,QACL,IAAI,OAAA,CAAQ,GAAA;AAAA,QACZ,IAAA,EACE,QAAQ,WAAA,IACR,OAAA,CAAQ,QACR,OAAA,CAAQ,kBAAA,IACR,QAAQ,KAAA,IACR,EAAA;AAAA,QACF,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,KAAA,EAAO,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,OAAA,IAAW;AAAA,OAC9C;AAAA,IACF,CAAA;AAAA,IACA,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,SAAA;AAAA,MACJ,IAAA,EAAM,MAAA;AAAA,MACN,IAAA,EAAM;AAAA,KACR;AAAA,IACA;AAAA,GACF;AACF","file":"nextauth.cjs","sourcesContent":["/**\n * NextAuth.js / Auth.js provider for IAM (OIDC-based).\n *\n * Provides a canonical NextAuth/Auth.js provider configuration\n * so all Next.js apps can share one implementation.\n *\n * @example\n * ```ts\n * // next-auth config\n * import { IamProvider } from \"@hanzo/iam/nextauth\";\n *\n * export default NextAuth({\n * providers: [\n * IamProvider({\n * serverUrl: process.env.IAM_ENDPOINT!,\n * clientId: process.env.IAM_CLIENT_ID!,\n * clientSecret: process.env.IAM_CLIENT_SECRET!,\n * }),\n * ],\n * });\n * ```\n *\n * @packageDocumentation\n */\n\nexport interface IamProfile extends Record<string, unknown> {\n sub: string;\n name: string;\n email: string;\n preferred_username?: string;\n picture?: string;\n avatar?: string;\n displayName?: string;\n email_verified?: boolean;\n}\n\n/**\n * NextAuth.js / Auth.js compatible OAuth provider for IAM.\n *\n * Uses standard OIDC well-known endpoint for automatic configuration.\n * JWT id_token validation (issuer, audience, signature) is handled by\n * openid-client using the JWKS published at `{serverUrl}/.well-known/jwks`.\n *\n * Pass `checks: [\"state\", \"pkce\"]` in options for PKCE alignment.\n */\nexport function IamProvider<P extends IamProfile>(\n options: {\n serverUrl: string;\n clientId: string;\n clientSecret?: string;\n orgName?: string;\n appName?: string;\n /** OAuth state/PKCE checks. Default: [\"state\"]. Add \"pkce\" for extra security. */\n checks?: (\"state\" | \"pkce\" | \"nonce\" | \"none\")[];\n [key: string]: unknown;\n },\n): Record<string, unknown> {\n const issuer = options.serverUrl.replace(/\\/$/, \"\");\n const checks = options.checks ?? [\"state\"];\n\n return {\n id: \"iam\",\n name: \"IAM\",\n type: \"oauth\",\n wellKnown: `${issuer}/.well-known/openid-configuration`,\n idToken: true,\n checks,\n authorization: { params: { scope: \"openid profile email\" } },\n profile(profile: P) {\n return {\n id: profile.sub,\n name:\n profile.displayName ||\n profile.name ||\n profile.preferred_username ||\n profile.email ||\n \"\",\n email: profile.email,\n image: profile.avatar || profile.picture || null,\n };\n },\n style: {\n bg: \"#050508\",\n text: \"#fff\",\n logo: \"\",\n },\n options,\n };\n}\n\n// Backwards-compatible aliases\n/** @deprecated Use IamProvider instead */\nexport { IamProvider as HanzoIamProvider };\n/** @deprecated Use IamProfile instead */\nexport type { IamProfile as HanzoIamProfile };\n"]}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * NextAuth.js / Auth.js provider for IAM (OIDC-based).
3
+ *
4
+ * Provides a canonical NextAuth/Auth.js provider configuration
5
+ * so all Next.js apps can share one implementation.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // next-auth config
10
+ * import { IamProvider } from "@hanzo/iam/nextauth";
11
+ *
12
+ * export default NextAuth({
13
+ * providers: [
14
+ * IamProvider({
15
+ * serverUrl: process.env.IAM_ENDPOINT!,
16
+ * clientId: process.env.IAM_CLIENT_ID!,
17
+ * clientSecret: process.env.IAM_CLIENT_SECRET!,
18
+ * }),
19
+ * ],
20
+ * });
21
+ * ```
22
+ *
23
+ * @packageDocumentation
24
+ */
25
+ interface IamProfile extends Record<string, unknown> {
26
+ sub: string;
27
+ name: string;
28
+ email: string;
29
+ preferred_username?: string;
30
+ picture?: string;
31
+ avatar?: string;
32
+ displayName?: string;
33
+ email_verified?: boolean;
34
+ }
35
+ /**
36
+ * NextAuth.js / Auth.js compatible OAuth provider for IAM.
37
+ *
38
+ * Uses standard OIDC well-known endpoint for automatic configuration.
39
+ * JWT id_token validation (issuer, audience, signature) is handled by
40
+ * openid-client using the JWKS published at `{serverUrl}/.well-known/jwks`.
41
+ *
42
+ * Pass `checks: ["state", "pkce"]` in options for PKCE alignment.
43
+ */
44
+ declare function IamProvider<P extends IamProfile>(options: {
45
+ serverUrl: string;
46
+ clientId: string;
47
+ clientSecret?: string;
48
+ orgName?: string;
49
+ appName?: string;
50
+ /** OAuth state/PKCE checks. Default: ["state"]. Add "pkce" for extra security. */
51
+ checks?: ("state" | "pkce" | "nonce" | "none")[];
52
+ [key: string]: unknown;
53
+ }): Record<string, unknown>;
54
+
55
+ export { type IamProfile as HanzoIamProfile, IamProvider as HanzoIamProvider, type IamProfile, IamProvider };
@@ -12,7 +12,7 @@
12
12
  * export default NextAuth({
13
13
  * providers: [
14
14
  * IamProvider({
15
- * serverUrl: process.env.IAM_SERVER_URL!,
15
+ * serverUrl: process.env.IAM_ENDPOINT!,
16
16
  * clientId: process.env.IAM_CLIENT_ID!,
17
17
  * clientSecret: process.env.IAM_CLIENT_SECRET!,
18
18
  * }),
@@ -22,7 +22,7 @@
22
22
  *
23
23
  * @packageDocumentation
24
24
  */
25
- export interface IamProfile extends Record<string, unknown> {
25
+ interface IamProfile extends Record<string, unknown> {
26
26
  sub: string;
27
27
  name: string;
28
28
  email: string;
@@ -41,7 +41,7 @@ export interface IamProfile extends Record<string, unknown> {
41
41
  *
42
42
  * Pass `checks: ["state", "pkce"]` in options for PKCE alignment.
43
43
  */
44
- export declare function IamProvider<P extends IamProfile>(options: {
44
+ declare function IamProvider<P extends IamProfile>(options: {
45
45
  serverUrl: string;
46
46
  clientId: string;
47
47
  clientSecret?: string;
@@ -51,8 +51,5 @@ export declare function IamProvider<P extends IamProfile>(options: {
51
51
  checks?: ("state" | "pkce" | "nonce" | "none")[];
52
52
  [key: string]: unknown;
53
53
  }): Record<string, unknown>;
54
- /** @deprecated Use IamProvider instead */
55
- export { IamProvider as HanzoIamProvider };
56
- /** @deprecated Use IamProfile instead */
57
- export type { IamProfile as HanzoIamProfile };
58
- //# sourceMappingURL=nextauth.d.ts.map
54
+
55
+ export { type IamProfile as HanzoIamProfile, IamProvider as HanzoIamProvider, type IamProfile, IamProvider };
package/dist/nextauth.js CHANGED
@@ -1,68 +1,32 @@
1
- /**
2
- * NextAuth.js / Auth.js provider for IAM (OIDC-based).
3
- *
4
- * Provides a canonical NextAuth/Auth.js provider configuration
5
- * so all Next.js apps can share one implementation.
6
- *
7
- * @example
8
- * ```ts
9
- * // next-auth config
10
- * import { IamProvider } from "@hanzo/iam/nextauth";
11
- *
12
- * export default NextAuth({
13
- * providers: [
14
- * IamProvider({
15
- * serverUrl: process.env.IAM_SERVER_URL!,
16
- * clientId: process.env.IAM_CLIENT_ID!,
17
- * clientSecret: process.env.IAM_CLIENT_SECRET!,
18
- * }),
19
- * ],
20
- * });
21
- * ```
22
- *
23
- * @packageDocumentation
24
- */
25
- /**
26
- * NextAuth.js / Auth.js compatible OAuth provider for IAM.
27
- *
28
- * Uses standard OIDC well-known endpoint for automatic configuration.
29
- * JWT id_token validation (issuer, audience, signature) is handled by
30
- * openid-client using the JWKS published at `{serverUrl}/.well-known/jwks`.
31
- *
32
- * Pass `checks: ["state", "pkce"]` in options for PKCE alignment.
33
- */
34
- export function IamProvider(options) {
35
- const issuer = options.serverUrl.replace(/\/$/, "");
36
- const checks = options.checks ?? ["state"];
37
- return {
38
- id: "iam",
39
- name: "IAM",
40
- type: "oauth",
41
- wellKnown: `${issuer}/.well-known/openid-configuration`,
42
- idToken: true,
43
- checks,
44
- authorization: { params: { scope: "openid profile email" } },
45
- profile(profile) {
46
- return {
47
- id: profile.sub,
48
- name: profile.displayName ||
49
- profile.name ||
50
- profile.preferred_username ||
51
- profile.email ||
52
- "",
53
- email: profile.email,
54
- image: profile.avatar || profile.picture || null,
55
- };
56
- },
57
- style: {
58
- bg: "#050508",
59
- text: "#fff",
60
- logo: "",
61
- },
62
- options,
63
- };
1
+ // src/nextauth.ts
2
+ function IamProvider(options) {
3
+ const issuer = options.serverUrl.replace(/\/$/, "");
4
+ const checks = options.checks ?? ["state"];
5
+ return {
6
+ id: "iam",
7
+ name: "IAM",
8
+ type: "oauth",
9
+ wellKnown: `${issuer}/.well-known/openid-configuration`,
10
+ idToken: true,
11
+ checks,
12
+ authorization: { params: { scope: "openid profile email" } },
13
+ profile(profile) {
14
+ return {
15
+ id: profile.sub,
16
+ name: profile.displayName || profile.name || profile.preferred_username || profile.email || "",
17
+ email: profile.email,
18
+ image: profile.avatar || profile.picture || null
19
+ };
20
+ },
21
+ style: {
22
+ bg: "#050508",
23
+ text: "#fff",
24
+ logo: ""
25
+ },
26
+ options
27
+ };
64
28
  }
65
- // Backwards-compatible aliases
66
- /** @deprecated Use IamProvider instead */
67
- export { IamProvider as HanzoIamProvider };
29
+
30
+ export { IamProvider as HanzoIamProvider, IamProvider };
31
+ //# sourceMappingURL=nextauth.js.map
68
32
  //# sourceMappingURL=nextauth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nextauth.js","sourceRoot":"","sources":["../src/nextauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAaH;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CACzB,OASC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IAE3C,OAAO;QACL,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,GAAG,MAAM,mCAAmC;QACvD,OAAO,EAAE,IAAI;QACb,MAAM;QACN,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE;QAC5D,OAAO,CAAC,OAAU;YAChB,OAAO;gBACL,EAAE,EAAE,OAAO,CAAC,GAAG;gBACf,IAAI,EACF,OAAO,CAAC,WAAW;oBACnB,OAAO,CAAC,IAAI;oBACZ,OAAO,CAAC,kBAAkB;oBAC1B,OAAO,CAAC,KAAK;oBACb,EAAE;gBACJ,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI;aACjD,CAAC;QACJ,CAAC;QACD,KAAK,EAAE;YACL,EAAE,EAAE,SAAS;YACb,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,EAAE;SACT;QACD,OAAO;KACR,CAAC;AACJ,CAAC;AAED,+BAA+B;AAC/B,0CAA0C;AAC1C,OAAO,EAAE,WAAW,IAAI,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"sources":["../src/nextauth.ts"],"names":[],"mappings":";AA6CO,SAAS,YACd,OAAA,EAUyB;AACzB,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,CAAU,OAAA,CAAQ,OAAO,EAAE,CAAA;AAClD,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,CAAC,OAAO,CAAA;AAEzC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,KAAA;AAAA,IACJ,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAM,OAAA;AAAA,IACN,SAAA,EAAW,GAAG,MAAM,CAAA,iCAAA,CAAA;AAAA,IACpB,OAAA,EAAS,IAAA;AAAA,IACT,MAAA;AAAA,IACA,eAAe,EAAE,MAAA,EAAQ,EAAE,KAAA,EAAO,wBAAuB,EAAE;AAAA,IAC3D,QAAQ,OAAA,EAAY;AAClB,MAAA,OAAO;AAAA,QACL,IAAI,OAAA,CAAQ,GAAA;AAAA,QACZ,IAAA,EACE,QAAQ,WAAA,IACR,OAAA,CAAQ,QACR,OAAA,CAAQ,kBAAA,IACR,QAAQ,KAAA,IACR,EAAA;AAAA,QACF,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,KAAA,EAAO,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,OAAA,IAAW;AAAA,OAC9C;AAAA,IACF,CAAA;AAAA,IACA,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,SAAA;AAAA,MACJ,IAAA,EAAM,MAAA;AAAA,MACN,IAAA,EAAM;AAAA,KACR;AAAA,IACA;AAAA,GACF;AACF","file":"nextauth.js","sourcesContent":["/**\n * NextAuth.js / Auth.js provider for IAM (OIDC-based).\n *\n * Provides a canonical NextAuth/Auth.js provider configuration\n * so all Next.js apps can share one implementation.\n *\n * @example\n * ```ts\n * // next-auth config\n * import { IamProvider } from \"@hanzo/iam/nextauth\";\n *\n * export default NextAuth({\n * providers: [\n * IamProvider({\n * serverUrl: process.env.IAM_ENDPOINT!,\n * clientId: process.env.IAM_CLIENT_ID!,\n * clientSecret: process.env.IAM_CLIENT_SECRET!,\n * }),\n * ],\n * });\n * ```\n *\n * @packageDocumentation\n */\n\nexport interface IamProfile extends Record<string, unknown> {\n sub: string;\n name: string;\n email: string;\n preferred_username?: string;\n picture?: string;\n avatar?: string;\n displayName?: string;\n email_verified?: boolean;\n}\n\n/**\n * NextAuth.js / Auth.js compatible OAuth provider for IAM.\n *\n * Uses standard OIDC well-known endpoint for automatic configuration.\n * JWT id_token validation (issuer, audience, signature) is handled by\n * openid-client using the JWKS published at `{serverUrl}/.well-known/jwks`.\n *\n * Pass `checks: [\"state\", \"pkce\"]` in options for PKCE alignment.\n */\nexport function IamProvider<P extends IamProfile>(\n options: {\n serverUrl: string;\n clientId: string;\n clientSecret?: string;\n orgName?: string;\n appName?: string;\n /** OAuth state/PKCE checks. Default: [\"state\"]. Add \"pkce\" for extra security. */\n checks?: (\"state\" | \"pkce\" | \"nonce\" | \"none\")[];\n [key: string]: unknown;\n },\n): Record<string, unknown> {\n const issuer = options.serverUrl.replace(/\\/$/, \"\");\n const checks = options.checks ?? [\"state\"];\n\n return {\n id: \"iam\",\n name: \"IAM\",\n type: \"oauth\",\n wellKnown: `${issuer}/.well-known/openid-configuration`,\n idToken: true,\n checks,\n authorization: { params: { scope: \"openid profile email\" } },\n profile(profile: P) {\n return {\n id: profile.sub,\n name:\n profile.displayName ||\n profile.name ||\n profile.preferred_username ||\n profile.email ||\n \"\",\n email: profile.email,\n image: profile.avatar || profile.picture || null,\n };\n },\n style: {\n bg: \"#050508\",\n text: \"#fff\",\n logo: \"\",\n },\n options,\n };\n}\n\n// Backwards-compatible aliases\n/** @deprecated Use IamProvider instead */\nexport { IamProvider as HanzoIamProvider };\n/** @deprecated Use IamProfile instead */\nexport type { IamProfile as HanzoIamProfile };\n"]}
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var OAuth2Strategy = require('passport-oauth2');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var OAuth2Strategy__default = /*#__PURE__*/_interopDefault(OAuth2Strategy);
8
+
9
+ // src/passport.ts
10
+ function createIamPassportStrategy(config) {
11
+ const baseUrl = config.serverUrl.replace(/\/+$/, "");
12
+ const verify = async (...args) => {
13
+ const accessToken = args[1];
14
+ const refreshToken = args[2];
15
+ const done = args[4];
16
+ try {
17
+ const res = await fetch(`${baseUrl}/oauth/userinfo`, {
18
+ headers: { Authorization: `Bearer ${accessToken}` }
19
+ });
20
+ if (!res.ok) {
21
+ return done(new Error(`IAM userinfo failed: ${res.status}`));
22
+ }
23
+ const userinfo = await res.json();
24
+ done(null, { accessToken, refreshToken, userinfo });
25
+ } catch (err) {
26
+ done(err instanceof Error ? err : new Error(String(err)));
27
+ }
28
+ };
29
+ return new OAuth2Strategy__default.default(
30
+ {
31
+ authorizationURL: `${baseUrl}/oauth/authorize`,
32
+ tokenURL: `${baseUrl}/oauth/token`,
33
+ clientID: config.clientId,
34
+ clientSecret: config.clientSecret ?? "",
35
+ callbackURL: config.callbackUrl,
36
+ scope: config.scope ?? "openid profile email",
37
+ state: true,
38
+ pkce: true,
39
+ passReqToCallback: true
40
+ },
41
+ verify
42
+ );
43
+ }
44
+
45
+ exports.createIamPassportStrategy = createIamPassportStrategy;
46
+ //# sourceMappingURL=passport.cjs.map
47
+ //# sourceMappingURL=passport.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/passport.ts"],"names":["OAuth2Strategy"],"mappings":";;;;;;;;;AAmDO,SAAS,0BACd,MAAA,EACS;AAET,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAEnD,EAAA,MAAM,MAAA,GAAS,UACV,IAAA,KACe;AAElB,IAAA,MAAM,WAAA,GAAc,KAAK,CAAC,CAAA;AAC1B,IAAA,MAAM,YAAA,GAAe,KAAK,CAAC,CAAA;AAC3B,IAAA,MAAM,IAAA,GAAO,KAAK,CAAC,CAAA;AAEnB,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,eAAA,CAAA,EAAmB;AAAA,QACnD,OAAA,EAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,WAAW,CAAA,CAAA;AAAG,OACnD,CAAA;AACD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,OAAO,KAAK,IAAI,KAAA,CAAM,wBAAwB,GAAA,CAAI,MAAM,EAAE,CAAC,CAAA;AAAA,MAC7D;AACA,MAAA,MAAM,QAAA,GAAY,MAAM,GAAA,CAAI,IAAA,EAAK;AACjC,MAAA,IAAA,CAAK,IAAA,EAAM,EAAE,WAAA,EAAa,YAAA,EAAc,UAAU,CAAA;AAAA,IACpD,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,IAC1D;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,IAAIA,+BAAA;AAAA,IACT;AAAA,MACE,gBAAA,EAAkB,GAAG,OAAO,CAAA,gBAAA,CAAA;AAAA,MAC5B,QAAA,EAAU,GAAG,OAAO,CAAA,YAAA,CAAA;AAAA,MACpB,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,YAAA,EAAc,OAAO,YAAA,IAAgB,EAAA;AAAA,MACrC,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,KAAA,EAAO,OAAO,KAAA,IAAS,sBAAA;AAAA,MACvB,KAAA,EAAO,IAAA;AAAA,MACP,IAAA,EAAM,IAAA;AAAA,MACN,iBAAA,EAAmB;AAAA,KACrB;AAAA,IACA;AAAA,GACF;AACF","file":"passport.cjs","sourcesContent":["/**\n * Passport.js OAuth2 strategy factory for Hanzo IAM.\n *\n * Creates a pre-configured passport-oauth2 strategy that authenticates\n * against hanzo.id with PKCE and fetches user info on callback.\n *\n * @example\n * ```ts\n * import passport from \"passport\";\n * import { createIamPassportStrategy } from \"@hanzo/iam/passport\";\n *\n * passport.use(\"iam\", createIamPassportStrategy({\n * serverUrl: \"https://hanzo.id\",\n * clientId: \"hanzo-kms-client-id\",\n * clientSecret: process.env.IAM_CLIENT_SECRET!,\n * callbackUrl: \"https://kms.hanzo.ai/api/v1/sso/oidc/callback\",\n * }));\n * ```\n *\n * @packageDocumentation\n */\n\nimport OAuth2Strategy from \"passport-oauth2\";\n\nimport type { IamConfig } from \"./types.js\";\n\nexport interface IamPassportConfig extends IamConfig {\n /** Full callback URL for OAuth2 redirect. */\n callbackUrl: string;\n /** OAuth2 scopes. Default: \"openid profile email\". */\n scope?: string;\n}\n\nexport interface IamPassportUser {\n accessToken: string;\n refreshToken?: string;\n userinfo: Record<string, unknown>;\n}\n\n/**\n * Create a Passport OAuth2 strategy for Hanzo IAM.\n *\n * Returns an OAuth2Strategy instance ready to pass to `passport.use()`.\n * The verify callback fetches userinfo from the IAM server and passes\n * `{ accessToken, refreshToken, userinfo }` as the user object.\n *\n * `passport-oauth2` is a runtime dependency of this entry — using a\n * static import lets downstream bundlers (esbuild, webpack, etc.)\n * statically resolve and bundle it. Consumers who don't need passport\n * can import from `@hanzo/iam` directly to avoid pulling it in.\n */\nexport function createIamPassportStrategy(\n config: IamPassportConfig,\n): unknown {\n\n const baseUrl = config.serverUrl.replace(/\\/+$/, \"\");\n\n const verify = async (\n ...args: unknown[]\n ): Promise<void> => {\n // passReqToCallback=true: (req, accessToken, refreshToken, profile, done)\n const accessToken = args[1] as string;\n const refreshToken = args[2] as string | undefined;\n const done = args[4] as (err: Error | null, user?: IamPassportUser) => void;\n\n try {\n const res = await fetch(`${baseUrl}/oauth/userinfo`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!res.ok) {\n return done(new Error(`IAM userinfo failed: ${res.status}`));\n }\n const userinfo = (await res.json()) as Record<string, unknown>;\n done(null, { accessToken, refreshToken, userinfo });\n } catch (err) {\n done(err instanceof Error ? err : new Error(String(err)));\n }\n };\n\n return new OAuth2Strategy(\n {\n authorizationURL: `${baseUrl}/oauth/authorize`,\n tokenURL: `${baseUrl}/oauth/token`,\n clientID: config.clientId,\n clientSecret: config.clientSecret ?? \"\",\n callbackURL: config.callbackUrl,\n scope: config.scope ?? \"openid profile email\",\n state: true,\n pkce: true,\n passReqToCallback: true,\n },\n verify,\n );\n}\n"]}
@@ -0,0 +1,50 @@
1
+ import { IamConfig } from './types.cjs';
2
+
3
+ /**
4
+ * Passport.js OAuth2 strategy factory for Hanzo IAM.
5
+ *
6
+ * Creates a pre-configured passport-oauth2 strategy that authenticates
7
+ * against hanzo.id with PKCE and fetches user info on callback.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import passport from "passport";
12
+ * import { createIamPassportStrategy } from "@hanzo/iam/passport";
13
+ *
14
+ * passport.use("iam", createIamPassportStrategy({
15
+ * serverUrl: "https://hanzo.id",
16
+ * clientId: "hanzo-kms-client-id",
17
+ * clientSecret: process.env.IAM_CLIENT_SECRET!,
18
+ * callbackUrl: "https://kms.hanzo.ai/api/v1/sso/oidc/callback",
19
+ * }));
20
+ * ```
21
+ *
22
+ * @packageDocumentation
23
+ */
24
+
25
+ interface IamPassportConfig extends IamConfig {
26
+ /** Full callback URL for OAuth2 redirect. */
27
+ callbackUrl: string;
28
+ /** OAuth2 scopes. Default: "openid profile email". */
29
+ scope?: string;
30
+ }
31
+ interface IamPassportUser {
32
+ accessToken: string;
33
+ refreshToken?: string;
34
+ userinfo: Record<string, unknown>;
35
+ }
36
+ /**
37
+ * Create a Passport OAuth2 strategy for Hanzo IAM.
38
+ *
39
+ * Returns an OAuth2Strategy instance ready to pass to `passport.use()`.
40
+ * The verify callback fetches userinfo from the IAM server and passes
41
+ * `{ accessToken, refreshToken, userinfo }` as the user object.
42
+ *
43
+ * `passport-oauth2` is a runtime dependency of this entry — using a
44
+ * static import lets downstream bundlers (esbuild, webpack, etc.)
45
+ * statically resolve and bundle it. Consumers who don't need passport
46
+ * can import from `@hanzo/iam` directly to avoid pulling it in.
47
+ */
48
+ declare function createIamPassportStrategy(config: IamPassportConfig): unknown;
49
+
50
+ export { type IamPassportConfig, type IamPassportUser, createIamPassportStrategy };
@@ -1,3 +1,5 @@
1
+ import { IamConfig } from './types.js';
2
+
1
3
  /**
2
4
  * Passport.js OAuth2 strategy factory for Hanzo IAM.
3
5
  *
@@ -19,14 +21,14 @@
19
21
  *
20
22
  * @packageDocumentation
21
23
  */
22
- import type { IamConfig } from "./types.js";
23
- export interface IamPassportConfig extends IamConfig {
24
+
25
+ interface IamPassportConfig extends IamConfig {
24
26
  /** Full callback URL for OAuth2 redirect. */
25
27
  callbackUrl: string;
26
28
  /** OAuth2 scopes. Default: "openid profile email". */
27
29
  scope?: string;
28
30
  }
29
- export interface IamPassportUser {
31
+ interface IamPassportUser {
30
32
  accessToken: string;
31
33
  refreshToken?: string;
32
34
  userinfo: Record<string, unknown>;
@@ -34,11 +36,15 @@ export interface IamPassportUser {
34
36
  /**
35
37
  * Create a Passport OAuth2 strategy for Hanzo IAM.
36
38
  *
37
- * Requires `passport-oauth2` as a peer dependency.
38
39
  * Returns an OAuth2Strategy instance ready to pass to `passport.use()`.
39
- *
40
40
  * The verify callback fetches userinfo from the IAM server and passes
41
41
  * `{ accessToken, refreshToken, userinfo }` as the user object.
42
+ *
43
+ * `passport-oauth2` is a runtime dependency of this entry — using a
44
+ * static import lets downstream bundlers (esbuild, webpack, etc.)
45
+ * statically resolve and bundle it. Consumers who don't need passport
46
+ * can import from `@hanzo/iam` directly to avoid pulling it in.
42
47
  */
43
- export declare function createIamPassportStrategy(config: IamPassportConfig): unknown;
44
- //# sourceMappingURL=passport.d.ts.map
48
+ declare function createIamPassportStrategy(config: IamPassportConfig): unknown;
49
+
50
+ export { type IamPassportConfig, type IamPassportUser, createIamPassportStrategy };