@kysera/rls 0.8.4 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/policy/schema.ts","../src/policy/builder.ts","../src/policy/registry.ts","../src/context/storage.ts","../src/context/manager.ts","../src/utils/type-utils.ts","../src/transformer/select.ts","../src/transformer/mutation.ts","../src/version.ts","../src/plugin.ts","../src/utils/helpers.ts","../src/resolvers/types.ts","../src/resolvers/manager.ts","../src/rebac/types.ts","../src/rebac/registry.ts","../src/rebac/transformer.ts","../src/field-access/types.ts","../src/field-access/registry.ts","../src/field-access/processor.ts","../src/composition/builder.ts","../src/audit/types.ts","../src/audit/logger.ts","../src/testing/index.ts"],"names":["allow","deny","validate","filter","silentLogger","sql"],"mappings":";;;;;;;AAuBO,IAAM,aAAA,GAAgB;AAAA;AAAA,EAE3B,mBAAA,EAAqB,qBAAA;AAAA;AAAA,EAErB,oBAAA,EAAsB,sBAAA;AAAA;AAAA,EAEtB,kBAAA,EAAoB,oBAAA;AAAA;AAAA,EAEpB,kBAAA,EAAoB,oBAAA;AAAA;AAAA,EAEpB,mBAAA,EAAqB,qBAAA;AAAA;AAAA,EAErB,2BAAA,EAA6B;AAC/B;AAsBO,IAAM,QAAA,GAAN,cAAuB,aAAA,CAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1C,WAAA,CAAY,SAAiB,IAAA,EAAoB;AAC/C,IAAA,KAAA,CAAM,SAAS,IAAI,CAAA;AACnB,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AAAA,EACd;AACF;AAuBO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM5C,WAAA,CAAY,UAAU,gEAAA,EAAkE;AACtF,IAAA,KAAA,CAAM,OAAA,EAAS,cAAc,mBAAmB,CAAA;AAChD,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AAAA,EACd;AACF;AAyBO,IAAM,yBAAA,GAAN,cAAwC,QAAA,CAAS;AAAA,EACtC,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhB,WAAA,CAAY,SAAiB,KAAA,EAAe;AAC1C,IAAA,KAAA,CAAM,OAAA,EAAS,cAAc,mBAAmB,CAAA;AAChD,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AAAA,EAES,MAAA,GAAkC;AACzC,IAAA,OAAO;AAAA,MACL,GAAG,MAAM,MAAA,EAAO;AAAA,MAChB,OAAO,IAAA,CAAK;AAAA,KACd;AAAA,EACF;AACF;AAwBO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC/B,SAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUhB,WAAA,CAAY,SAAA,EAAmB,KAAA,EAAe,MAAA,EAAgB,UAAA,EAAqB;AACjF,IAAA,KAAA;AAAA,MACE,CAAA,sBAAA,EAAyB,SAAS,CAAA,IAAA,EAAO,KAAK,MAAM,MAAM,CAAA,CAAA;AAAA,MAC1D,aAAA,CAAc;AAAA,KAChB;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAES,MAAA,GAAkC;AACzC,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,GAAG,MAAM,MAAA,EAAO;AAAA,MAChB,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,QAAQ,IAAA,CAAK;AAAA,KACf;AACA,IAAA,IAAI,IAAA,CAAK,eAAe,MAAA,EAAW;AACjC,MAAA,IAAA,CAAK,YAAY,IAAI,IAAA,CAAK,UAAA;AAAA,IAC5B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAsBO,IAAM,wBAAA,GAAN,cAAuC,QAAA,CAAS;AAAA,EACrC,SAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWhB,WAAA,CACE,SAAA,EACA,KAAA,EACA,OAAA,EACA,YACA,aAAA,EACA;AACA,IAAA,KAAA;AAAA,MACE,CAAA,mCAAA,EAAsC,SAAS,CAAA,IAAA,EAAO,KAAK,KAAK,OAAO,CAAA,CAAA;AAAA,MACvE,aAAA,CAAc;AAAA,KAChB;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,0BAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAAA,IACpB;AACA,IAAA,IAAI,kBAAkB,MAAA,EAAW;AAC/B,MAAA,IAAA,CAAK,aAAA,GAAgB,aAAA;AAErB,MAAA,IAAI,cAAc,KAAA,EAAO;AACvB,QAAA,IAAA,CAAK,KAAA,GAAQ,CAAA,EAAG,IAAA,CAAK,KAAK;;AAAA;AAAA,EAAmB,cAAc,KAAK,CAAA,CAAA;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAAA,EAES,MAAA,GAAkC;AACzC,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,GAAG,MAAM,MAAA,EAAO;AAAA,MAChB,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,OAAO,IAAA,CAAK;AAAA,KACd;AACA,IAAA,IAAI,IAAA,CAAK,eAAe,MAAA,EAAW;AACjC,MAAA,IAAA,CAAK,YAAY,IAAI,IAAA,CAAK,UAAA;AAAA,IAC5B;AACA,IAAA,IAAI,IAAA,CAAK,kBAAkB,MAAA,EAAW;AACpC,MAAA,IAAA,CAAK,eAAe,CAAA,GAAI;AAAA,QACtB,IAAA,EAAM,KAAK,aAAA,CAAc,IAAA;AAAA,QACzB,OAAA,EAAS,KAAK,aAAA,CAAc;AAAA,OAC9B;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAiCO,IAAM,cAAA,GAAN,cAA6B,QAAA,CAAS;AAAA,EAC3B,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhB,WAAA,CAAY,OAAA,EAAiB,OAAA,GAAmC,EAAC,EAAG;AAClE,IAAA,KAAA,CAAM,OAAA,EAAS,cAAc,kBAAkB,CAAA;AAC/C,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAES,MAAA,GAAkC;AACzC,IAAA,OAAO;AAAA,MACL,GAAG,MAAM,MAAA,EAAO;AAAA,MAChB,SAAS,IAAA,CAAK;AAAA,KAChB;AAAA,EACF;AACF;;;AC9SO,SAAS,gBAAoB,MAAA,EAAsC;AAExE,EAAA,cAAA,CAAe,MAAM,CAAA;AACrB,EAAA,OAAO,MAAA;AACT;AAQA,SAAS,eAAmB,MAAA,EAA6B;AACvD,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACpD,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,IAAA,MAAM,WAAA,GAAc,MAAA;AAEpB,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,WAAA,CAAY,QAAQ,CAAA,EAAG;AACxC,MAAA,MAAM,IAAI,cAAA,CAAe,CAAA,4BAAA,EAA+B,KAAK,CAAA,mBAAA,CAAA,EAAuB,EAAE,OAAO,CAAA;AAAA,IAC/F;AAGA,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,WAAA,CAAY,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACpD,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,QAAA,CAAS,CAAC,CAAA;AACrC,MAAA,IAAI,WAAW,MAAA,EAAW;AACxB,QAAA,cAAA,CAAe,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,MACjC;AAAA,IACF;AAGA,IAAA,IAAI,WAAA,CAAY,YAAY,MAAA,EAAW;AACrC,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,WAAA,CAAY,OAAO,CAAA,EAAG;AACvC,QAAA,MAAM,IAAI,cAAA;AAAA,UACR,8BAA8B,KAAK,CAAA,iCAAA,CAAA;AAAA,UACnC,EAAE,KAAA;AAAM,SACV;AAAA,MACF;AAGA,MAAA,KAAA,MAAW,IAAA,IAAQ,YAAY,OAAA,EAAS;AACtC,QAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,IAAA,OAAW,EAAA,EAAI;AAClD,UAAA,MAAM,IAAI,cAAA;AAAA,YACR,sCAAsC,KAAK,CAAA,6BAAA,CAAA;AAAA,YAC3C,EAAE,KAAA;AAAM,WACV;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAI,YAAY,WAAA,KAAgB,MAAA,IAAa,OAAO,WAAA,CAAY,gBAAgB,SAAA,EAAW;AACzF,MAAA,MAAM,IAAI,cAAA,CAAe,CAAA,+BAAA,EAAkC,KAAK,CAAA,oBAAA,CAAA,EAAwB;AAAA,QACtF;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF;AACF;AAQA,SAAS,cAAA,CAAe,MAAA,EAA0B,KAAA,EAAe,KAAA,EAAqB;AACpF,EAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAChB,IAAA,MAAM,IAAI,cAAA,CAAe,CAAA,OAAA,EAAU,KAAK,CAAA,YAAA,EAAe,KAAK,CAAA,cAAA,CAAA,EAAkB,EAAE,KAAA,EAAO,KAAA,EAAO,CAAA;AAAA,EAChG;AAEA,EAAA,MAAM,UAAA,GAAa,CAAC,OAAA,EAAS,MAAA,EAAQ,UAAU,UAAU,CAAA;AACzD,EAAA,IAAI,CAAC,UAAA,CAAW,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA,EAAG;AACrC,IAAA,MAAM,IAAI,cAAA;AAAA,MACR,UAAU,KAAK,CAAA,YAAA,EAAe,KAAK,CAAA,oBAAA,EAAuB,OAAO,IAAI,CAAA,CAAA;AAAA,MACrE,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,OAAO,IAAA;AAAK,KACpC;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,IAAA,MAAM,IAAI,cAAA,CAAe,CAAA,OAAA,EAAU,KAAK,CAAA,YAAA,EAAe,KAAK,CAAA,mBAAA,CAAA,EAAuB;AAAA,MACjF,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,WAAW,CAAC,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,UAAU,KAAK,CAAA;AAC7D,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,SAAS,IAAI,MAAA,CAAO,SAAA,GAAY,CAAC,MAAA,CAAO,SAAS,CAAA;AAElF,EAAA,KAAA,MAAW,MAAM,GAAA,EAAK;AACpB,IAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,EAAE,CAAA,EAAG;AAC1B,MAAA,MAAM,IAAI,cAAA;AAAA,QACR,CAAA,OAAA,EAAU,KAAK,CAAA,YAAA,EAAe,KAAK,4BAA4B,EAAE,CAAA,CAAA;AAAA,QACjE,EAAE,KAAA,EAAO,KAAA,EAAO,SAAA,EAAW,EAAA;AAAG,OAChC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,CAAO,SAAA,KAAc,MAAA,IAAa,MAAA,CAAO,cAAc,IAAA,EAAM;AAC/D,IAAA,MAAM,IAAI,cAAA,CAAe,CAAA,OAAA,EAAU,KAAK,CAAA,YAAA,EAAe,KAAK,CAAA,mBAAA,CAAA,EAAuB;AAAA,MACjF,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,OAAO,MAAA,CAAO,SAAA,KAAc,cAAc,OAAO,MAAA,CAAO,cAAc,QAAA,EAAU;AAClF,IAAA,MAAM,IAAI,cAAA;AAAA,MACR,CAAA,OAAA,EAAU,KAAK,CAAA,YAAA,EAAe,KAAK,CAAA,wCAAA,CAAA;AAAA,MACnC,EAAE,OAAO,KAAA;AAAM,KACjB;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,QAAA,KAAa,MAAA,IAAa,OAAO,MAAA,CAAO,aAAa,QAAA,EAAU;AACxE,IAAA,MAAM,IAAI,cAAA,CAAe,CAAA,OAAA,EAAU,KAAK,CAAA,YAAA,EAAe,KAAK,CAAA,2BAAA,CAAA,EAA+B;AAAA,MACzF,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,OAAO,IAAA,KAAS,MAAA,IAAa,OAAO,MAAA,CAAO,SAAS,QAAA,EAAU;AAChE,IAAA,MAAM,IAAI,cAAA,CAAe,CAAA,OAAA,EAAU,KAAK,CAAA,YAAA,EAAe,KAAK,CAAA,uBAAA,CAAA,EAA2B;AAAA,MACrF,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AACF;AA4BO,SAAS,mBAAuB,OAAA,EAAyC;AAC9E,EAAA,MAAM,SAAwB,EAAC;AAE/B,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACpD,MAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,MAAA,MAAM,cAAA,GAAiB,OAAO,KAAiB,CAAA;AAC/C,MAAA,MAAM,SAAA,GAAY,MAAA;AAElB,MAAA,IAAI,cAAA,EAAgB;AAElB,QAAA,cAAA,CAAe,WAAW,CAAC,GAAG,eAAe,QAAA,EAAU,GAAG,UAAU,QAAQ,CAAA;AAG5E,QAAA,IAAI,UAAU,OAAA,EAAS;AACrB,UAAA,MAAM,eAAA,GAAkB,cAAA,CAAe,OAAA,IAAW,EAAC;AACnD,UAAA,MAAM,kBAAkB,CAAC,GAAG,eAAA,EAAiB,GAAG,UAAU,OAAO,CAAA;AACjE,UAAA,cAAA,CAAe,UAAU,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAI,eAAe,CAAC,CAAA;AAAA,QAC9D;AAGA,QAAA,IAAI,SAAA,CAAU,gBAAgB,MAAA,EAAW;AACvC,UAAA,cAAA,CAAe,cAAc,SAAA,CAAU,WAAA;AAAA,QACzC;AAAA,MACF,CAAA,MAAO;AAOL,QAAA,MAAA,CAAO,KAAiB,CAAA,GAAI;AAAA,UAC1B,QAAA,EAAU,CAAC,GAAG,SAAA,CAAU,QAAQ,CAAA;AAAA,UAChC,SAAS,SAAA,CAAU,OAAA,GAAU,CAAC,GAAG,SAAA,CAAU,OAAO,CAAA,GAAI,MAAA;AAAA,UACtD,aAAa,SAAA,CAAU;AAAA,SACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,cAAA,CAAe,MAAM,CAAA;AAErB,EAAA,OAAO,MAAA;AACT;;;AC5KO,SAAS,KAAA,CACd,SAAA,EACA,SAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,MAAA,GAAsC;AAAA,IAC1C,IAAA,EAAM,OAAA;AAAA,IACN,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA,GACjC;AAEA,EAAA,IAAI,OAAA,EAAS,SAAS,MAAA,EAAW;AAC/B,IAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,EACxB;AAEA,EAAA,IAAI,OAAA,EAAS,UAAU,MAAA,EAAW;AAChC,IAAA,MAAA,CAAO,QAAQ,OAAA,CAAQ,KAAA;AAAA,EACzB;AAEA,EAAA,IAAI,OAAA,EAAS,cAAc,MAAA,EAAW;AACpC,IAAA,MAAA,CAAO,sBAAsB,OAAA,CAAQ,SAAA;AAAA,EACvC;AAEA,EAAA,OAAO,MAAA;AACT;AAyBO,SAAS,IAAA,CACd,SAAA,EACA,SAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,MAAA,GAAsC;AAAA,IAC1C,IAAA,EAAM,MAAA;AAAA,IACN,SAAA;AAAA,IACA,SAAA,EAAW,cAAc,MAAM,IAAA,CAAA;AAAA,IAC/B,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA;AAAA,GACjC;AAEA,EAAA,IAAI,OAAA,EAAS,SAAS,MAAA,EAAW;AAC/B,IAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,EACxB;AAEA,EAAA,IAAI,OAAA,EAAS,UAAU,MAAA,EAAW;AAChC,IAAA,MAAA,CAAO,QAAQ,OAAA,CAAQ,KAAA;AAAA,EACzB;AAEA,EAAA,IAAI,OAAA,EAAS,cAAc,MAAA,EAAW;AACpC,IAAA,MAAA,CAAO,sBAAsB,OAAA,CAAQ,SAAA;AAAA,EACvC;AAEA,EAAA,OAAO,MAAA;AACT;AAsCO,SAAS,MAAA,CACd,SAAA,EACA,SAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,MAAA,GAAsC;AAAA,IAC1C,IAAA,EAAM,QAAA;AAAA,IACN,SAAA,EAAW,SAAA,KAAc,KAAA,GAAQ,MAAA,GAAS,SAAA;AAAA,IAC1C,SAAA;AAAA,IACA,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA,GACjC;AAEA,EAAA,IAAI,OAAA,EAAS,SAAS,MAAA,EAAW;AAC/B,IAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,EACxB;AAEA,EAAA,IAAI,OAAA,EAAS,UAAU,MAAA,EAAW;AAChC,IAAA,MAAA,CAAO,QAAQ,OAAA,CAAQ,KAAA;AAAA,EACzB;AAEA,EAAA,IAAI,OAAA,EAAS,cAAc,MAAA,EAAW;AACpC,IAAA,MAAA,CAAO,sBAAsB,OAAA,CAAQ,SAAA;AAAA,EACvC;AAEA,EAAA,OAAO,MAAA;AACT;AA0BO,SAAS,QAAA,CACd,SAAA,EACA,SAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,MAAM,GAAA,GAAmB,cAAc,KAAA,GAAQ,CAAC,UAAU,QAAQ,CAAA,GAAI,CAAC,SAAS,CAAA;AAEhF,EAAA,MAAM,MAAA,GAAsC;AAAA,IAC1C,IAAA,EAAM,UAAA;AAAA,IACN,SAAA,EAAW,GAAA;AAAA,IACX,SAAA;AAAA,IACA,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA,GACjC;AAEA,EAAA,IAAI,OAAA,EAAS,SAAS,MAAA,EAAW;AAC/B,IAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,EACxB;AAEA,EAAA,IAAI,OAAA,EAAS,UAAU,MAAA,EAAW;AAChC,IAAA,MAAA,CAAO,QAAQ,OAAA,CAAQ,KAAA;AAAA,EACzB;AAEA,EAAA,IAAI,OAAA,EAAS,cAAc,MAAA,EAAW;AACpC,IAAA,MAAA,CAAO,sBAAsB,OAAA,CAAQ,SAAA;AAAA,EACvC;AAEA,EAAA,OAAO,MAAA;AACT;AA0BO,SAAS,eAAA,CACd,cACA,QAAA,EAC6B;AAC7B,EAAA,MAAM,SAAS,QAAA,EAAS;AACxB,EAAA,MAAM,oBAAoB,MAAA,CAAO,mBAAA;AACjC,EAAA,MAAA,CAAO,sBAAsB,CAAA,GAAA,KAAO;AAClC,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,QAAA,CAAS,GAAA,CAAI,eAAe,EAAE,CAAA;AAC5D,IAAA,IAAI,CAAC,UAAU,OAAO,KAAA;AAEtB,IAAA,OAAO,iBAAA,GAAoB,iBAAA,CAAkB,GAAG,CAAA,GAAI,IAAA;AAAA,EACtD,CAAA;AACA,EAAA,OAAO,MAAA;AACT;AAiBO,SAAS,WAAA,CACd,SACA,QAAA,EAC6B;AAC7B,EAAA,MAAM,SAAS,QAAA,EAAS;AACxB,EAAA,MAAM,oBAAoB,MAAA,CAAO,mBAAA;AACjC,EAAA,MAAA,CAAO,sBAAsB,CAAA,GAAA,KAAO;AAClC,IAAA,IAAI,cAAA,GAAiB,KAAA;AACrB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC/B,MAAA,cAAA,GAAiB,GAAA,CAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA;AAAA,IAChD,CAAA,MAAA,IAAW,IAAI,QAAA,IAAY,OAAO,IAAI,QAAA,KAAa,QAAA,IAAY,KAAA,IAAS,GAAA,CAAI,QAAA,EAAU;AAEpF,MAAA,cAAA,GAAkB,GAAA,CAAI,QAAA,CAAyB,GAAA,CAAI,OAAO,CAAA;AAAA,IAC5D,WAAW,GAAA,CAAI,QAAA,IAAY,OAAO,GAAA,CAAI,aAAa,QAAA,EAAU;AAE3D,MAAA,cAAA,GAAiB,CAAC,CAAE,GAAA,CAAI,QAAA,CAAqC,OAAO,CAAA;AAAA,IACtE;AACA,IAAA,IAAI,CAAC,gBAAgB,OAAO,KAAA;AAE5B,IAAA,OAAO,iBAAA,GAAoB,iBAAA,CAAkB,GAAG,CAAA,GAAI,IAAA;AAAA,EACtD,CAAA;AACA,EAAA,OAAO,MAAA;AACT;AAkBO,SAAS,aAAA,CACd,SAAA,EACA,OAAA,EACA,QAAA,EAC6B;AAC7B,EAAA,MAAM,SAAS,QAAA,EAAS;AACxB,EAAA,MAAM,oBAAoB,MAAA,CAAO,mBAAA;AACjC,EAAA,MAAA,CAAO,sBAAsB,CAAA,GAAA,KAAO;AAClC,IAAA,MAAM,QAAQ,GAAA,CAAI,SAAA,oBAAa,IAAI,IAAA,IAAQ,QAAA,EAAS;AACpD,IAAA,IAAI,OAAA;AAEJ,IAAA,IAAI,YAAY,OAAA,EAAS;AACvB,MAAA,OAAA,GAAU,IAAA,IAAQ,aAAa,IAAA,GAAO,OAAA;AAAA,IACxC,CAAA,MAAO;AACL,MAAA,OAAA,GAAU,IAAA,IAAQ,aAAa,IAAA,GAAO,OAAA;AAAA,IACxC;AACA,IAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AAErB,IAAA,OAAO,iBAAA,GAAoB,iBAAA,CAAkB,GAAG,CAAA,GAAI,IAAA;AAAA,EACtD,CAAA;AACA,EAAA,OAAO,MAAA;AACT;AAkBO,SAAS,aAAA,CACd,WACA,QAAA,EAC6B;AAC7B,EAAA,MAAM,SAAS,QAAA,EAAS;AACxB,EAAA,MAAA,CAAO,mBAAA,GAAsB,SAAA;AAC7B,EAAA,OAAO,MAAA;AACT;ACnWO,IAAM,iBAAN,MAAmC;AAAA,EAChC,MAAA,uBAAa,GAAA,EAA+B;AAAA,EAC5C,QAAA,GAAW,KAAA;AAAA,EACX,MAAA;AAAA,EAER,WAAA,CAAY,QAAwB,OAAA,EAAqC;AACvE,IAAA,IAAA,CAAK,MAAA,GAAS,SAAS,MAAA,IAAU,YAAA;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,WAAW,MAAA,EAA6B;AACtC,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACpD,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,IAAA,CAAK,aAAA,CAAc,OAAO,MAAwB,CAAA;AAAA,IACpD;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAA,CAAc,OAAe,MAAA,EAA8B;AACzD,IAAA,MAAM,WAAA,GAAiC;AAAA,MACrC,QAAQ,EAAC;AAAA,MACT,QAAQ,EAAC;AAAA,MACT,SAAS,EAAC;AAAA,MACV,WAAW,EAAC;AAAA,MACZ,OAAA,EAAS,MAAA,CAAO,OAAA,IAAW,EAAC;AAAA,MAC5B,WAAA,EAAa,OAAO,WAAA,IAAe;AAAA,KACrC;AAGA,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC/C,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA;AAChC,MAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,MAAA,MAAM,aAAa,MAAA,CAAO,IAAA,IAAQ,CAAA,EAAG,KAAK,WAAW,CAAC,CAAA,CAAA;AAEtD,MAAA,IAAI;AACF,QAAA,IAAI,MAAA,CAAO,SAAS,QAAA,EAAU;AAC5B,UAAA,MAAM,QAAA,GAAW,IAAA,CAAK,mBAAA,CAAoB,MAAA,EAAQ,UAAU,CAAA;AAC5D,UAAA,WAAA,CAAY,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,QACnC,CAAA,MAAO;AACL,UAAA,MAAM,QAAA,GAAW,IAAA,CAAK,aAAA,CAAc,MAAA,EAAQ,UAAU,CAAA;AAEtD,UAAA,QAAQ,OAAO,IAAA;AAAM,YACnB,KAAK,OAAA;AACH,cAAA,WAAA,CAAY,MAAA,CAAO,KAAK,QAAQ,CAAA;AAChC,cAAA;AAAA,YACF,KAAK,MAAA;AACH,cAAA,WAAA,CAAY,MAAA,CAAO,KAAK,QAAQ,CAAA;AAChC,cAAA;AAAA,YACF,KAAK,UAAA;AACH,cAAA,WAAA,CAAY,SAAA,CAAU,KAAK,QAAQ,CAAA;AACnC,cAAA;AAAA;AACJ,QACF;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,IAAI,cAAA;AAAA,UACR,CAAA,0BAAA,EAA6B,UAAU,CAAA,aAAA,EAAgB,KAAK,CAAA,GAAA,EAAM,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAAA,UACxH,EAAE,KAAA,EAAO,MAAA,EAAQ,UAAA;AAAW,SAC9B;AAAA,MACF;AAAA,IACF;AAGA,IAAA,WAAA,CAAY,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,QAAA,GAAW,EAAE,QAAQ,CAAA;AACzD,IAAA,WAAA,CAAY,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,QAAA,GAAW,EAAE,QAAQ,CAAA;AACzD,IAAA,WAAA,CAAY,SAAA,CAAU,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,QAAA,GAAW,EAAE,QAAQ,CAAA;AAE5D,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,WAAW,CAAA;AAAA,EACpC;AAAA,EAiBA,QAAA,CACE,aAAA,EACA,QAAA,EACA,OAAA,EAIM;AAEN,IAAA,IAAI,OAAO,aAAA,KAAkB,QAAA,IAAY,aAAA,KAAkB,IAAA,EAAM;AAC/D,MAAA,IAAA,CAAK,WAAW,aAAa,CAAA;AAC7B,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,KAAA,GAAQ,aAAA;AACd,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,MAAM,IAAI,cAAA,CAAe,sDAAA,EAAwD,EAAE,OAAO,CAAA;AAAA,IAC5F;AAEA,IAAA,MAAM,MAAA,GAAyB;AAAA,MAC7B;AAAA,KACF;AAEA,IAAA,IAAI,OAAA,EAAS,YAAY,MAAA,EAAW;AAClC,MAAA,MAAA,CAAO,UAAU,OAAA,CAAQ,OAAA;AAAA,IAC3B;AAEA,IAAA,IAAI,OAAA,EAAS,gBAAgB,MAAA,EAAW;AACtC,MAAA,MAAA,CAAO,cAAc,OAAA,CAAQ,WAAA;AAAA,IAC/B;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,OAAO,MAAM,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,aAAA,CAAc,QAA0B,IAAA,EAAsC;AACpF,IAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,SAAS,IAAI,MAAA,CAAO,SAAA,GAAY,CAAC,MAAA,CAAO,SAAS,CAAA;AAGzF,IAAA,MAAM,cAAc,UAAA,CAAW,OAAA;AAAA,MAAQ,CAAA,EAAA,KACrC,EAAA,KAAO,KAAA,GAAS,CAAC,MAAA,EAAQ,UAAU,QAAA,EAAU,QAAQ,CAAA,GAAc,CAAC,EAAE;AAAA,KACxE;AAEA,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,UAAA,EAAY,IAAI,GAAA,CAAI,WAAW,CAAA;AAAA,MAC/B,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,UAAU,MAAA,CAAO,SAAA;AAAA,MACjB,UAAU,MAAA,CAAO,QAAA,KAAa,MAAA,CAAO,IAAA,KAAS,SAAS,GAAA,GAAM,CAAA;AAAA,KAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,mBAAA,CAAoB,QAA0B,IAAA,EAAoC;AACxF,IAAA,MAAM,YAAY,MAAA,CAAO,SAAA;AAEzB,IAAA,OAAO;AAAA,MACL,SAAA,EAAW,MAAA;AAAA,MACX,aAAA,EAAe,SAAA;AAAA,MACf;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,QAAA,EAAkD;AACzE,IAAA,OAAO;AAAA,MACL,MAAM,QAAA,CAAS,IAAA;AAAA,MACf,MAAM,QAAA,CAAS,IAAA;AAAA,MACf,SAAA,EAAW,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA;AAAA,MACzC,UAAU,QAAA,CAAS,QAAA;AAAA,MACnB,UAAU,QAAA,CAAS;AAAA,KACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,CAAU,OAAe,SAAA,EAAwC;AAC/D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AAErB,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,UAAA,CAAW,GAAA,CAAI,SAAS,CAAC,EAAE,GAAA,CAAI,CAAA,CAAA,KAAK,IAAA,CAAK,gBAAA,CAAiB,CAAC,CAAC,CAAA;AAAA,EACjG;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,CAAU,OAAe,SAAA,EAAwC;AAC/D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AAErB,IAAA,OAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,UAAA,CAAW,GAAA,CAAI,SAAS,CAAC,EAAE,GAAA,CAAI,CAAA,CAAA,KAAK,IAAA,CAAK,gBAAA,CAAiB,CAAC,CAAC,CAAA;AAAA,EACjG;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,OAAe,SAAA,EAAwC;AAClE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AAErB,IAAA,OAAO,MAAA,CAAO,SAAA,CACX,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,UAAA,CAAW,GAAA,CAAI,SAAS,CAAC,EACvC,GAAA,CAAI,CAAA,CAAA,KAAK,IAAA,CAAK,gBAAA,CAAiB,CAAC,CAAC,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,KAAA,EAAuC;AAChD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,OAAO,MAAA,EAAQ,WAAW,EAAC;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,KAAA,EAAyB;AAClC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,OAAO,MAAA,EAAQ,WAAW,EAAC;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,KAAA,EAAwB;AACrC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,OAAO,QAAQ,WAAA,IAAe,IAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAA,EAAwB;AAC/B,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAsB;AACpB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAsB;AACpB,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAA,GAAiB;AACf,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,MAAM,CAAA,IAAK,KAAK,MAAA,EAAQ;AAEzC,MAAA,MAAM,SAAA,GACJ,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,KACvB,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAA,IACvB,OAAO,OAAA,CAAQ,MAAA,GAAS,CAAA,IACxB,MAAA,CAAO,UAAU,MAAA,GAAS,CAAA;AAE5B,MAAA,IAAI,CAAC,SAAA,IAAa,CAAC,MAAA,CAAO,WAAA,EAAa;AAErC,QAAA,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,UACV,gBAAgB,KAAK,CAAA,2EAAA;AAAA,SAEvB;AAAA,MACF;AAGA,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAC7B,QAAA,MAAM,eAAA,uBAAsB,GAAA,EAAe;AAE3C,QAAA,KAAA,MAAWA,MAAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,UAAAA,OAAM,UAAA,CAAW,OAAA,CAAQ,QAAM,eAAA,CAAgB,GAAA,CAAI,EAAE,CAAC,CAAA;AAAA,QACxD;AACA,QAAA,KAAA,MAAWC,KAAAA,IAAQ,OAAO,MAAA,EAAQ;AAChC,UAAAA,MAAK,UAAA,CAAW,OAAA,CAAQ,QAAM,eAAA,CAAgB,GAAA,CAAI,EAAE,CAAC,CAAA;AAAA,QACvD;AACA,QAAA,KAAA,MAAWC,SAAAA,IAAY,OAAO,SAAA,EAAW;AACvC,UAAAA,UAAS,UAAA,CAAW,OAAA,CAAQ,QAAM,eAAA,CAAgB,GAAA,CAAI,EAAE,CAAC,CAAA;AAAA,QAC3D;AACA,QAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAC7B,UAAA,eAAA,CAAgB,IAAI,MAAM,CAAA;AAAA,QAC5B;AAEA,QAAA,MAAM,sBAAA,GAAyB,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,CAAA,EAAA,KAAM;AAEzD,UAAA,IAAI,EAAA,KAAO,KAAA,EAAO,OAAO,eAAA,CAAgB,IAAA,GAAO,CAAA;AAEhD,UAAA,OAAO,eAAA,CAAgB,IAAI,EAAe,CAAA;AAAA,QAC5C,CAAC,CAAA;AAED,QAAA,IAAI,sBAAA,CAAuB,SAAS,CAAA,EAAG;AACrC,UAAA,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,YACV,gBAAgB,KAAK,CAAA,kDAAA,EAAqD,sBAAA,CAAuB,IAAA,CAAK,IAAI,CAAC,CAAA,oDAAA;AAAA,WAE7G;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAA,EAAqB;AAC1B,IAAA,IAAA,CAAK,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,EAC1B;AACF;ACtYO,IAAM,UAAA,GAAa,IAAI,iBAAA,EAA8B;;;ACSrD,SAAS,iBACd,OAAA,EAC0B;AAC1B,EAAA,mBAAA,CAAoB,QAAQ,IAAI,CAAA;AAEhC,EAAA,MAAM,OAAA,GAAoC;AAAA,IACxC,IAAA,EAAM;AAAA,MACJ,GAAG,OAAA,CAAQ,IAAA;AAAA,MACX,QAAA,EAAU,OAAA,CAAQ,IAAA,CAAK,QAAA,IAAY;AAAA;AAAA,KACrC;AAAA,IACA,SAAA,sBAAe,IAAA;AAAK,GACtB;AAEA,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,OAAA,CAAQ,OAAA,GAAU;AAAA,MAChB,GAAG,OAAA,CAAQ,OAAA;AAAA,MACX,SAAA,EAAW,OAAA,CAAQ,OAAA,CAAQ,SAAA,wBAAiB,IAAA;AAAK,KACnD;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAW;AAC9B,IAAA,OAAA,CAAQ,OAAO,OAAA,CAAQ,IAAA;AAAA,EACzB;AAEA,EAAA,OAAO,OAAA;AACT;AAKA,SAAS,oBAAoB,IAAA,EAA4B;AACvD,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,MAAA,IAAa,IAAA,CAAK,WAAW,IAAA,EAAM;AACrD,IAAA,MAAM,IAAI,yBAAA,CAA0B,oCAAA,EAAsC,QAAQ,CAAA;AAAA,EACpF;AAEA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,yBAAA,CAA0B,wBAAA,EAA0B,OAAO,CAAA;AAAA,EACvE;AACF;AAMA,IAAM,oBAAN,MAAwB;AAAA;AAAA;AAAA;AAAA,EAItB,GAAA,CAAO,SAAqB,EAAA,EAAgB;AAC1C,IAAA,OAAO,UAAA,CAAW,GAAA,CAAI,OAAA,EAAS,EAAE,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CAAY,OAAA,EAAqB,EAAA,EAAkC;AACvE,IAAA,OAAO,MAAM,UAAA,CAAW,GAAA,CAAI,OAAA,EAAS,EAAE,CAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAA,GAAyB;AACvB,IAAA,MAAM,GAAA,GAAM,WAAW,QAAA,EAAS;AAChC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,IAAI,eAAA,EAAgB;AAAA,IAC5B;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,GAAsC;AACpC,IAAA,OAAO,UAAA,CAAW,UAAS,IAAK,IAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAsB;AACpB,IAAA,OAAO,UAAA,CAAW,UAAS,KAAM,MAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,YAAW,CAAE,IAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAA,GAA6B;AAC3B,IAAA,OAAO,IAAA,CAAK,SAAQ,CAAE,MAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAA,GAA2C;AACzC,IAAA,OAAO,IAAA,CAAK,SAAQ,CAAE,QAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,IAAA,EAAuB;AAC7B,IAAA,MAAM,GAAA,GAAM,KAAK,gBAAA,EAAiB;AAClC,IAAA,OAAO,GAAA,EAAK,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,IAAK,KAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,UAAA,EAA6B;AACzC,IAAA,MAAM,GAAA,GAAM,KAAK,gBAAA,EAAiB;AAClC,IAAA,OAAO,GAAA,EAAK,IAAA,CAAK,WAAA,EAAa,QAAA,CAAS,UAAU,CAAA,IAAK,KAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAoB;AAClB,IAAA,MAAM,GAAA,GAAM,KAAK,gBAAA,EAAiB;AAClC,IAAA,OAAO,GAAA,EAAK,KAAK,QAAA,IAAY,KAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAY,EAAA,EAAgB;AAC1B,IAAA,MAAM,UAAA,GAAa,KAAK,gBAAA,EAAiB;AACzC,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,MAAM,IAAI,gBAAgB,uDAAuD,CAAA;AAAA,IACnF;AAEA,IAAA,MAAM,SAAA,GAAwB;AAAA,MAC5B,GAAG,UAAA;AAAA,MACH,MAAM,EAAE,GAAG,UAAA,CAAW,IAAA,EAAM,UAAU,IAAA;AAAK,KAC7C;AAEA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,SAAA,EAAW,EAAE,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAiB,EAAA,EAAkC;AACvD,IAAA,MAAM,UAAA,GAAa,KAAK,gBAAA,EAAiB;AACzC,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,MAAM,IAAI,gBAAgB,uDAAuD,CAAA;AAAA,IACnF;AAEA,IAAA,MAAM,SAAA,GAAwB;AAAA,MAC5B,GAAG,UAAA;AAAA,MACH,MAAM,EAAE,GAAG,UAAA,CAAW,IAAA,EAAM,UAAU,IAAA;AAAK,KAC7C;AAEA,IAAA,OAAO,MAAM,IAAA,CAAK,QAAA,CAAS,SAAA,EAAW,EAAE,CAAA;AAAA,EAC1C;AACF,CAAA;AAGO,IAAM,UAAA,GAAa,IAAI,iBAAA;AAKvB,SAAS,cAAA,CAAkB,SAAqB,EAAA,EAAgB;AACrE,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,OAAA,EAAS,EAAE,CAAA;AACnC;AAKA,eAAsB,mBAAA,CACpB,SACA,EAAA,EACY;AACZ,EAAA,OAAO,MAAM,UAAA,CAAW,QAAA,CAAS,OAAA,EAAS,EAAE,CAAA;AAC9C;ACxKO,SAAS,qBAAA,CAAsB,OAAe,MAAA,EAAwB;AAC3E,EAAA,OAAO,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAC3B;AAcO,SAAS,mBAAA,CACd,EAAA,EACA,MAAA,EACA,QAAA,EACA,KAAA,EAC+B;AAC/B,EAAA,OAAO,EAAA,CAAG,KAAA,CAAM,MAAA,EAAe,QAAA,EAAiB,KAAY,CAAA;AAC9D;AAQO,SAAS,mBAAmB,UAAA,EAAyC;AAC1E,EAAA,OAAO,GAAA,CAAA,EAAM,GAAA,CAAI,GAAA,CAAI,UAAU,CAAC,CAAA,CAAA;AAClC;AAaO,SAAS,sBAAA,CACd,IACA,KAAA,EAC8E;AAC9E,EAAA,OAAO,EAAA,CAAG,UAAA,CAAW,KAAY,CAAA,CAAE,SAAA,EAAU;AAC/C;AAWO,SAAS,aAAA,CACd,EAAA,EACA,EAAA,EACA,gBAAA,GAAmB,IAAA,EACgB;AACnC,EAAA,OAAO,EAAA,CAAG,KAAA,CAAM,gBAAA,EAAyB,GAAA,EAAK,EAAS,CAAA;AACzD;AAcO,SAAS,qBAAA,CACd,EAAA,EACA,SAAA,EACA,SAAA,EAGI;AACJ,EAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,UAAU,EAAS,CAAA;AACvC,EAAA,OAAO,WAAA;AACT;AAQO,SAAS,SACd,QAAA,EACkD;AAClD,EAAA,OAAO,SAAA,IAAa,QAAA,IAAa,QAAA,CAAiB,OAAA,KAAY,MAAA;AAChE;;;ACxHO,IAAM,oBAAN,MAAsC;AAAA,EAC3C,YAAoB,QAAA,EAA8B;AAA9B,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBnD,SAAA,CACE,IACA,KAAA,EAC+B;AAE/B,IAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AACxC,IAAA,IAAI,CAAC,GAAA,EAAK;AAKR,MAAA,OAAO,mBAAA;AAAA,QACL,EAAA;AAAA,QACA,mBAAmB,OAAO,CAAA;AAAA,QAC1B,GAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAGA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA,OAAO,EAAA;AAAA,IACT;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC9C,IAAA,IAAI,OAAA,CAAQ,KAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACvD,MAAA,OAAO,EAAA;AAAA,IACT;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC9C,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,OAAO,EAAA;AAAA,IACT;AAGA,IAAA,IAAI,MAAA,GAAS,EAAA;AACb,IAAA,KAAA,MAAWC,WAAU,OAAA,EAAS;AAC5B,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,cAAA,CAAeA,OAAAA,EAAQ,KAAK,KAAK,CAAA;AACzD,MAAA,MAAA,GAAS,IAAA,CAAK,eAAA,CAAgB,MAAA,EAAQ,UAAA,EAAY,KAAK,CAAA;AAAA,IACzD;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,cAAA,CACNA,OAAAA,EAMA,GAAA,EACA,KAAA,EACyB;AACzB,IAAA,MAAM,OAAA,GAAmC;AAAA,MACvC,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,GAAI,GAAA,CAAI,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,IAAI,IAAA;AAAgC,KAC5E;AAEA,IAAA,MAAM,MAAA,GAASA,OAAAA,CAAO,aAAA,CAAc,OAAO,CAAA;AAI3C,IAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,MAAA,MAAM,IAAI,QAAA;AAAA,QACR,CAAA,wEAAA,EACaA,OAAAA,CAAO,IAAI,CAAA,YAAA,EAAe,KAAK,CAAA,qEAAA,CAAA;AAAA,QAE5C,aAAA,CAAc;AAAA,OAChB;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBQ,eAAA,CACN,EAAA,EACA,UAAA,EACA,KAAA,EAC+B;AAC/B,IAAA,IAAI,MAAA,GAAS,EAAA;AAEb,IAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AAExD,MAAA,MAAM,eAAA,GAAkB,qBAAA,CAAsB,KAAA,EAAO,MAAM,CAAA;AAE3D,MAAA,IAAI,UAAU,IAAA,EAAM;AAElB,QAAA,MAAA,GAAS,mBAAA,CAAoB,MAAA,EAAQ,eAAA,EAAiB,IAAA,EAAM,IAAI,CAAA;AAAA,MAClE,CAAA,MAAA,IAAW,UAAU,MAAA,EAAW;AAE9B,QAAA;AAAA,MACF,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC/B,QAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAItB,UAAA,MAAA,GAAS,mBAAA;AAAA,YACP,MAAA;AAAA,YACA,mBAAmB,OAAO,CAAA;AAAA,YAC1B,GAAA;AAAA,YACA;AAAA,WACF;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,MAAA,GAAS,mBAAA,CAAoB,MAAA,EAAQ,eAAA,EAAiB,IAAA,EAAM,KAAK,CAAA;AAAA,QACnE;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,MAAA,GAAS,mBAAA,CAAoB,MAAA,EAAQ,eAAA,EAAiB,GAAA,EAAK,KAAK,CAAA;AAAA,MAClE;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;;;ACtKA,IAAM,kBAAA,GAAqB,GAAA;AAMpB,IAAM,gBAAN,MAAkC;AAAA,EACvC,YAAoB,QAAA,EAA8B;AAA9B,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAenD,MAAM,WAAA,CAAY,KAAA,EAAe,IAAA,EAA8C;AAC7E,IAAA,MAAM,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,QAAA,EAAU,QAAW,IAAI,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,WAAA,CACJ,KAAA,EACA,WAAA,EACA,IAAA,EACe;AACf,IAAA,MAAM,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,QAAA,EAAU,aAAa,IAAI,CAAA;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,WAAA,CAAY,KAAA,EAAe,WAAA,EAAqD;AACpF,IAAA,MAAM,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,QAAA,EAAU,WAAW,CAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,SAAA,CAAU,KAAA,EAAe,GAAA,EAAgD;AAC7E,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,MAAA,EAAQ,GAAG,CAAA;AAC3C,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,KAAA,EAAO;AAEd,MAAA,IAAI,KAAA,YAAiB,kBAAA,IAAsB,KAAA,YAAiB,wBAAA,EAA0B;AACpF,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,SAAA,CACJ,SAAA,EACA,KAAA,EACA,KACA,IAAA,EACkB;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,aAAA,CAAc,KAAA,EAAO,SAAA,EAAW,KAAK,IAAI,CAAA;AACpD,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,KAAA,EAAO;AAEd,MAAA,IAAI,KAAA,YAAiB,kBAAA,IAAsB,KAAA,YAAiB,wBAAA,EAA0B;AACpF,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,gBAAA,CACJ,SAAA,EACA,KAAA,EACA,MACA,GAAA,EACkB;AAClB,IAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AACxC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,KAAA;AAAA,IACT;AAGA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC9C,IAAA,IAAI,OAAA,CAAQ,KAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACvD,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,OAAO,SAAS,CAAA;AAC7D,IAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,OAAA,GAAmC;AAAA,MACvC,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,GAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAI,GAAA,CAAI,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,IAAI,IAAA;AAAgC,KAC5E;AAGA,IAAA,KAAA,MAAWD,aAAY,SAAA,EAAW;AAChC,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,UAAS,QAAA,EAAU,OAAA,EAASA,UAAS,IAAI,CAAA;AAClF,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,aAAA,CACZ,KAAA,EACA,SAAA,EACA,KACA,IAAA,EACe;AACf,IAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AACxC,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,IAAI,kBAAA,CAAmB,SAAA,EAAW,KAAA,EAAO,0BAA0B,CAAA;AAAA,IAC3E;AAGA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC9C,IAAA,IAAI,OAAA,CAAQ,KAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACvD,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,OAAO,SAAS,CAAA;AACvD,IAAA,KAAA,MAAWD,SAAQ,MAAA,EAAQ;AACzB,MAAA,MAAM,UAAU,IAAA,CAAK,iBAAA,CAAkB,KAAK,KAAA,EAAO,SAAA,EAAW,KAAK,IAAI,CAAA;AACvE,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,MAAK,QAAA,EAAU,OAAA,EAASA,MAAK,IAAI,CAAA;AAE1E,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,MAAM,IAAI,kBAAA,CAAmB,SAAA,EAAW,OAAO,CAAA,kBAAA,EAAqBA,KAAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AAAA,MACjF;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,QAAA,KAAa,IAAA,EAAM;AAC9D,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,OAAO,SAAS,CAAA;AAC7D,MAAA,KAAA,MAAWC,aAAY,SAAA,EAAW;AAChC,QAAA,MAAM,UAAU,IAAA,CAAK,iBAAA,CAAkB,KAAK,KAAA,EAAO,SAAA,EAAW,KAAK,IAAI,CAAA;AACvE,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,UAAS,QAAA,EAAU,OAAA,EAASA,UAAS,IAAI,CAAA;AAElF,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,MAAM,IAAI,kBAAA,CAAmB,SAAA,EAAW,OAAO,CAAA,mBAAA,EAAsBA,SAAAA,CAAS,IAAI,CAAA,CAAE,CAAA;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,OAAO,SAAS,CAAA;AACvD,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAA,CAAe,KAAK,CAAA;AAEtD,IAAA,IAAI,WAAA,IAAe,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AACtC,MAAA,MAAM,IAAI,kBAAA,CAAmB,SAAA,EAAW,KAAA,EAAO,0CAA0C,CAAA;AAAA,IAC3F;AAEA,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AAErB,MAAA,IAAI,OAAA,GAAU,KAAA;AAEd,MAAA,KAAA,MAAWF,UAAS,MAAA,EAAQ;AAC1B,QAAA,MAAM,UAAU,IAAA,CAAK,iBAAA,CAAkB,KAAK,KAAA,EAAO,SAAA,EAAW,KAAK,IAAI,CAAA;AACvE,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,OAAM,QAAA,EAAU,OAAA,EAASA,OAAM,IAAI,CAAA;AAE5E,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,OAAA,GAAU,IAAA;AACV,UAAA;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,IAAI,kBAAA,CAAmB,SAAA,EAAW,KAAA,EAAO,2BAA2B,CAAA;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,CACN,GAAA,EACA,KAAA,EACA,SAAA,EACA,KACA,IAAA,EACyB;AACzB,IAAA,OAAO;AAAA,MACL,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,GAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAI,GAAA,CAAI,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,IAAI,IAAA;AAAgC,KAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,cAAA,CACZ,SAAA,EACA,OAAA,EACA,UAAA,EACkB;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,UAAU,OAAO,CAAA;AAChC,MAAA,OAAO,MAAA,YAAkB,OAAA,GAAU,MAAM,MAAA,GAAS,MAAA;AAAA,IACpD,SAAS,KAAA,EAAO;AAGd,MAAA,MAAM,aAAA,GAAgB,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,MAAA;AACvD,MAAA,MAAM,IAAI,wBAAA;AAAA,QACR,QAAQ,SAAA,IAAa,SAAA;AAAA,QACrB,QAAQ,KAAA,IAAS,SAAA;AAAA,QACjB,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAAA,QACzC,UAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,UAAA,CACJ,KAAA,EACA,IAAA,EACA,YAAoB,kBAAA,EACN;AACd,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAE/B,IAAA,MAAM,UAAe,EAAC;AAGtB,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,KAAK,SAAA,EAAW;AAC/C,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAI,SAAS,CAAA;AAGzC,MAAA,MAAM,YAAA,GAAe,MAAM,OAAA,CAAQ,GAAA;AAAA,QACjC,KAAA,CAAM,GAAA,CAAI,OAAO,GAAA,KAAQ;AACvB,UAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,OAAO,GAAG,CAAA;AAC/C,UAAA,OAAO,UAAU,GAAA,GAAM,IAAA;AAAA,QACzB,CAAC;AAAA,OACH;AAGA,MAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,QAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,UAAA,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AACF,CAAA;;;ACpXA,IAAM,WAAA,GAAc,aAAA;AACb,IAAM,OAAA,GAAU,WAAA,CAAY,UAAA,CAAW,IAAI,IAAI,WAAA,GAAc,WAAA;ACkG7D,IAAM,sBAAA,GAAyB,EAAE,MAAA,CAAO;AAAA,EAC7C,eAAe,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,EAC5C,aAAa,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,EAC1C,cAAA,EAAgB,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EACrC,sBAAA,EAAwB,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC7C,cAAA,EAAgB,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EACrC,gBAAA,EAAkB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAC/B,CAAC;AAyDM,SAAS,UAAc,OAAA,EAAuC;AACnE,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,gBAAgB,EAAC;AAAA,IACjB,cAAc,EAAC;AAAA,IACf,MAAA,GAASI,YAAAA;AAAA,IACT,cAAA,GAAiB,IAAA;AAAA;AAAA,IACjB,sBAAA,GAAyB,KAAA;AAAA;AAAA,IACzB,cAAA,GAAiB,KAAA;AAAA,IACjB,WAAA;AAAA,IACA,gBAAA,GAAmB;AAAA,GACrB,GAAI,OAAA;AAGJ,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,iBAAA;AACJ,EAAA,IAAI,aAAA;AAEJ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,aAAA;AAAA,IACN,OAAA,EAAS,OAAA;AAAA;AAAA,IAGT,QAAA,EAAU,EAAA;AAAA;AAAA,IAGV,cAAc,EAAC;AAAA;AAAA;AAAA;AAAA,IAKf,OAAY,SAAA,EAA8B;AACxC,MAAA,MAAA,CAAO,OAAO,+BAAA,EAAiC;AAAA,QAC7C,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,MAAA;AAAA,QAC5B,eAAe,aAAA,CAAc,MAAA;AAAA,QAC7B,aAAa,WAAA,CAAY;AAAA,OAC1B,CAAA;AAKD,MAAA,QAAA,GAAW,IAAI,eAAmB,MAAM,CAAA;AACxC,MAAA,QAAA,CAAS,QAAA,EAAS;AAGlB,MAAA,iBAAA,GAAoB,IAAI,kBAAsB,QAAQ,CAAA;AACtD,MAAA,aAAA,GAAgB,IAAI,cAAkB,QAAQ,CAAA;AAE9C,MAAA,MAAA,CAAO,OAAO,2CAA2C,CAAA;AAAA,IAC3D,CAAA;AAAA;AAAA;AAAA;AAAA,IAKA,SAAA,GAA2B;AAEzB,MAAA,QAAA,CAAS,KAAA,EAAM;AACf,MAAA,MAAA,CAAO,OAAO,qDAAqD,CAAA;AACnE,MAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,IACzB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,cAAA,CAAmB,IAAQ,OAAA,EAAkC;AAC3D,MAAA,MAAM,EAAE,SAAA,EAAW,KAAA,EAAO,QAAA,EAAS,GAAI,OAAA;AAGvC,MAAA,IAAI,aAAA,CAAc,QAAA,CAAS,KAAK,CAAA,EAAG;AACjC,QAAA,MAAA,CAAO,KAAA,GAAQ,CAAA,uCAAA,EAA0C,KAAK,CAAA,CAAE,CAAA;AAChE,QAAA,OAAO,EAAA;AAAA,MACT;AAGA,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,KAAM,IAAA,EAAM;AAChC,QAAA,MAAA,CAAO,KAAA,GAAQ,CAAA,oCAAA,EAAuC,KAAK,CAAA,CAAE,CAAA;AAC7D,QAAA,OAAO,EAAA;AAAA,MACT;AAGA,MAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AAExC,MAAA,IAAI,CAAC,GAAA,EAAK;AAER,QAAA,IAAI,cAAA,EAAgB;AAClB,UAAA,MAAM,IAAI,eAAA;AAAA,YACR,CAAA,uCAAA,EAA0C,SAAS,CAAA,IAAA,EAAO,KAAK,CAAA,yJAAA;AAAA,WAGjE;AAAA,QACF;AAEA,QAAA,IAAI,CAAC,sBAAA,EAAwB;AAE3B,UAAA,MAAA,CAAO,IAAA;AAAA,YACL,CAAA,0BAAA,EAA6B,SAAS,CAAA,IAAA,EAAO,KAAK,CAAA,kIAAA;AAAA,WAGpD;AAEA,UAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,YAAA,OAAO,qBAAA,CAAsB,EAAA,EAAI,SAAA,EAAW,CAAA,QAAA,KAAY;AAEtD,cAAA,OAAO,mBAAA;AAAA,gBACL,QAAA;AAAA,gBACA,mBAAmB,OAAO,CAAA;AAAA,gBAC1B,GAAA;AAAA,gBACA;AAAA,eACF;AAAA,YACF,CAAC,CAAA;AAAA,UACH;AAGA,UAAA,OAAO,EAAA;AAAA,QACT;AAGA,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,CAAA,qBAAA,EAAwB,SAAS,CAAA,IAAA,EAAO,KAAK,CAAA,kGAAA;AAAA,SAG/C;AACA,QAAA,OAAO,EAAA;AAAA,MACT;AAGA,MAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,QAAA,MAAA,CAAO,KAAA,GAAQ,CAAA,mCAAA,EAAsC,KAAK,CAAA,CAAE,CAAA;AAC5D,QAAA,OAAO,EAAA;AAAA,MACT;AAGA,MAAA,IAAI,WAAA,CAAY,KAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AAC3D,QAAA,MAAA,CAAO,KAAA,GAAQ,CAAA,mCAAA,EAAsC,KAAK,CAAA,CAAE,CAAA;AAC5D,QAAA,OAAO,EAAA;AAAA,MACT;AAGA,MAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,QAAA,IAAI;AACF,UAAA,MAAM,WAAA,GAAc,qBAAA;AAAA,YAClB,EAAA;AAAA,YACA,SAAA;AAAA;AAAA,YAEA,CAAA,QAAA,KAAY,iBAAA,CAAkB,SAAA,CAAU,QAAA,EAAiB,KAAK;AAAA,WAChE;AAEA,UAAA,IAAI,cAAA,EAAgB;AAClB,YAAA,MAAA,CAAO,OAAO,sBAAA,EAAwB;AAAA,cACpC,KAAA;AAAA,cACA,SAAA;AAAA,cACA,MAAA,EAAQ,IAAI,IAAA,CAAK;AAAA,aAClB,CAAA;AAAA,UACH;AAEA,UAAA,OAAO,WAAA;AAAA,QACT,SAAS,KAAA,EAAO;AACd,UAAA,MAAA,CAAO,KAAA,GAAQ,6BAAA,EAA+B,EAAE,KAAA,EAAO,OAAO,CAAA;AAC9D,UAAA,MAAM,KAAA;AAAA,QACR;AAAA,MACF;AAGA,MAAA,IAAI,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,QAAA,IAAY,cAAc,QAAA,EAAU;AAC9E,QAAA,QAAA,CAAS,eAAe,CAAA,GAAI,IAAA;AAC5B,QAAA,QAAA,CAAS,YAAY,CAAA,GAAI,KAAA;AAAA,MAC3B;AAEA,MAAA,OAAO,EAAA;AAAA,IACT,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,iBAAmC,IAAA,EAAY;AAE7C,MAAA,IAAI,CAAC,gBAAA,CAAiB,IAAI,CAAA,EAAG;AAC3B,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,QAAA,GAAW,IAAA;AAEjB,MAAA,MAAM,QAAQ,QAAA,CAAS,SAAA;AAGvB,MAAA,IAAI,aAAA,CAAc,QAAA,CAAS,KAAK,CAAA,EAAG;AACjC,QAAA,MAAA,CAAO,KAAA,GAAQ,CAAA,wDAAA,EAA2D,KAAK,CAAA,CAAE,CAAA;AACjF,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,QAAA,MAAA,CAAO,KAAA,GAAQ,CAAA,aAAA,EAAgB,KAAK,CAAA,6BAAA,CAA+B,CAAA;AACnE,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAA,CAAO,KAAA,GAAQ,CAAA,sCAAA,EAAyC,KAAK,CAAA,CAAE,CAAA;AAG/D,MAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AACrD,MAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AACrD,MAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AACrD,MAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,QAAA,EAAU,IAAA,CAAK,QAAQ,CAAA;AAIzD,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,QAAA,CAAS,QAAQ,CAAA;AACxC,MAAA,MAAM,gBAAA,GAAmB,QAAA,CAAa,QAAA,CAAS,QAAQ,CAAA;AAEvD,MAAA,MAAM,YAAA,GAAe;AAAA,QACnB,GAAG,QAAA;AAAA;AAAA;AAAA;AAAA,QAKH,MAAM,OAAO,IAAA,EAAiC;AAC5C,UAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,YAAA,MAAM,IAAI,QAAA;AAAA,cACR,8CAAA;AAAA,cACA,aAAA,CAAc;AAAA,aAChB;AAAA,UACF;AAEA,UAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AAGxC,UAAA,IACE,GAAA,IACA,CAAC,GAAA,CAAI,IAAA,CAAK,YACV,CAAC,WAAA,CAAY,IAAA,CAAK,CAAA,IAAA,KAAQ,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EACvD;AACA,YAAA,IAAI;AACF,cAAA,MAAM,aAAA,CAAc,WAAA,CAAY,KAAA,EAAO,IAA+B,CAAA;AAEtE,cAAA,IAAI,cAAA,EAAgB;AAClB,gBAAA,MAAA,CAAO,IAAA,GAAO,wBAAwB,EAAE,KAAA,EAAO,QAAQ,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA;AAAA,cAC1E;AAAA,YACF,SAAS,KAAA,EAAO;AACd,cAAA,IAAI,iBAAiB,kBAAA,EAAoB;AACvC,gBAAA,WAAA,GAAc,KAAK,CAAA;AACnB,gBAAA,IAAI,cAAA,EAAgB;AAClB,kBAAA,MAAA,CAAO,OAAO,qBAAA,EAAuB;AAAA,oBACnC,KAAA;AAAA,oBACA,MAAA,EAAQ,IAAI,IAAA,CAAK,MAAA;AAAA,oBACjB,QAAQ,KAAA,CAAM;AAAA,mBACf,CAAA;AAAA,gBACH;AAAA,cACF;AACA,cAAA,MAAM,KAAA;AAAA,YACR;AAAA,UACF;AAEA,UAAA,OAAO,MAAM,eAAe,IAAI,CAAA;AAAA,QAClC,CAAA;AAAA;AAAA;AAAA;AAAA,QAKA,MAAM,MAAA,CAAO,EAAA,EAAa,IAAA,EAAiC;AACzD,UAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,YAAA,MAAM,IAAI,QAAA;AAAA,cACR,8CAAA;AAAA,cACA,aAAA,CAAc;AAAA,aAChB;AAAA,UACF;AAEA,UAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AAExC,UAAA,IACE,GAAA,IACA,CAAC,GAAA,CAAI,IAAA,CAAK,YACV,CAAC,WAAA,CAAY,IAAA,CAAK,CAAA,IAAA,KAAQ,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EACvD;AAGA,YAAA,IAAI,WAAA;AAEJ,YAAA,IAAI,gBAAA,EAAkB;AAEpB,cAAA,MAAM,KAAA,GAAQ,sBAAA,CAAuB,KAAA,EAAO,KAAK,CAAA;AACjD,cAAA,WAAA,GAAc,MAAM,aAAA,CAAc,KAAA,EAAO,EAAA,EAAI,gBAAgB,EAAE,gBAAA,EAAiB;AAAA,YAClF,WAAW,gBAAA,EAAkB;AAE3B,cAAA,WAAA,GAAc,MAAM,iBAAiB,EAAE,CAAA;AAAA,YACzC,CAAA,MAAO;AACL,cAAA,MAAM,IAAI,QAAA;AAAA,gBACR,8CAAA;AAAA,gBACA,aAAA,CAAc;AAAA,eAChB;AAAA,YACF;AAEA,YAAA,IAAI,CAAC,WAAA,EAAa;AAEhB,cAAA,OAAO,MAAM,cAAA,CAAe,EAAA,EAAI,IAAI,CAAA;AAAA,YACtC;AAEA,YAAA,IAAI;AACF,cAAA,MAAM,aAAA,CAAc,WAAA;AAAA,gBAClB,KAAA;AAAA,gBACA,WAAA;AAAA,gBACA;AAAA,eACF;AAEA,cAAA,IAAI,cAAA,EAAgB;AAClB,gBAAA,MAAA,CAAO,IAAA,GAAO,wBAAwB,EAAE,KAAA,EAAO,IAAI,MAAA,EAAQ,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,cAC9E;AAAA,YACF,SAAS,KAAA,EAAO;AACd,cAAA,IAAI,iBAAiB,kBAAA,EAAoB;AACvC,gBAAA,WAAA,GAAc,KAAK,CAAA;AACnB,gBAAA,IAAI,cAAA,EAAgB;AAClB,kBAAA,MAAA,CAAO,OAAO,qBAAA,EAAuB;AAAA,oBACnC,KAAA;AAAA,oBACA,EAAA;AAAA,oBACA,MAAA,EAAQ,IAAI,IAAA,CAAK,MAAA;AAAA,oBACjB,QAAQ,KAAA,CAAM;AAAA,mBACf,CAAA;AAAA,gBACH;AAAA,cACF;AACA,cAAA,MAAM,KAAA;AAAA,YACR;AAAA,UACF;AAEA,UAAA,OAAO,MAAM,cAAA,CAAe,EAAA,EAAI,IAAI,CAAA;AAAA,QACtC,CAAA;AAAA;AAAA;AAAA;AAAA,QAKA,MAAM,OAAO,EAAA,EAA+B;AAC1C,UAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,YAAA,MAAM,IAAI,QAAA;AAAA,cACR,8CAAA;AAAA,cACA,aAAA,CAAc;AAAA,aAChB;AAAA,UACF;AAEA,UAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AAExC,UAAA,IACE,GAAA,IACA,CAAC,GAAA,CAAI,IAAA,CAAK,YACV,CAAC,WAAA,CAAY,IAAA,CAAK,CAAA,IAAA,KAAQ,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EACvD;AAGA,YAAA,IAAI,WAAA;AAEJ,YAAA,IAAI,gBAAA,EAAkB;AAEpB,cAAA,MAAM,KAAA,GAAQ,sBAAA,CAAuB,KAAA,EAAO,KAAK,CAAA;AACjD,cAAA,WAAA,GAAc,MAAM,aAAA,CAAc,KAAA,EAAO,EAAA,EAAI,gBAAgB,EAAE,gBAAA,EAAiB;AAAA,YAClF,WAAW,gBAAA,EAAkB;AAE3B,cAAA,WAAA,GAAc,MAAM,iBAAiB,EAAE,CAAA;AAAA,YACzC,CAAA,MAAO;AACL,cAAA,MAAM,IAAI,QAAA;AAAA,gBACR,8CAAA;AAAA,gBACA,aAAA,CAAc;AAAA,eAChB;AAAA,YACF;AAEA,YAAA,IAAI,CAAC,WAAA,EAAa;AAEhB,cAAA,OAAO,MAAM,eAAe,EAAE,CAAA;AAAA,YAChC;AAEA,YAAA,IAAI;AACF,cAAA,MAAM,aAAA,CAAc,WAAA,CAAY,KAAA,EAAO,WAAsC,CAAA;AAE7E,cAAA,IAAI,cAAA,EAAgB;AAClB,gBAAA,MAAA,CAAO,IAAA,GAAO,wBAAwB,EAAE,KAAA,EAAO,IAAI,MAAA,EAAQ,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,cAC9E;AAAA,YACF,SAAS,KAAA,EAAO;AACd,cAAA,IAAI,iBAAiB,kBAAA,EAAoB;AACvC,gBAAA,WAAA,GAAc,KAAK,CAAA;AACnB,gBAAA,IAAI,cAAA,EAAgB;AAClB,kBAAA,MAAA,CAAO,OAAO,qBAAA,EAAuB;AAAA,oBACnC,KAAA;AAAA,oBACA,EAAA;AAAA,oBACA,MAAA,EAAQ,IAAI,IAAA,CAAK,MAAA;AAAA,oBACjB,QAAQ,KAAA,CAAM;AAAA,mBACf,CAAA;AAAA,gBACH;AAAA,cACF;AACA,cAAA,MAAM,KAAA;AAAA,YACR;AAAA,UACF;AAEA,UAAA,OAAO,MAAM,eAAe,EAAE,CAAA;AAAA,QAChC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAcA,MAAM,WAAc,EAAA,EAAkC;AACpD,UAAA,OAAO,MAAM,UAAA,CAAW,aAAA,CAAc,EAAE,CAAA;AAAA,QAC1C,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAcA,MAAM,SAAA,CAAU,SAAA,EAAsB,GAAA,EAAgD;AACpF,UAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AACxC,UAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AACjB,UAAA,IAAI,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU,OAAO,IAAA;AAC9B,UAAA,IAAI,WAAA,CAAY,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,IAAA,CAAK,MAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG,OAAO,IAAA;AAEpE,UAAA,IAAI;AACF,YAAA,QAAQ,SAAA;AAAW,cACjB,KAAK,MAAA;AACH,gBAAA,OAAO,MAAM,aAAA,CAAc,SAAA,CAAU,KAAA,EAAO,GAAG,CAAA;AAAA,cACjD,KAAK,QAAA;AACH,gBAAA,MAAM,aAAA,CAAc,WAAA,CAAY,KAAA,EAAO,GAAG,CAAA;AAC1C,gBAAA,OAAO,IAAA;AAAA,cACT,KAAK,QAAA;AACH,gBAAA,MAAM,aAAA,CAAc,WAAA,CAAY,KAAA,EAAO,GAAA,EAAK,EAAE,CAAA;AAC9C,gBAAA,OAAO,IAAA;AAAA,cACT,KAAK,QAAA;AACH,gBAAA,MAAM,aAAA,CAAc,WAAA,CAAY,KAAA,EAAO,GAAG,CAAA;AAC1C,gBAAA,OAAO,IAAA;AAAA,cACT;AACE,gBAAA,OAAO,KAAA;AAAA;AACX,UACF,SAAS,KAAA,EAAO;AACd,YAAA,MAAA,CAAO,QAAQ,2BAAA,EAA6B;AAAA,cAC1C,KAAA;AAAA,cACA,SAAA;AAAA,cACA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,aAC7D,CAAA;AACD,YAAA,OAAO,KAAA;AAAA,UACT;AAAA,QACF;AAAA,OACF;AAEA,MAAA,OAAO,YAAA;AAAA,IACT;AAAA,GACF;AACF;;;AC7mBO,SAAS,uBAAA,CACd,QACA,OAAA,EAI+C;AAC/C,EAAA,MAAM,GAAA,GAAqD;AAAA,IACzD,MAAM,MAAA,CAAO;AAAA,GACf;AAEA,EAAA,IAAI,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC9B,IAAA,GAAA,CAAI,MAAM,OAAA,CAAQ,GAAA;AAAA,EACpB;AAEA,EAAA,IAAI,OAAA,EAAS,SAAS,MAAA,EAAW;AAC/B,IAAA,GAAA,CAAI,OAAO,OAAA,CAAQ,IAAA;AAAA,EACrB;AAEA,EAAA,IAAI,MAAA,CAAO,YAAY,MAAA,EAAW;AAChC,IAAA,GAAA,CAAI,UAAU,MAAA,CAAO,OAAA;AAAA,EACvB;AAEA,EAAA,IAAI,MAAA,CAAO,SAAS,MAAA,EAAW;AAC7B,IAAA,GAAA,CAAI,OAAO,MAAA,CAAO,IAAA;AAAA,EACpB;AAEA,EAAA,OAAO,GAAA;AACT;AASO,SAAS,gBAAgB,EAAA,EAA6D;AAC3F,EAAA,IAAI,EAAE,cAAc,QAAA,CAAA,EAAW;AAC7B,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,EAAA,CAAG,WAAA,CAAY,IAAA,KAAS,eAAA,EAAiB;AAC3C,IAAA,OAAO,IAAA;AAAA,EACT;AAIA,EAAA,IAAI;AACF,IAAA,MAAM,SAAU,EAAA,EAAgB;AAChC,IAAA,OAAO,MAAA,YAAkB,OAAA;AAAA,EAC3B,CAAA,CAAA,MAAQ;AAGN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAKA,eAAsB,YAAA,CAAgB,IAA0B,YAAA,EAA6B;AAC3F,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,EAAA,EAAG;AAClB,IAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,MAAA,OAAO,MAAM,MAAA;AAAA,IACf;AACA,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,MAAA,EAAQ;AAGf,IAAA,OAAO,YAAA;AAAA,EACT;AACF;AAKO,SAAS,SAAA,CAA6C,QAAW,MAAA,EAAuB;AAC7F,EAAA,MAAM,MAAA,GAAS,EAAE,GAAG,MAAA,EAAO;AAE3B,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAkB;AACpD,IAAA,MAAM,WAAA,GAAc,OAAO,GAAG,CAAA;AAC9B,IAAA,MAAM,WAAA,GAAc,OAAO,GAAG,CAAA;AAE9B,IAAA,IACE,WAAA,KAAgB,UAChB,OAAO,WAAA,KAAgB,YACvB,WAAA,KAAgB,IAAA,IAChB,CAAC,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,IAC1B,OAAO,gBAAgB,QAAA,IACvB,WAAA,KAAgB,QAChB,CAAC,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,EAC1B;AACA,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,SAAA;AAAA,QACZ,WAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA,MAAA,IAAW,gBAAgB,MAAA,EAAW;AACpC,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,WAAA;AAAA,IAChB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,WAAW,GAAA,EAAqB;AAC9C,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,UAAA,CAAW,CAAC,CAAA;AAC7B,IAAA,IAAA,GAAA,CAAQ,IAAA,IAAQ,KAAK,IAAA,GAAO,IAAA;AAC5B,IAAA,IAAA,GAAO,IAAA,GAAO,IAAA;AAAA,EAChB;AACA,EAAA,OAAO,IAAA,CAAK,SAAS,EAAE,CAAA;AACzB;AAKO,SAAS,oBAAoB,SAAA,EAAiD;AACnF,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC5B,IAAA,IAAI,SAAA,CAAU,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,MAAA,OAAO,CAAC,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,QAAQ,CAAA;AAAA,IAC9C;AACA,IAAA,OAAO,SAAA;AAAA,EACT;AAEA,EAAA,IAAI,cAAc,KAAA,EAAO;AACvB,IAAA,OAAO,CAAC,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,QAAQ,CAAA;AAAA,EAC9C;AAEA,EAAA,OAAO,CAAC,SAAS,CAAA;AACnB;;;AC8GO,IAAM,wBAAN,MAA6D;AAAA,EAC1D,KAAA,uBAAY,GAAA,EAAmD;AAAA,EAEvE,IAAO,GAAA,EAAgC;AACrC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAChC,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,OAAA,CAAQ,QAAQ,IAAI,CAAA;AACvC,IAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA,CAAM,SAAA,EAAW;AAChC,MAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AACrB,MAAA,OAAO,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,KAAU,CAAA;AAAA,EACzC;AAAA,EAEA,GAAA,CAAO,GAAA,EAAa,KAAA,EAAU,UAAA,EAAmC;AAC/D,IAAA,IAAA,CAAK,KAAA,CAAM,IAAI,GAAA,EAAK;AAAA,MAClB,KAAA;AAAA,MACA,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,GAAI,UAAA,GAAa;AAAA,KACtC,CAAA;AACD,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA,EAEA,OAAO,GAAA,EAA4B;AACjC,IAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AACrB,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA,EAEA,cAAc,OAAA,EAAgC;AAE5C,IAAA,MAAM,MAAA,GAAS,QAAQ,QAAA,CAAS,GAAG,IAAI,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,OAAA;AAC9D,IAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,IAAA,EAAK,EAAG;AACnC,MAAA,IAAI,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,QAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,MACvB;AAAA,IACF;AACA,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,KAAK,KAAA,CAAM,IAAA;AAAA,EACpB;AACF;;;ACxPO,IAAM,kBAAN,MAAqE;AAAA,EAClE,SAAA,uBAAgB,GAAA,EAA6B;AAAA,EAC7C,aAAA;AAAA,EACA,eAAA;AAAA,EACA,kBAAA;AAAA,EACA,eAAA;AAAA,EACA,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAkC,EAAC,EAAG;AAChD,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAA,CAAQ,aAAA,IAAiB,IAAI,qBAAA,EAAsB;AACxE,IAAA,IAAA,CAAK,eAAA,GAAkB,QAAQ,eAAA,IAAmB,GAAA;AAClD,IAAA,IAAA,CAAK,kBAAA,GAAqB,QAAQ,kBAAA,IAAsB,IAAA;AACxD,IAAA,IAAA,CAAK,eAAA,GAAkB,QAAQ,eAAA,IAAmB,GAAA;AAClD,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAiC,QAAA,EAAoC;AACnE,IAAA,IAAI,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAA,CAAS,IAAI,CAAA,EAAG;AACrC,MAAA,MAAM,IAAI,QAAA;AAAA,QACR,CAAA,UAAA,EAAa,SAAS,IAAI,CAAA,uBAAA,CAAA;AAAA,QAC1B,aAAA,CAAc;AAAA,OAChB;AAAA,IACF;AAGA,IAAA,IAAI,SAAS,SAAA,EAAW;AACtB,MAAA,KAAA,MAAW,GAAA,IAAO,SAAS,SAAA,EAAW;AACpC,QAAA,IAAI,GAAA,KAAQ,SAAS,IAAA,EAAM;AACzB,UAAA,MAAM,IAAI,QAAA;AAAA,YACR,CAAA,UAAA,EAAa,SAAS,IAAI,CAAA,yBAAA,CAAA;AAAA,YAC1B,aAAA,CAAc;AAAA,WAChB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,QAA2B,CAAA;AAC7D,IAAA,IAAA,CAAK,MAAA,EAAQ,KAAA,GAAQ,CAAA,uCAAA,EAA0C,QAAA,CAAS,IAAI,CAAA,CAAE,CAAA;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,IAAA,EAAuB;AAChC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA;AAC1C,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAA,GAAQ,CAAA,yCAAA,EAA4C,IAAI,CAAA,CAAE,CAAA;AAAA,IACzE;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,IAAA,EAAuB;AACjC,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,GAA6B;AAC3B,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAM,QAAQ,WAAA,EAAmF;AAC/F,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,IAAA,MAAM,aAAA,GAAgB,KAAK,gBAAA,EAAiB;AAE5C,IAAA,IAAA,CAAK,QAAQ,KAAA,GAAQ,CAAA,+CAAA,EAAkD,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA,CAAA,EAAI;AAAA,MAChG,eAAe,aAAA,CAAc,MAAA;AAAA,MAC7B,SAAA,EAAW,aAAA,CAAc,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,IAAI;AAAA,KACzC,CAAA;AAED,IAAA,MAAM,OAAA,uBAAc,GAAA,EAA0B;AAE9C,IAAA,IAAI,KAAK,kBAAA,EAAoB;AAC3B,MAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,WAAA,EAAa,aAAA,EAAe,OAAO,CAAA;AAAA,IAChE,CAAA,MAAO;AACL,MAAA,MAAM,IAAA,CAAK,iBAAA,CAAkB,WAAA,EAAa,aAAA,EAAe,OAAO,CAAA;AAAA,IAClE;AAGA,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,iBAAA,CAAkB,OAAO,CAAA;AAErD,IAAA,MAAM,eAAA,GAA0D;AAAA,MAC9D,IAAA,EAAM;AAAA,QACJ,GAAG,WAAA,CAAY,IAAA;AAAA,QACf,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,WAAW,WAAA,CAAY;AAAA,KACzB;AAEA,IAAA,IAAI,WAAA,CAAY,SAAS,MAAA,EAAW;AAClC,MAAA,eAAA,CAAgB,OAAO,WAAA,CAAY,IAAA;AAAA,IACrC;AAEA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC9B,IAAA,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAA,sCAAA,CAAA,EAA0C;AAAA,MAC5D,MAAA,EAAQ,YAAY,IAAA,CAAK,MAAA;AAAA,MACzB,UAAA,EAAY,QAAA;AAAA,MACZ,eAAe,OAAA,CAAQ;AAAA,KACxB,CAAA;AAED,IAAA,OAAO,eAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAA,CACJ,IAAA,EACA,WAAA,EACmB;AACnB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AACxC,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,IAAA,CAAK,MAAA,EAAQ,IAAA,GAAO,CAAA,sCAAA,EAAyC,IAAI,CAAA,CAAE,CAAA;AACnE,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAQ,MAAM,IAAA,CAAK,gBAAA,CAAiB,QAAA,EAAU,WAAW,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAA,CAAgB,MAAA,EAAyB,YAAA,EAAsC;AACnF,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,YAAY,CAAA;AAChD,MAAA,IAAI,UAAU,QAAA,EAAU;AACtB,QAAA,MAAM,GAAA,GAAM,QAAA,CAAS,QAAA,CAAS,EAAE,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAG,EAAG,SAAA,kBAAW,IAAI,IAAA,IAAQ,CAAA;AACpF,QAAA,IAAI,GAAA,EAAK;AACP,UAAA,MAAM,IAAA,CAAK,aAAA,CAAc,MAAA,CAAO,GAAG,CAAA;AACnC,UAAA,IAAA,CAAK,QAAQ,KAAA,GAAQ,CAAA,wCAAA,EAA2C,YAAY,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAA;AAAA,QACxF;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,MAAM,OAAA,GAAU,SAAS,MAAM,CAAA,EAAA,CAAA;AAC/B,MAAA,IAAI,IAAA,CAAK,cAAc,aAAA,EAAe;AACpC,QAAA,MAAM,IAAA,CAAK,aAAA,CAAc,aAAA,CAAc,OAAO,CAAA;AAAA,MAChD;AACA,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAA,GAAQ,CAAA,iDAAA,EAAoD,MAAM,CAAA,CAAE,CAAA;AAAA,IACnF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,IAAA,CAAK,yBAAyB,qBAAA,EAAuB;AACvD,MAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AAAA,IAC3B,CAAA,MAAA,IAAW,IAAA,CAAK,aAAA,CAAc,aAAA,EAAe;AAC3C,MAAA,MAAM,IAAA,CAAK,aAAA,CAAc,aAAA,CAAc,OAAO,CAAA;AAAA,IAChD;AACA,IAAA,IAAA,CAAK,MAAA,EAAQ,OAAO,qCAAqC,CAAA;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,gBAAA,GAAsC;AAC5C,IAAA,MAAM,UAA6B,EAAC;AACpC,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AAEjC,IAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAAuB;AACpC,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,MAAA,IAAI,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,EAAG;AACtB,QAAA,MAAM,IAAI,QAAA;AAAA,UACR,wDAAwD,IAAI,CAAA,CAAA,CAAA;AAAA,UAC5D,aAAA,CAAc;AAAA,SAChB;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AACxC,MAAA,IAAI,CAAC,QAAA,EAAU;AAEf,MAAA,QAAA,CAAS,IAAI,IAAI,CAAA;AAGjB,MAAA,IAAI,SAAS,SAAA,EAAW;AACtB,QAAA,KAAA,MAAW,GAAA,IAAO,SAAS,SAAA,EAAW;AACpC,UAAA,KAAA,CAAM,GAAG,CAAA;AAAA,QACX;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,OAAO,IAAI,CAAA;AACpB,MAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,MAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,IACvB,CAAA;AAGA,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,SAAA,CAAU,IAAA,EAAK,EAAG;AACxC,MAAA,KAAA,CAAM,IAAI,CAAA;AAAA,IACZ;AAIA,IAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAA,CAAO,EAAE,QAAA,IAAY,CAAA,KAAM,CAAA,CAAE,QAAA,IAAY,CAAA,CAAE,CAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAA,CACZ,WAAA,EACA,SAAA,EACA,OAAA,EACe;AACf,IAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,gBAAA,CAAiB,UAAU,WAAW,CAAA;AAC9D,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,OAAA,CAAQ,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAA,CACZ,WAAA,EACA,SAAA,EACA,OAAA,EACe;AAEf,IAAA,MAAM,SAA8B,EAAC;AACrC,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AAEjC,IAAA,MAAM,QAAA,GAAW,CAAC,QAAA,KAAsC;AACtD,MAAA,IAAI,CAAC,QAAA,CAAS,SAAA,IAAa,QAAA,CAAS,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1D,QAAA,OAAO,CAAA;AAAA,MACT;AACA,MAAA,IAAI,WAAA,GAAc,CAAA;AAClB,MAAA,KAAA,MAAW,GAAA,IAAO,SAAS,SAAA,EAAW;AACpC,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AAC1C,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,WAAA,GAAc,KAAK,GAAA,CAAI,WAAA,EAAa,QAAA,CAAS,WAAW,IAAI,CAAC,CAAA;AAAA,QAC/D;AAAA,MACF;AACA,MAAA,OAAO,WAAA;AAAA,IACT,CAAA;AAGA,IAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,MAAA,MAAM,KAAA,GAAQ,SAAS,QAAQ,CAAA;AAC/B,MAAA,OAAO,MAAA,CAAO,UAAU,KAAA,EAAO;AAC7B,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAAA,MAChB;AACA,MAAA,MAAA,CAAO,KAAK,CAAA,CAAG,IAAA,CAAK,QAAQ,CAAA;AAC5B,MAAA,QAAA,CAAS,GAAA,CAAI,SAAS,IAAI,CAAA;AAAA,IAC5B;AAGA,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,KAAA,CAAM,GAAA,CAAI,OAAM,QAAA,KAAY;AAC1B,UAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,gBAAA,CAAiB,UAAU,WAAW,CAAA;AAC9D,UAAA,IAAI,IAAA,EAAM;AACR,YAAA,OAAA,CAAQ,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,OACH;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBAAA,CACZ,QAAA,EACA,WAAA,EAC8B;AAC9B,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,IAAA,IAAI;AAEF,MAAA,IAAI,SAAS,QAAA,EAAU;AACrB,QAAA,MAAM,QAAA,GAAW,QAAA,CAAS,QAAA,CAAS,WAAW,CAAA;AAC9C,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,aAAA,CAAc,IAAkB,QAAQ,CAAA;AAClE,UAAA,IAAI,MAAA,EAAQ;AACV,YAAA,IAAA,CAAK,MAAA,EAAQ,QAAQ,CAAA,gCAAA,EAAmC,QAAA,CAAS,IAAI,CAAA,CAAA,EAAI,EAAE,UAAU,CAAA;AACrF,YAAA,OAAO,MAAA;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAGA,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,WAAA;AAAA,QACtB,QAAA,CAAS,QAAQ,WAAW,CAAA;AAAA,QAC5B,IAAA,CAAK,eAAA;AAAA,QACL,CAAA,UAAA,EAAa,QAAA,CAAS,IAAI,CAAA,kBAAA,EAAqB,KAAK,eAAe,CAAA,EAAA;AAAA,OACrE;AAGA,MAAA,IAAI,SAAS,QAAA,EAAU;AACrB,QAAA,MAAM,QAAA,GAAW,QAAA,CAAS,QAAA,CAAS,WAAW,CAAA;AAC9C,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,MAAM,GAAA,GAAM,QAAA,CAAS,QAAA,IAAY,IAAA,CAAK,eAAA;AACtC,UAAA,MAAM,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAA,EAAU,MAAM,GAAG,CAAA;AAChD,UAAA,IAAA,CAAK,MAAA,EAAQ,QAAQ,CAAA,yBAAA,EAA4B,QAAA,CAAS,IAAI,CAAA,CAAA,EAAI,EAAE,QAAA,EAAU,GAAA,EAAK,CAAA;AAAA,QACrF;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC9B,MAAA,IAAA,CAAK,MAAA,EAAQ,QAAQ,CAAA,2BAAA,EAA8B,QAAA,CAAS,IAAI,CAAA,CAAA,EAAI,EAAE,UAAA,EAAY,QAAA,EAAU,CAAA;AAE5F,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC9B,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAA,GAAQ,CAAA,oCAAA,EAAuC,QAAA,CAAS,IAAI,CAAA,CAAA,EAAI;AAAA,QAC3E,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAAA,QAC5D,UAAA,EAAY;AAAA,OACb,CAAA;AAED,MAAA,IAAI,QAAA,CAAS,aAAa,KAAA,EAAO;AAC/B,QAAA,MAAM,IAAI,QAAA;AAAA,UACR,CAAA,mBAAA,EAAsB,QAAA,CAAS,IAAI,CAAA,UAAA,EAAa,KAAA,YAAiB,QAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAAA,UACtG,aAAA,CAAc;AAAA,SAChB;AAAA,MACF;AAEA,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAA,CAAe,OAAA,EAAqB,SAAA,EAAmB,OAAA,EAA6B;AAChG,IAAA,OAAO,MAAM,QAAQ,IAAA,CAAK;AAAA,MACxB,OAAA;AAAA,MACA,IAAI,OAAA,CAAW,CAAC,CAAA,EAAG,MAAA,KAAW,WAAW,MAAM;AAAE,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAC,CAAA;AAAA,MAAG,CAAA,EAAG,SAAS,CAAC;AAAA,KAC3F,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,OAAA,EAAkD;AAC1E,IAAA,MAAM,MAAA,GAAiD;AAAA,MACrD,UAAA,sBAAgB,IAAA;AAAK,KACvB;AAEA,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,OAAA,EAAS;AAElC,MAAA,MAAA,CAAO,IAAI,CAAA,GAAI,IAAA;AAGf,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AAC/C,QAAA,IAAI,GAAA,KAAQ,YAAA,IAAgB,GAAA,KAAQ,UAAA,EAAY;AAC9C,UAAA,IAAI,MAAA,CAAO,GAAG,CAAA,KAAM,MAAA,EAAW;AAC7B,YAAA,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAYO,SAAS,sBACd,OAAA,EAC4B;AAC5B,EAAA,OAAO,IAAI,gBAA2B,OAAO,CAAA;AAC/C;AAwBO,SAAS,eACd,MAAA,EAC4B;AAC5B,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,IAAA;AAAA,IACV,QAAA,EAAU,CAAA;AAAA,IACV,GAAG;AAAA,GACL;AACF;;;ACnMO,SAAS,iBAAA,CACd,aAAA,EACA,kBAAA,GAAqB,iBAAA,EACH;AAClB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,GAAG,aAAa,CAAA,eAAA,CAAA;AAAA,IACtB,WAAA,EAAa,UAAU,aAAa,CAAA,gCAAA,CAAA;AAAA,IACpC,KAAA,EAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,aAAA;AAAA,QACN,EAAA,EAAI,eAAA;AAAA,QACJ,UAAA,EAAY,kBAAA;AAAA,QACZ,QAAA,EAAU;AAAA,OACZ;AAAA,MACA;AAAA,QACE,IAAA,EAAM,eAAA;AAAA,QACN,EAAA,EAAI,WAAA;AAAA,QACJ,UAAA,EAAY,IAAA;AAAA,QACZ,QAAA,EAAU;AAAA;AACZ;AACF,GACF;AACF;AAcO,SAAS,qBAAA,CACd,aAAA,EACA,UAAA,GAAa,SAAA,EACK;AAClB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,GAAG,aAAa,CAAA,oBAAA,CAAA;AAAA,IACtB,WAAA,EAAa,UAAU,aAAa,CAAA,uCAAA,CAAA;AAAA,IACpC,KAAA,EAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,aAAA;AAAA,QACN,EAAA,EAAI,OAAA;AAAA,QACJ,UAAA,EAAY,UAAA;AAAA,QACZ,QAAA,EAAU;AAAA,OACZ;AAAA,MACA;AAAA,QACE,IAAA,EAAM,OAAA;AAAA,QACN,EAAA,EAAI,eAAA;AAAA,QACJ,UAAA,EAAY,iBAAA;AAAA,QACZ,QAAA,EAAU;AAAA,OACZ;AAAA,MACA;AAAA,QACE,IAAA,EAAM,eAAA;AAAA,QACN,EAAA,EAAI,WAAA;AAAA,QACJ,UAAA,EAAY,IAAA;AAAA,QACZ,QAAA,EAAU;AAAA;AACZ;AACF,GACF;AACF;AAcO,SAAS,iBAAA,CACd,aAAA,EACA,UAAA,GAAa,SAAA,EACK;AAClB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,GAAG,aAAa,CAAA,YAAA,CAAA;AAAA,IACtB,WAAA,EAAa,UAAU,aAAa,CAAA,wBAAA,CAAA;AAAA,IACpC,KAAA,EAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,aAAA;AAAA,QACN,EAAA,EAAI,OAAA;AAAA,QACJ,UAAA,EAAY,UAAA;AAAA,QACZ,QAAA,EAAU;AAAA,OACZ;AAAA,MACA;AAAA,QACE,IAAA,EAAM,OAAA;AAAA,QACN,EAAA,EAAI,cAAA;AAAA,QACJ,UAAA,EAAY,IAAA;AAAA,QACZ,QAAA,EAAU;AAAA;AACZ;AACF,GACF;AACF;ACzVO,IAAM,gBAAN,MAAkC;AAAA,EAC/B,MAAA,uBAAa,GAAA,EAAgC;AAAA,EAC7C,mBAAA,uBAA0B,GAAA,EAAsC;AAAA,EAChE,MAAA;AAAA,EAER,WAAA,CAAY,QAA0B,OAAA,EAAqC;AACzE,IAAA,IAAA,CAAK,MAAA,GAAS,SAAS,MAAA,IAAUA,YAAAA;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,MAAA,EAA+B;AACxC,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACpD,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,IAAA,CAAK,aAAA,CAAc,OAAO,MAA0B,CAAA;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,CAAc,OAAe,MAAA,EAAgC;AAC3D,IAAA,MAAM,QAAA,GAA+B;AAAA,MACnC,aAAA,sBAAmB,GAAA,EAAI;AAAA,MACvB,UAAU;AAAC,KACb;AAGA,IAAA,KAAA,MAAW,GAAA,IAAO,OAAO,aAAA,EAAe;AACtC,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,uBAAA,CAAwB,GAAA,EAAK,KAAK,CAAA;AAC5D,MAAA,QAAA,CAAS,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,YAAY,CAAA;AAEjD,MAAA,IAAA,CAAK,mBAAA,CAAoB,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,YAAY,CAAA;AAAA,IACrD;AAGA,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AAC/C,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA;AAChC,MAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,MAAA,MAAM,aAAa,MAAA,CAAO,IAAA,IAAQ,CAAA,EAAG,KAAK,iBAAiB,CAAC,CAAA,CAAA;AAC5D,MAAA,MAAM,iBAAiB,IAAA,CAAK,aAAA,CAAc,QAAQ,UAAA,EAAY,KAAA,EAAO,SAAS,aAAa,CAAA;AAC3F,MAAA,QAAA,CAAS,QAAA,CAAS,KAAK,cAAc,CAAA;AAAA,IACvC;AAGA,IAAA,QAAA,CAAS,QAAA,CAAS,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,QAAA,GAAW,EAAE,QAAQ,CAAA;AAExD,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA;AAC/B,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,GAAO,CAAA,0BAAA,EAA6B,KAAK,CAAA,CAAA,EAAI;AAAA,MACvD,aAAA,EAAe,OAAO,aAAA,CAAc,MAAA;AAAA,MACpC,QAAA,EAAU,OAAO,QAAA,CAAS;AAAA,KAC3B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,IAAA,EAA8B;AACjD,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,MAAA,EAAQ;AACtB,MAAA,MAAM,IAAI,cAAA,CAAe,CAAA,mBAAA,EAAsB,IAAA,CAAK,IAAI,CAAA,cAAA,CAAA,EAAkB;AAAA,QACxE,MAAM,IAAA,CAAK;AAAA,OACZ,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,QAAA,GAAW,KAAK,uBAAA,CAAwB,IAAA,EAAM,KAAK,KAAA,CAAM,CAAC,EAAG,IAAI,CAAA;AACvE,IAAA,IAAA,CAAK,mBAAA,CAAoB,GAAA,CAAI,IAAA,CAAK,IAAA,EAAM,QAAQ,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,CAAY,OAAe,SAAA,EAA6C;AACtE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AAErB,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,SAAS,CAAA,IAAK,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,CAAgB,MAAc,KAAA,EAAsD;AAElF,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACzC,MAAA,MAAM,SAAA,GAAY,WAAA,EAAa,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA;AACrD,MAAA,IAAI,WAAW,OAAO,SAAA;AAAA,IACxB;AAGA,IAAA,OAAO,IAAA,CAAK,mBAAA,CAAoB,GAAA,CAAI,IAAI,CAAA;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAA,EAAwB;AAC/B,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAsB;AACpB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,oBAAoB,KAAA,EAAM;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,uBAAA,CAAwB,MAAwB,WAAA,EAA+C;AACrG,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAI,cAAA,CAAe,CAAA,mBAAA,EAAsB,IAAA,CAAK,IAAI,CAAA,6BAAA,CAAA,EAAiC;AAAA,QACvF,MAAM,IAAA,CAAK;AAAA,OACZ,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,gBAA8C,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AAElF,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,IAAQ,CAAC,KAAK,EAAA,EAAI;AAC1B,QAAA,MAAM,IAAI,cAAA;AAAA,UACR,CAAA,kBAAA,EAAqB,KAAK,CAAA,KAAA,EAAQ,IAAA,CAAK,IAAI,CAAA,kCAAA,CAAA;AAAA,UAC3C,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,MAAM,KAAA;AAAM,SACjC;AAAA,MACF;AAGA,MAAA,OAAO;AAAA,QACL,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,IAAI,IAAA,CAAK,EAAA;AAAA,QACT,UAAA,EAAY,IAAA,CAAK,UAAA,IAAc,CAAA,EAAG,KAAK,EAAE,CAAA,GAAA,CAAA;AAAA,QACzC,QAAA,EAAU,KAAK,QAAA,IAAY,IAAA;AAAA,QAC3B,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,EAAA;AAAA,QAC1B,QAAA,EAAU,KAAK,QAAA,IAAY,OAAA;AAAA,QAC3B,oBAAA,EAAsB,IAAA,CAAK,oBAAA,IAAwB;AAAC,OACtD;AAAA,IACF,CAAC,CAAA;AAGD,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,CAAc,QAAQ,CAAA,EAAA,EAAK;AAC7C,MAAA,MAAM,QAAA,GAAW,aAAA,CAAc,CAAA,GAAI,CAAC,CAAA;AACpC,MAAA,MAAM,WAAA,GAAc,cAAc,CAAC,CAAA;AAGnC,MAAA,IAAI,YAAY,IAAA,KAAS,QAAA,CAAS,MAAM,WAAA,CAAY,IAAA,KAAS,SAAS,KAAA,EAAO;AAC3E,QAAA,MAAM,IAAI,cAAA;AAAA,UACR,CAAA,mBAAA,EAAsB,IAAA,CAAK,IAAI,CAAA,2BAAA,EAA8B,CAAC,eAC/C,QAAA,CAAS,EAAE,CAAA,WAAA,EAAc,WAAA,CAAY,IAAI,CAAA,CAAA,CAAA;AAAA,UACxD,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAAE,SAC7B;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,aAAA,CAAc,MAAA,GAAS,CAAC,CAAA;AAEvD,IAAA,OAAO;AAAA,MACL,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,KAAA,EAAO,aAAA;AAAA,MACP,WAAA;AAAA,MACA,aAAa,QAAA,CAAS;AAAA,KACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAA,CACN,MAAA,EACA,IAAA,EACA,KAAA,EACA,kBAAA,EACqB;AAErB,IAAA,MAAM,gBAAA,GACJ,kBAAA,CAAmB,GAAA,CAAI,MAAA,CAAO,gBAAgB,KAC9C,IAAA,CAAK,mBAAA,CAAoB,GAAA,CAAI,MAAA,CAAO,gBAAgB,CAAA;AAEtD,IAAA,IAAI,CAAC,gBAAA,EAAkB;AACrB,MAAA,MAAM,IAAI,cAAA;AAAA,QACR,CAAA,cAAA,EAAiB,IAAI,CAAA,wCAAA,EAA2C,MAAA,CAAO,gBAAgB,CAAA,CAAA,CAAA;AAAA,QACvF,EAAE,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,gBAAA,EAAkB,OAAO,gBAAA;AAAiB,OACnE;AAAA,IACF;AAGA,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,SAAS,IAAI,MAAA,CAAO,SAAA,GAAY,CAAC,MAAA,CAAO,SAAS,CAAA;AAClF,IAAA,MAAM,cAAc,GAAA,CAAI,OAAA;AAAA,MAAQ,CAAA,EAAA,KAC9B,EAAA,KAAO,KAAA,GAAQ,CAAC,MAAA,EAAQ,UAAU,QAAA,EAAU,QAAQ,CAAA,GAAI,CAAC,EAAE;AAAA,KAC7D;AAGA,IAAA,MAAM,gBAAA,GACJ,OAAO,MAAA,CAAO,YAAA,KAAiB,aAC3B,MAAA,CAAO,YAAA,GACP,MAAM,MAAA,CAAO,YAAA;AAEnB,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,IAAA,EAAM,OAAO,UAAA,IAAc,OAAA;AAAA,MAC3B,UAAA,EAAY,IAAI,GAAA,CAAI,WAAW,CAAA;AAAA,MAC/B,gBAAA;AAAA,MACA,gBAAA;AAAA,MACA,QAAA,EAAU,OAAO,QAAA,IAAY;AAAA,KAC/B;AAAA,EACF;AACF;AASO,SAAS,mBAAA,CACd,QACA,OAAA,EACmB;AACnB,EAAA,OAAO,IAAI,aAAA,CAAkB,MAAA,EAAQ,OAAO,CAAA;AAC9C;AChQO,IAAM,mBAAN,MAAqC;AAAA,EAC1C,WAAA,CACU,QAAA,EACA,OAAA,GAA6B,EAAC,EACtC;AAFQ,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAER,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,cAAA,EAAgB,IAAA;AAAA,MAChB,OAAA,EAAS,UAAA;AAAA,MACT,GAAG;AAAA,KACL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,SAAA,CACE,EAAA,EACA,KAAA,EACA,SAAA,GAAuB,MAAA,EACQ;AAC/B,IAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AACxC,IAAA,IAAI,CAAC,GAAA,EAAK;AAER,MAAA,OAAO,EAAA;AAAA,IACT;AAGA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA,OAAO,EAAA;AAAA,IACT;AAGA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,WAAA,CAAY,OAAO,SAAS,CAAA;AAC3D,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,OAAO,EAAA;AAAA,IACT;AAGA,IAAA,IAAI,MAAA,GAAS,EAAA;AACb,IAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,MAAA,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,MAAA,EAAQ,MAAA,EAAQ,KAAK,KAAK,CAAA;AAAA,IACtD;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,iBAAA,CACE,MAAA,EACA,GAAA,EACA,SAAA,EACA,cAAA,EACoC;AACpC,IAAA,MAAM,EAAE,kBAAiB,GAAI,MAAA;AAC7B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,iBAAA,CAAkB,GAAA,EAAK,SAAS,CAAA;AACrD,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,gBAAA,CAAiB,OAAO,CAAA;AAErD,IAAA,MAAM,QAAQ,cAAA,IAAkB,SAAA;AAChC,IAAA,MAAM,SAAoB,EAAC;AAC3B,IAAA,IAAI,UAAA,GAAa,CAAA;AAGjB,IAAA,MAAM,QAAQ,gBAAA,CAAiB,KAAA;AAC/B,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,MAAA,EAAQ,EAAC,EAAE;AAAA,IACnC;AAGA,IAAA,MAAM,SAAA,GAAY,MAAM,CAAC,CAAA;AACzB,IAAA,IAAIC,OAAM,CAAA,cAAA,EAAiB,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,EAAE,CAAC,CAAA,CAAA;AACnD,IAAA,IAAI,SAAA,CAAU,KAAA,KAAU,SAAA,CAAU,EAAA,EAAI;AACpC,MAAAA,QAAO,CAAA,IAAA,EAAO,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA;AAAA,IAC3C;AAGA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,MAAA,MAAM,QAAA,GAAW,KAAK,QAAA,KAAa,MAAA,GAAS,cAAc,IAAA,CAAK,QAAA,KAAa,UAAU,YAAA,GAAe,MAAA;AAErG,MAAAA,IAAAA,IAAO,IAAI,QAAQ,CAAA,CAAA,EAAI,KAAK,KAAA,CAAM,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AAC1C,MAAA,IAAI,IAAA,CAAK,KAAA,KAAU,IAAA,CAAK,EAAA,EAAI;AAC1B,QAAAA,QAAO,CAAA,IAAA,EAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAA,CAAA;AAAA,MACtC;AAGA,MAAA,MAAM,QAAA,GAAW,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA;AAC5B,MAAA,MAAM,YAAY,QAAA,CAAS,KAAA;AAC3B,MAAAA,IAAAA,IAAO,OAAO,IAAA,CAAK,KAAA,CAAM,SAAS,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,UAAU,CAAC,CAAA,GAAA,EAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAC,CAAA,CAAA;AAG3H,MAAA,IAAI,OAAO,IAAA,CAAK,IAAA,CAAK,oBAAoB,CAAA,CAAE,SAAS,CAAA,EAAG;AACrD,QAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,oBAAoB,CAAA,EAAG;AAClE,UAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,YAAAA,IAAAA,IAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,QAAA,CAAA;AAAA,UAC1D,CAAA,MAAO;AACL,YAAAA,QAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,GAAA,EAAM,IAAA,CAAK,KAAA,CAAM,YAAY,CAAC,CAAA,CAAA;AACtF,YAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAAA,IAAAA,IAAO,UAAU,IAAA,CAAK,KAAA,CAAM,UAAU,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,QAAQ,CAAC,CAAA,GAAA,EAAM,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,IAAI,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,UAAU,CAAC,CAAA,CAAA;AAGzI,IAAA,IAAI,OAAO,IAAA,CAAK,SAAA,CAAU,oBAAoB,CAAA,CAAE,SAAS,CAAA,EAAG;AAC1D,MAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,SAAA,CAAU,oBAAoB,CAAA,EAAG;AACvE,QAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,UAAAA,IAAAA,IAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,QAAA,CAAA;AAAA,QAC/D,CAAA,MAAO;AACL,UAAAA,QAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,GAAA,EAAM,IAAA,CAAK,KAAA,CAAM,YAAY,CAAC,CAAA,CAAA;AAC3F,UAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAGA,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AACvC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAA,EAAG;AACtD,MAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,QAAAA,IAAAA,IAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,QAAA,CAAA;AAAA,MAC9D,CAAA,MAAA,IAAW,QAAQ,MAAA,EAAW;AAE5B,QAAA;AAAA,MACF,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC7B,QAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,UAAAA,IAAAA,IAAO,CAAA,UAAA,CAAA;AAAA,QACT,CAAA,MAAO;AACL,UAAA,MAAM,YAAA,GAAe,GAAA,CAAI,GAAA,CAAI,MAAM,IAAA,CAAK,MAAM,UAAA,EAAY,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AACtE,UAAAA,IAAAA,IAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,QAAQ,YAAY,CAAA,CAAA,CAAA;AAChF,UAAA,MAAA,CAAO,IAAA,CAAK,GAAG,GAAG,CAAA;AAAA,QACpB;AAAA,MACF,CAAA,MAAO;AACL,QAAAA,QAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,GAAA,EAAM,IAAA,CAAK,KAAA,CAAM,YAAY,CAAC,CAAA,CAAA;AAC1F,QAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,MACjB;AAAA,IACF;AAGA,IAAA,MAAM,UAAA,GAAa,OAAO,IAAA,KAAS,MAAA,GAAS,eAAeA,IAAG,CAAA,CAAA,CAAA,GAAM,WAAWA,IAAG,CAAA,CAAA,CAAA;AAElF,IAAA,OAAO,EAAE,GAAA,EAAK,UAAA,EAAY,MAAA,EAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,WAAA,CACN,EAAA,EACA,MAAA,EACA,GAAA,EACA,KAAA,EAC+B;AAC/B,IAAA,MAAM,EAAE,GAAA,EAAK,SAAA,EAAW,MAAA,EAAO,GAAI,IAAA,CAAK,iBAAA,CAAkB,MAAA,EAAQ,GAAA,EAAK,KAAA,EAAO,IAAA,CAAK,OAAA,CAAQ,cAAc,CAAA;AAIzG,IAAA,MAAM,QAAA,GAAW,SAAA,CAAU,KAAA,CAAM,OAAO,CAAA;AAIxC,IAAA,MAAM,aAAaA,GAAAA,CAAI,IAAA;AAAA,MACrB,QAAA,CAAS,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM;AACxB,QAAA,IAAI,CAAA,GAAI,OAAO,MAAA,EAAQ;AACrB,UAAA,OAAOA,GAAAA,CAAAA,EAAMA,IAAI,GAAA,CAAI,IAAI,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAAA,QACxC;AACA,QAAA,OAAOA,GAAAA,CAAI,IAAI,IAAI,CAAA;AAAA,MACrB,CAAC;AAAA,KACH;AAMA,IAAA,OAAO,EAAA,CAAG,MAAM,UAAiB,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,CAAkB,KAAiB,KAAA,EAAwC;AACjF,IAAA,OAAO;AAAA,MACL,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,KAAA;AAAA,MACA,SAAA,EAAW,MAAA;AAAA,MACX,GAAI,GAAA,CAAI,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,IAAI,IAAA;AAAgC,KAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,MAAM,UAAA,EAA4B;AACxC,IAAA,QAAQ,IAAA,CAAK,QAAQ,OAAA;AAAS,MAC5B,KAAK,OAAA;AACH,QAAA,OAAO,KAAK,UAAU,CAAA,EAAA,CAAA;AAAA,MACxB,KAAK,QAAA;AACH,QAAA,OAAO,IAAI,UAAU,CAAA,CAAA,CAAA;AAAA,MACvB,KAAK,UAAA;AAAA,MACL;AACE,QAAA,OAAO,IAAI,UAAU,CAAA,CAAA,CAAA;AAAA;AACzB,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,MAAM,KAAA,EAAuB;AACnC,IAAA,QAAQ,IAAA,CAAK,QAAQ,OAAA;AAAS,MAC5B,KAAK,OAAA;AAAA,MACL,KAAK,QAAA;AACH,QAAA,OAAO,GAAA;AAAA,MACT,KAAK,UAAA;AAAA,MACL;AACE,QAAA,OAAO,IAAI,KAAK,CAAA,CAAA;AAAA;AACpB,EACF;AACF;AAyBO,SAAS,aAAA,CACd,SAAA,EACA,gBAAA,EACA,YAAA,EACA,OAAA,EACuB;AACvB,EAAA,MAAM,MAAA,GAAgC;AAAA,IACpC,IAAA,EAAM,QAAA;AAAA,IACN,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA,EAAY;AAAA,GACd;AAEA,EAAA,IAAI,OAAA,EAAS,SAAS,MAAA,EAAW;AAC/B,IAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,EACxB;AAEA,EAAA,IAAI,OAAA,EAAS,aAAa,MAAA,EAAW;AACnC,IAAA,MAAA,CAAO,WAAW,OAAA,CAAQ,QAAA;AAAA,EAC5B;AAEA,EAAA,OAAO,MAAA;AACT;AAqBO,SAAS,YAAA,CACd,SAAA,EACA,gBAAA,EACA,YAAA,EACA,OAAA,EACuB;AACvB,EAAA,MAAM,MAAA,GAAgC;AAAA,IACpC,IAAA,EAAM,QAAA;AAAA,IACN,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA,EAAY,MAAA;AAAA,IACZ,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA;AAAA,GACjC;AAEA,EAAA,IAAI,OAAA,EAAS,SAAS,MAAA,EAAW;AAC/B,IAAA,MAAA,CAAO,OAAO,OAAA,CAAQ,IAAA;AAAA,EACxB;AAEA,EAAA,OAAO,MAAA;AACT;AASO,SAAS,sBAAA,CACd,UACA,OAAA,EACsB;AACtB,EAAA,OAAO,IAAI,gBAAA,CAAqB,QAAA,EAAU,OAAO,CAAA;AACnD;;;ACtGO,SAAS,eAAA,GAAqC;AACnD,EAAA,OAAO;AAAA,IACL,MAAM,MAAM,KAAA;AAAA,IACZ,OAAO,MAAM,KAAA;AAAA,IACb,cAAA,EAAgB;AAAA,GAClB;AACF;AAiBO,SAAS,SAAA,CAAU,aAAa,IAAA,EAAyB;AAC9D,EAAA,OAAO;AAAA,IACL,MAAM,CAAA,GAAA,KAAO;AACX,MAAA,MAAM,QAAA,GAAY,GAAA,CAAI,GAAA,GAAkC,UAAU,CAAA;AAElE,MAAA,OAAO,OAAO,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,KAAM,OAAO,QAAQ,CAAA;AAAA,IACpD,CAAA;AAAA,IACA,OAAO,CAAA,GAAA,KAAO;AACZ,MAAA,MAAM,QAAA,GAAY,GAAA,CAAI,GAAA,GAAkC,UAAU,CAAA;AAClE,MAAA,OAAO,OAAO,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,KAAM,OAAO,QAAQ,CAAA;AAAA,IACpD;AAAA,GACF;AACF;AAkBO,SAAS,YAAA,CAAa,KAAA,EAAiB,UAAA,GAAa,IAAA,EAAyB;AAClF,EAAA,OAAO;AAAA,IACL,MAAM,CAAA,GAAA,KAAO;AACX,MAAA,MAAM,QAAA,GAAY,GAAA,CAAI,GAAA,GAAkC,UAAU,CAAA;AAClE,MAAA,OAAO,OAAO,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,KAAM,OAAO,QAAQ,CAAA,IAAK,KAAA,CAAM,IAAA,CAAK,OAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,IACnG,CAAA;AAAA,IACA,OAAO,CAAA,GAAA,KAAO;AACZ,MAAA,MAAM,QAAA,GAAY,GAAA,CAAI,GAAA,GAAkC,UAAU,CAAA;AAClE,MAAA,OAAO,OAAO,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,KAAM,OAAO,QAAQ,CAAA,IAAK,KAAA,CAAM,IAAA,CAAK,OAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,IACnG;AAAA,GACF;AACF;AAiBO,SAAS,UAAU,KAAA,EAAoC;AAC5D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,CAAA,GAAA,KAAO,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,IACvD,KAAA,EAAO,CAAA,GAAA,KAAO,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC;AAAA,GAC1D;AACF;AAiBO,SAAS,SAAS,aAAA,EAAyD;AAChF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,kBAAkB,MAAM,IAAA,CAAA;AAAA,IAC9B,OAAO,MAAM;AAAA,GACf;AACF;AAiBO,SAAS,0BAA0B,cAAA,EAAyD;AACjG,EAAA,OAAO;AAAA,IACL,MAAM,MAAM,IAAA;AAAA,IACZ,KAAA,EAAO;AAAA,GACT;AACF;AAwBO,SAAS,WAAA,CACd,QACA,aAAA,EAC6D;AAC7D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,aAAA;AAAA,IACN,KAAA,EAAO,aAAA;AAAA,IACP,WAAA,EAAa,MAAA;AAAA;AAAA,IACb;AAAA,GACF;AACF;ACtZO,IAAM,sBAAN,MAAwC;AAAA,EACrC,MAAA,uBAAa,GAAA,EAAsC;AAAA,EACnD,MAAA;AAAA,EAER,WAAA,CAAY,QAAgC,OAAA,EAAqC;AAC/E,IAAA,IAAA,CAAK,MAAA,GAAS,SAAS,MAAA,IAAUD,YAAAA;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,MAAA,EAAqC;AAC9C,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACpD,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,IAAA,CAAK,aAAA,CAAc,OAAO,MAAgC,CAAA;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,CAAc,OAAe,MAAA,EAAsC;AACjE,IAAA,MAAM,QAAA,GAAqC;AAAA,MACzC,KAAA;AAAA,MACA,aAAA,EAAe,OAAO,OAAA,IAAW,OAAA;AAAA,MACjC,OAAA,EAAS,MAAA,CAAO,OAAA,IAAW,EAAC;AAAA,MAC5B,MAAA,sBAAY,GAAA;AAAI,KAClB;AAGA,IAAA,KAAA,MAAW,CAAC,OAAO,WAAW,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,EAAG;AAChE,MAAA,IAAI,CAAC,WAAA,EAAa;AAElB,MAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,kBAAA,CAAmB,KAAA,EAAO,WAAgC,CAAA;AACrF,MAAA,QAAA,CAAS,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,aAAa,CAAA;AAAA,IAC1C;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA;AAC/B,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,GAAO,CAAA,gCAAA,EAAmC,KAAK,CAAA,CAAA,EAAI;AAAA,MAC7D,MAAA,EAAQ,SAAS,MAAA,CAAO,IAAA;AAAA,MACxB,eAAe,QAAA,CAAS;AAAA,KACzB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,YAAA,CAAa,KAAA,EAAe,KAAA,EAAe,GAAA,EAAgD;AAC/F,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEX,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AAC9D,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAC3C,IAAA,IAAI,CAAC,WAAA,EAAa;AAEhB,MAAA,OAAO,OAAO,aAAA,KAAkB,OAAA;AAAA,IAClC;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,OAAA,CAAQ,GAAG,CAAA;AACtC,MAAA,OAAO,MAAA,YAAkB,OAAA,GAAU,MAAM,MAAA,GAAS,MAAA;AAAA,IACpD,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,OAAO,KAAA,GAAQ,CAAA,6CAAA,EAAgD,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI;AAAA,QACpF,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC7D,CAAA;AACD,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAA,CAAc,KAAA,EAAe,KAAA,EAAe,GAAA,EAAgD;AAChG,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AAC9D,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAC3C,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO,OAAO,aAAA,KAAkB,OAAA;AAAA,IAClC;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA;AACvC,MAAA,OAAO,MAAA,YAAkB,OAAA,GAAU,MAAM,MAAA,GAAS,MAAA;AAAA,IACpD,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,OAAO,KAAA,GAAQ,CAAA,8CAAA,EAAiD,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI;AAAA,QACrF,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC7D,CAAA;AACD,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,cAAA,CAAe,OAAe,KAAA,EAAgD;AAC5E,IAAA,OAAO,KAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,EAAG,MAAA,CAAO,IAAI,KAAK,CAAA;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAe,KAAA,EAAqD;AAClE,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAA,EAAwB;AAC/B,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAsB;AACpB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAoB,KAAA,EAAyB;AAC3C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,OAAO,MAAA,GAAS,MAAM,IAAA,CAAK,MAAA,CAAO,OAAO,IAAA,EAAM,IAAI,EAAC;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,kBAAA,CAAmB,OAAe,MAAA,EAAgD;AACxF,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,OAAA,EAAS,MAAA,CAAO,IAAA,KAAS,MAAM,IAAA,CAAA;AAAA,MAC/B,QAAA,EAAU,MAAA,CAAO,KAAA,KAAU,MAAM,IAAA,CAAA;AAAA,MACjC,WAAA,EAAa,OAAO,WAAA,IAAe,IAAA;AAAA,MACnC,cAAA,EAAgB,OAAO,cAAA,IAAkB;AAAA,KAC3C;AAAA,EACF;AACF;AASO,SAAS,yBAAA,CACd,QACA,OAAA,EACyB;AACzB,EAAA,OAAO,IAAI,mBAAA,CAAwB,MAAA,EAAQ,OAAO,CAAA;AACpD;;;ACrNO,IAAM,uBAAN,MAAyC;AAAA,EAC9C,WAAA,CACU,QAAA,EACA,gBAAA,GAA4B,IAAA,EACpC;AAFQ,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,gBAAA,GAAA,gBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUH,MAAM,OAAA,CACJ,KAAA,EACA,GAAA,EACA,OAAA,GAA8B,EAAC,EACR;AACvB,IAAA,MAAM,GAAA,GAAM,KAAK,UAAA,EAAW;AAC5B,IAAA,IAAI,CAAC,GAAA,EAAK;AAER,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,GAAA;AAAA,QACN,cAAc,EAAC;AAAA,QACf,eAAe;AAAC,OAClB;AAAA,IACF;AAGA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,GAAA;AAAA,QACN,cAAc,EAAC;AAAA,QACf,eAAe;AAAC,OAClB;AAAA,IACF;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAA,CAAe,KAAK,CAAA;AACtD,IAAA,IAAI,CAAC,WAAA,EAAa;AAEhB,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,GAAA;AAAA,QACN,cAAc,EAAC;AAAA,QACf,eAAe;AAAC,OAClB;AAAA,IACF;AAGA,IAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACnE,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,GAAA;AAAA,QACN,cAAc,EAAC;AAAA,QACf,eAAe;AAAC,OAClB;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,iBAAA,CAAkB,GAAA,EAAK,KAAK,KAAK,CAAA;AACtD,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,MAAM,eAAyB,EAAC;AAChC,IAAA,MAAM,gBAA0B,EAAC;AAGjC,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAEhD,MAAA,IAAI,OAAA,CAAQ,aAAA,EAAe,QAAA,CAAS,KAAK,CAAA,EAAG;AAC1C,QAAA;AAAA,MACF;AACA,MAAA,IAAI,QAAQ,aAAA,IAAiB,CAAC,QAAQ,aAAA,CAAc,QAAA,CAAS,KAAK,CAAA,EAAG;AACnE,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,mBAAA;AAAA,QAC7B,WAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,aAAA,CAAc,KAAK,KAAK,CAAA;AAAA,MAC1B,CAAA,MAAA,IAAW,CAAC,WAAA,CAAY,UAAA,EAAY;AAClC,QAAA,YAAA,CAAa,KAAK,KAAK,CAAA;AACtB,QAAC,MAAA,CAAmC,KAAK,CAAA,GAAI,WAAA,CAAY,KAAA;AAAA,MAC5D,CAAA,MAAO;AACJ,QAAC,MAAA,CAAmC,KAAK,CAAA,GAAI,KAAA;AAAA,MAChD;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,MAAA;AAAA,MACN,YAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAA,CACJ,KAAA,EACA,IAAA,EACA,OAAA,GAA8B,EAAC,EACN;AACzB,IAAA,OAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,KAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,GAAA,EAAK,OAAO,CAAC,CAAC,CAAA;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAA,CACJ,KAAA,EACA,IAAA,EACA,WAAA,EACe;AACf,IAAA,MAAM,GAAA,GAAM,KAAK,UAAA,EAAW;AAC5B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAA,CAAe,KAAK,CAAA;AACtD,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACnE,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,KAAK,iBAAA,CAAkB,GAAA,EAAK,eAAe,EAAC,EAAG,OAAO,IAAI,CAAA;AAG1E,IAAA,MAAM,mBAA6B,EAAC;AAEpC,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG;AACrC,MAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,aAAA,CAAc,KAAA,EAAO,OAAO,OAAO,CAAA;AACxE,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,gBAAA,CAAiB,KAAK,KAAK,CAAA;AAAA,MAC7B;AAAA,IACF;AAEA,IAAA,IAAI,gBAAA,CAAiB,SAAS,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAI,kBAAA;AAAA,QACR,OAAA;AAAA,QACA,KAAA;AAAA,QACA,CAAA,kCAAA,EAAqC,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,OAClE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAA,CACJ,KAAA,EACA,IAAA,EACA,WAAA,EACqE;AACrE,IAAA,MAAM,GAAA,GAAM,KAAK,UAAA,EAAW;AAC5B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,EAAC,EAAE;AAAA,IACnC;AAEA,IAAA,IAAI,GAAA,CAAI,KAAK,QAAA,EAAU;AACrB,MAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,EAAC,EAAE;AAAA,IACnC;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAA,CAAe,KAAK,CAAA;AACtD,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,EAAC,EAAE;AAAA,IACnC;AAGA,IAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACnE,MAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,EAAC,EAAE;AAAA,IACnC;AAEA,IAAA,MAAM,OAAA,GAAU,KAAK,iBAAA,CAAkB,GAAA,EAAK,eAAe,EAAC,EAAG,OAAO,IAAI,CAAA;AAC1E,IAAA,MAAM,SAAkC,EAAC;AACzC,IAAA,MAAM,gBAA0B,EAAC;AAEjC,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AACjD,MAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,aAAA,CAAc,KAAA,EAAO,OAAO,OAAO,CAAA;AACxE,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,MAAA,CAAO,KAAK,CAAA,GAAI,KAAA;AAAA,MAClB,CAAA,MAAO;AACL,QAAA,aAAA,CAAc,KAAK,KAAK,CAAA;AAAA,MAC1B;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,aAAA,EAAc;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,iBAAA,CAAkB,KAAA,EAAe,GAAA,EAAiD;AACtF,IAAA,MAAM,GAAA,GAAM,KAAK,UAAA,EAAW;AAC5B,IAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU;AAC7B,MAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,IACxB;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAA,CAAe,KAAK,CAAA;AACtD,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,IACxB;AAGA,IAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACnE,MAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,IACxB;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,iBAAA,CAAkB,GAAA,EAAK,KAAK,KAAK,CAAA;AACtD,IAAA,MAAM,WAAqB,EAAC;AAE5B,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG;AACpC,MAAA,MAAM,UAAU,MAAM,IAAA,CAAK,SAAS,YAAA,CAAa,KAAA,EAAO,OAAO,OAAO,CAAA;AACtE,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,iBAAA,CAAkB,KAAA,EAAe,GAAA,EAAiD;AACtF,IAAA,MAAM,GAAA,GAAM,KAAK,UAAA,EAAW;AAC5B,IAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU;AAC7B,MAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,IACxB;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAA,CAAe,KAAK,CAAA;AACtD,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,IACxB;AAGA,IAAA,IAAI,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,KAAQ,GAAA,CAAI,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AACnE,MAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,IACxB;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,iBAAA,CAAkB,GAAA,EAAK,KAAK,KAAK,CAAA;AACtD,IAAA,MAAM,WAAqB,EAAC;AAE5B,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG;AACpC,MAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,aAAA,CAAc,KAAA,EAAO,OAAO,OAAO,CAAA;AACxE,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,UAAA,GAAgC;AACtC,IAAA,OAAO,WAAW,gBAAA,EAAiB;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,CACN,GAAA,EACA,GAAA,EACA,KAAA,EACA,IAAA,EACyB;AACzB,IAAA,OAAO;AAAA,MACL,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,GAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAA;AAAA,MACA,GAAI,GAAA,CAAI,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,IAAI,IAAA;AAAgC,KAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBAAA,CACZ,WAAA,EAIA,KAAA,EACA,KAAA,EACA,KACA,OAAA,EAC4B;AAC5B,IAAA,MAAM,WAAA,GAAc,WAAA,CAAY,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAEhD,IAAA,IAAI,CAAC,WAAA,EAAa;AAEhB,MAAA,MAAM,UAAA,GAAa,YAAY,aAAA,KAAkB,OAAA;AACjD,MAAA,OAAO;AAAA,QACL,UAAA;AAAA,QACA,KAAA,EAAO,UAAA,GAAa,KAAA,GAAQ,IAAA,CAAK,gBAAA;AAAA,QACjC,IAAA,EAAM,CAAC,UAAA,IAAc,OAAA,CAAQ,aAAA,KAAkB;AAAA,OACjD;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,OAAA,CAAQ,GAAG,CAAA;AAE7C,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,OAAO;AAAA,UACL,UAAA,EAAY,IAAA;AAAA,UACZ;AAAA,SACF;AAAA,MACF;AAEA,MAAA,IAAI,QAAQ,aAAA,EAAe;AACzB,QAAA,MAAM,IAAI,mBAAmB,MAAA,EAAQ,GAAA,CAAI,SAAS,SAAA,EAAW,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAAA,MAC5F;AAGA,MAAA,MAAM,cAAA,GAAiB,WAAA;AAGvB,MAAA,MAAM,WAAA,GAAc,eAAe,MAAA,GAC/B,cAAA,CAAe,OAAO,KAAK,CAAA,GAC3B,WAAA,CAAY,WAAA,IAAe,IAAA,CAAK,gBAAA;AAEpC,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,KAAA;AAAA,QACZ,MAAA,EAAQ,UAAU,KAAK,CAAA,mBAAA,CAAA;AAAA,QACvB,KAAA,EAAO,WAAA;AAAA,QACP,MAAM,WAAA,CAAY;AAAA,OACpB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiB,kBAAA,EAAoB;AACvC,QAAA,MAAM,KAAA;AAAA,MACR;AAGA,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,KAAA;AAAA,QACZ,MAAA,EAAQ,4BAA4B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAAA,QAC1F,OAAO,IAAA,CAAK,gBAAA;AAAA,QACZ,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAAA,EACF;AACF;AASO,SAAS,0BAAA,CACd,UACA,gBAAA,EAC0B;AAC1B,EAAA,OAAO,IAAI,oBAAA,CAAyB,QAAA,EAAU,gBAAgB,CAAA;AAChE;;;ACvYO,SAAS,YAAA,CACd,QACA,QAAA,EACgB;AAChB,EAAA,MAAM,MAAA,GAAyB;AAAA,IAC7B,MAAM,MAAA,CAAO,IAAA;AAAA,IACb;AAAA,GACF;AAEA,EAAA,IAAI,MAAA,CAAO,gBAAgB,MAAA,EAAW;AACpC,IAAA,MAAA,CAAO,cAAc,MAAA,CAAO,WAAA;AAAA,EAC9B;AAEA,EAAA,IAAI,MAAA,CAAO,SAAS,MAAA,EAAW;AAC7B,IAAA,MAAA,CAAO,OAAO,MAAA,CAAO,IAAA;AAAA,EACvB;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,kBAAA,CACd,IAAA,EACA,QAAA,EACA,OAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,MAAA,CAAO,QAAQ,QAAA,EAAU;AAAA,QACvB,IAAA,EAAM,GAAG,IAAI,CAAA,OAAA,CAAA;AAAA,QACb,GAAI,OAAA,EAAS,QAAA,KAAa,UAAa,EAAE,QAAA,EAAU,QAAQ,QAAA;AAAS,OACrE;AAAA;AACH,GACF;AACF;AAWO,SAAS,iBAAA,CACd,IAAA,EACA,SAAA,EACA,SAAA,EACA,OAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,KAAA,CAAM,WAAW,SAAA,EAAW;AAAA,QAC1B,IAAA,EAAM,GAAG,IAAI,CAAA,MAAA,CAAA;AAAA,QACb,GAAI,OAAA,EAAS,QAAA,KAAa,UAAa,EAAE,QAAA,EAAU,QAAQ,QAAA;AAAS,OACrE;AAAA;AACH,GACF;AACF;AAWO,SAAS,gBAAA,CACd,IAAA,EACA,SAAA,EACA,SAAA,EACA,OAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,IAAA,CAAK,WAAW,SAAA,EAAW;AAAA,QACzB,IAAA,EAAM,GAAG,IAAI,CAAA,KAAA,CAAA;AAAA,QACb,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA,OAChC;AAAA;AACH,GACF;AACF;AAWO,SAAS,oBAAA,CACd,IAAA,EACA,SAAA,EACA,SAAA,EACA,OAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,QAAA,CAAS,WAAW,SAAA,EAAW;AAAA,QAC7B,IAAA,EAAM,GAAG,IAAI,CAAA,SAAA,CAAA;AAAA,QACb,GAAI,OAAA,EAAS,QAAA,KAAa,UAAa,EAAE,QAAA,EAAU,QAAQ,QAAA;AAAS,OACrE;AAAA;AACH,GACF;AACF;AASO,SAAS,oBAAA,CACd,MACA,MAAA,EASgB;AAChB,EAAA,MAAM,WAA+B,EAAC;AAGtC,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ;AAAA,QAC5B,IAAA,EAAM,GAAG,IAAI,CAAA,OAAA;AAAA,OACd;AAAA,KACH;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,KAAA,EAAO;AAChB,IAAA,KAAA,MAAW,CAAC,IAAI,SAAS,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,EAAG;AAC1D,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,QAAA,CAAS,IAAA;AAAA,UACP,KAAA,CAAM,IAAiB,SAAA,EAAW;AAAA,YAChC,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,OAAA,EAAU,EAAE,CAAA;AAAA,WAC1B;AAAA,SACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,KAAA,MAAW,CAAC,IAAI,SAAS,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,EAAG;AACzD,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,QAAA,CAAS,IAAA;AAAA,UACP,IAAA,CAAK,IAAiB,SAAA,EAAW;AAAA,YAC/B,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,MAAA,EAAS,EAAE,CAAA,CAAA;AAAA,YACxB,QAAA,EAAU;AAAA,WACX;AAAA,SACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,QAAA,EAAU;AACnB,IAAA,IAAI,MAAA,CAAO,SAAS,MAAA,EAAQ;AAC1B,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,QAAA,CAAS,QAAA,EAAU,MAAA,CAAO,QAAA,CAAS,MAAA,EAAQ;AAAA,UACzC,IAAA,EAAM,GAAG,IAAI,CAAA,gBAAA;AAAA,SACd;AAAA,OACH;AAAA,IACF;AACA,IAAA,IAAI,MAAA,CAAO,SAAS,MAAA,EAAQ;AAC1B,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,QAAA,CAAS,QAAA,EAAU,MAAA,CAAO,QAAA,CAAS,MAAA,EAAQ;AAAA,UACzC,IAAA,EAAM,GAAG,IAAI,CAAA,gBAAA;AAAA,SACd;AAAA,OACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA;AAAA,GACF;AACF;AAcO,SAAS,2BAAA,CAA4B,MAAA,GAAgC,EAAC,EAAmB;AAC9F,EAAA,MAAM,EAAE,YAAA,GAAe,WAAA,EAAa,kBAAA,GAAqB,MAAK,GAAI,MAAA;AAElE,EAAA,MAAM,QAAA,GAA+B;AAAA;AAAA,IAEnC,MAAA,CAAO,MAAA,EAAQ,CAAA,GAAA,MAAQ,EAAE,CAAC,YAAY,GAAG,GAAA,CAAI,IAAA,CAAK,QAAA,EAAS,CAAA,EAAI;AAAA,MAC7D,IAAA,EAAM,yBAAA;AAAA,MACN,QAAA,EAAU;AAAA,KACX;AAAA,GACH;AAGA,EAAA,IAAI,kBAAA,EAAoB;AACtB,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,QAAA,CAAS,UAAU,CAAA,GAAA,KAAO;AACxB,QAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,QAAA,OAAO,IAAA,GAAO,YAAY,CAAA,KAAM,GAAA,CAAI,IAAA,CAAK,QAAA;AAAA,MAC3C,CAAA,EAAG;AAAA,QACD,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,MACD,QAAA,CAAS,UAAU,CAAA,GAAA,KAAO;AACxB,QAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AAEjB,QAAA,IAAI,IAAA,GAAO,YAAY,CAAA,KAAM,MAAA,EAAW;AACtC,UAAA,OAAO,IAAA,CAAK,YAAY,CAAA,KAAM,GAAA,CAAI,IAAA,CAAK,QAAA;AAAA,QACzC;AACA,QAAA,OAAO,IAAA;AAAA,MACT,CAAA,EAAG;AAAA,QACD,IAAA,EAAM;AAAA,OACP;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,iBAAA;AAAA,IACN,WAAA,EAAa,aAAa,YAAY,CAAA,kBAAA,CAAA;AAAA,IACtC,QAAA;AAAA,IACA,IAAA,EAAM,CAAC,cAAA,EAAgB,WAAW;AAAA,GACpC;AACF;AAUO,SAAS,qBAAA,CAAsB,MAAA,GAA0B,EAAC,EAAmB;AAClF,EAAA,MAAM,EAAE,WAAA,GAAc,UAAA,EAAY,eAAA,GAAkB,CAAC,MAAA,EAAQ,QAAA,EAAU,QAAQ,CAAA,EAAG,SAAA,GAAY,IAAA,EAAK,GAAI,MAAA;AAEvG,EAAA,MAAM,WAA+B,EAAC;AAGtC,EAAA,MAAM,MAAM,eAAA,CAAgB,MAAA,CAAO,CAAA,EAAA,KAAM,EAAA,KAAO,YAAY,SAAS,CAAA;AAErE,EAAA,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG;AAClB,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,KAAA,CAAM,KAAK,CAAA,GAAA,KAAO;AAChB,QAAA,MAAM,MAAM,GAAA,CAAI,GAAA;AAChB,QAAA,OAAO,GAAA,CAAI,IAAA,CAAK,MAAA,KAAW,GAAA,GAAM,WAAW,CAAA;AAAA,MAC9C,CAAA,EAAG;AAAA,QACD,IAAA,EAAM;AAAA,OACP;AAAA,KACH;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,SAAA,IAAa,eAAA,CAAgB,QAAA,CAAS,QAAQ,CAAA,EAAG;AACpD,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,IAAA,CAAK,QAAA,EAAU,MAAM,IAAA,EAAM;AAAA,QACzB,IAAA,EAAM,qBAAA;AAAA,QACN,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,WAAA;AAAA,IACN,WAAA,EAAa,oBAAoB,WAAW,CAAA,CAAA;AAAA,IAC5C,QAAA;AAAA,IACA,IAAA,EAAM,CAAC,WAAW;AAAA,GACpB;AACF;AAUO,SAAS,sBAAA,CAAuB,MAAA,GAA2B,EAAC,EAAmB;AACpF,EAAA,MAAM,EAAE,aAAA,GAAgB,YAAA,EAAc,eAAe,IAAA,EAAM,iBAAA,GAAoB,MAAK,GAAI,MAAA;AAExF,EAAA,MAAM,WAA+B,EAAC;AAGtC,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,MAAA,CAAO,QAAQ,OAAO,EAAE,CAAC,aAAa,GAAG,MAAK,CAAA,EAAI;AAAA,QAChD,IAAA,EAAM,oBAAA;AAAA,QACN,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,EACF;AAGA,EAAA,IAAI,iBAAA,EAAmB;AACrB,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,IAAA,CAAK,QAAA,EAAU,MAAM,IAAA,EAAM;AAAA,QACzB,IAAA,EAAM,4BAAA;AAAA,QACN,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,YAAA;AAAA,IACN,WAAA,EAAa,mBAAmB,aAAa,CAAA,CAAA;AAAA,IAC7C,QAAA;AAAA,IACA,IAAA,EAAM,CAAC,aAAa;AAAA,GACtB;AACF;AAUO,SAAS,yBAAyB,MAAA,EAA4C;AACnF,EAAA,MAAM,EAAE,YAAA,GAAe,QAAA,EAAU,cAAA,GAAiB,EAAC,EAAG,gBAAA,GAAmB,EAAC,EAAG,iBAAA,GAAoB,EAAC,EAAE,GAAI,MAAA;AAExG,EAAA,MAAM,WAA+B,EAAC;AAGtC,EAAA,IAAI,cAAA,CAAe,SAAS,CAAA,EAAG;AAC7B,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,KAAA,CAAM,QAAQ,CAAA,GAAA,KAAO;AACnB,QAAA,MAAM,MAAM,GAAA,CAAI,GAAA;AAChB,QAAA,OAAO,cAAA,CAAe,QAAA,CAAS,GAAA,GAAM,YAAY,CAAW,CAAA;AAAA,MAC9D,CAAA,EAAG;AAAA,QACD,IAAA,EAAM;AAAA,OACP;AAAA,KACH;AAAA,EACF;AAGA,EAAA,IAAI,gBAAA,CAAiB,SAAS,CAAA,EAAG;AAC/B,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,IAAA,CAAK,UAAU,CAAA,GAAA,KAAO;AACpB,QAAA,MAAM,MAAM,GAAA,CAAI,GAAA;AAChB,QAAA,OAAO,CAAC,gBAAA,CAAiB,QAAA,CAAS,GAAA,GAAM,YAAY,CAAW,CAAA;AAAA,MACjE,CAAA,EAAG;AAAA,QACD,IAAA,EAAM,wBAAA;AAAA,QACN,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,EACF;AAGA,EAAA,IAAI,iBAAA,CAAkB,SAAS,CAAA,EAAG;AAChC,IAAA,QAAA,CAAS,IAAA;AAAA,MACP,IAAA,CAAK,UAAU,CAAA,GAAA,KAAO;AACpB,QAAA,MAAM,MAAM,GAAA,CAAI,GAAA;AAChB,QAAA,OAAO,CAAC,iBAAA,CAAkB,QAAA,CAAS,GAAA,GAAM,YAAY,CAAW,CAAA;AAAA,MAClE,CAAA,EAAG;AAAA,QACD,IAAA,EAAM,wBAAA;AAAA,QACN,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA,IACN,WAAA,EAAa,2BAA2B,YAAY,CAAA,CAAA;AAAA,IACpD,QAAA;AAAA,IACA,IAAA,EAAM,CAAC,QAAQ;AAAA,GACjB;AACF;AAUO,SAAS,kBAAkB,KAAA,EAAiC;AACjE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,aAAA;AAAA,IACN,WAAA,EAAa,CAAA,wBAAA,EAA2B,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,IACxD,QAAA,EAAU;AAAA,MACR,KAAA,CAAM,KAAA,EAAO,CAAA,GAAA,KAAO,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,KAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAA,EAAG;AAAA,QAC/D,IAAA,EAAM,cAAA;AAAA,QACN,QAAA,EAAU;AAAA,OACX;AAAA,KACH;AAAA,IACA,IAAA,EAAM,CAAC,OAAO;AAAA,GAChB;AACF;AAaO,SAAS,eAAA,CAAgB,MAAc,QAAA,EAA4C;AACxF,EAAA,MAAM,cAAkC,EAAC;AACzC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,IAAA,WAAA,CAAY,IAAA,CAAK,GAAG,MAAA,CAAO,QAAQ,CAAA;AACnC,IAAA,MAAA,CAAO,MAAM,OAAA,CAAQ,CAAA,GAAA,KAAO,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,EAC9C;AAEA,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,WAAA,EAAa,CAAA,eAAA,EAAkB,QAAA,CAAS,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,IACnE,QAAA,EAAU,WAAA;AAAA,IACV,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,OAAO;AAAA,GAC1B;AACF;AASO,SAAS,YAAA,CAAa,MAAsB,UAAA,EAAgD;AACjG,EAAA,MAAM,MAAA,GAAyB;AAAA,IAC7B,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,SAAA,CAAA;AAAA,IAClB,UAAU,CAAC,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,UAAU;AAAA,GAC5C;AAEA,EAAA,IAAI,IAAA,CAAK,gBAAgB,MAAA,EAAW;AAClC,IAAA,MAAA,CAAO,cAAc,IAAA,CAAK,WAAA;AAAA,EAC5B;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAW;AAC3B,IAAA,MAAA,CAAO,OAAO,IAAA,CAAK,IAAA;AAAA,EACrB;AAEA,EAAA,OAAO,MAAA;AACT;AASO,SAAS,cAAA,CACd,MACA,SAAA,EACgB;AAChB,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAA,MAAA,KAAU;AAC9C,IAAA,MAAM,WAAW,MAAA,CAAO,IAAA,GAAO,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA,GAAI,MAAA;AACxD,IAAA,OAAO,QAAA,IAAY,MAAA;AAAA,EACrB,CAAC,CAAA;AAED,EAAA,MAAM,MAAA,GAAyB;AAAA,IAC7B,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,WAAA,CAAA;AAAA,IAClB,QAAA,EAAU;AAAA,GACZ;AAEA,EAAA,IAAI,IAAA,CAAK,gBAAgB,MAAA,EAAW;AAClC,IAAA,MAAA,CAAO,cAAc,IAAA,CAAK,WAAA;AAAA,EAC5B;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAW;AAC3B,IAAA,MAAA,CAAO,OAAO,IAAA,CAAK,IAAA;AAAA,EACrB;AAEA,EAAA,OAAO,MAAA;AACT;;;AClHO,IAAM,sBAAN,MAAqD;AAAA,EAClD,OAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAsC,EAAC,EAAG;AACpD,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,MAAA,EAAQ,QAAQ,MAAA,IAAU,MAAA;AAAA,MAC1B,MAAA,EAAQ,QAAQ,MAAA,IAAU,IAAA;AAAA,MAC1B,gBAAA,EAAkB,QAAQ,gBAAA,IAAoB;AAAA,KAChD;AAAA,EACF;AAAA,EAEA,IAAI,KAAA,EAAqC;AACvC,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAQ;AAElC,MAAA,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,IACnC,CAAA,MAAO;AACL,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,QAAQ,CAAA;AAC5C,MAAA,MAAM,SAAA,GAAY,KAAK,OAAA,CAAQ,gBAAA,GAAmB,IAAI,KAAA,CAAM,SAAA,CAAU,WAAA,EAAa,CAAA,EAAA,CAAA,GAAO,EAAA;AAE1F,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,EAAG,SAAS,CAAA,EAAG,MAAM,QAAQ,KAAA,CAAM,QAAA,CAAS,WAAA,EAAa,KAAK,KAAA,CAAM,SAAS,CAAA,IAAA,EAAO,KAAA,CAAM,KAAK,CAAA,CAAA,IAC5F,KAAA,CAAM,UAAA,GAAa,CAAA,UAAA,EAAa,MAAM,UAAU,CAAA,CAAA,CAAA,GAAM,EAAA,CAAA,IACtD,KAAA,CAAM,SAAS,CAAA,GAAA,EAAM,KAAA,CAAM,MAAM,CAAA,CAAA,GAAK,OACtC,KAAA,CAAM,MAAA,GAAS,CAAA,QAAA,EAAW,KAAA,CAAM,MAAM,CAAA,CAAA,CAAA,GAAM,EAAA;AAAA,OACjD;AAAA,IACF;AACA,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA,EAEA,MAAM,SAAS,MAAA,EAAwC;AACrD,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,IAAA,CAAK,IAAI,KAAK,CAAA;AAAA,IACtB;AAAA,EACF;AAAA,EAEQ,UAAU,QAAA,EAAiC;AACjD,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ;AACxB,MAAA,OAAO,QAAA,KAAa,OAAA,GAAU,QAAA,GAAM,QAAA,KAAa,SAAS,QAAA,GAAM,GAAA;AAAA,IAClE;AAEA,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,OAAA;AACH,QAAA,OAAO,uBAAA;AAAA;AAAA,MACT,KAAK,MAAA;AACH,QAAA,OAAO,uBAAA;AAAA;AAAA,MACT,KAAK,QAAA;AACH,QAAA,OAAO,kBAAA;AAAA;AAAA,MACT;AACE,QAAA,OAAO,GAAA;AAAA;AACX,EACF;AACF;AAWO,IAAM,uBAAN,MAAsD;AAAA,EACnD,SAA0B,EAAC;AAAA,EAC3B,OAAA;AAAA,EAER,WAAA,CAAY,UAAU,GAAA,EAAO;AAC3B,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,IAAI,KAAA,EAAqC;AACvC,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAEtB,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,GAAS,IAAA,CAAK,OAAA,EAAS;AACrC,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAC,KAAK,OAAO,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA,EAEA,SAAS,MAAA,EAAwC;AAC/C,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,GAAG,MAAM,CAAA;AAC1B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,GAAS,IAAA,CAAK,OAAA,EAAS;AACrC,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAC,KAAK,OAAO,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA6B;AAC3B,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,MAAM,CAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,EAA2C;AAC/C,IAAA,IAAI,OAAA,GAAU,CAAC,GAAG,IAAA,CAAK,MAAM,CAAA;AAE7B,IAAA,IAAI,MAAA,CAAO,WAAW,MAAA,EAAW;AAC/B,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,KAAW,OAAO,MAAM,CAAA;AAAA,IAC1D;AACA,IAAA,IAAI,MAAA,CAAO,aAAa,MAAA,EAAW;AACjC,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,QAAA,KAAa,OAAO,QAAQ,CAAA;AAAA,IAC9D;AACA,IAAA,IAAI,OAAO,KAAA,EAAO;AAChB,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,KAAA,KAAU,OAAO,KAAK,CAAA;AAAA,IACxD;AACA,IAAA,IAAI,OAAO,SAAA,EAAW;AACpB,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAA,KAAc,OAAO,SAAS,CAAA;AAAA,IAChE;AACA,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,QAAA,KAAa,OAAO,QAAQ,CAAA;AAAA,IAC9D;AACA,IAAA,IAAI,OAAO,SAAA,EAAW;AACpB,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAA,IAAa,OAAO,SAAU,CAAA;AAAA,IAChE;AACA,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAA,GAAY,OAAO,OAAQ,CAAA;AAAA,IAC7D;AACA,IAAA,IAAI,OAAO,SAAA,EAAW;AACpB,MAAA,OAAA,GAAU,QAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAA,KAAc,OAAO,SAAS,CAAA;AAAA,IAChE;AAEA,IAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,MAAA,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA;AAAA,IACvC;AACA,IAAA,IAAI,OAAO,KAAA,EAAO;AAChB,MAAA,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA;AAAA,IACzC;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,MAAA,EAAsE;AAC7E,IAAA,IAAI,SAAS,IAAA,CAAK,MAAA;AAElB,IAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,MAAA,MAAA,GAAS,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAA,IAAa,OAAO,SAAU,CAAA;AAAA,IAC9D;AACA,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,MAAA,GAAS,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAA,GAAY,OAAO,OAAQ,CAAA;AAAA,IAC3D;AAEA,IAAA,MAAM,aAA4C,EAAE,KAAA,EAAO,GAAG,IAAA,EAAM,CAAA,EAAG,QAAQ,CAAA,EAAE;AACjF,IAAA,MAAM,WAAA,GAAyC,EAAE,IAAA,EAAM,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,GAAA,EAAK,CAAA,EAAE;AAClG,IAAA,MAAM,UAAkC,EAAC;AAEzC,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,UAAA,CAAW,MAAM,QAAQ,CAAA,EAAA;AACzB,MAAA,WAAA,CAAY,MAAM,SAAS,CAAA,EAAA;AAC3B,MAAA,OAAA,CAAQ,MAAM,KAAK,CAAA,GAAA,CAAK,QAAQ,KAAA,CAAM,KAAK,KAAK,CAAA,IAAK,CAAA;AAAA,IACvD;AAEA,IAAA,OAAO;AAAA,MACL,aAAa,MAAA,CAAO,MAAA;AAAA,MACpB,UAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAA,EAAW;AAAA,QACT,OAAO,MAAA,CAAO,CAAC,CAAA,EAAG,SAAA,wBAAiB,IAAA,EAAK;AAAA,QACxC,GAAA,EAAK,OAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA,EAAG,SAAA,wBAAiB,IAAA;AAAK;AACxD,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,SAAS,EAAC;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,KAAK,MAAA,CAAO,MAAA;AAAA,EACrB;AACF;;;AC3jBO,IAAM,cAAN,MAAkB;AAAA,EACf,OAAA;AAAA,EACA,MAAA;AAAA,EAIA,SAA0B,EAAC;AAAA,EAC3B,UAAA,GAAoC,IAAA;AAAA,EACpC,cAAA,GAAiB,KAAA;AAAA,EAEzB,YAAY,MAAA,EAAqB;AAC/B,IAAA,IAAA,CAAK,UAAU,MAAA,CAAO,OAAA;AACtB,IAAA,MAAM,UAAA,GAAa;AAAA,MACjB,OAAA,EAAS,OAAO,OAAA,IAAW,IAAA;AAAA,MAC3B,QAAA,EAAU,OAAO,QAAA,IAAY;AAAA,QAC3B,UAAA,EAAY,KAAA;AAAA,QACZ,SAAA,EAAW,IAAA;AAAA,QACX,UAAA,EAAY;AAAA,OACd;AAAA,MACA,MAAA,EAAQ,MAAA,CAAO,MAAA,IAAU,EAAC;AAAA,MAC1B,UAAA,EAAY,OAAO,UAAA,IAAc,GAAA;AAAA,MACjC,aAAA,EAAe,OAAO,aAAA,IAAiB,GAAA;AAAA,MACvC,KAAA,EAAO,OAAO,KAAA,IAAS,IAAA;AAAA,MACvB,UAAA,EAAY,OAAO,UAAA,IAAc;AAAA,KACnC;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA,CAAO,OAAA,KAAY,MAAA,GAC7B,EAAE,GAAG,UAAA,EAAY,OAAA,EAAS,MAAA,CAAO,OAAA,EAAQ,GACzC,UAAA;AAGJ,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,aAAA,GAAgB,CAAA,EAAG;AACjC,MAAA,IAAA,CAAK,eAAA,EAAgB;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,WAAA,CACJ,SAAA,EACA,KAAA,EACA,QAAA,EACA,YACA,OAAA,EAOe;AACf,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,KAAK,cAAA,EAAgB;AAC/C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,CAAK,OAAO,UAAA,GAAa,CAAA,IAAO,KAAK,MAAA,EAAO,GAAI,IAAA,CAAK,MAAA,CAAO,UAAA,EAAY;AAC1E,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,cAAA,CAAe,KAAK,CAAA;AAG7C,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,WAAW,CAAA,EAAG;AAC1C,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,GAAA,GAAM,WAAW,gBAAA,EAAiB;AAGxC,IAAA,MAAM,KAAA,GAAQ,KAAK,UAAA,CAAW,SAAA,EAAW,OAAO,QAAA,EAAU,UAAA,EAAY,GAAA,EAAK,WAAA,EAAa,OAAO,CAAA;AAG/F,IAAA,IAAI,YAAY,MAAA,IAAU,CAAC,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA,EAAG;AACpD,MAAA,KAAA,CAAM,QAAA,GAAW,IAAA;AACjB,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CACJ,SAAA,EACA,KAAA,EACA,YACA,OAAA,EAKe;AACf,IAAA,MAAM,KAAK,WAAA,CAAY,SAAA,EAAW,KAAA,EAAO,OAAA,EAAS,YAAY,OAAO,CAAA;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,CACJ,SAAA,EACA,KAAA,EACA,YACA,OAAA,EAKe;AACf,IAAA,MAAM,KAAK,WAAA,CAAY,SAAA,EAAW,KAAA,EAAO,MAAA,EAAQ,YAAY,OAAO,CAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,CACJ,KAAA,EACA,UAAA,EACA,OAAA,EAGe;AACf,IAAA,MAAM,KAAK,WAAA,CAAY,MAAA,EAAQ,KAAA,EAAO,QAAA,EAAU,YAAY,OAAO,CAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAC5B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,GAAG,IAAA,CAAK,MAAM,CAAA;AACrC,IAAA,IAAA,CAAK,SAAS,EAAC;AAEf,IAAA,IAAI;AACF,MAAA,IAAI,IAAA,CAAK,QAAQ,QAAA,EAAU;AACzB,QAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,aAAa,CAAA;AAAA,MAC3C,CAAA,MAAO;AACL,QAAA,KAAA,MAAW,SAAS,aAAA,EAAe;AACjC,UAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,aAAa,CAAA;AAAA,IAChG;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAEtB,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,aAAA,CAAc,KAAK,UAAU,CAAA;AAC7B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AAEA,IAAA,MAAM,KAAK,KAAA,EAAM;AACjB,IAAA,MAAM,IAAA,CAAK,QAAQ,KAAA,IAAQ;AAC3B,IAAA,MAAM,IAAA,CAAK,QAAQ,KAAA,IAAQ;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAA,GAAqB;AACvB,IAAA,OAAO,KAAK,MAAA,CAAO,MAAA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAA,GAAmB;AACrB,IAAA,OAAO,KAAK,MAAA,CAAO,OAAA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAA,EAAwB;AACjC,IAAA,IAAA,CAAK,OAAO,OAAA,GAAU,OAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,eAAe,KAAA,EAAiC;AACtD,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAC9C,IAAA,OAAO;AAAA,MACL,GAAG,KAAK,MAAA,CAAO,QAAA;AAAA,MACf,GAAG,aAAA;AAAA,MACH,OAAA,EAAS,eAAe,OAAA,IAAW;AAAA,KACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAA,CAAU,UAAyB,WAAA,EAAwC;AACjF,IAAA,IAAI,CAAC,YAAY,OAAA,EAAS;AACxB,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,OAAA;AACH,QAAA,OAAO,YAAY,UAAA,IAAc,KAAA;AAAA,MACnC,KAAK,MAAA;AACH,QAAA,OAAO,YAAY,SAAA,IAAa,IAAA;AAAA,MAClC,KAAK,QAAA;AACH,QAAA,OAAO,YAAY,UAAA,IAAc,KAAA;AAAA,MACnC;AACE,QAAA,OAAO,KAAA;AAAA;AACX,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,WACN,SAAA,EACA,KAAA,EACA,UACA,UAAA,EACA,GAAA,EACA,aACA,OAAA,EAOe;AACf,IAAA,MAAM,KAAA,GAAuB;AAAA,MAC3B,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB,MAAA,EAAQ,GAAA,EAAK,IAAA,CAAK,MAAA,IAAU,WAAA;AAAA,MAC5B,SAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF;AAGA,IAAA,IAAI,GAAA,EAAK,IAAA,CAAK,QAAA,KAAa,MAAA,EAAW;AACpC,MAAA,KAAA,CAAM,QAAA,GAAW,IAAI,IAAA,CAAK,QAAA;AAAA,IAC5B;AAGA,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,KAAA,CAAM,UAAA,GAAa,UAAA;AAAA,IACrB;AAGA,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AAAA,IACzB;AACA,IAAA,IAAI,OAAA,EAAS,MAAA,IAAU,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAG;AAChD,MAAA,KAAA,CAAM,SAAS,OAAA,CAAQ,MAAA;AAAA,IACzB;AACA,IAAA,IAAI,SAAS,SAAA,EAAW;AACtB,MAAA,KAAA,CAAM,YAAY,OAAA,CAAQ,SAAA;AAAA,IAC5B;AACA,IAAA,IAAI,OAAA,EAAS,eAAe,MAAA,EAAW;AACrC,MAAA,KAAA,CAAM,aAAa,OAAA,CAAQ,UAAA;AAAA,IAC7B;AAGA,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,IAAI,GAAA,CAAI,QAAQ,SAAA,EAAW;AACzB,QAAA,KAAA,CAAM,SAAA,GAAY,IAAI,OAAA,CAAQ,SAAA;AAAA,MAChC;AACA,MAAA,IAAI,GAAA,CAAI,QAAQ,SAAA,EAAW;AACzB,QAAA,KAAA,CAAM,SAAA,GAAY,IAAI,OAAA,CAAQ,SAAA;AAAA,MAChC;AACA,MAAA,IAAI,GAAA,CAAI,QAAQ,SAAA,EAAW;AACzB,QAAA,KAAA,CAAM,SAAA,GAAY,IAAI,OAAA,CAAQ,SAAA;AAAA,MAChC;AAAA,IACF;AAGA,IAAA,MAAM,UAAU,IAAA,CAAK,YAAA,CAAa,GAAA,EAAK,WAAA,EAAa,SAAS,OAAO,CAAA;AACpE,IAAA,IAAI,YAAY,MAAA,EAAW;AACzB,MAAA,KAAA,CAAM,OAAA,GAAU,OAAA;AAAA,IAClB;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAA,CACN,GAAA,EACA,WAAA,EACA,iBAAA,EACqC;AACrC,IAAA,MAAM,UAAmC,EAAC;AAG1C,IAAA,IAAI,KAAK,IAAA,CAAK,KAAA,IAAS,IAAI,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,EAAG;AAChD,MAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,GAAA,CAAI,IAAA,CAAK,KAAA;AAAA,IAC9B;AAGA,IAAA,IAAI,KAAK,IAAA,CAAK,eAAA,IAAmB,IAAI,IAAA,CAAK,eAAA,CAAgB,SAAS,CAAA,EAAG;AACpE,MAAA,OAAA,CAAQ,iBAAiB,CAAA,GAAI,GAAA,CAAI,IAAA,CAAK,eAAA;AAAA,IACxC;AAGA,IAAA,IAAI,GAAA,EAAK,IAAA,IAAQ,OAAO,GAAA,CAAI,SAAS,QAAA,EAAU;AAC7C,MAAA,MAAA,CAAO,MAAA,CAAO,OAAA,EAAS,GAAA,CAAI,IAAI,CAAA;AAAA,IACjC;AAGA,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,MAAA,CAAO,MAAA,CAAO,SAAS,iBAAiB,CAAA;AAAA,IAC1C;AAGA,IAAA,IAAI,eAAA,GAAkB,OAAA;AAEtB,IAAA,IAAI,WAAA,CAAY,cAAA,IAAkB,WAAA,CAAY,cAAA,CAAe,SAAS,CAAA,EAAG;AACvE,MAAA,eAAA,GAAkB,EAAC;AACnB,MAAA,KAAA,MAAW,GAAA,IAAO,YAAY,cAAA,EAAgB;AAC5C,QAAA,IAAI,OAAO,OAAA,EAAS;AAClB,UAAA,eAAA,CAAgB,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAG,CAAA;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,cAAA,IAAkB,WAAA,CAAY,cAAA,CAAe,SAAS,CAAA,EAAG;AACvE,MAAA,KAAA,MAAW,GAAA,IAAO,YAAY,cAAA,EAAgB;AAE5C,QAAA,MAAM,EAAE,CAAC,GAAG,GAAG,CAAA,EAAG,GAAG,MAAK,GAAI,eAAA;AAC9B,QAAA,eAAA,GAAkB,IAAA;AAAA,MACpB;AAAA,IACF;AAEA,IAAA,OAAO,OAAO,IAAA,CAAK,eAAe,CAAA,CAAE,MAAA,GAAS,IAAI,eAAA,GAAkB,MAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,SAAS,KAAA,EAAqC;AAC1D,IAAA,IAAI,KAAK,MAAA,CAAO,KAAA,IAAS,IAAA,CAAK,MAAA,CAAO,aAAa,CAAA,EAAG;AAEnD,MAAA,IAAA,CAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAEtB,MAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,IAAU,IAAA,CAAK,OAAO,UAAA,EAAY;AAEhD,QAAA,MAAM,KAAK,KAAA,EAAM;AAAA,MACnB;AAAA,IACF,CAAA,MAAA,IAAW,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO;AAE5B,MAAA,IAAA,CAAK,QAAQ,GAAA,CAAI,KAAK,CAAA,CAAE,KAAA,CAAM,CAAC,KAAA,KAAmB;AAChD,QAAA,IAAA,CAAK,MAAA,CAAO,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAAA,MAC1F,CAAC,CAAA;AAAA,IACH,CAAA,MAAO;AAEL,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AAAA,MAC9B,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,MAAA,CAAO,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAA,GAAwB;AAC9B,IAAA,IAAA,CAAK,UAAA,GAAa,YAAY,MAAM;AAClC,MAAA,IAAA,CAAK,KAAA,EAAM,CAAE,KAAA,CAAM,CAAC,KAAA,KAAmB;AACrC,QAAA,IAAA,CAAK,MAAA,CAAO,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,QAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,CAAC,GAAG,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,MACnG,CAAC,CAAA;AAAA,IACH,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,aAAa,CAAA;AAG5B,IAAA,IAAI,IAAA,CAAK,WAAW,KAAA,EAAO;AACzB,MAAA,IAAA,CAAK,WAAW,KAAA,EAAM;AAAA,IACxB;AAAA,EACF;AACF;AASO,SAAS,kBAAkB,MAAA,EAAkC;AAClE,EAAA,OAAO,IAAI,YAAY,MAAM,CAAA;AAC/B;;;ACnUO,IAAM,eAAN,MAAiC;AAAA,EAC9B,QAAA;AAAA,EAER,YAAY,MAAA,EAAuB;AACjC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,cAAA,CAAmB,MAAM,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAA,CACJ,KAAA,EACA,SAAA,EACA,OAAA,EACiC;AACjC,IAAA,MAAM,oBAAiE,EAAC;AAGxE,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG;AAClC,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,YAAA,EAAc,SAAA;AAAA,QACd,MAAA,EAAQ,2BAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAGA,IAAA,IAAI,OAAA,CAAQ,KAAK,QAAA,EAAU;AACzB,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,YAAA,EAAc,OAAA;AAAA,QACd,MAAA,EAAQ,0BAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC9C,IAAA,IAAI,OAAA,CAAQ,KAAK,CAAA,IAAA,KAAQ,OAAA,CAAQ,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AAC3D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,YAAA,EAAc,OAAA;AAAA,QACd,MAAA,EAAQ,CAAA,aAAA,EAAgB,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAA,KAAK,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA,CAAA;AAAA,QACzE;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,OAAA,GAAmC;AAAA,MACvC,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,KAAK,OAAA,CAAQ,GAAA;AAAA,MACb,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,KAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAI,OAAA,CAAQ,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,QAAQ,IAAA;AAAK,KACzD;AAGA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,OAAO,SAAS,CAAA;AACvD,IAAA,KAAA,MAAWH,SAAQ,MAAA,EAAQ;AACzB,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,OAAM,OAAO,CAAA;AACtD,MAAA,iBAAA,CAAkB,IAAA,CAAK;AAAA,QACrB,MAAMA,KAAAA,CAAK,IAAA;AAAA,QACX,IAAA,EAAM,MAAA;AAAA,QACN;AAAA,OACD,CAAA;AAED,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,YAAYA,KAAAA,CAAK,IAAA;AAAA,UACjB,YAAA,EAAc,MAAA;AAAA,UACd,MAAA,EAAQ,CAAA,kBAAA,EAAqBA,KAAAA,CAAK,IAAI,CAAA,CAAA;AAAA,UACtC;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,QAAA,KAAa,QAAQ,IAAA,EAAM;AACtE,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,OAAO,SAAS,CAAA;AAC7D,MAAA,KAAA,MAAWC,aAAY,SAAA,EAAW;AAChC,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,WAAU,OAAO,CAAA;AAC1D,QAAA,iBAAA,CAAkB,IAAA,CAAK;AAAA,UACrB,MAAMA,SAAAA,CAAS,IAAA;AAAA,UACf,IAAA,EAAM,UAAA;AAAA,UACN;AAAA,SACD,CAAA;AAED,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,KAAA;AAAA,YACT,YAAYA,SAAAA,CAAS,IAAA;AAAA,YACrB,YAAA,EAAc,MAAA;AAAA,YACd,MAAA,EAAQ,CAAA,mBAAA,EAAsBA,SAAAA,CAAS,IAAI,CAAA,CAAA;AAAA,YAC3C;AAAA,WACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,OAAO,SAAS,CAAA;AACvD,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,QAAA,CAAS,cAAA,CAAe,KAAK,CAAA;AAEtD,IAAA,IAAI,WAAA,IAAe,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AACtC,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,YAAA,EAAc,SAAA;AAAA,QACd,MAAA,EAAQ,0CAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,KAAA,MAAWF,UAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,QAAO,OAAO,CAAA;AACvD,MAAA,iBAAA,CAAkB,IAAA,CAAK;AAAA,QACrB,MAAMA,MAAAA,CAAM,IAAA;AAAA,QACZ,IAAA,EAAM,OAAA;AAAA,QACN;AAAA,OACD,CAAA;AAED,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,YAAYA,MAAAA,CAAM,IAAA;AAAA,UAClB,YAAA,EAAc,OAAA;AAAA,UACd,MAAA,EAAQ,CAAA,mBAAA,EAAsBA,MAAAA,CAAM,IAAI,CAAA,CAAA;AAAA,UACxC;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,YAAA,EAAc,SAAA;AAAA,QACd,MAAA,EAAQ,0CAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,YAAA,EAAc,SAAA;AAAA,MACd,MAAA,EAAQ,qCAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,UAAA,CACE,KAAA,EACA,UAAA,EACA,OAAA,EACwB;AACxB,IAAA,MAAM,aAAsC,EAAC;AAC7C,IAAA,MAAM,iBAA2B,EAAC;AAGlC,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG;AAClC,MAAA,OAAO,EAAE,YAAY,cAAA,EAAe;AAAA,IACtC;AAGA,IAAA,IAAI,OAAA,CAAQ,KAAK,QAAA,EAAU;AACzB,MAAA,OAAO,EAAE,YAAY,cAAA,EAAe;AAAA,IACtC;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAC9C,IAAA,IAAI,OAAA,CAAQ,KAAK,CAAA,IAAA,KAAQ,OAAA,CAAQ,KAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG;AAC3D,MAAA,OAAO,EAAE,YAAY,cAAA,EAAe;AAAA,IACtC;AAGA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA;AAG9C,IAAA,MAAM,OAAA,GAAmC;AAAA,MACvC,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,GAAI,OAAA,CAAQ,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,QAAQ,IAAA;AAAK,KACzD;AAGA,IAAA,KAAA,MAAWG,WAAU,OAAA,EAAS;AAC5B,MAAA,MAAM,gBAAA,GAAmBA,OAAAA,CAAO,aAAA,CAAc,OAAO,CAAA;AACrD,MAAA,MAAA,CAAO,MAAA,CAAO,YAAY,gBAAgB,CAAA;AAC1C,MAAA,cAAA,CAAe,IAAA,CAAKA,QAAO,IAAI,CAAA;AAAA,IACjC;AAEA,IAAA,OAAO,EAAE,YAAY,cAAA,EAAe;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,UAAA,CACJ,KAAA,EACA,UAAA,EACA,OAAA,EAC+C;AAE/C,IAAA,MAAM,UAAA,GAA0B,CAAC,MAAA,EAAQ,QAAA,EAAU,UAAU,QAAQ,CAAA;AAErE,IAAA,KAAA,MAAW,MAAM,UAAA,EAAY;AAE3B,MAAA,MAAM,OAAA,GAAmC;AAAA,QACvC,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,KAAK,OAAA,CAAQ,GAAA;AAAA,QACb,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,KAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,QACX,GAAI,OAAA,CAAQ,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,QAAQ,IAAA;AAAK,OACzD;AAGA,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,OAAO,EAAE,CAAA;AAChD,MAAA,MAAMH,SAAQ,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,UAAU,CAAA;AACpD,MAAA,IAAIA,MAAAA,EAAO;AACT,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,QAAO,OAAO,CAAA;AACvD,QAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAO;AAAA,MAC/B;AAGA,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,OAAO,EAAE,CAAA;AAChD,MAAA,MAAMC,QAAO,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,UAAU,CAAA;AACnD,MAAA,IAAIA,KAAAA,EAAM;AACR,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,OAAM,OAAO,CAAA;AACtD,QAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAO;AAAA,MAC/B;AAGA,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,OAAO,EAAE,CAAA;AACtD,MAAA,MAAMC,YAAW,SAAA,CAAU,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,UAAU,CAAA;AAC1D,MAAA,IAAIA,SAAAA,EAAU;AACZ,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAeA,WAAU,OAAO,CAAA;AAC1D,QAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAO;AAAA,MAC/B;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,OAAO,KAAA,EAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAAA,EAKX;AACA,IAAA,MAAM,UAAA,GAA0B,CAAC,MAAA,EAAQ,QAAA,EAAU,UAAU,QAAQ,CAAA;AACrE,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,IAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AAEpC,IAAA,KAAA,MAAW,MAAM,UAAA,EAAY;AAC3B,MAAA,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,KAAA,EAAO,EAAE,CAAA,CAAE,OAAA,CAAQ,CAAA,CAAA,KAAK,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AACpE,MAAA,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,KAAA,EAAO,EAAE,CAAA,CAAE,OAAA,CAAQ,CAAA,CAAA,KAAK,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AACnE,MAAA,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,KAAA,EAAO,EAAE,CAAA,CAAE,OAAA,CAAQ,CAAA,CAAA,KAAK,WAAA,CAAY,GAAA,CAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC5E;AAEA,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC3B,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAAA,MAC1B,OAAA,EAAS,KAAK,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAA;AAAA,MACxD,SAAA,EAAW,KAAA,CAAM,IAAA,CAAK,WAAW;AAAA,KACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAAsB;AACpB,IAAA,OAAO,IAAA,CAAK,SAAS,SAAA,EAAU;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAAA,CACZ,MAAA,EACA,GAAA,EACkB;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA;AAClC,MAAA,OAAO,MAAA,YAAkB,OAAA,GAAU,MAAM,MAAA,GAAS,MAAA;AAAA,IACpD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AACF;AAYO,SAAS,mBAAiC,MAAA,EAAyC;AACxF,EAAA,OAAO,IAAI,aAAiB,MAAM,CAAA;AACpC;AAYO,SAAS,sBACd,SAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACL,OAAO,EAAC;AAAA,IACR,QAAA,EAAU,KAAA;AAAA,IACV,GAAG;AAAA,GACL;AACF;AAQO,SAAS,cAAiD,IAAA,EAAY;AAC3E,EAAA,OAAO,EAAE,GAAG,IAAA,EAAK;AACnB;AAKO,IAAM,gBAAA,GAAmB;AAAA;AAAA;AAAA;AAAA,EAI9B,aAAA,CAAc,QAAgC,OAAA,EAAwB;AACpE,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,OAAA,IAAW,CAAA,0CAAA,EAA6C,MAAA,CAAO,MAAM,CAAA;AAAA,OACvE;AAAA,IACF;AAAA,EACF,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,CAAa,QAAgC,OAAA,EAAwB;AACnE,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,OAAA,IAAW,CAAA,0CAAA,EAA6C,MAAA,CAAO,MAAM,CAAA;AAAA,OACvE;AAAA,IACF;AAAA,EACF,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAA,CAAiB,MAAA,EAAgC,UAAA,EAAoB,OAAA,EAAwB;AAC3F,IAAA,IAAI,MAAA,CAAO,eAAe,UAAA,EAAY;AACpC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,OAAA,IAAW,CAAA,iBAAA,EAAoB,UAAU,CAAA,WAAA,EAAc,OAAO,UAAU,CAAA,CAAA;AAAA,OAC1E;AAAA,IACF;AAAA,EACF,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAA,CACE,MAAA,EACA,QAAA,EACA,OAAA,EACM;AACN,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACnD,MAAA,IAAI,MAAA,CAAO,UAAA,CAAW,GAAG,CAAA,KAAM,KAAA,EAAO;AACpC,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,OAAA,IACE,CAAA,0BAAA,EAA6B,GAAG,CAAA,CAAA,EAAI,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,SAAA,EAAY,KAAK,SAAA,CAAU,MAAA,CAAO,UAAA,CAAW,GAAG,CAAC,CAAC,CAAA;AAAA,SAC/G;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF","file":"index.js","sourcesContent":["/**\n * RLS Error Classes\n *\n * This module provides specialized error classes for Row-Level Security operations.\n * All errors extend base error classes from @kysera/core for consistency across\n * the Kysera ecosystem.\n *\n * @module @kysera/rls/errors\n */\n\nimport { DatabaseError } from '@kysera/core'\nimport type { ErrorCode } from '@kysera/core'\n\n// ============================================================================\n// RLS Error Codes\n// ============================================================================\n\n/**\n * RLS-specific error codes\n *\n * These codes extend the unified error codes from @kysera/core with\n * RLS-specific error conditions.\n */\nexport const RLSErrorCodes = {\n /** RLS context is missing or not set */\n RLS_CONTEXT_MISSING: 'RLS_CONTEXT_MISSING' as ErrorCode,\n /** RLS policy violation occurred */\n RLS_POLICY_VIOLATION: 'RLS_POLICY_VIOLATION' as ErrorCode,\n /** RLS policy definition is invalid */\n RLS_POLICY_INVALID: 'RLS_POLICY_INVALID' as ErrorCode,\n /** RLS schema definition is invalid */\n RLS_SCHEMA_INVALID: 'RLS_SCHEMA_INVALID' as ErrorCode,\n /** RLS context validation failed */\n RLS_CONTEXT_INVALID: 'RLS_CONTEXT_INVALID' as ErrorCode,\n /** RLS policy evaluation threw an error */\n RLS_POLICY_EVALUATION_ERROR: 'RLS_POLICY_EVALUATION_ERROR' as ErrorCode\n} as const\n\n/**\n * Type for RLS error codes\n */\nexport type RLSErrorCode = (typeof RLSErrorCodes)[keyof typeof RLSErrorCodes]\n\n// ============================================================================\n// Base RLS Error\n// ============================================================================\n\n/**\n * Base class for all RLS-related errors\n *\n * Extends DatabaseError from @kysera/core for consistency with other Kysera packages.\n * Provides common error functionality including error codes and JSON serialization.\n *\n * @example\n * ```typescript\n * throw new RLSError('Something went wrong', RLSErrorCodes.RLS_POLICY_INVALID);\n * ```\n */\nexport class RLSError extends DatabaseError {\n /**\n * Creates a new RLS error\n *\n * @param message - Error message\n * @param code - RLS error code\n */\n constructor(message: string, code: RLSErrorCode) {\n super(message, code)\n this.name = 'RLSError'\n }\n}\n\n// ============================================================================\n// Context Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS context is missing\n *\n * This error occurs when an operation requiring RLS context is executed\n * outside of a context scope (i.e., without calling withRLSContext()).\n *\n * @example\n * ```typescript\n * // This will throw RLSContextError\n * const result = await db.selectFrom('posts').execute();\n *\n * // Correct usage with context\n * await withRLSContext(rlsContext, async () => {\n * const result = await db.selectFrom('posts').execute();\n * });\n * ```\n */\nexport class RLSContextError extends RLSError {\n /**\n * Creates a new RLS context error\n *\n * @param message - Error message (defaults to standard message)\n */\n constructor(message = 'No RLS context found. Ensure code runs within withRLSContext()') {\n super(message, RLSErrorCodes.RLS_CONTEXT_MISSING)\n this.name = 'RLSContextError'\n }\n}\n\n/**\n * Error thrown when RLS context validation fails\n *\n * Extends RLSError as context validation failures are RLS-specific errors.\n *\n * This error occurs when the provided RLS context is invalid or missing\n * required fields.\n *\n * @example\n * ```typescript\n * // Missing required userId field\n * const invalidContext = {\n * auth: {\n * roles: ['user']\n * // userId is missing!\n * },\n * timestamp: new Date()\n * };\n *\n * // This will throw RLSContextValidationError\n * validateRLSContext(invalidContext);\n * ```\n */\nexport class RLSContextValidationError extends RLSError {\n public readonly field: string\n\n /**\n * Creates a new context validation error\n *\n * @param message - Error message\n * @param field - Field that failed validation\n */\n constructor(message: string, field: string) {\n super(message, RLSErrorCodes.RLS_CONTEXT_INVALID)\n this.name = 'RLSContextValidationError'\n this.field = field\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n field: this.field\n }\n }\n}\n\n// ============================================================================\n// Policy Errors\n// ============================================================================\n\n/**\n * Error thrown when an RLS policy violation occurs\n *\n * This error is thrown when a database operation is denied by RLS policies.\n * It provides detailed information about the violation including the operation,\n * table, and reason for denial.\n *\n * @example\n * ```typescript\n * // User tries to update a post they don't own\n * throw new RLSPolicyViolation(\n * 'update',\n * 'posts',\n * 'User does not own this post',\n * 'ownership_policy'\n * );\n * ```\n */\nexport class RLSPolicyViolation extends RLSError {\n public readonly operation: string\n public readonly table: string\n public readonly reason: string\n public readonly policyName?: string\n\n /**\n * Creates a new policy violation error\n *\n * @param operation - Database operation that was denied (read, create, update, delete)\n * @param table - Table name where violation occurred\n * @param reason - Reason for the policy violation\n * @param policyName - Name of the policy that denied access (optional)\n */\n constructor(operation: string, table: string, reason: string, policyName?: string) {\n super(\n `RLS policy violation: ${operation} on ${table} - ${reason}`,\n RLSErrorCodes.RLS_POLICY_VIOLATION\n )\n this.name = 'RLSPolicyViolation'\n this.operation = operation\n this.table = table\n this.reason = reason\n if (policyName !== undefined) {\n this.policyName = policyName\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n ...super.toJSON(),\n operation: this.operation,\n table: this.table,\n reason: this.reason\n }\n if (this.policyName !== undefined) {\n json['policyName'] = this.policyName\n }\n return json\n }\n}\n\n// ============================================================================\n// Policy Evaluation Errors\n// ============================================================================\n\n/**\n * Error thrown when a policy condition throws an error during evaluation\n *\n * This error is distinct from RLSPolicyViolation - it indicates a bug in the\n * policy condition function itself, not a legitimate access denial.\n *\n * @example\n * ```typescript\n * // A policy with a bug\n * allow('read', ctx => {\n * return ctx.row.someField.value; // Throws if someField is undefined\n * });\n *\n * // This will throw RLSPolicyEvaluationError, not RLSPolicyViolation\n * ```\n */\nexport class RLSPolicyEvaluationError extends RLSError {\n public readonly operation: string\n public readonly table: string\n public readonly policyName?: string\n public readonly originalError?: Error\n\n /**\n * Creates a new policy evaluation error\n *\n * @param operation - Database operation being performed\n * @param table - Table name where error occurred\n * @param message - Error message from the policy\n * @param policyName - Name of the policy that threw\n * @param originalError - The original error thrown by the policy\n */\n constructor(\n operation: string,\n table: string,\n message: string,\n policyName?: string,\n originalError?: Error\n ) {\n super(\n `RLS policy evaluation error during ${operation} on ${table}: ${message}`,\n RLSErrorCodes.RLS_POLICY_EVALUATION_ERROR\n )\n this.name = 'RLSPolicyEvaluationError'\n this.operation = operation\n this.table = table\n if (policyName !== undefined) {\n this.policyName = policyName\n }\n if (originalError !== undefined) {\n this.originalError = originalError\n // Preserve the original stack trace for debugging\n if (originalError.stack) {\n this.stack = `${this.stack}\\n\\nCaused by:\\n${originalError.stack}`\n }\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n ...super.toJSON(),\n operation: this.operation,\n table: this.table\n }\n if (this.policyName !== undefined) {\n json['policyName'] = this.policyName\n }\n if (this.originalError !== undefined) {\n json['originalError'] = {\n name: this.originalError.name,\n message: this.originalError.message\n }\n }\n return json\n }\n}\n\n// ============================================================================\n// Schema Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS schema validation fails\n *\n * Extends RLSError as schema validation failures are RLS-specific errors.\n *\n * This error occurs when the RLS schema definition is invalid or contains\n * configuration errors.\n *\n * @example\n * ```typescript\n * // Invalid policy definition\n * const invalidSchema = {\n * posts: {\n * policies: [\n * {\n * type: 'invalid-type', // Invalid policy type!\n * operation: 'read',\n * condition: (ctx) => true\n * }\n * ]\n * }\n * };\n *\n * // This will throw RLSSchemaError\n * validateRLSSchema(invalidSchema);\n * ```\n */\nexport class RLSSchemaError extends RLSError {\n public readonly details: Record<string, unknown>\n\n /**\n * Creates a new schema validation error\n *\n * @param message - Error message\n * @param details - Additional details about the validation failure\n */\n constructor(message: string, details: Record<string, unknown> = {}) {\n super(message, RLSErrorCodes.RLS_SCHEMA_INVALID)\n this.name = 'RLSSchemaError'\n this.details = details\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n details: this.details\n }\n }\n}\n","/**\n * RLS schema definition and validation\n *\n * Provides functions to define, validate, and merge RLS schemas.\n */\n\nimport type { RLSSchema, TableRLSConfig, PolicyDefinition } from './types.js'\nimport { RLSSchemaError } from '../errors.js'\n\n/**\n * Define RLS schema with full type safety\n *\n * @example\n * ```typescript\n * interface Database {\n * users: { id: number; email: string; tenant_id: number };\n * posts: { id: number; user_id: number; tenant_id: number };\n * }\n *\n * const schema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * // Users can read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * // Filter by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Admins bypass all checks\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * posts: {\n * policies: [\n * // Filter posts by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Users can only edit their own posts\n * allow(['update', 'delete'], ctx => ctx.auth.userId === ctx.row.user_id),\n * // Validate new posts belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * defaultDeny: true, // Require explicit allow\n * },\n * });\n * ```\n */\nexport function defineRLSSchema<DB>(schema: RLSSchema<DB>): RLSSchema<DB> {\n // Validate schema\n validateSchema(schema)\n return schema\n}\n\n/**\n * Validate RLS schema\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validateSchema<DB>(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n\n const tableConfig = config as TableRLSConfig\n\n if (!Array.isArray(tableConfig.policies)) {\n throw new RLSSchemaError(`Invalid policies for table \"${table}\": must be an array`, { table })\n }\n\n // Validate each policy\n for (let i = 0; i < tableConfig.policies.length; i++) {\n const policy = tableConfig.policies[i]\n if (policy !== undefined) {\n validatePolicy(policy, table, i)\n }\n }\n\n // Validate skipFor if present (array of role names that bypass RLS)\n if (tableConfig.skipFor !== undefined) {\n if (!Array.isArray(tableConfig.skipFor)) {\n throw new RLSSchemaError(\n `Invalid skipFor for table \"${table}\": must be an array of role names`,\n { table }\n )\n }\n\n // skipFor contains role names (strings), not operations\n for (const role of tableConfig.skipFor) {\n if (typeof role !== 'string' || role.trim() === '') {\n throw new RLSSchemaError(\n `Invalid role in skipFor for table \"${table}\": must be a non-empty string`,\n { table }\n )\n }\n }\n }\n\n // Validate defaultDeny if present\n if (tableConfig.defaultDeny !== undefined && typeof tableConfig.defaultDeny !== 'boolean') {\n throw new RLSSchemaError(`Invalid defaultDeny for table \"${table}\": must be a boolean`, {\n table\n })\n }\n }\n}\n\n/**\n * Validate a single policy\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validatePolicy(policy: PolicyDefinition, table: string, index: number): void {\n if (!policy.type) {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" missing type`, { table, index })\n }\n\n const validTypes = ['allow', 'deny', 'filter', 'validate']\n if (!validTypes.includes(policy.type)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid type: ${policy.type}`,\n { table, index, type: policy.type }\n )\n }\n\n if (!policy.operation) {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" missing operation`, {\n table,\n index\n })\n }\n\n const validOps = ['read', 'create', 'update', 'delete', 'all']\n const ops = Array.isArray(policy.operation) ? policy.operation : [policy.operation]\n\n for (const op of ops) {\n if (!validOps.includes(op)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid operation: ${op}`,\n { table, index, operation: op }\n )\n }\n }\n\n if (policy.condition === undefined || policy.condition === null) {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" missing condition`, {\n table,\n index\n })\n }\n\n if (typeof policy.condition !== 'function' && typeof policy.condition !== 'string') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" condition must be a function or string`,\n { table, index }\n )\n }\n\n // Validate priority if present\n if (policy.priority !== undefined && typeof policy.priority !== 'number') {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" priority must be a number`, {\n table,\n index\n })\n }\n\n // Validate name if present\n if (policy.name !== undefined && typeof policy.name !== 'string') {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" name must be a string`, {\n table,\n index\n })\n }\n}\n\n/**\n * Merge multiple RLS schemas\n * Later schemas override earlier ones for the same table\n *\n * @example\n * ```typescript\n * const baseSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * },\n * });\n *\n * const adminSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * });\n *\n * // Merged schema will have both filters and admin allow\n * const merged = mergeRLSSchemas(baseSchema, adminSchema);\n * ```\n */\nexport function mergeRLSSchemas<DB>(...schemas: RLSSchema<DB>[]): RLSSchema<DB> {\n const merged: RLSSchema<DB> = {}\n\n for (const schema of schemas) {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n\n const existingConfig = merged[table as keyof DB]\n const newConfig = config as TableRLSConfig\n\n if (existingConfig) {\n // Merge policies (append new policies)\n existingConfig.policies = [...existingConfig.policies, ...newConfig.policies]\n\n // Merge skipFor (combine arrays and deduplicate)\n if (newConfig.skipFor) {\n const existingSkipFor = existingConfig.skipFor ?? []\n const combinedSkipFor = [...existingSkipFor, ...newConfig.skipFor]\n existingConfig.skipFor = Array.from(new Set(combinedSkipFor))\n }\n\n // Override defaultDeny if explicitly set in new config\n if (newConfig.defaultDeny !== undefined) {\n existingConfig.defaultDeny = newConfig.defaultDeny\n }\n } else {\n // Deep copy the config to avoid mutation\n // Type cast necessary: TypeScript cannot infer that the spread object matches\n // the TableRLSConfig type exactly due to optional properties and type narrowing.\n // Runtime safety: We've validated the schema structure via validateSchema(),\n // and we're creating a proper TableRLSConfig from validated components.\n\n merged[table as keyof DB] = {\n policies: [...newConfig.policies],\n skipFor: newConfig.skipFor ? [...newConfig.skipFor] : undefined,\n defaultDeny: newConfig.defaultDeny\n } as TableRLSConfig\n }\n }\n }\n\n // Validate merged schema\n validateSchema(merged)\n\n return merged\n}\n","/**\n * Fluent policy builders for Row-Level Security\n *\n * Provides intuitive builder functions for creating RLS policies:\n * - allow: Grants access when condition is true\n * - deny: Blocks access when condition is true (overrides allow)\n * - filter: Adds WHERE conditions to SELECT queries\n * - validate: Validates mutation data before execution\n */\n\nimport type {\n Operation,\n PolicyCondition,\n FilterCondition,\n PolicyHints,\n PolicyActivationCondition,\n ConditionalPolicyDefinition\n} from './types.js'\n\n/**\n * Options for policy definitions\n */\nexport interface PolicyOptions {\n /** Policy name for debugging and identification */\n name?: string\n /** Priority (higher runs first, deny policies default to 100) */\n priority?: number\n /** Performance optimization hints */\n hints?: PolicyHints\n /**\n * Condition that determines if this policy is active\n * The policy will only be evaluated if this returns true\n *\n * @example\n * ```typescript\n * // Only apply in production\n * allow('read', () => true, {\n * condition: ctx => ctx.meta?.environment === 'production'\n * })\n *\n * // Feature-gated policy\n * filter('read', ctx => ({ strict: true }), {\n * condition: ctx => ctx.meta?.features?.strictMode\n * })\n * ```\n */\n condition?: PolicyActivationCondition\n}\n\n/**\n * Create an allow policy\n * Grants access when condition evaluates to true\n *\n * @example\n * ```typescript\n * // Allow users to read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Allow admins to do everything\n * allow('all', ctx => ctx.auth.roles.includes('admin'))\n *\n * // Allow with multiple operations\n * allow(['read', 'update'], ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Named policy with priority\n * allow('read', ctx => ctx.auth.roles.includes('verified'), {\n * name: 'verified-users-only',\n * priority: 10\n * })\n * ```\n */\nexport function allow(\n operation: Operation | Operation[],\n condition: PolicyCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const policy: ConditionalPolicyDefinition = {\n type: 'allow',\n operation,\n condition: condition,\n priority: options?.priority ?? 0\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n/**\n * Create a deny policy\n * Blocks access when condition evaluates to true (overrides allow)\n * If no condition is provided, always denies\n *\n * @example\n * ```typescript\n * // Deny access to banned users\n * deny('all', ctx => ctx.auth.attributes?.banned === true)\n *\n * // Deny deletions on archived records\n * deny('delete', ctx => ctx.row.archived === true)\n *\n * // Deny all access to sensitive table\n * deny('all')\n *\n * // Named deny with high priority\n * deny('all', ctx => ctx.auth.attributes?.suspended === true, {\n * name: 'block-suspended-users',\n * priority: 200\n * })\n * ```\n */\nexport function deny(\n operation: Operation | Operation[],\n condition?: PolicyCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const policy: ConditionalPolicyDefinition = {\n type: 'deny',\n operation,\n condition: condition ?? (() => true),\n priority: options?.priority ?? 100 // Deny policies run first by default\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n/**\n * Create a filter policy\n * Adds WHERE conditions to SELECT queries\n *\n * **IMPORTANT**: Filter conditions must be synchronous functions.\n * Async filter policies are not currently supported because filters are applied\n * directly to query builders at query construction time.\n *\n * @example\n * ```typescript\n * // ✅ CORRECT: Filter by tenant (synchronous)\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n *\n * // ✅ CORRECT: Filter by organization with soft delete\n * filter('read', ctx => ({\n * organization_id: ctx.auth.organizationIds?.[0],\n * deleted_at: null\n * }))\n *\n * // ❌ WRONG: Async filter (not supported)\n * // filter('read', async ctx => {\n * // const tenantId = await fetchTenantId(ctx.auth.userId)\n * // return { tenant_id: tenantId }\n * // })\n *\n * // ✅ WORKAROUND: Fetch data before creating context\n * // const tenantId = await fetchTenantId(userId)\n * // const ctx = createRLSContext({ auth: { userId, tenantId, roles: [] } })\n * // filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n *\n * // Named filter\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }), {\n * name: 'tenant-filter'\n * })\n * ```\n */\nexport function filter(\n operation: 'read' | 'all',\n condition: FilterCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const policy: ConditionalPolicyDefinition = {\n type: 'filter',\n operation: operation === 'all' ? 'read' : operation,\n condition: condition as unknown as PolicyCondition,\n priority: options?.priority ?? 0\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n/**\n * Create a validate policy\n * Validates mutation data before execution\n *\n * @example\n * ```typescript\n * // Validate user can only set their own user_id\n * validate('create', ctx => ctx.data.userId === ctx.auth.userId)\n *\n * // Validate status transitions\n * validate('update', ctx => {\n * const { status } = ctx.data;\n * return !status || ['draft', 'published'].includes(status);\n * })\n *\n * // Apply to both create and update\n * validate('all', ctx => ctx.data.price >= 0)\n *\n * // Named validation\n * validate('create', ctx => validateEmail(ctx.data.email), {\n * name: 'validate-email'\n * })\n * ```\n */\nexport function validate(\n operation: 'create' | 'update' | 'all',\n condition: PolicyCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const ops: Operation[] = operation === 'all' ? ['create', 'update'] : [operation]\n\n const policy: ConditionalPolicyDefinition = {\n type: 'validate',\n operation: ops,\n condition: condition,\n priority: options?.priority ?? 0\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n// ============================================================================\n// Conditional Policy Helpers\n// ============================================================================\n\n/**\n * Create a policy that is only active in specific environments\n *\n * @param environments - Environments where the policy is active\n * @param policyFn - Function that creates the policy\n * @returns Policy with environment condition\n *\n * @example\n * ```typescript\n * // Policy only active in production\n * const prodPolicy = whenEnvironment(['production'], () =>\n * allow('read', () => true, { name: 'prod-read' })\n * );\n *\n * // Policy active in staging and production\n * const nonDevPolicy = whenEnvironment(['staging', 'production'], () =>\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n * );\n * ```\n */\nexport function whenEnvironment(\n environments: string[],\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n const existingCondition = policy.activationCondition\n policy.activationCondition = ctx => {\n const envMatch = environments.includes(ctx.environment ?? '')\n if (!envMatch) return false\n // If there was an existing condition (from inner wrapper), it must also pass\n return existingCondition ? existingCondition(ctx) : true\n }\n return policy\n}\n\n/**\n * Create a policy that is only active when a feature flag is enabled\n *\n * @param feature - Feature flag name\n * @param policyFn - Function that creates the policy\n * @returns Policy with feature flag condition\n *\n * @example\n * ```typescript\n * // Policy only active when 'strict_rls' feature is enabled\n * const strictPolicy = whenFeature('strict_rls', () =>\n * deny('delete', () => true, { name: 'strict-no-delete' })\n * );\n * ```\n */\nexport function whenFeature(\n feature: string,\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n const existingCondition = policy.activationCondition\n policy.activationCondition = ctx => {\n let featureEnabled = false\n if (Array.isArray(ctx.features)) {\n featureEnabled = ctx.features.includes(feature)\n } else if (ctx.features && typeof ctx.features === 'object' && 'has' in ctx.features) {\n // Support Set<string>\n featureEnabled = (ctx.features as Set<string>).has(feature)\n } else if (ctx.features && typeof ctx.features === 'object') {\n // Support object-style features: { feature_name: boolean }\n featureEnabled = !!(ctx.features as Record<string, unknown>)[feature]\n }\n if (!featureEnabled) return false\n // If there was an existing condition (from inner wrapper), it must also pass\n return existingCondition ? existingCondition(ctx) : true\n }\n return policy\n}\n\n/**\n * Create a policy that is only active during specific hours\n *\n * @param startHour - Start hour (0-23)\n * @param endHour - End hour (0-23)\n * @param policyFn - Function that creates the policy\n * @returns Policy with time-based condition\n *\n * @example\n * ```typescript\n * // Policy only active during business hours (9 AM - 5 PM)\n * const businessHoursPolicy = whenTimeRange(9, 17, () =>\n * allow('update', () => true, { name: 'business-hours-update' })\n * );\n * ```\n */\nexport function whenTimeRange(\n startHour: number,\n endHour: number,\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n const existingCondition = policy.activationCondition\n policy.activationCondition = ctx => {\n const hour = (ctx.timestamp ?? new Date()).getHours()\n let inRange: boolean\n // Handle midnight crossing (e.g., 22:00 to 06:00)\n if (startHour > endHour) {\n inRange = hour >= startHour || hour < endHour\n } else {\n inRange = hour >= startHour && hour < endHour\n }\n if (!inRange) return false\n // If there was an existing condition (from inner wrapper), it must also pass\n return existingCondition ? existingCondition(ctx) : true\n }\n return policy\n}\n\n/**\n * Create a policy that is only active when a custom condition is met\n *\n * @param condition - Custom activation condition\n * @param policyFn - Function that creates the policy\n * @returns Policy with custom condition\n *\n * @example\n * ```typescript\n * // Policy only active when user is in beta program\n * const betaPolicy = whenCondition(\n * ctx => ctx.meta?.betaUser === true,\n * () => allow('read', () => true, { name: 'beta-read' })\n * );\n * ```\n */\nexport function whenCondition(\n condition: PolicyActivationCondition,\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n policy.activationCondition = condition\n return policy\n}\n","/**\n * Policy Registry\n * Central registry for managing RLS policies across all tables\n *\n * The PolicyRegistry compiles and stores RLS policies for efficient runtime lookup.\n * It categorizes policies by type (allow/deny/filter/validate) and operation,\n * and provides methods to query policies for specific tables and operations.\n */\n\nimport type {\n Operation,\n PolicyDefinition,\n FilterCondition,\n RLSSchema,\n TableRLSConfig,\n CompiledPolicy,\n CompiledFilterPolicy,\n PolicyEvaluationContext\n} from './types.js'\nimport { RLSSchemaError } from '../errors.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\n\n/**\n * Internal compiled policy with operations as Set for efficient lookup\n */\ninterface InternalCompiledPolicy {\n name: string\n operations: Set<Operation>\n type: 'allow' | 'deny' | 'validate'\n evaluate: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n priority: number\n}\n\n/**\n * Table policy configuration\n */\ninterface TablePolicyConfig {\n allows: InternalCompiledPolicy[]\n denies: InternalCompiledPolicy[]\n filters: CompiledFilterPolicy[]\n validates: InternalCompiledPolicy[]\n skipFor: string[] // Role names that bypass RLS\n defaultDeny: boolean\n}\n\n/**\n * Policy Registry\n * Manages and provides access to RLS policies\n */\nexport class PolicyRegistry<DB = unknown> {\n private tables = new Map<string, TablePolicyConfig>()\n private compiled = false\n private logger: KyseraLogger\n\n constructor(schema?: RLSSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger\n if (schema) {\n this.loadSchema(schema)\n }\n }\n\n /**\n * Load and compile policies from schema\n *\n * @example\n * ```typescript\n * const registry = new PolicyRegistry<Database>();\n * registry.loadSchema({\n * users: {\n * policies: [\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * defaultDeny: true,\n * },\n * });\n * ```\n */\n loadSchema(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n this.registerTable(table, config as TableRLSConfig)\n }\n this.compiled = true\n }\n\n /**\n * Register policies for a single table\n *\n * @param table - Table name\n * @param config - Table RLS configuration\n */\n registerTable(table: string, config: TableRLSConfig): void {\n const tableConfig: TablePolicyConfig = {\n allows: [],\n denies: [],\n filters: [],\n validates: [],\n skipFor: config.skipFor ?? [],\n defaultDeny: config.defaultDeny ?? true\n }\n\n // Compile and categorize policies\n for (let i = 0; i < config.policies.length; i++) {\n const policy = config.policies[i]\n if (!policy) continue\n\n const policyName = policy.name ?? `${table}_policy_${i}`\n\n try {\n if (policy.type === 'filter') {\n const compiled = this.compileFilterPolicy(policy, policyName)\n tableConfig.filters.push(compiled)\n } else {\n const compiled = this.compilePolicy(policy, policyName)\n\n switch (policy.type) {\n case 'allow':\n tableConfig.allows.push(compiled)\n break\n case 'deny':\n tableConfig.denies.push(compiled)\n break\n case 'validate':\n tableConfig.validates.push(compiled)\n break\n }\n }\n } catch (error) {\n throw new RLSSchemaError(\n `Failed to compile policy \"${policyName}\" for table \"${table}\": ${error instanceof Error ? error.message : String(error)}`,\n { table, policy: policyName }\n )\n }\n }\n\n // Sort by priority (higher priority first)\n tableConfig.allows.sort((a, b) => b.priority - a.priority)\n tableConfig.denies.sort((a, b) => b.priority - a.priority)\n tableConfig.validates.sort((a, b) => b.priority - a.priority)\n\n this.tables.set(table, tableConfig)\n }\n\n /**\n * Register policies - supports both schema and table-based registration\n *\n * @overload Register a full schema\n * @overload Register policies for a single table (deprecated)\n */\n register(schemaOrTable: RLSSchema<DB>): void\n register(\n schemaOrTable: keyof DB & string,\n policies: PolicyDefinition[],\n options?: {\n skipFor?: string[]\n defaultDeny?: boolean\n }\n ): void\n register(\n schemaOrTable: RLSSchema<DB> | (keyof DB & string),\n policies?: PolicyDefinition[],\n options?: {\n skipFor?: string[] // Role names that bypass RLS\n defaultDeny?: boolean\n }\n ): void {\n // If first argument is an object with policies, treat as schema\n if (typeof schemaOrTable === 'object' && schemaOrTable !== null) {\n this.loadSchema(schemaOrTable)\n return\n }\n\n // Otherwise, treat as table-based registration\n const table = schemaOrTable\n if (!policies) {\n throw new RLSSchemaError('Policies are required when registering by table name', { table })\n }\n\n const config: TableRLSConfig = {\n policies\n }\n\n if (options?.skipFor !== undefined) {\n config.skipFor = options.skipFor\n }\n\n if (options?.defaultDeny !== undefined) {\n config.defaultDeny = options.defaultDeny\n }\n\n this.registerTable(table, config)\n }\n\n /**\n * Compile a policy definition into an internal compiled policy\n *\n * @param policy - Policy definition to compile\n * @param name - Policy name for debugging\n * @returns Compiled policy ready for evaluation\n */\n private compilePolicy(policy: PolicyDefinition, name: string): InternalCompiledPolicy {\n const operations = Array.isArray(policy.operation) ? policy.operation : [policy.operation]\n\n // Expand 'all' to all operations\n const expandedOps = operations.flatMap(op =>\n op === 'all' ? (['read', 'create', 'update', 'delete'] as const) : [op]\n ) as Operation[]\n\n return {\n name,\n operations: new Set(expandedOps),\n type: policy.type as 'allow' | 'deny' | 'validate',\n evaluate: policy.condition as (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n priority: policy.priority ?? (policy.type === 'deny' ? 100 : 0)\n }\n }\n\n /**\n * Compile a filter policy\n *\n * @param policy - Filter policy definition\n * @param name - Policy name for debugging\n * @returns Compiled filter policy\n */\n private compileFilterPolicy(policy: PolicyDefinition, name: string): CompiledFilterPolicy {\n const condition = policy.condition as unknown as FilterCondition\n\n return {\n operation: 'read',\n getConditions: condition as (ctx: PolicyEvaluationContext) => Record<string, unknown>,\n name\n }\n }\n\n /**\n * Convert internal compiled policy to public CompiledPolicy\n */\n private toCompiledPolicy(internal: InternalCompiledPolicy): CompiledPolicy {\n return {\n name: internal.name,\n type: internal.type,\n operation: Array.from(internal.operations),\n evaluate: internal.evaluate,\n priority: internal.priority\n }\n }\n\n /**\n * Get allow policies for a table and operation\n */\n getAllows(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.allows.filter(p => p.operations.has(operation)).map(p => this.toCompiledPolicy(p))\n }\n\n /**\n * Get deny policies for a table and operation\n */\n getDenies(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.denies.filter(p => p.operations.has(operation)).map(p => this.toCompiledPolicy(p))\n }\n\n /**\n * Get validate policies for a table and operation\n */\n getValidates(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.validates\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p))\n }\n\n /**\n * Get filter policies for a table\n */\n getFilters(table: string): CompiledFilterPolicy[] {\n const config = this.tables.get(table)\n return config?.filters ?? []\n }\n\n /**\n * Get roles that skip RLS for a table\n */\n getSkipFor(table: string): string[] {\n const config = this.tables.get(table)\n return config?.skipFor ?? []\n }\n\n /**\n * Check if table has default deny\n */\n hasDefaultDeny(table: string): boolean {\n const config = this.tables.get(table)\n return config?.defaultDeny ?? true\n }\n\n /**\n * Check if a table is registered\n */\n hasTable(table: string): boolean {\n return this.tables.has(table)\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys())\n }\n\n /**\n * Check if registry is compiled\n */\n isCompiled(): boolean {\n return this.compiled\n }\n\n /**\n * Validate that all policies are properly defined\n *\n * This method checks for common issues:\n * - Tables with no policies and defaultDeny=false (warns)\n * - Tables with skipFor operations but no corresponding policies\n */\n validate(): void {\n for (const [table, config] of this.tables) {\n // Check that at least one operation has policies\n const hasPolicy =\n config.allows.length > 0 ||\n config.denies.length > 0 ||\n config.filters.length > 0 ||\n config.validates.length > 0\n\n if (!hasPolicy && !config.defaultDeny) {\n // Warning: table has no policies and defaultDeny is false\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has no policies and defaultDeny is false. ` +\n `All operations will be allowed.`\n )\n }\n\n // Warn if skipFor includes operations that have policies\n if (config.skipFor.length > 0) {\n const opsWithPolicies = new Set<Operation>()\n\n for (const allow of config.allows) {\n allow.operations.forEach(op => opsWithPolicies.add(op))\n }\n for (const deny of config.denies) {\n deny.operations.forEach(op => opsWithPolicies.add(op))\n }\n for (const validate of config.validates) {\n validate.operations.forEach(op => opsWithPolicies.add(op))\n }\n if (config.filters.length > 0) {\n opsWithPolicies.add('read')\n }\n\n const skippedOpsWithPolicies = config.skipFor.filter(op => {\n // 'all' means skip all operations\n if (op === 'all') return opsWithPolicies.size > 0\n // Check if this is an operation name (for backwards compatibility)\n return opsWithPolicies.has(op as Operation)\n })\n\n if (skippedOpsWithPolicies.length > 0) {\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has skipFor operations that also have policies: ${skippedOpsWithPolicies.join(', ')}. ` +\n `The policies will be ignored for these operations.`\n )\n }\n }\n }\n }\n\n /**\n * Clear all policies\n */\n clear(): void {\n this.tables.clear()\n this.compiled = false\n }\n\n /**\n * Remove policies for a specific table\n */\n remove(table: string): void {\n this.tables.delete(table)\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RLSContext } from './types.js'\n\n/**\n * AsyncLocalStorage instance for RLS context\n * Provides automatic context propagation across async boundaries\n */\nexport const rlsStorage = new AsyncLocalStorage<RLSContext>()\n","import { rlsStorage } from './storage.js'\nimport type { RLSContext, RLSAuthContext, RLSRequestContext } from './types.js'\nimport { RLSContextError, RLSContextValidationError } from '../errors.js'\n\n/**\n * Options for creating RLS context\n */\nexport interface CreateRLSContextOptions<TUser = unknown, TMeta = unknown> {\n auth: RLSAuthContext<TUser>\n request?: Partial<RLSRequestContext>\n meta?: TMeta\n}\n\n/**\n * Create a new RLS context\n */\nexport function createRLSContext<TUser = unknown, TMeta = unknown>(\n options: CreateRLSContextOptions<TUser, TMeta>\n): RLSContext<TUser, TMeta> {\n validateAuthContext(options.auth)\n\n const context: RLSContext<TUser, TMeta> = {\n auth: {\n ...options.auth,\n isSystem: options.auth.isSystem ?? false // Default to false if not provided\n },\n timestamp: new Date()\n }\n\n if (options.request) {\n context.request = {\n ...options.request,\n timestamp: options.request.timestamp ?? new Date()\n } as RLSRequestContext\n }\n\n if (options.meta !== undefined) {\n context.meta = options.meta\n }\n\n return context\n}\n\n/**\n * Validate auth context\n */\nfunction validateAuthContext(auth: RLSAuthContext): void {\n if (auth.userId === undefined || auth.userId === null) {\n throw new RLSContextValidationError('userId is required in auth context', 'userId')\n }\n\n if (!Array.isArray(auth.roles)) {\n throw new RLSContextValidationError('roles must be an array', 'roles')\n }\n}\n\n/**\n * RLS Context Manager\n * Manages RLS context using AsyncLocalStorage for automatic propagation\n */\nclass RLSContextManager {\n /**\n * Run a synchronous function within an RLS context\n */\n run<T>(context: RLSContext, fn: () => T): T {\n return rlsStorage.run(context, fn)\n }\n\n /**\n * Run an async function within an RLS context\n */\n async runAsync<T>(context: RLSContext, fn: () => Promise<T>): Promise<T> {\n return await rlsStorage.run(context, fn)\n }\n\n /**\n * Get current RLS context\n * @throws RLSContextError if no context is set\n */\n getContext(): RLSContext {\n const ctx = rlsStorage.getStore()\n if (!ctx) {\n throw new RLSContextError()\n }\n return ctx\n }\n\n /**\n * Get current RLS context or null if not set\n */\n getContextOrNull(): RLSContext | null {\n return rlsStorage.getStore() ?? null\n }\n\n /**\n * Check if running within RLS context\n */\n hasContext(): boolean {\n return rlsStorage.getStore() !== undefined\n }\n\n /**\n * Get current auth context\n * @throws RLSContextError if no context is set\n */\n getAuth(): RLSAuthContext {\n return this.getContext().auth\n }\n\n /**\n * Get current user ID\n * @throws RLSContextError if no context is set\n */\n getUserId(): string | number {\n return this.getAuth().userId\n }\n\n /**\n * Get current tenant ID\n * @throws RLSContextError if no context is set\n */\n getTenantId(): string | number | undefined {\n return this.getAuth().tenantId\n }\n\n /**\n * Check if current user has a specific role\n */\n hasRole(role: string): boolean {\n const ctx = this.getContextOrNull()\n return ctx?.auth.roles.includes(role) ?? false\n }\n\n /**\n * Check if current user has a specific permission\n */\n hasPermission(permission: string): boolean {\n const ctx = this.getContextOrNull()\n return ctx?.auth.permissions?.includes(permission) ?? false\n }\n\n /**\n * Check if current context is a system context (bypasses RLS)\n */\n isSystem(): boolean {\n const ctx = this.getContextOrNull()\n return ctx?.auth.isSystem ?? false\n }\n\n /**\n * Create a system context for operations that should bypass RLS\n */\n asSystem<T>(fn: () => T): T {\n const currentCtx = this.getContextOrNull()\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context')\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true }\n }\n\n return this.run(systemCtx, fn)\n }\n\n /**\n * Create a system context for async operations\n */\n async asSystemAsync<T>(fn: () => Promise<T>): Promise<T> {\n const currentCtx = this.getContextOrNull()\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context')\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true }\n }\n\n return await this.runAsync(systemCtx, fn)\n }\n}\n\n// Export singleton instance\nexport const rlsContext = new RLSContextManager()\n\n/**\n * Convenience function to run code within RLS context\n */\nexport function withRLSContext<T>(context: RLSContext, fn: () => T): T {\n return rlsContext.run(context, fn)\n}\n\n/**\n * Convenience function to run async code within RLS context\n */\nexport async function withRLSContextAsync<T>(\n context: RLSContext,\n fn: () => Promise<T>\n): Promise<T> {\n return await rlsContext.runAsync(context, fn)\n}\n","/**\n * Type utilities for RLS plugin\n *\n * These utilities provide type-safe wrappers around dynamic operations\n * that require runtime flexibility beyond TypeScript's compile-time constraints.\n *\n * NOTE: This file intentionally uses `any` types to bridge the gap between\n * Kysely's compile-time type system and RLS's runtime dynamic requirements.\n * All `any` usage is documented and justified with runtime safety guarantees.\n *\n * @module @kysera/rls/utils/type-utils\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { SelectQueryBuilder, Kysely, RawBuilder } from 'kysely'\nimport { sql } from 'kysely'\n\n/**\n * Type-safe wrapper for dynamic column references in WHERE clauses\n *\n * Kysely's type system requires compile-time known column names, but RLS policies\n * work with dynamic column names at runtime. This utility provides a type-safe\n * boundary for this conversion.\n *\n * Type safety is maintained through:\n * 1. Column names come from validated policy definitions (developer-controlled)\n * 2. Values are type-checked by policy condition functions\n * 3. Runtime validation during policy registration\n *\n * @param table - Table name (from validated policy schema)\n * @param column - Column name (from validated policy definition)\n * @returns Type-safe column reference for Kysely query builder\n */\nexport function createQualifiedColumn(table: string, column: string): string {\n return `${table}.${column}`\n}\n\n/**\n * Type-safe wrapper for applying WHERE conditions from RLS filters\n *\n * This function encapsulates the type boundary between runtime policy conditions\n * and Kysely's compile-time type system.\n *\n * @param qb - Query builder to modify\n * @param column - Qualified column name (table.column)\n * @param operator - Comparison operator\n * @param value - Value to compare against\n * @returns Modified query builder\n */\nexport function applyWhereCondition<DB, TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n column: string,\n operator: 'is' | '=' | 'in',\n value: unknown\n): SelectQueryBuilder<DB, TB, O> {\n return qb.where(column as any, operator as any, value as any)\n}\n\n/**\n * Type-safe wrapper for raw SQL expressions\n *\n * @param expression - SQL expression (e.g., 'FALSE' for impossible conditions)\n * @returns Type-safe raw builder for WHERE clauses\n */\nexport function createRawCondition(expression: string): RawBuilder<boolean> {\n return sql`${sql.raw(expression)}`\n}\n\n/**\n * Type-safe wrapper for dynamic table queries (used in raw db queries)\n *\n * This is used by plugins to bypass RLS filtering when fetching existing rows\n * for mutation validation. The table name comes from repository configuration\n * and is validated during repository creation.\n *\n * @param db - Kysely database instance\n * @param table - Table name (from repository config)\n * @returns Query builder for the table\n */\nexport function selectFromDynamicTable<DB>(\n db: Kysely<DB>,\n table: string\n): SelectQueryBuilder<Record<string, unknown>, string, Record<string, unknown>> {\n return db.selectFrom(table as any).selectAll() as any\n}\n\n/**\n * Add WHERE clause for primary key equality.\n * Supports custom primary key column names.\n *\n * @param qb - Select query builder\n * @param id - Primary key value\n * @param primaryKeyColumn - Primary key column name (default: 'id')\n * @returns Query builder with ID filter\n */\nexport function whereIdEquals(\n qb: SelectQueryBuilder<any, any, any>,\n id: unknown,\n primaryKeyColumn = 'id'\n): SelectQueryBuilder<any, any, any> {\n return qb.where(primaryKeyColumn as any, '=', id as any)\n}\n\n/**\n * Type-safe wrapper for transforming query builders in plugin interceptors\n *\n * Used when plugins need to transform a generic query builder (QB) to a specific\n * type (e.g., SelectQueryBuilder) and back. This is necessary because the executor's\n * interceptQuery hook receives unconstrained QB types to preserve type inference.\n *\n * @param qb - Generic query builder from interceptor\n * @param operation - Operation type (for runtime validation)\n * @param transform - Transformation function\n * @returns Transformed query builder\n */\nexport function transformQueryBuilder<QB>(\n qb: QB,\n operation: string,\n transform: (\n qb: SelectQueryBuilder<Record<string, unknown>, string, Record<string, unknown>>\n ) => SelectQueryBuilder<Record<string, unknown>, string, Record<string, unknown>>\n): QB {\n if (operation !== 'select') {\n return qb\n }\n\n const transformed = transform(qb as any)\n return transformed as QB\n}\n\n/**\n * Type guard to check if an executor has a raw db instance\n *\n * @param executor - Kysely executor (may have __rawDb property)\n * @returns True if executor has __rawDb property\n */\nexport function hasRawDb<DB>(\n executor: Kysely<DB>\n): executor is Kysely<DB> & { __rawDb: Kysely<DB> } {\n return '__rawDb' in executor && (executor as any).__rawDb !== undefined\n}\n\n/**\n * Type-safe wrapper to get raw db from executor\n *\n * @param executor - Kysely executor with optional __rawDb\n * @returns Raw db instance or original executor\n */\nexport function getRawDbSafe<DB>(executor: Kysely<DB>): Kysely<DB> {\n if (hasRawDb(executor)) {\n return executor.__rawDb\n }\n return executor\n}\n","/**\n * SELECT Query Transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\n\nimport type { SelectQueryBuilder } from 'kysely'\nimport type { PolicyRegistry } from '../policy/registry.js'\nimport type { PolicyEvaluationContext } from '../policy/types.js'\nimport type { RLSContext } from '../context/types.js'\nimport { rlsContext } from '../context/manager.js'\nimport { RLSError, RLSErrorCodes } from '../errors.js'\nimport {\n createQualifiedColumn,\n applyWhereCondition,\n createRawCondition\n} from '../utils/type-utils.js'\n\n/**\n * SELECT query transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\nexport class SelectTransformer<DB = unknown> {\n constructor(private registry: PolicyRegistry<DB>) {}\n\n /**\n * Transform a SELECT query by applying filter policies\n *\n * @param qb - The query builder to transform\n * @param table - Table name being queried\n * @returns Transformed query builder with RLS filters applied\n *\n * @example\n * ```typescript\n * const transformer = new SelectTransformer(registry);\n * let query = db.selectFrom('posts').selectAll();\n * query = transformer.transform(query, 'posts');\n * // Query now includes WHERE conditions from RLS policies\n * ```\n */\n transform<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n // Check for context\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n // SECURITY FIX (H-11): This should never happen as plugin.interceptQuery\n // now handles missing context. If we reach here, apply defensive WHERE FALSE\n // to prevent unfiltered queries from leaking through.\n // This is a defense-in-depth measure.\n return applyWhereCondition(\n qb,\n createRawCondition('FALSE') as unknown as string,\n '=',\n true\n ) as SelectQueryBuilder<DB, TB, O>\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n return qb\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return qb\n }\n\n // Get filter policies for this table\n const filters = this.registry.getFilters(table)\n if (filters.length === 0) {\n return qb\n }\n\n // Apply each filter as WHERE condition\n let result = qb\n for (const filter of filters) {\n const conditions = this.evaluateFilter(filter, ctx, table)\n result = this.applyConditions(result, conditions, table)\n }\n\n return result\n }\n\n /**\n * Evaluate a filter policy to get WHERE conditions\n *\n * @param filter - The filter policy to evaluate\n * @param ctx - RLS context\n * @param table - Table name\n * @returns WHERE clause conditions as key-value pairs\n */\n private evaluateFilter(\n filter: {\n name: string\n getConditions: (\n ctx: PolicyEvaluationContext\n ) => Record<string, unknown> | Promise<Record<string, unknown>>\n },\n ctx: RLSContext,\n table: string\n ): Record<string, unknown> {\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n\n const result = filter.getConditions(evalCtx)\n\n // Note: If async filters are needed, this method signature would need to change\n // For now, we assume synchronous filter evaluation\n if (result instanceof Promise) {\n throw new RLSError(\n `Async filter policies are not supported in SELECT transformers. ` +\n `Filter '${filter.name}' on table '${table}' returned a Promise. ` +\n `Use synchronous conditions for filter policies.`,\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n return result\n }\n\n /**\n * Apply filter conditions to query builder\n *\n * Uses type-safe wrappers from utils/type-utils.ts to encapsulate the boundary\n * between runtime policy conditions and Kysely's compile-time type system.\n *\n * Type safety is maintained through:\n * 1. Policy conditions are validated during schema registration\n * 2. Column names come from policy definitions (developer-controlled)\n * 3. Values are type-checked by the policy condition functions\n *\n * @param qb - Query builder to modify\n * @param conditions - WHERE clause conditions\n * @param table - Table name (for qualified column names)\n * @returns Modified query builder\n */\n private applyConditions<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n conditions: Record<string, unknown>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n let result = qb\n\n for (const [column, value] of Object.entries(conditions)) {\n // Use table-qualified column name to avoid ambiguity in joins\n const qualifiedColumn = createQualifiedColumn(table, column)\n\n if (value === null) {\n // NULL check\n result = applyWhereCondition(result, qualifiedColumn, 'is', null)\n } else if (value === undefined) {\n // Skip undefined values\n continue\n } else if (Array.isArray(value)) {\n if (value.length === 0) {\n // Empty array means no matches - add impossible condition using SQL FALSE\n // This ensures the query returns no rows without using magic strings\n // that could potentially match actual data\n result = applyWhereCondition(\n result,\n createRawCondition('FALSE') as unknown as string,\n '=',\n true\n )\n } else {\n // IN clause for array values\n result = applyWhereCondition(result, qualifiedColumn, 'in', value)\n }\n } else {\n // Equality check\n result = applyWhereCondition(result, qualifiedColumn, '=', value)\n }\n }\n\n return result\n }\n}\n","/**\n * Mutation Guard\n * Validates CREATE, UPDATE, DELETE operations against RLS policies\n */\n\nimport type { PolicyRegistry } from '../policy/registry.js'\nimport type { PolicyEvaluationContext, Operation } from '../policy/types.js'\nimport type { RLSContext } from '../context/types.js'\nimport { rlsContext } from '../context/manager.js'\nimport { RLSPolicyViolation, RLSPolicyEvaluationError } from '../errors.js'\n\n/**\n * Default chunk size for parallel row filtering\n */\nconst DEFAULT_CHUNK_SIZE = 100\n\n/**\n * Mutation guard\n * Validates mutations (CREATE, UPDATE, DELETE) against allow/deny/validate policies\n */\nexport class MutationGuard<DB = unknown> {\n constructor(private registry: PolicyRegistry<DB>) {}\n\n /**\n * Check if CREATE operation is allowed\n *\n * @param table - Table name\n * @param data - Data being inserted\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * await guard.checkCreate('posts', { title: 'Hello', tenant_id: 1 });\n * ```\n */\n async checkCreate(table: string, data: Record<string, unknown>): Promise<void> {\n await this.checkMutation(table, 'create', undefined, data)\n }\n\n /**\n * Check if UPDATE operation is allowed\n *\n * @param table - Table name\n * @param existingRow - Current row data\n * @param data - Data being updated\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * const existingPost = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * await guard.checkUpdate('posts', existingPost, { title: 'Updated' });\n * ```\n */\n async checkUpdate(\n table: string,\n existingRow: Record<string, unknown>,\n data: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'update', existingRow, data)\n }\n\n /**\n * Check if DELETE operation is allowed\n *\n * @param table - Table name\n * @param existingRow - Row to be deleted\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * const existingPost = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * await guard.checkDelete('posts', existingPost);\n * ```\n */\n async checkDelete(table: string, existingRow: Record<string, unknown>): Promise<void> {\n await this.checkMutation(table, 'delete', existingRow)\n }\n\n /**\n * Check if READ operation is allowed on a specific row\n *\n * @param table - Table name\n * @param row - Row to check access for\n * @returns true if access is allowed\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * const post = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * const canRead = await guard.checkRead('posts', post);\n * ```\n */\n async checkRead(table: string, row: Record<string, unknown>): Promise<boolean> {\n try {\n await this.checkMutation(table, 'read', row)\n return true\n } catch (error) {\n // Both policy violations and evaluation errors result in denial\n if (error instanceof RLSPolicyViolation || error instanceof RLSPolicyEvaluationError) {\n return false\n }\n throw error\n }\n }\n\n /**\n * Generic check for any operation (helper for testing)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @returns true if access is allowed, false otherwise\n */\n async canMutate(\n operation: Operation,\n table: string,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<boolean> {\n try {\n await this.checkMutation(table, operation, row, data)\n return true\n } catch (error) {\n // Both policy violations and evaluation errors result in denial\n if (error instanceof RLSPolicyViolation || error instanceof RLSPolicyEvaluationError) {\n return false\n }\n throw error\n }\n }\n\n /**\n * Validate mutation data (for validate policies)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param data - New data (for CREATE/UPDATE)\n * @param row - Existing row (for UPDATE)\n * @returns true if valid, false otherwise\n */\n async validateMutation(\n operation: Operation,\n table: string,\n data: Record<string, unknown>,\n row?: Record<string, unknown>\n ): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n return false\n }\n\n // System users bypass validation\n if (ctx.auth.isSystem) {\n return true\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true\n }\n\n // Get validate policies for this operation\n const validates = this.registry.getValidates(table, operation)\n if (validates.length === 0) {\n return true\n }\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n row: row,\n data: data,\n table: table,\n operation: operation,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n\n // All validate policies must pass\n for (const validate of validates) {\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx, validate.name)\n if (!result) {\n return false\n }\n }\n\n return true\n }\n\n /**\n * Check mutation against RLS policies\n *\n * @param table - Table name\n * @param operation - Operation type\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @throws RLSPolicyViolation if access is denied\n */\n private async checkMutation(\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<void> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n throw new RLSPolicyViolation(operation, table, 'No RLS context available')\n }\n\n // System users bypass all checks\n if (ctx.auth.isSystem) {\n return\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return\n }\n\n // Evaluate deny policies first (they override allows)\n const denies = this.registry.getDenies(table, operation)\n for (const deny of denies) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data)\n const result = await this.evaluatePolicy(deny.evaluate, evalCtx, deny.name)\n\n if (result) {\n throw new RLSPolicyViolation(operation, table, `Denied by policy: ${deny.name}`)\n }\n }\n\n // Evaluate validate policies (for CREATE/UPDATE)\n if ((operation === 'create' || operation === 'update') && data) {\n const validates = this.registry.getValidates(table, operation)\n for (const validate of validates) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data)\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx, validate.name)\n\n if (!result) {\n throw new RLSPolicyViolation(operation, table, `Validation failed: ${validate.name}`)\n }\n }\n }\n\n // Evaluate allow policies\n const allows = this.registry.getAllows(table, operation)\n const defaultDeny = this.registry.hasDefaultDeny(table)\n\n if (defaultDeny && allows.length === 0) {\n throw new RLSPolicyViolation(operation, table, 'No allow policies defined (default deny)')\n }\n\n if (allows.length > 0) {\n // At least one allow policy must pass\n let allowed = false\n\n for (const allow of allows) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data)\n const result = await this.evaluatePolicy(allow.evaluate, evalCtx, allow.name)\n\n if (result) {\n allowed = true\n break\n }\n }\n\n if (!allowed) {\n throw new RLSPolicyViolation(operation, table, 'No allow policies matched')\n }\n }\n }\n\n /**\n * Create policy evaluation context\n */\n private createEvalContext(\n ctx: RLSContext,\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n row,\n data,\n table,\n operation,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n }\n\n /**\n * Evaluate a policy condition\n *\n * @param condition - Policy condition function\n * @param evalCtx - Policy evaluation context\n * @param policyName - Name of the policy being evaluated (for error reporting)\n * @returns Boolean result of policy evaluation\n * @throws RLSPolicyEvaluationError if the policy throws an error\n */\n private async evaluatePolicy(\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n evalCtx: PolicyEvaluationContext,\n policyName?: string\n ): Promise<boolean> {\n try {\n const result = condition(evalCtx)\n return result instanceof Promise ? await result : result\n } catch (error) {\n // Distinguish between policy evaluation errors and policy violations\n // RLSPolicyEvaluationError indicates a bug in the policy, not a legitimate denial\n const originalError = error instanceof Error ? error : undefined\n throw new RLSPolicyEvaluationError(\n evalCtx.operation ?? 'unknown',\n evalCtx.table ?? 'unknown',\n error instanceof Error ? error.message : 'Unknown error',\n policyName,\n originalError\n )\n }\n }\n\n /**\n * Filter rows based on read policies.\n * Uses parallel processing with chunking for performance.\n *\n * @param table - Table name\n * @param rows - Rows to filter\n * @param chunkSize - Number of rows to process in parallel (default: 100)\n * @returns Filtered array containing only accessible rows\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * const allPosts = await db.selectFrom('posts').selectAll().execute();\n * const accessiblePosts = await guard.filterRows('posts', allPosts);\n *\n * // With custom chunk size for large datasets\n * const accessiblePosts = await guard.filterRows('posts', allPosts, 50);\n * ```\n */\n async filterRows<T extends Record<string, unknown>>(\n table: string,\n rows: T[],\n chunkSize: number = DEFAULT_CHUNK_SIZE\n ): Promise<T[]> {\n if (rows.length === 0) return []\n\n const results: T[] = []\n\n // Process in chunks to avoid overwhelming the event loop\n for (let i = 0; i < rows.length; i += chunkSize) {\n const chunk = rows.slice(i, i + chunkSize)\n\n // Process chunk in parallel\n const chunkResults = await Promise.all(\n chunk.map(async (row) => {\n const allowed = await this.checkRead(table, row)\n return allowed ? row : null\n })\n )\n\n // Filter out nulls and add to results\n for (const row of chunkResults) {\n if (row !== null) {\n results.push(row)\n }\n }\n }\n\n return results\n }\n}\n","/**\n * Package version - injected at build time by tsup\n * Falls back to development version if not replaced\n * @internal\n */\nconst RAW_VERSION = '__VERSION__'\nexport const VERSION = RAW_VERSION.startsWith('__') ? '0.0.0-dev' : RAW_VERSION\n","/**\n * RLS Plugin for Kysera Repository\n *\n * Implements Row-Level Security as a Kysera plugin, providing:\n * - Automatic query filtering for SELECT operations\n * - Policy enforcement for CREATE, UPDATE, DELETE operations\n * - Repository method extensions for RLS-aware operations\n * - System context bypass for privileged operations\n *\n * @module @kysera/rls\n */\n\nimport type { Plugin, QueryBuilderContext, BaseRepositoryLike } from '@kysera/executor'\nimport { getRawDb, isRepositoryLike } from '@kysera/executor'\nimport type { Kysely } from 'kysely'\nimport { z } from 'zod'\nimport type { RLSSchema, Operation } from './policy/types.js'\nimport { PolicyRegistry } from './policy/registry.js'\nimport { SelectTransformer } from './transformer/select.js'\nimport { MutationGuard } from './transformer/mutation.js'\nimport { rlsContext } from './context/manager.js'\nimport { VERSION } from './version.js'\nimport { RLSContextError, RLSPolicyViolation, RLSError, RLSErrorCodes } from './errors.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\nimport {\n transformQueryBuilder,\n selectFromDynamicTable,\n whereIdEquals,\n hasRawDb as hasRawDbUtil,\n applyWhereCondition,\n createRawCondition\n} from './utils/type-utils.js'\n\n/**\n * RLS Plugin configuration options\n */\nexport interface RLSPluginOptions<DB = unknown> {\n /** RLS policy schema */\n schema: RLSSchema<DB>\n\n /**\n * Tables to exclude from RLS (always bypass policies)\n * @default []\n */\n excludeTables?: string[]\n\n /** Roles that bypass RLS entirely (e.g., ['admin', 'superuser']) */\n bypassRoles?: string[]\n\n /** Logger instance for RLS operations */\n logger?: KyseraLogger\n\n /**\n * Require RLS context for all operations (throws if missing)\n *\n * **Security**: Defaults to `true` for secure-by-default behavior.\n * When `true`, missing RLS context throws RLSContextError, preventing\n * unfiltered database access which could expose sensitive data.\n *\n * Only set to `false` if you explicitly want to allow queries without\n * RLS context (not recommended in production).\n *\n * @default true\n * @see allowUnfilteredQueries for explicit unfiltered query control\n */\n requireContext?: boolean\n\n /**\n * Allow unfiltered queries when RLS context is missing\n *\n * **SECURITY WARNING**: Setting this to `true` allows database queries\n * to execute without RLS filtering when context is missing. This can\n * expose sensitive data across tenant boundaries or user permissions.\n *\n * Only enable this if you:\n * 1. Understand the security implications\n * 2. Have other security controls in place\n * 3. Are running background jobs or system operations that don't have user context\n *\n * When both `requireContext: false` and `allowUnfilteredQueries: false`:\n * - Missing context logs a warning and returns empty results\n *\n * @default false (secure-by-default)\n */\n allowUnfilteredQueries?: boolean\n\n /** Enable audit logging of policy decisions */\n auditDecisions?: boolean\n\n /** Custom error handler for policy violations */\n onViolation?: (violation: RLSPolicyViolation) => void\n\n /**\n * Primary key column name for row lookups.\n * @default 'id'\n */\n primaryKeyColumn?: string\n}\n\n/**\n * Zod schema for RLSPluginOptions\n * Used for validation and configuration in the kysera-cli.\n * Note: 'schema' and 'onViolation' are not included as they are complex runtime objects.\n */\nexport const RLSPluginOptionsSchema = z.object({\n excludeTables: z.array(z.string()).optional(),\n bypassRoles: z.array(z.string()).optional(),\n requireContext: z.boolean().optional(),\n allowUnfilteredQueries: z.boolean().optional(),\n auditDecisions: z.boolean().optional(),\n primaryKeyColumn: z.string().optional()\n})\n\n/**\n * Base repository interface for type safety.\n * Type alias for BaseRepositoryLike from @kysera/executor with concrete DB type.\n * @internal\n */\ntype BaseRepository = BaseRepositoryLike<Record<string, unknown>>\n\n/**\n * Create RLS plugin for Kysera\n *\n * The RLS plugin provides declarative row-level security for your database operations.\n * It automatically filters SELECT queries and validates mutations (CREATE, UPDATE, DELETE)\n * against your policy schema.\n *\n * @example\n * ```typescript\n * import { rlsPlugin, defineRLSSchema, allow, filter } from '@kysera/rls';\n * import { createORM } from '@kysera/repository';\n *\n * // Define your RLS schema\n * const schema = defineRLSSchema<Database>({\n * resources: {\n * policies: [\n * // Filter reads by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Allow updates for resource owners\n * allow('update', ctx => ctx.auth.userId === ctx.row.owner_id),\n * // Validate creates belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * },\n * });\n *\n * // Create repository with RLS plugin\n * const orm = await createORM(db, [\n * rlsPlugin({ schema }),\n * ]);\n *\n * // Use within RLS context\n * await rlsContext.runAsync(\n * {\n * auth: { userId: 1, tenantId: 100, roles: ['user'], isSystem: false },\n * timestamp: new Date(),\n * },\n * async () => {\n * // All queries automatically filtered by tenant_id\n * const resources = await orm.resources.findAll();\n * }\n * );\n * ```\n *\n * @param options - Plugin configuration options\n * @returns Kysera plugin instance\n */\n// eslint-disable-next-line max-lines-per-function\nexport function rlsPlugin<DB>(options: RLSPluginOptions<DB>): Plugin {\n const {\n schema,\n excludeTables = [],\n bypassRoles = [],\n logger = silentLogger,\n requireContext = true, // SECURITY: Changed to true for secure-by-default (CRIT-2 fix)\n allowUnfilteredQueries = false, // SECURITY: Explicit opt-in for unfiltered queries\n auditDecisions = false,\n onViolation,\n primaryKeyColumn = 'id'\n } = options\n\n // Registry and transformers (initialized in onInit)\n let registry: PolicyRegistry<DB>\n let selectTransformer: SelectTransformer<DB>\n let mutationGuard: MutationGuard<DB>\n\n return {\n name: '@kysera/rls',\n version: VERSION,\n\n // Run after soft-delete (priority 0), before audit\n priority: 50,\n\n // No dependencies by default\n dependencies: [],\n\n /**\n * Initialize plugin - compile policies\n */\n onInit<TDB>(_executor: Kysely<TDB>): void {\n logger.info?.('[RLS] Initializing RLS plugin', {\n tables: Object.keys(schema).length,\n excludeTables: excludeTables.length,\n bypassRoles: bypassRoles.length\n })\n\n // Create and compile registry\n // Type assertion: The plugin is configured with a specific DB schema,\n // but onInit receives a generic TDB. We use the schema's DB type.\n registry = new PolicyRegistry<DB>(schema)\n registry.validate()\n\n // Create transformers\n selectTransformer = new SelectTransformer<DB>(registry)\n mutationGuard = new MutationGuard<DB>(registry)\n\n logger.info?.('[RLS] RLS plugin initialized successfully')\n },\n\n /**\n * Cleanup resources when executor is destroyed\n */\n onDestroy(): Promise<void> {\n // Clear registry to free up memory\n registry.clear()\n logger.info?.('[RLS] RLS plugin destroyed, cleared policy registry')\n return Promise.resolve()\n },\n\n /**\n * Intercept queries to apply RLS filtering\n *\n * This hook is called for every query builder operation. For SELECT queries,\n * it applies filter policies as WHERE conditions. For mutations, it marks\n * that RLS validation is required (performed in extendRepository).\n */\n interceptQuery<QB>(qb: QB, context: QueryBuilderContext): QB {\n const { operation, table, metadata } = context\n\n // Skip if table is excluded\n if (excludeTables.includes(table)) {\n logger.debug?.(`[RLS] Skipping RLS for excluded table: ${table}`)\n return qb\n }\n\n // Skip if explicitly disabled via metadata\n if (metadata['skipRLS'] === true) {\n logger.debug?.(`[RLS] Skipping RLS (explicit skip): ${table}`)\n return qb\n }\n\n // Check for context\n const ctx = rlsContext.getContextOrNull()\n\n if (!ctx) {\n // SECURITY FIX (CRIT-2): Secure-by-default behavior for missing context\n if (requireContext) {\n throw new RLSContextError(\n `RLS context required but not found for ${operation} on ${table}. ` +\n `This prevents unfiltered database access. ` +\n `Either provide RLS context or set 'requireContext: false' with 'allowUnfilteredQueries: true' if intentional.`\n )\n }\n\n if (!allowUnfilteredQueries) {\n // Log warning and return safe empty result\n logger.warn?.(\n `[RLS] Missing context for ${operation} on ${table}. ` +\n `Queries will return empty results for security. ` +\n `Set 'allowUnfilteredQueries: true' to allow unfiltered access (not recommended).`\n )\n // For SELECT, apply impossible condition to return no rows\n if (operation === 'select') {\n return transformQueryBuilder(qb, operation, selectQb => {\n // Apply WHERE FALSE to ensure no rows are returned\n return applyWhereCondition(\n selectQb,\n createRawCondition('FALSE') as unknown as string,\n '=',\n true\n ) as typeof selectQb\n })\n }\n // For mutations, we'll let them through but log warning\n // The extendRepository will handle mutation checks\n return qb\n }\n\n // allowUnfilteredQueries is true - allow but log warning\n logger.warn?.(\n `[RLS] No context for ${operation} on ${table}. ` +\n `Allowing unfiltered query due to 'allowUnfilteredQueries: true'. ` +\n `This may expose sensitive data.`\n )\n return qb\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n logger.debug?.(`[RLS] Bypassing RLS (system user): ${table}`)\n return qb\n }\n\n // Check bypass roles\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n logger.debug?.(`[RLS] Bypassing RLS (bypass role): ${table}`)\n return qb\n }\n\n // Apply SELECT filtering\n if (operation === 'select') {\n try {\n const transformed = transformQueryBuilder(\n qb,\n operation,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n selectQb => selectTransformer.transform(selectQb as any, table) as any\n )\n\n if (auditDecisions) {\n logger.info?.('[RLS] Filter applied', {\n table,\n operation,\n userId: ctx.auth.userId\n })\n }\n\n return transformed\n } catch (error) {\n logger.error?.('[RLS] Error applying filter', { table, error })\n throw error\n }\n }\n\n // For mutations, mark that RLS check is needed (done in extendRepository)\n if (operation === 'insert' || operation === 'update' || operation === 'delete') {\n metadata['__rlsRequired'] = true\n metadata['__rlsTable'] = table\n }\n\n return qb\n },\n\n /**\n * Extend repository with RLS-aware methods\n *\n * Wraps create, update, and delete methods to enforce RLS policies.\n * Also adds utility methods for bypassing RLS and checking access.\n */\n extendRepository<T extends object>(repo: T): T {\n // Use the shared type guard from @kysera/executor\n if (!isRepositoryLike(repo)) {\n return repo\n }\n\n const baseRepo = repo as unknown as BaseRepository\n\n const table = baseRepo.tableName\n\n // Skip excluded tables\n if (excludeTables.includes(table)) {\n logger.debug?.(`[RLS] Skipping repository extension for excluded table: ${table}`)\n return repo\n }\n\n // Skip if table not in schema\n if (!registry.hasTable(table)) {\n logger.debug?.(`[RLS] Table \"${table}\" not in RLS schema, skipping`)\n return repo\n }\n\n logger.debug?.(`[RLS] Extending repository for table: ${table}`)\n\n // Store original methods\n const originalCreate = baseRepo.create?.bind(baseRepo)\n const originalUpdate = baseRepo.update?.bind(baseRepo)\n const originalDelete = baseRepo.delete?.bind(baseRepo)\n const originalFindById = baseRepo.findById?.bind(baseRepo)\n\n // Get raw db for internal queries that need to bypass RLS\n // If executor doesn't have __rawDb (e.g., in tests), we'll use originalFindById\n const rawDb = getRawDb(baseRepo.executor)\n const hasRawDbInstance = hasRawDbUtil(baseRepo.executor)\n\n const extendedRepo = {\n ...baseRepo,\n\n /**\n * Wrapped create with RLS check\n */\n async create(data: unknown): Promise<unknown> {\n if (!originalCreate) {\n throw new RLSError(\n 'Repository does not support create operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n const ctx = rlsContext.getContextOrNull()\n\n // Check RLS if context exists and not system/bypass\n if (\n ctx &&\n !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))\n ) {\n try {\n await mutationGuard.checkCreate(table, data as Record<string, unknown>)\n\n if (auditDecisions) {\n logger.info?.('[RLS] Create allowed', { table, userId: ctx.auth.userId })\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error)\n if (auditDecisions) {\n logger.warn?.('[RLS] Create denied', {\n table,\n userId: ctx.auth.userId,\n reason: error.reason\n })\n }\n }\n throw error\n }\n }\n\n return await originalCreate(data)\n },\n\n /**\n * Wrapped update with RLS check\n */\n async update(id: unknown, data: unknown): Promise<unknown> {\n if (!originalUpdate) {\n throw new RLSError(\n 'Repository does not support update operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n const ctx = rlsContext.getContextOrNull()\n\n if (\n ctx &&\n !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))\n ) {\n // Fetch existing row for policy evaluation\n // Use raw db if available to bypass RLS filtering and prevent self-interception\n let existingRow: unknown\n\n if (hasRawDbInstance) {\n // Use raw db to bypass RLS filtering\n const query = selectFromDynamicTable(rawDb, table)\n existingRow = await whereIdEquals(query, id, primaryKeyColumn).executeTakeFirst()\n } else if (originalFindById) {\n // Fallback to originalFindById for tests/mocks\n existingRow = await originalFindById(id)\n } else {\n throw new RLSError(\n 'Repository does not support update operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n if (!existingRow) {\n // Let the original method handle not found\n return await originalUpdate(id, data)\n }\n\n try {\n await mutationGuard.checkUpdate(\n table,\n existingRow as Record<string, unknown>,\n data as Record<string, unknown>\n )\n\n if (auditDecisions) {\n logger.info?.('[RLS] Update allowed', { table, id, userId: ctx.auth.userId })\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error)\n if (auditDecisions) {\n logger.warn?.('[RLS] Update denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n })\n }\n }\n throw error\n }\n }\n\n return await originalUpdate(id, data)\n },\n\n /**\n * Wrapped delete with RLS check\n */\n async delete(id: unknown): Promise<unknown> {\n if (!originalDelete) {\n throw new RLSError(\n 'Repository does not support delete operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n const ctx = rlsContext.getContextOrNull()\n\n if (\n ctx &&\n !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))\n ) {\n // Fetch existing row for policy evaluation\n // Use raw db if available to bypass RLS filtering and prevent self-interception\n let existingRow: unknown\n\n if (hasRawDbInstance) {\n // Use raw db to bypass RLS filtering\n const query = selectFromDynamicTable(rawDb, table)\n existingRow = await whereIdEquals(query, id, primaryKeyColumn).executeTakeFirst()\n } else if (originalFindById) {\n // Fallback to originalFindById for tests/mocks\n existingRow = await originalFindById(id)\n } else {\n throw new RLSError(\n 'Repository does not support delete operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n if (!existingRow) {\n // Let the original method handle not found\n return await originalDelete(id)\n }\n\n try {\n await mutationGuard.checkDelete(table, existingRow as Record<string, unknown>)\n\n if (auditDecisions) {\n logger.info?.('[RLS] Delete allowed', { table, id, userId: ctx.auth.userId })\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error)\n if (auditDecisions) {\n logger.warn?.('[RLS] Delete denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n })\n }\n }\n throw error\n }\n }\n\n return await originalDelete(id)\n },\n\n /**\n * Bypass RLS for specific operation\n * Requires existing context\n *\n * @example\n * ```typescript\n * // Perform operation as system user\n * const result = await repo.withoutRLS(async () => {\n * return repo.findAll(); // No RLS filtering\n * });\n * ```\n */\n async withoutRLS<R>(fn: () => Promise<R>): Promise<R> {\n return await rlsContext.asSystemAsync(fn)\n },\n\n /**\n * Check if current user can perform operation on a row\n *\n * @example\n * ```typescript\n * const post = await repo.findById(1);\n * const canUpdate = await repo.canAccess('update', post);\n * if (canUpdate) {\n * await repo.update(1, { title: 'New title' });\n * }\n * ```\n */\n async canAccess(operation: Operation, row: Record<string, unknown>): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) return false\n if (ctx.auth.isSystem) return true\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) return true\n\n try {\n switch (operation) {\n case 'read':\n return await mutationGuard.checkRead(table, row)\n case 'create':\n await mutationGuard.checkCreate(table, row)\n return true\n case 'update':\n await mutationGuard.checkUpdate(table, row, {})\n return true\n case 'delete':\n await mutationGuard.checkDelete(table, row)\n return true\n default:\n return false\n }\n } catch (error) {\n logger.debug?.('[RLS] Access check failed', {\n table,\n operation,\n error: error instanceof Error ? error.message : String(error)\n })\n return false\n }\n }\n }\n\n return extendedRepo as T\n }\n }\n}\n","/**\n * Utility helper functions for RLS\n */\n\nimport type { RLSContext, PolicyEvaluationContext, Operation } from '../policy/types.js'\n\n/**\n * Create a policy evaluation context from RLS context\n */\nexport function createEvaluationContext<TRow = unknown, TData = unknown>(\n rlsCtx: RLSContext,\n options?: {\n row?: TRow\n data?: TData\n }\n): PolicyEvaluationContext<unknown, TRow, TData> {\n const ctx: PolicyEvaluationContext<unknown, TRow, TData> = {\n auth: rlsCtx.auth\n }\n\n if (options?.row !== undefined) {\n ctx.row = options.row\n }\n\n if (options?.data !== undefined) {\n ctx.data = options.data\n }\n\n if (rlsCtx.request !== undefined) {\n ctx.request = rlsCtx.request\n }\n\n if (rlsCtx.meta !== undefined) {\n ctx.meta = rlsCtx.meta as Record<string, unknown>\n }\n\n return ctx\n}\n\n/**\n * Check if a condition function is async\n *\n * NOTE: This function checks both constructor.name (for native async functions)\n * and return type (for transpiled code that returns Promise).\n * Transpilers often convert async functions to regular functions that return Promise.\n */\nexport function isAsyncFunction(fn: unknown): fn is (...args: unknown[]) => Promise<unknown> {\n if (!(fn instanceof Function)) {\n return false\n }\n\n // Check constructor name for native async functions\n if (fn.constructor.name === 'AsyncFunction') {\n return true\n }\n\n // For transpiled code: call the function with empty args and check if it returns a Promise\n // This is safe because policy conditions should be pure functions\n try {\n const result = (fn as Function)()\n return result instanceof Promise\n } catch {\n // If calling with no args throws, assume it's not async\n // (async functions that require args should be wrapped in the policy definition)\n return false\n }\n}\n\n/**\n * Safely evaluate a policy condition\n */\nexport async function safeEvaluate<T>(fn: () => T | Promise<T>, defaultValue: T): Promise<T> {\n try {\n const result = fn()\n if (result instanceof Promise) {\n return await result\n }\n return result\n } catch (_error) {\n // Expected failure during policy evaluation - return default value\n // Logger not available in this utility function, error is handled gracefully\n return defaultValue\n }\n}\n\n/**\n * Deep merge two objects\n */\nexport function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T {\n const result = { ...target }\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceValue = source[key]\n const targetValue = result[key]\n\n if (\n sourceValue !== undefined &&\n typeof sourceValue === 'object' &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n ) as T[keyof T]\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as T[keyof T]\n }\n }\n\n return result\n}\n\n/**\n * Create a simple hash for cache keys\n */\nexport function hashString(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32bit integer\n }\n return hash.toString(36)\n}\n\n/**\n * Normalize operations to array format\n */\nexport function normalizeOperations(operation: Operation | Operation[]): Operation[] {\n if (Array.isArray(operation)) {\n if (operation.includes('all')) {\n return ['read', 'create', 'update', 'delete']\n }\n return operation\n }\n\n if (operation === 'all') {\n return ['read', 'create', 'update', 'delete']\n }\n\n return [operation]\n}\n","/**\n * Context Resolver Types\n *\n * Provides infrastructure for pre-resolving async data before RLS policy evaluation.\n * This allows synchronous filters to access data that would otherwise require async lookups.\n *\n * @module @kysera/rls/resolvers/types\n */\n\nimport type { RLSAuthContext, RLSContext } from '../policy/types.js'\n\n// ============================================================================\n// Resolved Data Types\n// ============================================================================\n\n/**\n * Base interface for resolved data that can be added to RLS context\n *\n * @example\n * ```typescript\n * interface MyResolvedData extends ResolvedData {\n * organizationIds: string[];\n * permissions: Set<string>;\n * employeeRoles: Map<string, string[]>;\n * }\n * ```\n */\nexport interface ResolvedData {\n /**\n * Timestamp when data was resolved\n * Used for cache validation\n */\n resolvedAt: Date\n\n /**\n * Cache key used for this resolution (if cached)\n */\n cacheKey?: string\n}\n\n/**\n * Extended auth context with pre-resolved data\n *\n * @typeParam TUser - Custom user type\n * @typeParam TResolved - Type of pre-resolved data\n *\n * @example\n * ```typescript\n * interface OrgPermissions extends ResolvedData {\n * organizationIds: string[];\n * orgPermissions: Map<string, Set<string>>;\n * isOrgOwner: (orgId: string) => boolean;\n * hasOrgPermission: (orgId: string, permission: string) => boolean;\n * }\n *\n * type EnhancedAuth = EnhancedRLSAuthContext<User, OrgPermissions>;\n *\n * // Use in policy\n * filter('read', ctx => ({\n * organization_id: ctx.auth.resolved.organizationIds\n * }));\n * ```\n */\nexport interface EnhancedRLSAuthContext<TUser = unknown, TResolved extends ResolvedData = ResolvedData>\n extends RLSAuthContext<TUser> {\n /**\n * Pre-resolved data available synchronously in policies\n *\n * This data is populated by ContextResolvers before entering the RLS context.\n * Use this for async data lookups that policies need synchronously.\n */\n resolved: TResolved\n}\n\n/**\n * Extended RLS context with enhanced auth containing resolved data\n *\n * @typeParam TUser - Custom user type\n * @typeParam TResolved - Type of pre-resolved data\n * @typeParam TMeta - Custom metadata type\n */\nexport interface EnhancedRLSContext<\n TUser = unknown,\n TResolved extends ResolvedData = ResolvedData,\n TMeta = unknown\n> extends Omit<RLSContext<TUser, TMeta>, 'auth'> {\n auth: EnhancedRLSAuthContext<TUser, TResolved>\n}\n\n// ============================================================================\n// Context Resolver Interface\n// ============================================================================\n\n/**\n * Base context for resolver input (before resolution)\n */\nexport interface BaseResolverContext {\n auth: {\n userId: string | number\n roles: string[]\n tenantId?: string | number\n organizationIds?: (string | number)[]\n permissions?: string[]\n attributes?: Record<string, unknown>\n isSystem?: boolean\n }\n timestamp: Date\n meta?: unknown\n}\n\n/**\n * Context resolver that enriches base context with pre-resolved data\n *\n * Resolvers are responsible for fetching async data and making it available\n * synchronously in policy evaluation contexts.\n *\n * @typeParam TResolved - Type of resolved data this resolver produces\n *\n * @example\n * ```typescript\n * const orgPermissionResolver: ContextResolver<OrgPermissions> = {\n * name: 'org-permissions',\n *\n * async resolve(base) {\n * const employments = await db.selectFrom('employees')\n * .where('user_id', '=', base.auth.userId)\n * .where('status', '=', 'active')\n * .execute();\n *\n * const orgPermissions = new Map<string, Set<string>>();\n * // ... resolve permissions ...\n *\n * return {\n * resolvedAt: new Date(),\n * organizationIds: employments.map(e => e.organization_id),\n * orgPermissions,\n * isOrgOwner: (orgId) => employments.some(e => e.organization_id === orgId && e.is_owner),\n * hasOrgPermission: (orgId, permission) => {\n * const perms = orgPermissions.get(orgId);\n * return perms?.has('*') || perms?.has(permission) || false;\n * }\n * };\n * },\n *\n * cacheKey: (base) => `rls:org-perms:${base.auth.userId}`,\n * cacheTtl: 300 // 5 minutes\n * };\n * ```\n */\nexport interface ContextResolver<TResolved extends ResolvedData = ResolvedData> {\n /**\n * Unique name for this resolver\n * Used for logging and debugging\n */\n name: string\n\n /**\n * Resolve async data for the context\n *\n * @param base - Base context with user info\n * @returns Pre-resolved data to be added to context\n */\n resolve(base: BaseResolverContext): Promise<TResolved>\n\n /**\n * Generate cache key for this context\n * Return undefined to disable caching for this resolver\n *\n * @param base - Base context\n * @returns Cache key string or undefined\n */\n cacheKey?(base: BaseResolverContext): string | undefined\n\n /**\n * Cache TTL in seconds\n * @default 300 (5 minutes)\n */\n cacheTtl?: number\n\n /**\n * Whether this resolver is required\n * If true, resolution failure will throw an error\n * If false, the resolver will be skipped on failure\n *\n * @default true\n */\n required?: boolean\n\n /**\n * Dependencies on other resolvers (by name)\n * This resolver will wait for dependencies to complete first\n */\n dependsOn?: string[]\n\n /**\n * Priority for resolver execution order (higher = earlier)\n * @default 0\n */\n priority?: number\n}\n\n/**\n * Combined result of multiple resolvers\n *\n * @typeParam T - Union type of all resolved data types\n */\nexport interface CompositeResolvedData<T extends Record<string, ResolvedData>> extends ResolvedData {\n /**\n * Individual resolver results keyed by resolver name\n */\n resolvers: T\n}\n\n// ============================================================================\n// Resolver Manager Options\n// ============================================================================\n\n/**\n * Cache provider interface for storing resolved context data\n */\nexport interface ResolverCacheProvider {\n /**\n * Get cached data\n * @param key - Cache key\n * @returns Cached data or null if not found/expired\n */\n get<T>(key: string): Promise<T | null>\n\n /**\n * Set cached data\n * @param key - Cache key\n * @param value - Data to cache\n * @param ttlSeconds - Time to live in seconds\n */\n set<T>(key: string, value: T, ttlSeconds: number): Promise<void>\n\n /**\n * Delete cached data\n * @param key - Cache key\n */\n delete(key: string): Promise<void>\n\n /**\n * Delete all cached data matching a pattern\n * @param pattern - Pattern to match (e.g., \"rls:org-perms:*\")\n */\n deletePattern?(pattern: string): Promise<void>\n}\n\n/**\n * In-memory cache provider implementation\n *\n * Suitable for single-instance deployments or testing.\n * For distributed systems, use a Redis-based provider.\n */\nexport class InMemoryCacheProvider implements ResolverCacheProvider {\n private cache = new Map<string, { value: unknown; expiresAt: number }>()\n\n get<T>(key: string): Promise<T | null> {\n const entry = this.cache.get(key)\n if (!entry) return Promise.resolve(null)\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key)\n return Promise.resolve(null)\n }\n return Promise.resolve(entry.value as T)\n }\n\n set<T>(key: string, value: T, ttlSeconds: number): Promise<void> {\n this.cache.set(key, {\n value,\n expiresAt: Date.now() + ttlSeconds * 1000\n })\n return Promise.resolve()\n }\n\n delete(key: string): Promise<void> {\n this.cache.delete(key)\n return Promise.resolve()\n }\n\n deletePattern(pattern: string): Promise<void> {\n // Simple pattern matching: * at end matches any suffix\n const prefix = pattern.endsWith('*') ? pattern.slice(0, -1) : pattern\n for (const key of this.cache.keys()) {\n if (key.startsWith(prefix)) {\n this.cache.delete(key)\n }\n }\n return Promise.resolve()\n }\n\n /**\n * Clear all cached entries\n */\n clear(): void {\n this.cache.clear()\n }\n\n /**\n * Get current cache size\n */\n get size(): number {\n return this.cache.size\n }\n}\n\n/**\n * Options for ResolverManager\n */\nexport interface ResolverManagerOptions {\n /**\n * Cache provider for storing resolved data\n * @default InMemoryCacheProvider\n */\n cacheProvider?: ResolverCacheProvider\n\n /**\n * Default cache TTL in seconds\n * @default 300 (5 minutes)\n */\n defaultCacheTtl?: number\n\n /**\n * Whether to run resolvers in parallel when possible\n * @default true\n */\n parallelResolution?: boolean\n\n /**\n * Maximum time (ms) to wait for a single resolver\n * @default 5000 (5 seconds)\n */\n resolverTimeout?: number\n\n /**\n * Logger for resolver operations\n */\n logger?: {\n debug?: (message: string, context?: Record<string, unknown>) => void\n info?: (message: string, context?: Record<string, unknown>) => void\n warn?: (message: string, context?: Record<string, unknown>) => void\n error?: (message: string, context?: Record<string, unknown>) => void\n }\n}\n\n// ============================================================================\n// Common Resolved Data Patterns\n// ============================================================================\n\n/**\n * Common resolved data for organization-based permissions\n *\n * Pre-built pattern for multi-organization systems where users can\n * belong to multiple organizations with different roles/permissions.\n */\nexport interface OrganizationResolvedData extends ResolvedData {\n /**\n * List of organization IDs the user belongs to\n */\n organizationIds: (string | number)[]\n\n /**\n * Map of organization ID to user's permissions in that org\n */\n orgPermissions: Map<string | number, Set<string>>\n\n /**\n * Map of organization ID to user's roles in that org\n */\n orgRoles: Map<string | number, string[]>\n\n /**\n * Check if user is owner of an organization\n * @param orgId - Organization ID\n */\n isOrgOwner(orgId: string | number): boolean\n\n /**\n * Check if user has a specific permission in an organization\n * @param orgId - Organization ID\n * @param permission - Permission to check\n */\n hasOrgPermission(orgId: string | number, permission: string): boolean\n\n /**\n * Check if user has a specific role in an organization\n * @param orgId - Organization ID\n * @param role - Role to check\n */\n hasOrgRole(orgId: string | number, role: string): boolean\n}\n\n/**\n * Common resolved data for tenant-based systems\n */\nexport interface TenantResolvedData extends ResolvedData {\n /**\n * Current tenant ID (resolved from user context)\n */\n tenantId: string | number\n\n /**\n * Tenant-specific settings/restrictions\n */\n tenantSettings?: Record<string, unknown>\n\n /**\n * Tenant-specific feature flags\n */\n tenantFeatures?: Set<string>\n}\n\n/**\n * Common resolved data for hierarchical permissions\n *\n * For systems with resource hierarchies (e.g., team -> project -> task)\n */\nexport interface HierarchyResolvedData extends ResolvedData {\n /**\n * Resources the user has direct access to\n */\n directAccess: Set<string>\n\n /**\n * Resources the user has inherited access to (through hierarchy)\n */\n inheritedAccess: Set<string>\n\n /**\n * Check if user can access a resource (direct or inherited)\n * @param resourceId - Resource ID\n */\n canAccess(resourceId: string): boolean\n\n /**\n * Get the access level for a resource\n * @param resourceId - Resource ID\n * @returns Access level or null if no access\n */\n getAccessLevel(resourceId: string): string | null\n}\n\n/**\n * Combined resolved data type for common use cases\n */\nexport type CommonResolvedData = OrganizationResolvedData & TenantResolvedData\n","/**\n * Context Resolver Manager\n *\n * Orchestrates the resolution of context data from multiple resolvers,\n * handling caching, dependencies, and parallel execution.\n *\n * @module @kysera/rls/resolvers/manager\n */\n\nimport type {\n ContextResolver,\n ResolvedData,\n BaseResolverContext,\n ResolverManagerOptions,\n ResolverCacheProvider,\n EnhancedRLSContext\n} from './types.js'\nimport { InMemoryCacheProvider } from './types.js'\nimport { RLSError, RLSErrorCodes } from '../errors.js'\n\n// ============================================================================\n// Resolver Manager\n// ============================================================================\n\n/**\n * Manages context resolvers and orchestrates context resolution\n *\n * The ResolverManager is responsible for:\n * - Registering and organizing resolvers\n * - Resolving context data in the correct order (respecting dependencies)\n * - Caching resolved data\n * - Handling resolver failures\n *\n * @example\n * ```typescript\n * const manager = new ResolverManager({\n * cacheProvider: new RedisCacheProvider(redis),\n * defaultCacheTtl: 300,\n * parallelResolution: true\n * });\n *\n * // Register resolvers\n * manager.register(orgPermissionResolver);\n * manager.register(tenantSettingsResolver);\n *\n * // Resolve context\n * const enhancedCtx = await manager.resolve({\n * auth: { userId: '123', roles: ['user'] },\n * timestamp: new Date()\n * });\n *\n * // Use in RLS\n * await rlsContext.runAsync(enhancedCtx, async () => {\n * // Policies can access resolved data synchronously\n * });\n * ```\n */\nexport class ResolverManager<TResolved extends ResolvedData = ResolvedData> {\n private resolvers = new Map<string, ContextResolver>()\n private cacheProvider: ResolverCacheProvider\n private defaultCacheTtl: number\n private parallelResolution: boolean\n private resolverTimeout: number\n private logger: ResolverManagerOptions['logger']\n\n constructor(options: ResolverManagerOptions = {}) {\n this.cacheProvider = options.cacheProvider ?? new InMemoryCacheProvider()\n this.defaultCacheTtl = options.defaultCacheTtl ?? 300\n this.parallelResolution = options.parallelResolution ?? true\n this.resolverTimeout = options.resolverTimeout ?? 5000\n this.logger = options.logger\n }\n\n /**\n * Register a context resolver\n *\n * @param resolver - Resolver to register\n * @throws RLSError if resolver with same name already exists\n */\n register<T extends ResolvedData>(resolver: ContextResolver<T>): void {\n if (this.resolvers.has(resolver.name)) {\n throw new RLSError(\n `Resolver \"${resolver.name}\" is already registered`,\n RLSErrorCodes.RLS_SCHEMA_INVALID\n )\n }\n\n // Validate dependencies exist\n if (resolver.dependsOn) {\n for (const dep of resolver.dependsOn) {\n if (dep === resolver.name) {\n throw new RLSError(\n `Resolver \"${resolver.name}\" cannot depend on itself`,\n RLSErrorCodes.RLS_SCHEMA_INVALID\n )\n }\n }\n }\n\n this.resolvers.set(resolver.name, resolver as ContextResolver)\n this.logger?.debug?.(`[ResolverManager] Registered resolver: ${resolver.name}`)\n }\n\n /**\n * Unregister a context resolver\n *\n * @param name - Name of resolver to unregister\n * @returns true if resolver was removed, false if it didn't exist\n */\n unregister(name: string): boolean {\n const removed = this.resolvers.delete(name)\n if (removed) {\n this.logger?.debug?.(`[ResolverManager] Unregistered resolver: ${name}`)\n }\n return removed\n }\n\n /**\n * Check if a resolver is registered\n *\n * @param name - Resolver name\n */\n hasResolver(name: string): boolean {\n return this.resolvers.has(name)\n }\n\n /**\n * Get all registered resolver names\n */\n getResolverNames(): string[] {\n return Array.from(this.resolvers.keys())\n }\n\n /**\n * Resolve context data using all registered resolvers\n *\n * @param baseContext - Base context to resolve\n * @returns Enhanced context with resolved data\n *\n * @example\n * ```typescript\n * const baseCtx = {\n * auth: { userId: '123', roles: ['user'], tenantId: 'acme' },\n * timestamp: new Date()\n * };\n *\n * const enhancedCtx = await manager.resolve(baseCtx);\n * // enhancedCtx.auth.resolved contains all resolved data\n * ```\n */\n async resolve(baseContext: BaseResolverContext): Promise<EnhancedRLSContext<unknown, TResolved>> {\n const startTime = Date.now()\n const resolverOrder = this.getResolverOrder()\n\n this.logger?.debug?.(`[ResolverManager] Starting resolution for user ${baseContext.auth.userId}`, {\n resolverCount: resolverOrder.length,\n resolvers: resolverOrder.map(r => r.name)\n })\n\n const results = new Map<string, ResolvedData>()\n\n if (this.parallelResolution) {\n await this.resolveParallel(baseContext, resolverOrder, results)\n } else {\n await this.resolveSequential(baseContext, resolverOrder, results)\n }\n\n // Merge all resolved data\n const mergedResolved = this.mergeResolvedData(results)\n\n const enhancedContext: EnhancedRLSContext<unknown, TResolved> = {\n auth: {\n ...baseContext.auth,\n resolved: mergedResolved as TResolved\n },\n timestamp: baseContext.timestamp\n }\n\n if (baseContext.meta !== undefined) {\n enhancedContext.meta = baseContext.meta\n }\n\n const duration = Date.now() - startTime\n this.logger?.info?.(`[ResolverManager] Resolution completed`, {\n userId: baseContext.auth.userId,\n durationMs: duration,\n resolverCount: results.size\n })\n\n return enhancedContext\n }\n\n /**\n * Resolve a single resolver (useful for partial updates)\n *\n * @param name - Resolver name\n * @param baseContext - Base context\n * @returns Resolved data from the specific resolver\n */\n async resolveOne<T extends ResolvedData>(\n name: string,\n baseContext: BaseResolverContext\n ): Promise<T | null> {\n const resolver = this.resolvers.get(name)\n if (!resolver) {\n this.logger?.warn?.(`[ResolverManager] Resolver not found: ${name}`)\n return null\n }\n\n return (await this.resolveWithCache(resolver, baseContext)) as T | null\n }\n\n /**\n * Invalidate cached data for a user\n *\n * @param userId - User ID whose cache should be invalidated\n * @param resolverName - Optional specific resolver to invalidate\n */\n async invalidateCache(userId: string | number, resolverName?: string): Promise<void> {\n if (resolverName) {\n const resolver = this.resolvers.get(resolverName)\n if (resolver?.cacheKey) {\n const key = resolver.cacheKey({ auth: { userId, roles: [] }, timestamp: new Date() })\n if (key) {\n await this.cacheProvider.delete(key)\n this.logger?.debug?.(`[ResolverManager] Invalidated cache for ${resolverName}: ${key}`)\n }\n }\n } else {\n // Invalidate all resolvers for this user\n const pattern = `rls:*:${userId}:*`\n if (this.cacheProvider.deletePattern) {\n await this.cacheProvider.deletePattern(pattern)\n }\n this.logger?.debug?.(`[ResolverManager] Invalidated all cache for user ${userId}`)\n }\n }\n\n /**\n * Clear all cached data\n */\n async clearCache(): Promise<void> {\n if (this.cacheProvider instanceof InMemoryCacheProvider) {\n this.cacheProvider.clear()\n } else if (this.cacheProvider.deletePattern) {\n await this.cacheProvider.deletePattern('rls:*')\n }\n this.logger?.info?.('[ResolverManager] Cleared all cache')\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Get resolvers in dependency order (topological sort)\n */\n private getResolverOrder(): ContextResolver[] {\n const ordered: ContextResolver[] = []\n const visited = new Set<string>()\n const visiting = new Set<string>()\n\n const visit = (name: string): void => {\n if (visited.has(name)) return\n if (visiting.has(name)) {\n throw new RLSError(\n `Circular dependency detected in resolvers involving \"${name}\"`,\n RLSErrorCodes.RLS_SCHEMA_INVALID\n )\n }\n\n const resolver = this.resolvers.get(name)\n if (!resolver) return\n\n visiting.add(name)\n\n // Visit dependencies first\n if (resolver.dependsOn) {\n for (const dep of resolver.dependsOn) {\n visit(dep)\n }\n }\n\n visiting.delete(name)\n visited.add(name)\n ordered.push(resolver)\n }\n\n // Visit all resolvers\n for (const name of this.resolvers.keys()) {\n visit(name)\n }\n\n // Sort by priority within dependency constraints\n // Higher priority = earlier execution\n return ordered.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n }\n\n /**\n * Resolve resolvers sequentially\n */\n private async resolveSequential(\n baseContext: BaseResolverContext,\n resolvers: ContextResolver[],\n results: Map<string, ResolvedData>\n ): Promise<void> {\n for (const resolver of resolvers) {\n const data = await this.resolveWithCache(resolver, baseContext)\n if (data) {\n results.set(resolver.name, data)\n }\n }\n }\n\n /**\n * Resolve resolvers in parallel (respecting dependencies)\n */\n private async resolveParallel(\n baseContext: BaseResolverContext,\n resolvers: ContextResolver[],\n results: Map<string, ResolvedData>\n ): Promise<void> {\n // Group resolvers by their dependency depth\n const levels: ContextResolver[][] = []\n const assigned = new Set<string>()\n\n const getLevel = (resolver: ContextResolver): number => {\n if (!resolver.dependsOn || resolver.dependsOn.length === 0) {\n return 0\n }\n let maxDepLevel = 0\n for (const dep of resolver.dependsOn) {\n const depResolver = this.resolvers.get(dep)\n if (depResolver) {\n maxDepLevel = Math.max(maxDepLevel, getLevel(depResolver) + 1)\n }\n }\n return maxDepLevel\n }\n\n // Assign resolvers to levels\n for (const resolver of resolvers) {\n const level = getLevel(resolver)\n while (levels.length <= level) {\n levels.push([])\n }\n levels[level]!.push(resolver)\n assigned.add(resolver.name)\n }\n\n // Execute level by level\n for (const level of levels) {\n await Promise.all(\n level.map(async resolver => {\n const data = await this.resolveWithCache(resolver, baseContext)\n if (data) {\n results.set(resolver.name, data)\n }\n })\n )\n }\n }\n\n /**\n * Resolve a single resolver with caching\n */\n private async resolveWithCache(\n resolver: ContextResolver,\n baseContext: BaseResolverContext\n ): Promise<ResolvedData | null> {\n const startTime = Date.now()\n\n try {\n // Check cache first\n if (resolver.cacheKey) {\n const cacheKey = resolver.cacheKey(baseContext)\n if (cacheKey) {\n const cached = await this.cacheProvider.get<ResolvedData>(cacheKey)\n if (cached) {\n this.logger?.debug?.(`[ResolverManager] Cache hit for ${resolver.name}`, { cacheKey })\n return cached\n }\n }\n }\n\n // Resolve with timeout\n const data = await this.withTimeout(\n resolver.resolve(baseContext),\n this.resolverTimeout,\n `Resolver \"${resolver.name}\" timed out after ${this.resolverTimeout}ms`\n )\n\n // Cache the result\n if (resolver.cacheKey) {\n const cacheKey = resolver.cacheKey(baseContext)\n if (cacheKey) {\n const ttl = resolver.cacheTtl ?? this.defaultCacheTtl\n await this.cacheProvider.set(cacheKey, data, ttl)\n this.logger?.debug?.(`[ResolverManager] Cached ${resolver.name}`, { cacheKey, ttl })\n }\n }\n\n const duration = Date.now() - startTime\n this.logger?.debug?.(`[ResolverManager] Resolved ${resolver.name}`, { durationMs: duration })\n\n return data\n } catch (error) {\n const duration = Date.now() - startTime\n this.logger?.error?.(`[ResolverManager] Failed to resolve ${resolver.name}`, {\n error: error instanceof Error ? error.message : String(error),\n durationMs: duration\n })\n\n if (resolver.required !== false) {\n throw new RLSError(\n `Required resolver \"${resolver.name}\" failed: ${error instanceof Error ? error.message : String(error)}`,\n RLSErrorCodes.RLS_POLICY_EVALUATION_ERROR\n )\n }\n\n return null\n }\n }\n\n /**\n * Execute a promise with timeout\n */\n private async withTimeout<T>(promise: Promise<T>, timeoutMs: number, message: string): Promise<T> {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => setTimeout(() => { reject(new Error(message)); }, timeoutMs))\n ])\n }\n\n /**\n * Merge resolved data from multiple resolvers\n */\n private mergeResolvedData(results: Map<string, ResolvedData>): ResolvedData {\n const merged: ResolvedData & Record<string, unknown> = {\n resolvedAt: new Date()\n }\n\n for (const [name, data] of results) {\n // Add resolver data under its name\n merged[name] = data\n\n // Also spread properties to root level for convenience\n for (const [key, value] of Object.entries(data)) {\n if (key !== 'resolvedAt' && key !== 'cacheKey') {\n if (merged[key] === undefined) {\n merged[key] = value\n }\n }\n }\n }\n\n return merged\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a context resolver manager with common defaults\n *\n * @param options - Manager options\n * @returns Configured ResolverManager\n */\nexport function createResolverManager<TResolved extends ResolvedData = ResolvedData>(\n options?: ResolverManagerOptions\n): ResolverManager<TResolved> {\n return new ResolverManager<TResolved>(options)\n}\n\n/**\n * Helper to create a context resolver\n *\n * @param config - Resolver configuration\n * @returns ContextResolver instance\n *\n * @example\n * ```typescript\n * const resolver = createResolver({\n * name: 'org-permissions',\n * resolve: async (base) => {\n * const orgs = await getEmployeeOrganizations(base.auth.userId);\n * return {\n * resolvedAt: new Date(),\n * organizationIds: orgs.map(o => o.id)\n * };\n * },\n * cacheKey: (base) => `rls:org:${base.auth.userId}`,\n * cacheTtl: 300\n * });\n * ```\n */\nexport function createResolver<TResolved extends ResolvedData>(\n config: ContextResolver<TResolved>\n): ContextResolver<TResolved> {\n return {\n required: true,\n priority: 0,\n ...config\n }\n}\n","/**\n * ReBAC (Relationship-Based Access Control) Types\n *\n * Provides type definitions for relationship-based filtering in RLS policies.\n * ReBAC allows policies to be defined based on relationships between entities\n * in the database, enabling complex access control patterns like\n * \"show products if user is employee of product's shop's organization\".\n *\n * @module @kysera/rls/rebac/types\n */\n\nimport type { PolicyEvaluationContext, PolicyDefinition } from '../policy/types.js'\n\n// ============================================================================\n// Relationship Definition Types\n// ============================================================================\n\n/**\n * A single step in a relationship path\n *\n * Defines how to join from one table to another.\n *\n * @example\n * ```typescript\n * // Simple join: products.shop_id -> shops.id\n * const step: RelationshipStep = {\n * from: 'products',\n * to: 'shops',\n * fromColumn: 'shop_id',\n * toColumn: 'id'\n * };\n * ```\n */\nexport interface RelationshipStep {\n /**\n * Source table name\n */\n from: string\n\n /**\n * Target table name\n */\n to: string\n\n /**\n * Column in source table for the join\n * @default 'id' on target table side, '{to}_id' on source side\n */\n fromColumn?: string\n\n /**\n * Column in target table for the join\n * @default 'id'\n */\n toColumn?: string\n\n /**\n * Optional alias for the target table in the join\n * Useful when joining the same table multiple times\n */\n alias?: string\n\n /**\n * Join type\n * @default 'inner'\n */\n joinType?: 'inner' | 'left' | 'right'\n\n /**\n * Additional conditions for this join step\n * @example { 'shops.deleted_at': null, 'shops.status': 'active' }\n */\n additionalConditions?: Record<string, unknown>\n}\n\n/**\n * Complete relationship path definition\n *\n * Defines a chain of relationships from a source table to a target.\n *\n * @example\n * ```typescript\n * // Path: products -> shops -> organizations -> employees\n * const path: RelationshipPath = {\n * name: 'orgEmployee',\n * steps: [\n * { from: 'products', to: 'shops', fromColumn: 'shop_id' },\n * { from: 'shops', to: 'organizations', fromColumn: 'organization_id' },\n * { from: 'organizations', to: 'employees', toColumn: 'organization_id' }\n * ]\n * };\n * ```\n */\nexport interface RelationshipPath {\n /**\n * Unique name for this relationship path\n * Used in policy definitions to reference this path\n */\n name: string\n\n /**\n * Steps in the relationship chain\n */\n steps: RelationshipStep[]\n\n /**\n * Optional description for documentation\n */\n description?: string\n}\n\n/**\n * Condition to apply at the end of a relationship path\n *\n * @typeParam TCtx - Policy evaluation context type\n */\nexport type RelationshipCondition<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> =\n | ((ctx: TCtx) => Record<string, unknown>)\n | Record<string, unknown>\n\n/**\n * ReBAC policy definition\n *\n * Extends standard policy definition with relationship-based filtering.\n */\nexport interface ReBAcPolicyDefinition<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext>\n extends Omit<PolicyDefinition, 'condition'> {\n /**\n * Name of the relationship path to use (defined in relationships config)\n */\n relationshipPath: string\n\n /**\n * Conditions to apply at the end of the relationship\n * These conditions filter the final table in the relationship chain.\n *\n * @example\n * ```typescript\n * // Filter employees table at end of relationship\n * endCondition: ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'active'\n * })\n * ```\n */\n endCondition: RelationshipCondition<TCtx>\n\n /**\n * Whether this is a permissive or restrictive policy\n * - 'allow': Row is accessible if relationship exists\n * - 'deny': Row is NOT accessible if relationship exists\n * @default 'allow'\n */\n policyType?: 'allow' | 'deny'\n}\n\n// ============================================================================\n// Table ReBAC Configuration\n// ============================================================================\n\n/**\n * ReBAC configuration for a single table\n */\nexport interface TableReBAcConfig {\n /**\n * Relationship paths available for this table\n */\n relationships: RelationshipPath[]\n\n /**\n * ReBAC policies for this table\n */\n policies: ReBAcPolicyDefinition[]\n}\n\n/**\n * Complete ReBAC schema for all tables\n *\n * @typeParam DB - Database schema type\n */\nexport type ReBAcSchema<DB> = {\n [K in keyof DB]?: TableReBAcConfig\n}\n\n// ============================================================================\n// Compiled ReBAC Types\n// ============================================================================\n\n/**\n * Compiled relationship path ready for query generation\n */\nexport interface CompiledRelationshipPath {\n /**\n * Path name\n */\n name: string\n\n /**\n * Compiled join steps with defaults filled in\n */\n steps: Required<RelationshipStep>[]\n\n /**\n * Source table (first table in the chain)\n */\n sourceTable: string\n\n /**\n * Target table (final table in the chain)\n */\n targetTable: string\n}\n\n/**\n * Compiled ReBAC policy ready for evaluation\n */\nexport interface CompiledReBAcPolicy<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {\n /**\n * Policy name\n */\n name: string\n\n /**\n * Policy type (allow/deny)\n */\n type: 'allow' | 'deny'\n\n /**\n * Operations this policy applies to\n */\n operations: Set<string>\n\n /**\n * Compiled relationship path\n */\n relationshipPath: CompiledRelationshipPath\n\n /**\n * Function to get end conditions\n */\n getEndConditions: (ctx: TCtx) => Record<string, unknown>\n\n /**\n * Priority for policy evaluation\n */\n priority: number\n}\n\n// ============================================================================\n// Query Generation Types\n// ============================================================================\n\n/**\n * Generated EXISTS subquery for ReBAC filtering\n */\nexport interface ReBAcSubquery {\n /**\n * SQL for the EXISTS subquery\n */\n sql: string\n\n /**\n * Parameter values for the subquery\n */\n parameters: unknown[]\n\n /**\n * Whether this is an allow (EXISTS) or deny (NOT EXISTS) check\n */\n isNegated: boolean\n}\n\n/**\n * Options for ReBAC query generation\n */\nexport interface ReBAcQueryOptions {\n /**\n * Table alias for the main query table\n * @default table name\n */\n mainTableAlias?: string\n\n /**\n * Whether to use qualified column names\n * @default true\n */\n qualifyColumns?: boolean\n\n /**\n * Database dialect for query generation\n * @default 'postgres'\n */\n dialect?: 'postgres' | 'mysql' | 'sqlite'\n}\n\n// ============================================================================\n// Predefined Relationship Patterns\n// ============================================================================\n\n/**\n * Common relationship pattern: Resource belongs to organization via owner\n *\n * @param resourceTable - Table containing the resource\n * @param organizationColumn - Column linking to organization\n *\n * @example\n * ```typescript\n * const path = orgMembershipPath('products', 'organization_id');\n * // Creates path: products -> organizations -> employees\n * ```\n */\nexport function orgMembershipPath(\n resourceTable: string,\n organizationColumn = 'organization_id'\n): RelationshipPath {\n return {\n name: `${resourceTable}_org_membership`,\n description: `Access ${resourceTable} through organization membership`,\n steps: [\n {\n from: resourceTable,\n to: 'organizations',\n fromColumn: organizationColumn,\n toColumn: 'id'\n },\n {\n from: 'organizations',\n to: 'employees',\n fromColumn: 'id',\n toColumn: 'organization_id'\n }\n ]\n }\n}\n\n/**\n * Common relationship pattern: Resource belongs to shop's organization\n *\n * @param resourceTable - Table containing the resource\n * @param shopColumn - Column linking to shop\n *\n * @example\n * ```typescript\n * const path = shopOrgMembershipPath('products', 'shop_id');\n * // Creates path: products -> shops -> organizations -> employees\n * ```\n */\nexport function shopOrgMembershipPath(\n resourceTable: string,\n shopColumn = 'shop_id'\n): RelationshipPath {\n return {\n name: `${resourceTable}_shop_org_membership`,\n description: `Access ${resourceTable} through shop's organization membership`,\n steps: [\n {\n from: resourceTable,\n to: 'shops',\n fromColumn: shopColumn,\n toColumn: 'id'\n },\n {\n from: 'shops',\n to: 'organizations',\n fromColumn: 'organization_id',\n toColumn: 'id'\n },\n {\n from: 'organizations',\n to: 'employees',\n fromColumn: 'id',\n toColumn: 'organization_id'\n }\n ]\n }\n}\n\n/**\n * Common relationship pattern: Hierarchical team access\n *\n * @param resourceTable - Table containing the resource\n * @param teamColumn - Column linking to team\n *\n * @example\n * ```typescript\n * const path = teamHierarchyPath('tasks', 'team_id');\n * // Creates path: tasks -> teams -> team_members\n * ```\n */\nexport function teamHierarchyPath(\n resourceTable: string,\n teamColumn = 'team_id'\n): RelationshipPath {\n return {\n name: `${resourceTable}_team_access`,\n description: `Access ${resourceTable} through team membership`,\n steps: [\n {\n from: resourceTable,\n to: 'teams',\n fromColumn: teamColumn,\n toColumn: 'id'\n },\n {\n from: 'teams',\n to: 'team_members',\n fromColumn: 'id',\n toColumn: 'team_id'\n }\n ]\n }\n}\n","/**\n * ReBAC Policy Registry\n *\n * Manages relationship definitions and ReBAC policies for RLS.\n *\n * @module @kysera/rls/rebac/registry\n */\n\nimport type {\n RelationshipPath,\n RelationshipStep,\n ReBAcPolicyDefinition,\n ReBAcSchema,\n TableReBAcConfig,\n CompiledRelationshipPath,\n CompiledReBAcPolicy\n} from './types.js'\nimport type { PolicyEvaluationContext, Operation } from '../policy/types.js'\nimport { RLSSchemaError } from '../errors.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\n\n// ============================================================================\n// ReBAC Registry\n// ============================================================================\n\n/**\n * Internal compiled table configuration\n */\ninterface TableReBAcCompiled {\n relationships: Map<string, CompiledRelationshipPath>\n policies: CompiledReBAcPolicy[]\n}\n\n/**\n * ReBAC Registry\n *\n * Manages relationship paths and ReBAC policies across tables.\n *\n * @example\n * ```typescript\n * const registry = new ReBAcRegistry();\n *\n * // Register relationship paths and policies\n * registry.loadSchema({\n * products: {\n * relationships: [\n * shopOrgMembershipPath('products', 'shop_id')\n * ],\n * policies: [\n * {\n * type: 'filter',\n * operation: 'read',\n * relationshipPath: 'products_shop_org_membership',\n * endCondition: ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'active'\n * })\n * }\n * ]\n * }\n * });\n *\n * // Get policies for a table\n * const policies = registry.getPolicies('products', 'read');\n * ```\n */\nexport class ReBAcRegistry<DB = unknown> {\n private tables = new Map<string, TableReBAcCompiled>()\n private globalRelationships = new Map<string, CompiledRelationshipPath>()\n private logger: KyseraLogger\n\n constructor(schema?: ReBAcSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger\n if (schema) {\n this.loadSchema(schema)\n }\n }\n\n /**\n * Load ReBAC schema\n */\n loadSchema(schema: ReBAcSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n this.registerTable(table, config as TableReBAcConfig)\n }\n }\n\n /**\n * Register ReBAC configuration for a single table\n */\n registerTable(table: string, config: TableReBAcConfig): void {\n const compiled: TableReBAcCompiled = {\n relationships: new Map(),\n policies: []\n }\n\n // Compile relationships\n for (const rel of config.relationships) {\n const compiledPath = this.compileRelationshipPath(rel, table)\n compiled.relationships.set(rel.name, compiledPath)\n // Also register globally for cross-table references\n this.globalRelationships.set(rel.name, compiledPath)\n }\n\n // Compile policies\n for (let i = 0; i < config.policies.length; i++) {\n const policy = config.policies[i]\n if (!policy) continue\n\n const policyName = policy.name ?? `${table}_rebac_policy_${i}`\n const compiledPolicy = this.compilePolicy(policy, policyName, table, compiled.relationships)\n compiled.policies.push(compiledPolicy)\n }\n\n // Sort by priority\n compiled.policies.sort((a, b) => b.priority - a.priority)\n\n this.tables.set(table, compiled)\n this.logger.info?.(`[ReBAC] Registered table: ${table}`, {\n relationships: config.relationships.length,\n policies: config.policies.length\n })\n }\n\n /**\n * Register a global relationship path (available to all tables)\n */\n registerRelationship(path: RelationshipPath): void {\n if (!path.steps.length) {\n throw new RLSSchemaError(`Relationship path \"${path.name}\" has no steps`, {\n path: path.name\n })\n }\n\n const compiled = this.compileRelationshipPath(path, path.steps[0]!.from)\n this.globalRelationships.set(path.name, compiled)\n }\n\n /**\n * Get ReBAC policies for a table and operation\n */\n getPolicies(table: string, operation: Operation): CompiledReBAcPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.policies.filter(p => p.operations.has(operation) || p.operations.has('all'))\n }\n\n /**\n * Get a specific relationship path\n */\n getRelationship(name: string, table?: string): CompiledRelationshipPath | undefined {\n // Check table-specific first\n if (table) {\n const tableConfig = this.tables.get(table)\n const tablePath = tableConfig?.relationships.get(name)\n if (tablePath) return tablePath\n }\n\n // Fall back to global\n return this.globalRelationships.get(name)\n }\n\n /**\n * Check if table has ReBAC configuration\n */\n hasTable(table: string): boolean {\n return this.tables.has(table)\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys())\n }\n\n /**\n * Clear all registrations\n */\n clear(): void {\n this.tables.clear()\n this.globalRelationships.clear()\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Compile a relationship path definition\n */\n private compileRelationshipPath(path: RelationshipPath, sourceTable: string): CompiledRelationshipPath {\n if (path.steps.length === 0) {\n throw new RLSSchemaError(`Relationship path \"${path.name}\" must have at least one step`, {\n path: path.name\n })\n }\n\n const compiledSteps: Required<RelationshipStep>[] = path.steps.map((step, index) => {\n // Validate step\n if (!step.from || !step.to) {\n throw new RLSSchemaError(\n `Relationship step ${index} in \"${path.name}\" must have 'from' and 'to' tables`,\n { path: path.name, step: index }\n )\n }\n\n // Fill defaults\n return {\n from: step.from,\n to: step.to,\n fromColumn: step.fromColumn ?? `${step.to}_id`,\n toColumn: step.toColumn ?? 'id',\n alias: step.alias ?? step.to,\n joinType: step.joinType ?? 'inner',\n additionalConditions: step.additionalConditions ?? {}\n }\n })\n\n // Validate chain continuity\n for (let i = 1; i < compiledSteps.length; i++) {\n const prevStep = compiledSteps[i - 1]!\n const currentStep = compiledSteps[i]!\n\n // Each step's 'from' should match previous step's 'to'\n if (currentStep.from !== prevStep.to && currentStep.from !== prevStep.alias) {\n throw new RLSSchemaError(\n `Relationship path \"${path.name}\" has broken chain at step ${i}: ` +\n `expected '${prevStep.to}' but got '${currentStep.from}'`,\n { path: path.name, step: i }\n )\n }\n }\n\n const lastStep = compiledSteps[compiledSteps.length - 1]!\n\n return {\n name: path.name,\n steps: compiledSteps,\n sourceTable,\n targetTable: lastStep.to\n }\n }\n\n /**\n * Compile a ReBAC policy definition\n */\n private compilePolicy(\n policy: ReBAcPolicyDefinition,\n name: string,\n table: string,\n tableRelationships: Map<string, CompiledRelationshipPath>\n ): CompiledReBAcPolicy {\n // Get relationship path\n const relationshipPath =\n tableRelationships.get(policy.relationshipPath) ??\n this.globalRelationships.get(policy.relationshipPath)\n\n if (!relationshipPath) {\n throw new RLSSchemaError(\n `ReBAC policy \"${name}\" references unknown relationship path \"${policy.relationshipPath}\"`,\n { policy: name, table, relationshipPath: policy.relationshipPath }\n )\n }\n\n // Normalize operations\n const ops = Array.isArray(policy.operation) ? policy.operation : [policy.operation]\n const expandedOps = ops.flatMap(op =>\n op === 'all' ? ['read', 'create', 'update', 'delete'] : [op]\n )\n\n // Compile end condition\n const getEndConditions =\n typeof policy.endCondition === 'function'\n ? policy.endCondition\n : () => policy.endCondition as Record<string, unknown>\n\n return {\n name,\n type: policy.policyType ?? 'allow',\n operations: new Set(expandedOps),\n relationshipPath,\n getEndConditions: getEndConditions as (ctx: PolicyEvaluationContext) => Record<string, unknown>,\n priority: policy.priority ?? 0\n }\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a ReBAC registry\n */\nexport function createReBAcRegistry<DB = unknown>(\n schema?: ReBAcSchema<DB>,\n options?: { logger?: KyseraLogger }\n): ReBAcRegistry<DB> {\n return new ReBAcRegistry<DB>(schema, options)\n}\n","/**\n * ReBAC Query Transformer\n *\n * Transforms queries to apply relationship-based access control policies.\n * Generates EXISTS subqueries that filter rows based on relationship chains.\n *\n * @module @kysera/rls/rebac/transformer\n */\n\nimport type { SelectQueryBuilder } from 'kysely'\nimport { sql } from 'kysely'\nimport type { ReBAcRegistry } from './registry.js'\nimport type { CompiledReBAcPolicy, ReBAcQueryOptions, ReBAcPolicyDefinition } from './types.js'\nimport type { PolicyEvaluationContext, Operation, RLSContext } from '../policy/types.js'\nimport { rlsContext } from '../context/manager.js'\n\n// ============================================================================\n// ReBAC Transformer\n// ============================================================================\n\n/**\n * ReBAC query transformer\n *\n * Applies relationship-based access control to SELECT queries by generating\n * EXISTS subqueries that follow relationship paths.\n *\n * @example\n * ```typescript\n * const transformer = new ReBAcTransformer(registry);\n *\n * // Transform query\n * let query = db.selectFrom('products').selectAll();\n * query = transformer.transform(query, 'products', 'read');\n *\n * // Generated SQL includes EXISTS subquery:\n * // SELECT * FROM products p\n * // WHERE EXISTS (\n * // SELECT 1 FROM shops s\n * // JOIN organizations o ON s.organization_id = o.id\n * // JOIN employees e ON e.organization_id = o.id\n * // WHERE s.id = p.shop_id\n * // AND e.user_id = $1\n * // AND e.status = 'active'\n * // )\n * ```\n */\nexport class ReBAcTransformer<DB = unknown> {\n constructor(\n private registry: ReBAcRegistry<DB>,\n private options: ReBAcQueryOptions = {}\n ) {\n this.options = {\n qualifyColumns: true,\n dialect: 'postgres',\n ...options\n }\n }\n\n /**\n * Transform a SELECT query by applying ReBAC policies\n *\n * @param qb - Query builder to transform\n * @param table - Table being queried\n * @param operation - Operation being performed\n * @returns Transformed query builder\n */\n transform<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n table: string,\n operation: Operation = 'read'\n ): SelectQueryBuilder<DB, TB, O> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n // No context - handled by main RLS plugin\n return qb\n }\n\n // System users bypass ReBAC\n if (ctx.auth.isSystem) {\n return qb\n }\n\n // Get applicable ReBAC policies\n const policies = this.registry.getPolicies(table, operation)\n if (policies.length === 0) {\n return qb\n }\n\n // Apply each policy\n let result = qb\n for (const policy of policies) {\n result = this.applyPolicy(result, policy, ctx, table)\n }\n\n return result\n }\n\n /**\n * Generate EXISTS condition SQL for a policy\n *\n * This method can be used to get the raw SQL for debugging or manual query building.\n *\n * @param policy - ReBAC policy to generate SQL for\n * @param ctx - RLS context\n * @param mainTable - Main query table\n * @param mainTableAlias - Alias for main table\n * @returns SQL string and parameters\n */\n generateExistsSql(\n policy: CompiledReBAcPolicy,\n ctx: RLSContext,\n mainTable: string,\n mainTableAlias?: string\n ): { sql: string; params: unknown[] } {\n const { relationshipPath } = policy\n const evalCtx = this.createEvalContext(ctx, mainTable)\n const endConditions = policy.getEndConditions(evalCtx)\n\n const alias = mainTableAlias ?? mainTable\n const params: unknown[] = []\n let paramIndex = 1\n\n // Build the EXISTS subquery\n const steps = relationshipPath.steps\n if (steps.length === 0) {\n return { sql: 'TRUE', params: [] }\n }\n\n // Start with first join target\n const firstStep = steps[0]!\n let sql = `SELECT 1 FROM ${this.quote(firstStep.to)}`\n if (firstStep.alias !== firstStep.to) {\n sql += ` AS ${this.quote(firstStep.alias)}`\n }\n\n // Add joins for remaining steps\n for (let i = 1; i < steps.length; i++) {\n const step = steps[i]!\n const joinType = step.joinType === 'left' ? 'LEFT JOIN' : step.joinType === 'right' ? 'RIGHT JOIN' : 'JOIN'\n\n sql += ` ${joinType} ${this.quote(step.to)}`\n if (step.alias !== step.to) {\n sql += ` AS ${this.quote(step.alias)}`\n }\n\n // Join condition\n const prevStep = steps[i - 1]!\n const prevAlias = prevStep.alias\n sql += ` ON ${this.quote(prevAlias)}.${this.quote(step.fromColumn)} = ${this.quote(step.alias)}.${this.quote(step.toColumn)}`\n\n // Additional conditions for this step\n if (Object.keys(step.additionalConditions).length > 0) {\n for (const [col, val] of Object.entries(step.additionalConditions)) {\n if (val === null) {\n sql += ` AND ${this.quote(step.alias)}.${this.quote(col)} IS NULL`\n } else {\n sql += ` AND ${this.quote(step.alias)}.${this.quote(col)} = ${this.param(paramIndex++)}`\n params.push(val)\n }\n }\n }\n }\n\n // WHERE clause connecting to main table\n sql += ` WHERE ${this.quote(firstStep.alias)}.${this.quote(firstStep.toColumn)} = ${this.quote(alias)}.${this.quote(firstStep.fromColumn)}`\n\n // Additional conditions from first step\n if (Object.keys(firstStep.additionalConditions).length > 0) {\n for (const [col, val] of Object.entries(firstStep.additionalConditions)) {\n if (val === null) {\n sql += ` AND ${this.quote(firstStep.alias)}.${this.quote(col)} IS NULL`\n } else {\n sql += ` AND ${this.quote(firstStep.alias)}.${this.quote(col)} = ${this.param(paramIndex++)}`\n params.push(val)\n }\n }\n }\n\n // End conditions (applied to the final table in the chain)\n const lastStep = steps[steps.length - 1]!\n for (const [col, val] of Object.entries(endConditions)) {\n if (val === null) {\n sql += ` AND ${this.quote(lastStep.alias)}.${this.quote(col)} IS NULL`\n } else if (val === undefined) {\n // Skip undefined\n continue\n } else if (Array.isArray(val)) {\n if (val.length === 0) {\n sql += ` AND FALSE`\n } else {\n const placeholders = val.map(() => this.param(paramIndex++)).join(', ')\n sql += ` AND ${this.quote(lastStep.alias)}.${this.quote(col)} IN (${placeholders})`\n params.push(...val)\n }\n } else {\n sql += ` AND ${this.quote(lastStep.alias)}.${this.quote(col)} = ${this.param(paramIndex++)}`\n params.push(val)\n }\n }\n\n // Wrap in EXISTS or NOT EXISTS based on policy type\n const existsExpr = policy.type === 'deny' ? `NOT EXISTS (${sql})` : `EXISTS (${sql})`\n\n return { sql: existsExpr, params }\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Apply a single ReBAC policy to a query\n *\n * NOTE: Uses type casting for dynamic SQL because Kysely's type system\n * requires compile-time known types, but ReBAC policies work with\n * runtime-generated EXISTS clauses.\n */\n private applyPolicy<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n policy: CompiledReBAcPolicy,\n ctx: RLSContext,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n const { sql: existsSql, params } = this.generateExistsSql(policy, ctx, table, this.options.mainTableAlias)\n\n // Build the SQL template parts for parameterization\n // Replace $N placeholders with sql template placeholders\n const sqlParts = existsSql.split(/\\$\\d+/)\n\n // Use Kysely's sql template function with tagged template literal\n // Build a raw sql expression with proper parameter binding\n const rawBuilder = sql.join(\n sqlParts.map((part, i) => {\n if (i < params.length) {\n return sql`${sql.raw(part)}${params[i]}`\n }\n return sql.raw(part)\n })\n )\n\n // Add the EXISTS/NOT EXISTS condition to the WHERE clause\n // Type cast is necessary because sql.join returns RawBuilder<unknown>\n // but where() requires ExpressionOrFactory<SqlBool>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return qb.where(rawBuilder as any) as SelectQueryBuilder<DB, TB, O>\n }\n\n /**\n * Create evaluation context for policy conditions\n */\n private createEvalContext(ctx: RLSContext, table: string): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n table,\n operation: 'read',\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n }\n\n /**\n * Quote an identifier for the target dialect\n */\n private quote(identifier: string): string {\n switch (this.options.dialect) {\n case 'mysql':\n return `\\`${identifier}\\``\n case 'sqlite':\n return `\"${identifier}\"`\n case 'postgres':\n default:\n return `\"${identifier}\"`\n }\n }\n\n /**\n * Generate parameter placeholder for the target dialect\n */\n private param(index: number): string {\n switch (this.options.dialect) {\n case 'mysql':\n case 'sqlite':\n return '?'\n case 'postgres':\n default:\n return `$${index}`\n }\n }\n}\n\n// ============================================================================\n// Policy Builder Functions\n// ============================================================================\n\n/**\n * Create a ReBAC allow policy\n *\n * Rows are accessible if the relationship EXISTS with the given end conditions.\n *\n * @param operation - Operation(s) this policy applies to\n * @param relationshipPath - Name of the relationship path to use\n * @param endCondition - Conditions to apply at the end of the relationship\n * @param options - Additional policy options\n *\n * @example\n * ```typescript\n * // Allow read if user is employee of product's shop's organization\n * allowRelation('read', 'products_shop_org_membership', ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'active'\n * }))\n * ```\n */\nexport function allowRelation(\n operation: Operation | Operation[],\n relationshipPath: string,\n endCondition: ((ctx: PolicyEvaluationContext) => Record<string, unknown>) | Record<string, unknown>,\n options?: { name?: string; priority?: number }\n): ReBAcPolicyDefinition {\n const policy: ReBAcPolicyDefinition = {\n type: 'filter',\n operation,\n relationshipPath,\n endCondition,\n policyType: 'allow'\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.priority !== undefined) {\n policy.priority = options.priority\n }\n\n return policy\n}\n\n/**\n * Create a ReBAC deny policy\n *\n * Rows are NOT accessible if the relationship EXISTS with the given conditions.\n *\n * @param operation - Operation(s) this policy applies to\n * @param relationshipPath - Name of the relationship path to use\n * @param endCondition - Conditions to apply at the end of the relationship\n * @param options - Additional policy options\n *\n * @example\n * ```typescript\n * // Deny access if user is blocked in the organization\n * denyRelation('all', 'products_shop_org_membership', ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'blocked'\n * }))\n * ```\n */\nexport function denyRelation(\n operation: Operation | Operation[],\n relationshipPath: string,\n endCondition: ((ctx: PolicyEvaluationContext) => Record<string, unknown>) | Record<string, unknown>,\n options?: { name?: string; priority?: number }\n): ReBAcPolicyDefinition {\n const policy: ReBAcPolicyDefinition = {\n type: 'filter',\n operation,\n relationshipPath,\n endCondition,\n policyType: 'deny',\n priority: options?.priority ?? 100 // Higher priority for deny\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n return policy\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a ReBAC transformer\n */\nexport function createReBAcTransformer<DB = unknown>(\n registry: ReBAcRegistry<DB>,\n options?: ReBAcQueryOptions\n): ReBAcTransformer<DB> {\n return new ReBAcTransformer<DB>(registry, options)\n}\n","/**\n * Field-Level Access Control Types\n *\n * Provides type definitions for controlling access to individual columns\n * based on context. This allows hiding sensitive fields from unauthorized users.\n *\n * @module @kysera/rls/field-access/types\n */\n\nimport type { PolicyEvaluationContext } from '../policy/types.js'\n\n// ============================================================================\n// Field Access Types\n// ============================================================================\n\n/**\n * Operations that can be controlled at field level\n */\nexport type FieldOperation = 'read' | 'write'\n\n/**\n * Field access condition function\n *\n * Returns true if the field is accessible, false otherwise.\n *\n * @typeParam TCtx - Policy evaluation context type\n */\nexport type FieldAccessCondition<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> = (\n ctx: TCtx\n) => boolean | Promise<boolean>\n\n/**\n * Configuration for a single field's access control\n *\n * @example\n * ```typescript\n * const emailConfig: FieldAccessConfig = {\n * read: ctx => ctx.auth.userId === ctx.row.id || ctx.auth.roles.includes('admin'),\n * write: ctx => ctx.auth.userId === ctx.row.id\n * };\n * ```\n */\nexport interface FieldAccessConfig<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {\n /**\n * Condition for read access\n * If undefined, uses table default\n */\n read?: FieldAccessCondition<TCtx>\n\n /**\n * Condition for write access\n * If undefined, uses table default\n */\n write?: FieldAccessCondition<TCtx>\n\n /**\n * Value to use when field is not readable\n * @default null\n */\n maskedValue?: unknown\n\n /**\n * Whether to completely omit the field when not readable\n * @default false (uses maskedValue instead)\n */\n omitWhenHidden?: boolean\n}\n\n/**\n * Table field access configuration\n *\n * @typeParam TRow - Type of the database row\n * @typeParam TCtx - Policy evaluation context type\n *\n * @example\n * ```typescript\n * const usersFieldAccess: TableFieldAccessConfig<User> = {\n * default: 'allow',\n * fields: {\n * email: {\n * read: ctx => ctx.auth.userId === ctx.row.id || ctx.auth.roles.includes('admin')\n * },\n * password_hash: {\n * read: () => false,\n * write: () => false\n * },\n * mfa_totp_secret: {\n * read: ctx => ctx.auth.userId === ctx.row.id,\n * omitWhenHidden: true\n * }\n * }\n * };\n * ```\n */\nexport interface TableFieldAccessConfig<\n TRow = unknown,\n TCtx extends PolicyEvaluationContext = PolicyEvaluationContext\n> {\n /**\n * Default access policy for fields not explicitly configured\n * - 'allow': All fields are accessible by default\n * - 'deny': Only explicitly allowed fields are accessible\n * @default 'allow'\n */\n default?: 'allow' | 'deny'\n\n /**\n * Field-specific access configurations\n */\n fields: {\n [K in keyof TRow]?: FieldAccessConfig<TCtx>\n }\n\n /**\n * Roles that bypass field access control\n */\n skipFor?: string[]\n}\n\n/**\n * Complete field access schema for all tables\n *\n * @typeParam DB - Database schema type\n */\nexport type FieldAccessSchema<DB> = {\n [K in keyof DB]?: TableFieldAccessConfig<DB[K]>\n}\n\n// ============================================================================\n// Compiled Field Access Types\n// ============================================================================\n\n/**\n * Compiled field access configuration ready for evaluation\n */\nexport interface CompiledFieldAccess {\n /**\n * Field name\n */\n field: string\n\n /**\n * Compiled read condition\n * Returns true if field is readable\n */\n canRead: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n\n /**\n * Compiled write condition\n * Returns true if field is writable\n */\n canWrite: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n\n /**\n * Value to use when field is masked\n */\n maskedValue: unknown\n\n /**\n * Whether to omit the field entirely when hidden\n */\n omitWhenHidden: boolean\n}\n\n/**\n * Compiled table field access configuration\n */\nexport interface CompiledTableFieldAccess {\n /**\n * Table name\n */\n table: string\n\n /**\n * Default access policy\n */\n defaultAccess: 'allow' | 'deny'\n\n /**\n * Roles that bypass field access\n */\n skipFor: string[]\n\n /**\n * Field-specific configurations\n */\n fields: Map<string, CompiledFieldAccess>\n}\n\n// ============================================================================\n// Field Masking Result Types\n// ============================================================================\n\n/**\n * Result of field access evaluation\n */\nexport interface FieldAccessResult {\n /**\n * Whether the field is accessible\n */\n accessible: boolean\n\n /**\n * If not accessible, the reason\n */\n reason?: string\n\n /**\n * Value to use (original or masked)\n */\n value: unknown\n\n /**\n * Whether the field should be omitted entirely\n */\n omit: boolean\n}\n\n/**\n * Result of applying field access to a row\n */\nexport interface MaskedRow<T = Record<string, unknown>> {\n /**\n * The row with field access applied\n */\n data: Partial<T>\n\n /**\n * Fields that were masked\n */\n maskedFields: string[]\n\n /**\n * Fields that were omitted\n */\n omittedFields: string[]\n}\n\n// ============================================================================\n// Field Access Options\n// ============================================================================\n\n/**\n * Options for field access processing\n */\nexport interface FieldAccessOptions {\n /**\n * Whether to throw an error when accessing a denied field\n * @default false (returns masked value instead)\n */\n throwOnDenied?: boolean\n\n /**\n * Whether to include metadata about masked fields in the result\n * @default false\n */\n includeMetadata?: boolean\n\n /**\n * Fields to explicitly include (whitelist)\n * If specified, only these fields are processed\n */\n includeFields?: string[]\n\n /**\n * Fields to explicitly exclude (blacklist)\n * These fields are never included regardless of access\n */\n excludeFields?: string[]\n}\n\n// ============================================================================\n// Predefined Field Patterns\n// ============================================================================\n\n/**\n * Always deny access to a field\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * password_hash: neverAccessible(),\n * api_secret: neverAccessible()\n * }\n * };\n * ```\n */\nexport function neverAccessible(): FieldAccessConfig {\n return {\n read: () => false,\n write: () => false,\n omitWhenHidden: true\n }\n}\n\n/**\n * Only the resource owner can access this field\n *\n * @param ownerField - Field name containing the owner ID\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * email: ownerOnly('user_id'),\n * phone: ownerOnly('user_id')\n * }\n * };\n * ```\n */\nexport function ownerOnly(ownerField = 'id'): FieldAccessConfig {\n return {\n read: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n // Convert both to strings for comparison to handle number/string mismatches\n return String(ctx.auth.userId) === String(rowValue)\n },\n write: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n return String(ctx.auth.userId) === String(rowValue)\n }\n }\n}\n\n/**\n * Owner or users with specific roles can access this field\n *\n * @param roles - Roles that can access besides owner\n * @param ownerField - Field name containing the owner ID\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * email: ownerOrRoles(['admin', 'support'], 'user_id'),\n * address: ownerOrRoles(['admin'], 'user_id')\n * }\n * };\n * ```\n */\nexport function ownerOrRoles(roles: string[], ownerField = 'id'): FieldAccessConfig {\n return {\n read: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n return String(ctx.auth.userId) === String(rowValue) || roles.some(r => ctx.auth.roles.includes(r))\n },\n write: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n return String(ctx.auth.userId) === String(rowValue) || roles.some(r => ctx.auth.roles.includes(r))\n }\n }\n}\n\n/**\n * Only users with specific roles can access this field\n *\n * @param roles - Roles that can access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * internal_notes: rolesOnly(['admin', 'moderator']),\n * audit_log: rolesOnly(['admin'])\n * }\n * };\n * ```\n */\nexport function rolesOnly(roles: string[]): FieldAccessConfig {\n return {\n read: ctx => roles.some(r => ctx.auth.roles.includes(r)),\n write: ctx => roles.some(r => ctx.auth.roles.includes(r))\n }\n}\n\n/**\n * Field is read-only (no write access)\n *\n * @param readCondition - Optional condition for read access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * created_at: readOnly(),\n * version: readOnly()\n * }\n * };\n * ```\n */\nexport function readOnly(readCondition?: FieldAccessCondition): FieldAccessConfig {\n return {\n read: readCondition ?? (() => true),\n write: () => false\n }\n}\n\n/**\n * Field has public read access but restricted write\n *\n * @param writeCondition - Condition for write access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * display_name: publicReadRestrictedWrite(ctx => ctx.auth.userId === ctx.row.id),\n * bio: publicReadRestrictedWrite(ctx => ctx.auth.userId === ctx.row.id)\n * }\n * };\n * ```\n */\nexport function publicReadRestrictedWrite(writeCondition: FieldAccessCondition): FieldAccessConfig {\n return {\n read: () => true,\n write: writeCondition\n }\n}\n\n/**\n * Mask field value with custom masking function\n *\n * @param maskFn - Function to mask the value\n * @param readCondition - Condition for full read access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * email: maskedField(\n * value => value.replace(/(.{2}).*@/, '$1***@'),\n * ctx => ctx.auth.userId === ctx.row.id\n * ),\n * phone: maskedField(\n * value => value.replace(/\\d(?=\\d{4})/g, '*'),\n * ctx => ctx.auth.userId === ctx.row.id\n * )\n * }\n * };\n * ```\n */\nexport function maskedField(\n maskFn: (value: unknown) => unknown,\n readCondition: FieldAccessCondition\n): FieldAccessConfig & { maskFn: (value: unknown) => unknown } {\n return {\n read: readCondition,\n write: readCondition,\n maskedValue: undefined, // Will be computed by maskFn\n maskFn\n }\n}\n","/**\n * Field Access Registry\n *\n * Manages field-level access control configurations across tables.\n *\n * @module @kysera/rls/field-access/registry\n */\n\nimport type {\n FieldAccessSchema,\n TableFieldAccessConfig,\n FieldAccessConfig,\n CompiledTableFieldAccess,\n CompiledFieldAccess\n} from './types.js'\nimport type { PolicyEvaluationContext } from '../policy/types.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\n\n// ============================================================================\n// Field Access Registry\n// ============================================================================\n\n/**\n * Field Access Registry\n *\n * Manages field-level access control configurations for all tables.\n *\n * @example\n * ```typescript\n * const registry = new FieldAccessRegistry();\n *\n * registry.loadSchema<Database>({\n * users: {\n * default: 'allow',\n * fields: {\n * email: ownerOrRoles(['admin'], 'id'),\n * password_hash: neverAccessible(),\n * mfa_secret: ownerOnly('id')\n * }\n * }\n * });\n *\n * // Check if field is accessible\n * const canRead = await registry.canReadField('users', 'email', evalCtx);\n * ```\n */\nexport class FieldAccessRegistry<DB = unknown> {\n private tables = new Map<string, CompiledTableFieldAccess>()\n private logger: KyseraLogger\n\n constructor(schema?: FieldAccessSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger\n if (schema) {\n this.loadSchema(schema)\n }\n }\n\n /**\n * Load field access schema\n */\n loadSchema(schema: FieldAccessSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n this.registerTable(table, config as TableFieldAccessConfig)\n }\n }\n\n /**\n * Register field access configuration for a table\n */\n registerTable(table: string, config: TableFieldAccessConfig): void {\n const compiled: CompiledTableFieldAccess = {\n table,\n defaultAccess: config.default ?? 'allow',\n skipFor: config.skipFor ?? [],\n fields: new Map()\n }\n\n // Compile field configurations\n for (const [field, fieldConfig] of Object.entries(config.fields)) {\n if (!fieldConfig) continue\n\n const compiledField = this.compileFieldConfig(field, fieldConfig as FieldAccessConfig)\n compiled.fields.set(field, compiledField)\n }\n\n this.tables.set(table, compiled)\n this.logger.info?.(`[FieldAccess] Registered table: ${table}`, {\n fields: compiled.fields.size,\n defaultAccess: compiled.defaultAccess\n })\n }\n\n /**\n * Check if a field is readable in the current context\n *\n * @param table - Table name\n * @param field - Field name\n * @param ctx - Evaluation context\n * @returns True if field is readable\n */\n async canReadField(table: string, field: string, ctx: PolicyEvaluationContext): Promise<boolean> {\n const config = this.tables.get(table)\n if (!config) {\n // No field access config = all fields readable\n return true\n }\n\n // Check skipFor roles\n if (config.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true\n }\n\n // System user bypasses field access\n if (ctx.auth.isSystem) {\n return true\n }\n\n const fieldConfig = config.fields.get(field)\n if (!fieldConfig) {\n // Use default policy\n return config.defaultAccess === 'allow'\n }\n\n try {\n const result = fieldConfig.canRead(ctx)\n return result instanceof Promise ? await result : result\n } catch (error) {\n this.logger.error?.(`[FieldAccess] Error checking read access for ${table}.${field}`, {\n error: error instanceof Error ? error.message : String(error)\n })\n return false // Fail closed\n }\n }\n\n /**\n * Check if a field is writable in the current context\n *\n * @param table - Table name\n * @param field - Field name\n * @param ctx - Evaluation context\n * @returns True if field is writable\n */\n async canWriteField(table: string, field: string, ctx: PolicyEvaluationContext): Promise<boolean> {\n const config = this.tables.get(table)\n if (!config) {\n return true\n }\n\n // Check skipFor roles\n if (config.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true\n }\n\n // System user bypasses field access\n if (ctx.auth.isSystem) {\n return true\n }\n\n const fieldConfig = config.fields.get(field)\n if (!fieldConfig) {\n return config.defaultAccess === 'allow'\n }\n\n try {\n const result = fieldConfig.canWrite(ctx)\n return result instanceof Promise ? await result : result\n } catch (error) {\n this.logger.error?.(`[FieldAccess] Error checking write access for ${table}.${field}`, {\n error: error instanceof Error ? error.message : String(error)\n })\n return false\n }\n }\n\n /**\n * Get field configuration\n *\n * @param table - Table name\n * @param field - Field name\n * @returns Compiled field access config or undefined\n */\n getFieldConfig(table: string, field: string): CompiledFieldAccess | undefined {\n return this.tables.get(table)?.fields.get(field)\n }\n\n /**\n * Get table configuration\n *\n * @param table - Table name\n * @returns Compiled table field access config or undefined\n */\n getTableConfig(table: string): CompiledTableFieldAccess | undefined {\n return this.tables.get(table)\n }\n\n /**\n * Check if table has field access configuration\n */\n hasTable(table: string): boolean {\n return this.tables.has(table)\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys())\n }\n\n /**\n * Get all fields with explicit configuration for a table\n *\n * @param table - Table name\n * @returns Array of field names\n */\n getConfiguredFields(table: string): string[] {\n const config = this.tables.get(table)\n return config ? Array.from(config.fields.keys()) : []\n }\n\n /**\n * Clear all configurations\n */\n clear(): void {\n this.tables.clear()\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Compile a field access configuration\n */\n private compileFieldConfig(field: string, config: FieldAccessConfig): CompiledFieldAccess {\n return {\n field,\n canRead: config.read ?? (() => true),\n canWrite: config.write ?? (() => true),\n maskedValue: config.maskedValue ?? null,\n omitWhenHidden: config.omitWhenHidden ?? false\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a field access registry\n */\nexport function createFieldAccessRegistry<DB = unknown>(\n schema?: FieldAccessSchema<DB>,\n options?: { logger?: KyseraLogger }\n): FieldAccessRegistry<DB> {\n return new FieldAccessRegistry<DB>(schema, options)\n}\n","/**\n * Field Access Processor\n *\n * Applies field-level access control to database rows and mutation data.\n *\n * @module @kysera/rls/field-access/processor\n */\n\nimport type { FieldAccessRegistry } from './registry.js'\nimport type {\n MaskedRow,\n FieldAccessOptions,\n FieldAccessResult,\n CompiledFieldAccess\n} from './types.js'\nimport type { PolicyEvaluationContext, RLSContext } from '../policy/types.js'\nimport { rlsContext } from '../context/manager.js'\nimport { RLSPolicyViolation } from '../errors.js'\n\n// ============================================================================\n// Field Access Processor\n// ============================================================================\n\n/**\n * Field Access Processor\n *\n * Applies field-level access control rules to rows and mutation data.\n *\n * @example\n * ```typescript\n * const processor = new FieldAccessProcessor(registry);\n *\n * // Mask fields in a row\n * const result = await processor.maskRow('users', user, {\n * includeMetadata: true\n * });\n *\n * console.log(result.data); // Row with masked fields\n * console.log(result.maskedFields); // ['email', 'phone']\n * console.log(result.omittedFields); // ['mfa_secret']\n *\n * // Validate write access\n * await processor.validateWrite('users', { email: 'new@example.com' });\n * ```\n */\nexport class FieldAccessProcessor<DB = unknown> {\n constructor(\n private registry: FieldAccessRegistry<DB>,\n private defaultMaskValue: unknown = null\n ) {}\n\n /**\n * Apply field access control to a single row\n *\n * @param table - Table name\n * @param row - Row data\n * @param options - Processing options\n * @returns Masked row with metadata\n */\n async maskRow<T extends Record<string, unknown>>(\n table: string,\n row: T,\n options: FieldAccessOptions = {}\n ): Promise<MaskedRow<T>> {\n const ctx = this.getContext()\n if (!ctx) {\n // No context - return original row\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n // System user sees everything\n if (ctx.auth.isSystem) {\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n // No field access config - return original\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n const evalCtx = this.createEvalContext(ctx, row, table)\n const result: Partial<T> = {}\n const maskedFields: string[] = []\n const omittedFields: string[] = []\n\n // Process each field\n for (const [field, value] of Object.entries(row)) {\n // Check explicit include/exclude\n if (options.excludeFields?.includes(field)) {\n continue\n }\n if (options.includeFields && !options.includeFields.includes(field)) {\n continue\n }\n\n const fieldResult = await this.evaluateFieldAccess(\n tableConfig,\n field,\n value,\n evalCtx,\n options\n )\n\n if (fieldResult.omit) {\n omittedFields.push(field)\n } else if (!fieldResult.accessible) {\n maskedFields.push(field)\n ;(result as Record<string, unknown>)[field] = fieldResult.value\n } else {\n ;(result as Record<string, unknown>)[field] = value\n }\n }\n\n return {\n data: result,\n maskedFields,\n omittedFields\n }\n }\n\n /**\n * Apply field access control to multiple rows\n *\n * @param table - Table name\n * @param rows - Array of rows\n * @param options - Processing options\n * @returns Array of masked rows\n */\n async maskRows<T extends Record<string, unknown>>(\n table: string,\n rows: T[],\n options: FieldAccessOptions = {}\n ): Promise<MaskedRow<T>[]> {\n return await Promise.all(rows.map(row => this.maskRow(table, row, options)))\n }\n\n /**\n * Validate that all fields in mutation data are writable\n *\n * @param table - Table name\n * @param data - Mutation data\n * @param existingRow - Existing row (for update operations)\n * @throws RLSPolicyViolation if any field is not writable\n */\n async validateWrite(\n table: string,\n data: Record<string, unknown>,\n existingRow?: Record<string, unknown>\n ): Promise<void> {\n const ctx = this.getContext()\n if (!ctx) {\n return // No context = no validation\n }\n\n if (ctx.auth.isSystem) {\n return // System user can write anything\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return // No field access config\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return\n }\n\n const evalCtx = this.createEvalContext(ctx, existingRow ?? {}, table, data)\n\n // Check each field being written\n const unwritableFields: string[] = []\n\n for (const field of Object.keys(data)) {\n const canWrite = await this.registry.canWriteField(table, field, evalCtx)\n if (!canWrite) {\n unwritableFields.push(field)\n }\n }\n\n if (unwritableFields.length > 0) {\n throw new RLSPolicyViolation(\n 'write',\n table,\n `Cannot write to protected fields: ${unwritableFields.join(', ')}`\n )\n }\n }\n\n /**\n * Filter mutation data to only include writable fields\n *\n * @param table - Table name\n * @param data - Mutation data\n * @param existingRow - Existing row (for update operations)\n * @returns Filtered data with only writable fields\n */\n async filterWritableFields(\n table: string,\n data: Record<string, unknown>,\n existingRow?: Record<string, unknown>\n ): Promise<{ data: Record<string, unknown>; removedFields: string[] }> {\n const ctx = this.getContext()\n if (!ctx) {\n return { data, removedFields: [] }\n }\n\n if (ctx.auth.isSystem) {\n return { data, removedFields: [] }\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return { data, removedFields: [] }\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return { data, removedFields: [] }\n }\n\n const evalCtx = this.createEvalContext(ctx, existingRow ?? {}, table, data)\n const result: Record<string, unknown> = {}\n const removedFields: string[] = []\n\n for (const [field, value] of Object.entries(data)) {\n const canWrite = await this.registry.canWriteField(table, field, evalCtx)\n if (canWrite) {\n result[field] = value\n } else {\n removedFields.push(field)\n }\n }\n\n return { data: result, removedFields }\n }\n\n /**\n * Get list of readable fields for a table\n *\n * @param table - Table name\n * @param row - Row data (for context-dependent fields)\n * @returns Array of readable field names\n */\n async getReadableFields(table: string, row: Record<string, unknown>): Promise<string[]> {\n const ctx = this.getContext()\n if (!ctx || ctx.auth.isSystem) {\n return Object.keys(row)\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return Object.keys(row)\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return Object.keys(row)\n }\n\n const evalCtx = this.createEvalContext(ctx, row, table)\n const readable: string[] = []\n\n for (const field of Object.keys(row)) {\n const canRead = await this.registry.canReadField(table, field, evalCtx)\n if (canRead) {\n readable.push(field)\n }\n }\n\n return readable\n }\n\n /**\n * Get list of writable fields for a table\n *\n * @param table - Table name\n * @param row - Existing row data (for context-dependent fields)\n * @returns Array of writable field names\n */\n async getWritableFields(table: string, row: Record<string, unknown>): Promise<string[]> {\n const ctx = this.getContext()\n if (!ctx || ctx.auth.isSystem) {\n return Object.keys(row)\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return Object.keys(row)\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return Object.keys(row)\n }\n\n const evalCtx = this.createEvalContext(ctx, row, table)\n const writable: string[] = []\n\n for (const field of Object.keys(row)) {\n const canWrite = await this.registry.canWriteField(table, field, evalCtx)\n if (canWrite) {\n writable.push(field)\n }\n }\n\n return writable\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Get current RLS context\n */\n private getContext(): RLSContext | null {\n return rlsContext.getContextOrNull()\n }\n\n /**\n * Create evaluation context\n */\n private createEvalContext(\n ctx: RLSContext,\n row: Record<string, unknown>,\n table: string,\n data?: Record<string, unknown>\n ): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n row,\n data,\n table,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n }\n\n /**\n * Evaluate field access for a specific field\n */\n private async evaluateFieldAccess(\n tableConfig: {\n defaultAccess: 'allow' | 'deny'\n fields: Map<string, CompiledFieldAccess>\n },\n field: string,\n value: unknown,\n ctx: PolicyEvaluationContext,\n options: FieldAccessOptions\n ): Promise<FieldAccessResult> {\n const fieldConfig = tableConfig.fields.get(field)\n\n if (!fieldConfig) {\n // Use default access policy\n const accessible = tableConfig.defaultAccess === 'allow'\n return {\n accessible,\n value: accessible ? value : this.defaultMaskValue,\n omit: !accessible && options.throwOnDenied !== true\n }\n }\n\n try {\n const canRead = await fieldConfig.canRead(ctx)\n\n if (canRead) {\n return {\n accessible: true,\n value\n } as FieldAccessResult\n }\n\n if (options.throwOnDenied) {\n throw new RLSPolicyViolation('read', ctx.table ?? 'unknown', `Cannot read field: ${field}`)\n }\n\n // Check if there's a mask function\n const configWithMask = fieldConfig as CompiledFieldAccess & {\n maskFn?: (value: unknown) => unknown\n }\n const maskedValue = configWithMask.maskFn\n ? configWithMask.maskFn(value)\n : fieldConfig.maskedValue ?? this.defaultMaskValue\n\n return {\n accessible: false,\n reason: `Field \"${field}\" is not accessible`,\n value: maskedValue,\n omit: fieldConfig.omitWhenHidden\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n throw error\n }\n\n // Log error and fail closed\n return {\n accessible: false,\n reason: `Error evaluating access: ${error instanceof Error ? error.message : String(error)}`,\n value: this.defaultMaskValue,\n omit: true\n }\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a field access processor\n */\nexport function createFieldAccessProcessor<DB = unknown>(\n registry: FieldAccessRegistry<DB>,\n defaultMaskValue?: unknown\n): FieldAccessProcessor<DB> {\n return new FieldAccessProcessor<DB>(registry, defaultMaskValue)\n}\n","/**\n * Policy Composition Builder\n *\n * Factory functions for creating reusable, composable RLS policies.\n *\n * @module @kysera/rls/composition/builder\n */\n\nimport type {\n ReusablePolicy,\n ReusablePolicyConfig,\n TenantIsolationConfig,\n OwnershipConfig,\n SoftDeleteConfig,\n StatusAccessConfig\n} from './types.js'\nimport type { PolicyDefinition, PolicyEvaluationContext, Operation } from '../policy/types.js'\nimport { allow, deny, filter, validate } from '../policy/builder.js'\n\n// ============================================================================\n// Core Policy Builder\n// ============================================================================\n\n/**\n * Create a reusable policy template\n *\n * @param config - Policy configuration\n * @param policies - Array of policy definitions\n * @returns Reusable policy template\n *\n * @example\n * ```typescript\n * const tenantPolicy = definePolicy(\n * {\n * name: 'tenantIsolation',\n * description: 'Filter by tenant_id',\n * tags: ['multi-tenant']\n * },\n * [\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }), {\n * priority: 1000,\n * name: 'tenant-filter'\n * }),\n * validate('create', ctx => ctx.data?.tenant_id === ctx.auth.tenantId, {\n * name: 'tenant-validate'\n * })\n * ]\n * );\n * ```\n */\nexport function definePolicy(\n config: ReusablePolicyConfig,\n policies: PolicyDefinition[]\n): ReusablePolicy {\n const result: ReusablePolicy = {\n name: config.name,\n policies\n }\n\n if (config.description !== undefined) {\n result.description = config.description\n }\n\n if (config.tags !== undefined) {\n result.tags = config.tags\n }\n\n return result\n}\n\n/**\n * Create a filter-only policy\n *\n * @param name - Policy name\n * @param filterFn - Filter condition\n * @param options - Additional options\n * @returns Reusable filter policy\n */\nexport function defineFilterPolicy(\n name: string,\n filterFn: (ctx: PolicyEvaluationContext) => Record<string, unknown>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n filter('read', filterFn, {\n name: `${name}-filter`,\n ...(options?.priority !== undefined && { priority: options.priority })\n })\n ]\n }\n}\n\n/**\n * Create an allow-based policy\n *\n * @param name - Policy name\n * @param operation - Operations to allow\n * @param condition - Allow condition\n * @param options - Additional options\n * @returns Reusable allow policy\n */\nexport function defineAllowPolicy(\n name: string,\n operation: Operation | Operation[],\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n allow(operation, condition, {\n name: `${name}-allow`,\n ...(options?.priority !== undefined && { priority: options.priority })\n })\n ]\n }\n}\n\n/**\n * Create a deny-based policy\n *\n * @param name - Policy name\n * @param operation - Operations to deny\n * @param condition - Deny condition (optional - if not provided, always denies)\n * @param options - Additional options\n * @returns Reusable deny policy\n */\nexport function defineDenyPolicy(\n name: string,\n operation: Operation | Operation[],\n condition?: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n deny(operation, condition, {\n name: `${name}-deny`,\n priority: options?.priority ?? 100\n })\n ]\n }\n}\n\n/**\n * Create a validation policy\n *\n * @param name - Policy name\n * @param operation - Operations to validate\n * @param condition - Validation condition\n * @param options - Additional options\n * @returns Reusable validate policy\n */\nexport function defineValidatePolicy(\n name: string,\n operation: 'create' | 'update' | 'all',\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n validate(operation, condition, {\n name: `${name}-validate`,\n ...(options?.priority !== undefined && { priority: options.priority })\n })\n ]\n }\n}\n\n/**\n * Create a combined policy with multiple types\n *\n * @param name - Policy name\n * @param config - Policy configurations\n * @returns Reusable combined policy\n */\nexport function defineCombinedPolicy(\n name: string,\n config: {\n filter?: (ctx: PolicyEvaluationContext) => Record<string, unknown>\n allow?: Record<string, (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>>\n deny?: Record<string, (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>>\n validate?: {\n create?: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n update?: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n }\n }\n): ReusablePolicy {\n const policies: PolicyDefinition[] = []\n\n // Add filter policy\n if (config.filter) {\n policies.push(\n filter('read', config.filter, {\n name: `${name}-filter`\n })\n )\n }\n\n // Add allow policies\n if (config.allow) {\n for (const [op, condition] of Object.entries(config.allow)) {\n if (condition) {\n policies.push(\n allow(op as Operation, condition, {\n name: `${name}-allow-${op}`\n })\n )\n }\n }\n }\n\n // Add deny policies\n if (config.deny) {\n for (const [op, condition] of Object.entries(config.deny)) {\n if (condition) {\n policies.push(\n deny(op as Operation, condition, {\n name: `${name}-deny-${op}`,\n priority: 100\n })\n )\n }\n }\n }\n\n // Add validate policies\n if (config.validate) {\n if (config.validate.create) {\n policies.push(\n validate('create', config.validate.create, {\n name: `${name}-validate-create`\n })\n )\n }\n if (config.validate.update) {\n policies.push(\n validate('update', config.validate.update, {\n name: `${name}-validate-update`\n })\n )\n }\n }\n\n return {\n name,\n policies\n }\n}\n\n// ============================================================================\n// Common Policy Patterns\n// ============================================================================\n\n/**\n * Create a tenant isolation policy\n *\n * Automatically filters by tenant_id and validates mutations.\n *\n * @param config - Tenant isolation configuration\n * @returns Reusable tenant isolation policy\n */\nexport function createTenantIsolationPolicy(config: TenantIsolationConfig = {}): ReusablePolicy {\n const { tenantColumn = 'tenant_id', validateOnMutation = true } = config\n\n const policies: PolicyDefinition[] = [\n // Filter reads by tenant\n filter('read', ctx => ({ [tenantColumn]: ctx.auth.tenantId }), {\n name: 'tenant-isolation-filter',\n priority: 1000\n })\n ]\n\n // Validate tenant on mutations\n if (validateOnMutation) {\n policies.push(\n validate('create', ctx => {\n const data = ctx.data as Record<string, unknown> | undefined\n return data?.[tenantColumn] === ctx.auth.tenantId\n }, {\n name: 'tenant-isolation-validate-create'\n }),\n validate('update', ctx => {\n const data = ctx.data as Record<string, unknown> | undefined\n // Cannot change tenant on update\n if (data?.[tenantColumn] !== undefined) {\n return data[tenantColumn] === ctx.auth.tenantId\n }\n return true\n }, {\n name: 'tenant-isolation-validate-update'\n })\n )\n }\n\n return {\n name: 'tenantIsolation',\n description: `Filter by ${tenantColumn} for multi-tenancy`,\n policies,\n tags: ['multi-tenant', 'isolation']\n }\n}\n\n/**\n * Create an ownership policy\n *\n * Allows owners to read/update/delete their own resources.\n *\n * @param config - Ownership configuration\n * @returns Reusable ownership policy\n */\nexport function createOwnershipPolicy(config: OwnershipConfig = {}): ReusablePolicy {\n const { ownerColumn = 'owner_id', ownerOperations = ['read', 'update', 'delete'], canDelete = true } = config\n\n const policies: PolicyDefinition[] = []\n\n // Filter ops to only those allowed\n const ops = ownerOperations.filter(op => op !== 'delete' || canDelete)\n\n if (ops.length > 0) {\n policies.push(\n allow(ops, ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return ctx.auth.userId === row?.[ownerColumn]\n }, {\n name: 'ownership-allow'\n })\n )\n }\n\n // Explicit deny for delete if not allowed\n if (!canDelete && ownerOperations.includes('delete')) {\n policies.push(\n deny('delete', () => true, {\n name: 'ownership-no-delete',\n priority: 150\n })\n )\n }\n\n return {\n name: 'ownership',\n description: `Owner access via ${ownerColumn}`,\n policies,\n tags: ['ownership']\n }\n}\n\n/**\n * Create a soft delete policy\n *\n * Filters out soft-deleted rows and optionally prevents hard deletes.\n *\n * @param config - Soft delete configuration\n * @returns Reusable soft delete policy\n */\nexport function createSoftDeletePolicy(config: SoftDeleteConfig = {}): ReusablePolicy {\n const { deletedColumn = 'deleted_at', filterOnRead = true, preventHardDelete = true } = config\n\n const policies: PolicyDefinition[] = []\n\n // Filter soft-deleted rows\n if (filterOnRead) {\n policies.push(\n filter('read', () => ({ [deletedColumn]: null }), {\n name: 'soft-delete-filter',\n priority: 900\n })\n )\n }\n\n // Prevent hard deletes\n if (preventHardDelete) {\n policies.push(\n deny('delete', () => true, {\n name: 'soft-delete-no-hard-delete',\n priority: 150\n })\n )\n }\n\n return {\n name: 'softDelete',\n description: `Soft delete via ${deletedColumn}`,\n policies,\n tags: ['soft-delete']\n }\n}\n\n/**\n * Create a status-based access policy\n *\n * Controls access based on resource status.\n *\n * @param config - Status access configuration\n * @returns Reusable status policy\n */\nexport function createStatusAccessPolicy(config: StatusAccessConfig): ReusablePolicy {\n const { statusColumn = 'status', publicStatuses = [], editableStatuses = [], deletableStatuses = [] } = config\n\n const policies: PolicyDefinition[] = []\n\n // Allow public read for certain statuses\n if (publicStatuses.length > 0) {\n policies.push(\n allow('read', ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return publicStatuses.includes(row?.[statusColumn] as string)\n }, {\n name: 'status-public-read'\n })\n )\n }\n\n // Restrict updates to certain statuses\n if (editableStatuses.length > 0) {\n policies.push(\n deny('update', ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return !editableStatuses.includes(row?.[statusColumn] as string)\n }, {\n name: 'status-restrict-update',\n priority: 100\n })\n )\n }\n\n // Restrict deletes to certain statuses\n if (deletableStatuses.length > 0) {\n policies.push(\n deny('delete', ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return !deletableStatuses.includes(row?.[statusColumn] as string)\n }, {\n name: 'status-restrict-delete',\n priority: 100\n })\n )\n }\n\n return {\n name: 'statusAccess',\n description: `Status-based access via ${statusColumn}`,\n policies,\n tags: ['status']\n }\n}\n\n/**\n * Create an admin bypass policy\n *\n * Allows admin roles to perform all operations.\n *\n * @param roles - Roles that have admin access\n * @returns Reusable admin policy\n */\nexport function createAdminPolicy(roles: string[]): ReusablePolicy {\n return {\n name: 'adminBypass',\n description: `Admin access for roles: ${roles.join(', ')}`,\n policies: [\n allow('all', ctx => roles.some(r => ctx.auth.roles.includes(r)), {\n name: 'admin-bypass',\n priority: 500\n })\n ],\n tags: ['admin']\n }\n}\n\n// ============================================================================\n// Policy Composition Functions\n// ============================================================================\n\n/**\n * Compose multiple reusable policies into one\n *\n * @param name - Name for the composed policy\n * @param policies - Policies to compose\n * @returns Composed policy\n */\nexport function composePolicies(name: string, policies: ReusablePolicy[]): ReusablePolicy {\n const allPolicies: PolicyDefinition[] = []\n const allTags = new Set<string>()\n\n for (const policy of policies) {\n allPolicies.push(...policy.policies)\n policy.tags?.forEach(tag => allTags.add(tag))\n }\n\n return {\n name,\n description: `Composed from: ${policies.map(p => p.name).join(', ')}`,\n policies: allPolicies,\n tags: Array.from(allTags)\n }\n}\n\n/**\n * Extend a reusable policy with additional policies\n *\n * @param base - Base policy to extend\n * @param additional - Additional policies to add\n * @returns Extended policy\n */\nexport function extendPolicy(base: ReusablePolicy, additional: PolicyDefinition[]): ReusablePolicy {\n const result: ReusablePolicy = {\n name: `${base.name}_extended`,\n policies: [...base.policies, ...additional]\n }\n\n if (base.description !== undefined) {\n result.description = base.description\n }\n\n if (base.tags !== undefined) {\n result.tags = base.tags\n }\n\n return result\n}\n\n/**\n * Override policies from a base with new conditions\n *\n * @param base - Base policy\n * @param overrides - Policy name to new policy mapping\n * @returns Policy with overrides applied\n */\nexport function overridePolicy(\n base: ReusablePolicy,\n overrides: Record<string, PolicyDefinition>\n): ReusablePolicy {\n const newPolicies = base.policies.map(policy => {\n const override = policy.name ? overrides[policy.name] : undefined\n return override ?? policy\n })\n\n const result: ReusablePolicy = {\n name: `${base.name}_overridden`,\n policies: newPolicies\n }\n\n if (base.description !== undefined) {\n result.description = base.description\n }\n\n if (base.tags !== undefined) {\n result.tags = base.tags\n }\n\n return result\n}\n","/**\n * Audit Trail Types\n *\n * Provides type definitions for auditing RLS policy decisions.\n *\n * @module @kysera/rls/audit/types\n */\n\nimport type { Operation } from '../policy/types.js'\n\n// ============================================================================\n// Audit Event Types\n// ============================================================================\n\n/**\n * RLS policy decision result\n */\nexport type AuditDecision = 'allow' | 'deny' | 'filter'\n\n/**\n * RLS audit event\n *\n * Represents a single policy evaluation event for audit logging.\n *\n * @example\n * ```typescript\n * const event: RLSAuditEvent = {\n * timestamp: new Date(),\n * userId: '123',\n * operation: 'update',\n * table: 'posts',\n * policyName: 'ownership-allow',\n * decision: 'allow',\n * context: { rowId: '456', tenantId: 'acme' }\n * };\n * ```\n */\nexport interface RLSAuditEvent {\n /**\n * Timestamp of the event\n */\n timestamp: Date\n\n /**\n * User ID who performed the action\n */\n userId: string | number\n\n /**\n * Tenant ID (if multi-tenant)\n */\n tenantId?: string | number\n\n /**\n * Database operation\n */\n operation: Operation\n\n /**\n * Table name\n */\n table: string\n\n /**\n * Name of the policy that made the decision\n */\n policyName?: string\n\n /**\n * Decision result\n */\n decision: AuditDecision\n\n /**\n * Reason for the decision (especially for denials)\n */\n reason?: string\n\n /**\n * Additional context about the event\n */\n context?: Record<string, unknown>\n\n /**\n * Row ID(s) affected\n */\n rowIds?: (string | number)[]\n\n /**\n * Hash of the query (for grouping similar queries)\n */\n queryHash?: string\n\n /**\n * Request ID for tracing\n */\n requestId?: string\n\n /**\n * IP address of the requester\n */\n ipAddress?: string\n\n /**\n * User agent string\n */\n userAgent?: string\n\n /**\n * Duration of policy evaluation in milliseconds\n */\n durationMs?: number\n\n /**\n * Whether this event was filtered from logging\n * (set by filtering rules but still available for debugging)\n */\n filtered?: boolean\n}\n\n// ============================================================================\n// Audit Adapter Interface\n// ============================================================================\n\n/**\n * Adapter for persisting audit events\n *\n * Implement this interface to store audit events in your preferred backend.\n *\n * @example\n * ```typescript\n * class DatabaseAuditAdapter implements RLSAuditAdapter {\n * constructor(private db: Kysely<AuditDB>) {}\n *\n * async log(event: RLSAuditEvent): Promise<void> {\n * await this.db.insertInto('rls_audit_log')\n * .values({\n * user_id: event.userId,\n * operation: event.operation,\n * table_name: event.table,\n * decision: event.decision,\n * context: JSON.stringify(event.context),\n * created_at: event.timestamp\n * })\n * .execute();\n * }\n *\n * async logBatch(events: RLSAuditEvent[]): Promise<void> {\n * await this.db.insertInto('rls_audit_log')\n * .values(events.map(e => ({\n * user_id: e.userId,\n * operation: e.operation,\n * table_name: e.table,\n * decision: e.decision,\n * context: JSON.stringify(e.context),\n * created_at: e.timestamp\n * })))\n * .execute();\n * }\n * }\n * ```\n */\nexport interface RLSAuditAdapter {\n /**\n * Log a single audit event\n *\n * @param event - Event to log\n */\n log(event: RLSAuditEvent): Promise<void>\n\n /**\n * Log multiple audit events (for batch processing)\n *\n * @param events - Events to log\n */\n logBatch?(events: RLSAuditEvent[]): Promise<void>\n\n /**\n * Flush any buffered events\n */\n flush?(): Promise<void>\n\n /**\n * Close the adapter and release resources\n */\n close?(): Promise<void>\n}\n\n// ============================================================================\n// Audit Configuration\n// ============================================================================\n\n/**\n * Configuration for table-specific audit settings\n */\nexport interface TableAuditConfig {\n /**\n * Whether audit is enabled for this table\n * @default true (if audit is globally enabled)\n */\n enabled?: boolean\n\n /**\n * Log allowed decisions\n * @default false\n */\n logAllowed?: boolean\n\n /**\n * Log denied decisions\n * @default true\n */\n logDenied?: boolean\n\n /**\n * Log filter applications\n * @default false\n */\n logFilters?: boolean\n\n /**\n * Context fields to include in audit logs\n * If empty, includes all available context\n */\n includeContext?: string[]\n\n /**\n * Context fields to exclude from audit logs\n */\n excludeContext?: string[]\n\n /**\n * Whether to include row data in audit logs\n * @default false (for privacy)\n */\n includeRowData?: boolean\n\n /**\n * Whether to include mutation data in audit logs\n * @default false (for privacy)\n */\n includeMutationData?: boolean\n\n /**\n * Custom filter function to determine if an event should be logged\n */\n filter?: (event: RLSAuditEvent) => boolean\n}\n\n/**\n * Global audit configuration\n */\nexport interface AuditConfig {\n /**\n * Audit adapter for persisting events\n */\n adapter: RLSAuditAdapter\n\n /**\n * Whether audit is enabled globally\n * @default true\n */\n enabled?: boolean\n\n /**\n * Default settings for all tables\n */\n defaults?: Omit<TableAuditConfig, 'enabled'>\n\n /**\n * Table-specific audit configurations\n */\n tables?: Record<string, TableAuditConfig>\n\n /**\n * Buffer size for batch logging\n * Events are batched until this size is reached\n * @default 100\n */\n bufferSize?: number\n\n /**\n * Maximum time to buffer events before flushing (ms)\n * @default 5000 (5 seconds)\n */\n flushInterval?: number\n\n /**\n * Whether to log asynchronously (fire-and-forget)\n * @default true (for performance)\n */\n async?: boolean\n\n /**\n * Error handler for audit failures\n */\n onError?: (error: Error, events: RLSAuditEvent[]) => void\n\n /**\n * Sample rate for audit logging (0.0 to 1.0)\n * Use for high-traffic systems to reduce log volume\n * @default 1.0 (log all)\n */\n sampleRate?: number\n}\n\n// ============================================================================\n// Audit Query Types\n// ============================================================================\n\n/**\n * Query parameters for retrieving audit events\n */\nexport interface AuditQueryParams {\n /**\n * Filter by user ID\n */\n userId?: string | number\n\n /**\n * Filter by tenant ID\n */\n tenantId?: string | number\n\n /**\n * Filter by table name\n */\n table?: string\n\n /**\n * Filter by operation\n */\n operation?: Operation\n\n /**\n * Filter by decision\n */\n decision?: AuditDecision\n\n /**\n * Start timestamp (inclusive)\n */\n startTime?: Date\n\n /**\n * End timestamp (exclusive)\n */\n endTime?: Date\n\n /**\n * Filter by request ID\n */\n requestId?: string\n\n /**\n * Maximum results to return\n */\n limit?: number\n\n /**\n * Offset for pagination\n */\n offset?: number\n}\n\n/**\n * Aggregated audit statistics\n */\nexport interface AuditStats {\n /**\n * Total number of events\n */\n totalEvents: number\n\n /**\n * Events by decision type\n */\n byDecision: Record<AuditDecision, number>\n\n /**\n * Events by operation\n */\n byOperation: Record<Operation, number>\n\n /**\n * Events by table\n */\n byTable: Record<string, number>\n\n /**\n * Top denied users\n */\n topDeniedUsers?: { userId: string | number; count: number }[]\n\n /**\n * Time range of stats\n */\n timeRange: {\n start: Date\n end: Date\n }\n}\n\n// ============================================================================\n// Console Audit Adapter\n// ============================================================================\n\n/**\n * Simple console-based audit adapter for development/testing\n *\n * @example\n * ```typescript\n * const adapter = new ConsoleAuditAdapter({\n * format: 'json',\n * colors: true\n * });\n * ```\n */\nexport interface ConsoleAuditAdapterOptions {\n /**\n * Output format\n * @default 'text'\n */\n format?: 'text' | 'json'\n\n /**\n * Use colors in output (for text format)\n * @default true\n */\n colors?: boolean\n\n /**\n * Include timestamp in output\n * @default true\n */\n includeTimestamp?: boolean\n}\n\n/**\n * Console audit adapter implementation\n */\nexport class ConsoleAuditAdapter implements RLSAuditAdapter {\n private options: Required<ConsoleAuditAdapterOptions>\n\n constructor(options: ConsoleAuditAdapterOptions = {}) {\n this.options = {\n format: options.format ?? 'text',\n colors: options.colors ?? true,\n includeTimestamp: options.includeTimestamp ?? true\n }\n }\n\n log(event: RLSAuditEvent): Promise<void> {\n if (this.options.format === 'json') {\n // eslint-disable-next-line no-console\n console.log(JSON.stringify(event))\n } else {\n const prefix = this.getPrefix(event.decision)\n const timestamp = this.options.includeTimestamp ? `[${event.timestamp.toISOString()}] ` : ''\n // eslint-disable-next-line no-console\n console.log(\n `${timestamp}${prefix} RLS ${event.decision.toUpperCase()}: ${event.operation} on ${event.table}` +\n (event.policyName ? ` (policy: ${event.policyName})` : '') +\n (event.reason ? ` - ${event.reason}` : '') +\n (event.userId ? ` [user: ${event.userId}]` : '')\n )\n }\n return Promise.resolve()\n }\n\n async logBatch(events: RLSAuditEvent[]): Promise<void> {\n for (const event of events) {\n await this.log(event)\n }\n }\n\n private getPrefix(decision: AuditDecision): string {\n if (!this.options.colors) {\n return decision === 'allow' ? '✓' : decision === 'deny' ? '✗' : '~'\n }\n\n switch (decision) {\n case 'allow':\n return '\\x1b[32m✓\\x1b[0m' // Green\n case 'deny':\n return '\\x1b[31m✗\\x1b[0m' // Red\n case 'filter':\n return '\\x1b[33m~\\x1b[0m' // Yellow\n default:\n return '?'\n }\n }\n}\n\n// ============================================================================\n// In-Memory Audit Adapter\n// ============================================================================\n\n/**\n * In-memory audit adapter for testing\n *\n * Stores events in memory for later retrieval and assertion.\n */\nexport class InMemoryAuditAdapter implements RLSAuditAdapter {\n private events: RLSAuditEvent[] = []\n private maxSize: number\n\n constructor(maxSize = 10000) {\n this.maxSize = maxSize\n }\n\n log(event: RLSAuditEvent): Promise<void> {\n this.events.push(event)\n // Trim if exceeds max size\n if (this.events.length > this.maxSize) {\n this.events = this.events.slice(-this.maxSize)\n }\n return Promise.resolve()\n }\n\n logBatch(events: RLSAuditEvent[]): Promise<void> {\n this.events.push(...events)\n if (this.events.length > this.maxSize) {\n this.events = this.events.slice(-this.maxSize)\n }\n return Promise.resolve()\n }\n\n /**\n * Get all logged events\n */\n getEvents(): RLSAuditEvent[] {\n return [...this.events]\n }\n\n /**\n * Query events\n */\n query(params: AuditQueryParams): RLSAuditEvent[] {\n let results = [...this.events]\n\n if (params.userId !== undefined) {\n results = results.filter(e => e.userId === params.userId)\n }\n if (params.tenantId !== undefined) {\n results = results.filter(e => e.tenantId === params.tenantId)\n }\n if (params.table) {\n results = results.filter(e => e.table === params.table)\n }\n if (params.operation) {\n results = results.filter(e => e.operation === params.operation)\n }\n if (params.decision) {\n results = results.filter(e => e.decision === params.decision)\n }\n if (params.startTime) {\n results = results.filter(e => e.timestamp >= params.startTime!)\n }\n if (params.endTime) {\n results = results.filter(e => e.timestamp < params.endTime!)\n }\n if (params.requestId) {\n results = results.filter(e => e.requestId === params.requestId)\n }\n\n if (params.offset) {\n results = results.slice(params.offset)\n }\n if (params.limit) {\n results = results.slice(0, params.limit)\n }\n\n return results\n }\n\n /**\n * Get statistics\n */\n getStats(params?: Pick<AuditQueryParams, 'startTime' | 'endTime'>): AuditStats {\n let events = this.events\n\n if (params?.startTime) {\n events = events.filter(e => e.timestamp >= params.startTime!)\n }\n if (params?.endTime) {\n events = events.filter(e => e.timestamp < params.endTime!)\n }\n\n const byDecision: Record<AuditDecision, number> = { allow: 0, deny: 0, filter: 0 }\n const byOperation: Record<Operation, number> = { read: 0, create: 0, update: 0, delete: 0, all: 0 }\n const byTable: Record<string, number> = {}\n\n for (const event of events) {\n byDecision[event.decision]++\n byOperation[event.operation]++\n byTable[event.table] = (byTable[event.table] ?? 0) + 1\n }\n\n return {\n totalEvents: events.length,\n byDecision,\n byOperation,\n byTable,\n timeRange: {\n start: events[0]?.timestamp ?? new Date(),\n end: events[events.length - 1]?.timestamp ?? new Date()\n }\n }\n }\n\n /**\n * Clear all events\n */\n clear(): void {\n this.events = []\n }\n\n /**\n * Get event count\n */\n get size(): number {\n return this.events.length\n }\n}\n","/**\n * Audit Logger\n *\n * Manages audit event logging with buffering and filtering.\n *\n * @module @kysera/rls/audit/logger\n */\n\nimport type {\n RLSAuditEvent,\n RLSAuditAdapter,\n AuditConfig,\n TableAuditConfig,\n AuditDecision\n} from './types.js'\nimport type { Operation, RLSContext } from '../policy/types.js'\nimport { rlsContext } from '../context/manager.js'\n\n// ============================================================================\n// Audit Logger\n// ============================================================================\n\n/**\n * Audit Logger\n *\n * Manages RLS audit event logging with buffering, filtering, and sampling.\n *\n * @example\n * ```typescript\n * const logger = new AuditLogger({\n * adapter: new DatabaseAuditAdapter(db),\n * bufferSize: 50,\n * flushInterval: 5000,\n * defaults: {\n * logAllowed: false,\n * logDenied: true,\n * logFilters: false\n * },\n * tables: {\n * sensitive_data: {\n * logAllowed: true,\n * includeContext: ['requestId', 'ipAddress']\n * }\n * }\n * });\n *\n * // Log an event\n * await logger.logDecision('update', 'posts', 'allow', 'ownership-allow');\n *\n * // Ensure all events are flushed\n * await logger.flush();\n * ```\n */\nexport class AuditLogger {\n private adapter: RLSAuditAdapter\n private config: Required<Omit<AuditConfig, 'adapter' | 'tables' | 'onError'>> & {\n tables: Record<string, TableAuditConfig>\n onError?: (error: Error, events: RLSAuditEvent[]) => void\n }\n private buffer: RLSAuditEvent[] = []\n private flushTimer: NodeJS.Timeout | null = null\n private isShuttingDown = false\n\n constructor(config: AuditConfig) {\n this.adapter = config.adapter\n const baseConfig = {\n enabled: config.enabled ?? true,\n defaults: config.defaults ?? {\n logAllowed: false,\n logDenied: true,\n logFilters: false\n },\n tables: config.tables ?? {},\n bufferSize: config.bufferSize ?? 100,\n flushInterval: config.flushInterval ?? 5000,\n async: config.async ?? true,\n sampleRate: config.sampleRate ?? 1.0\n }\n\n this.config = config.onError !== undefined\n ? { ...baseConfig, onError: config.onError }\n : baseConfig\n\n // Start flush timer\n if (this.config.flushInterval > 0) {\n this.startFlushTimer()\n }\n }\n\n /**\n * Log a policy decision\n *\n * @param operation - Database operation\n * @param table - Table name\n * @param decision - Decision result\n * @param policyName - Name of the policy\n * @param options - Additional options\n */\n async logDecision(\n operation: Operation,\n table: string,\n decision: AuditDecision,\n policyName?: string,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n queryHash?: string\n durationMs?: number\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n if (!this.config.enabled || this.isShuttingDown) {\n return\n }\n\n // Check sampling\n if (this.config.sampleRate < 1.0 && Math.random() > this.config.sampleRate) {\n return\n }\n\n // Get table config\n const tableConfig = this.getTableConfig(table)\n\n // Check if this decision type should be logged\n if (!this.shouldLog(decision, tableConfig)) {\n return\n }\n\n // Get current RLS context\n const ctx = rlsContext.getContextOrNull()\n\n // Build event\n const event = this.buildEvent(operation, table, decision, policyName, ctx, tableConfig, options)\n\n // Apply custom filter if present\n if (tableConfig.filter && !tableConfig.filter(event)) {\n event.filtered = true\n return\n }\n\n // Log the event\n await this.logEvent(event)\n }\n\n /**\n * Log an allow decision\n */\n async logAllow(\n operation: Operation,\n table: string,\n policyName?: string,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n await this.logDecision(operation, table, 'allow', policyName, options)\n }\n\n /**\n * Log a deny decision\n */\n async logDeny(\n operation: Operation,\n table: string,\n policyName?: string,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n await this.logDecision(operation, table, 'deny', policyName, options)\n }\n\n /**\n * Log a filter application\n */\n async logFilter(\n table: string,\n policyName?: string,\n options?: {\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n await this.logDecision('read', table, 'filter', policyName, options)\n }\n\n /**\n * Flush buffered events\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) {\n return\n }\n\n const eventsToFlush = [...this.buffer]\n this.buffer = []\n\n try {\n if (this.adapter.logBatch) {\n await this.adapter.logBatch(eventsToFlush)\n } else {\n for (const event of eventsToFlush) {\n await this.adapter.log(event)\n }\n }\n } catch (error) {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), eventsToFlush)\n }\n }\n\n /**\n * Close the logger\n */\n async close(): Promise<void> {\n this.isShuttingDown = true\n\n if (this.flushTimer) {\n clearInterval(this.flushTimer)\n this.flushTimer = null\n }\n\n await this.flush()\n await this.adapter.flush?.()\n await this.adapter.close?.()\n }\n\n /**\n * Get buffer size\n */\n get bufferSize(): number {\n return this.buffer.length\n }\n\n /**\n * Check if logger is enabled\n */\n get enabled(): boolean {\n return this.config.enabled\n }\n\n /**\n * Enable or disable logging\n */\n setEnabled(enabled: boolean): void {\n this.config.enabled = enabled\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Get table-specific config with defaults\n */\n private getTableConfig(table: string): TableAuditConfig {\n const tableOverride = this.config.tables[table]\n return {\n ...this.config.defaults,\n ...tableOverride,\n enabled: tableOverride?.enabled ?? true\n }\n }\n\n /**\n * Check if decision should be logged\n */\n private shouldLog(decision: AuditDecision, tableConfig: TableAuditConfig): boolean {\n if (!tableConfig.enabled) {\n return false\n }\n\n switch (decision) {\n case 'allow':\n return tableConfig.logAllowed ?? false\n case 'deny':\n return tableConfig.logDenied ?? true\n case 'filter':\n return tableConfig.logFilters ?? false\n default:\n return false\n }\n }\n\n /**\n * Build audit event\n */\n private buildEvent(\n operation: Operation,\n table: string,\n decision: AuditDecision,\n policyName: string | undefined,\n ctx: RLSContext | null,\n tableConfig: TableAuditConfig,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n queryHash?: string\n durationMs?: number\n context?: Record<string, unknown>\n }\n ): RLSAuditEvent {\n const event: RLSAuditEvent = {\n timestamp: new Date(),\n userId: ctx?.auth.userId ?? 'anonymous',\n operation,\n table,\n decision\n }\n\n // Add tenant ID if present\n if (ctx?.auth.tenantId !== undefined) {\n event.tenantId = ctx.auth.tenantId\n }\n\n // Add policy name\n if (policyName) {\n event.policyName = policyName\n }\n\n // Add options\n if (options?.reason) {\n event.reason = options.reason\n }\n if (options?.rowIds && options.rowIds.length > 0) {\n event.rowIds = options.rowIds\n }\n if (options?.queryHash) {\n event.queryHash = options.queryHash\n }\n if (options?.durationMs !== undefined) {\n event.durationMs = options.durationMs\n }\n\n // Add request context\n if (ctx?.request) {\n if (ctx.request.requestId) {\n event.requestId = ctx.request.requestId\n }\n if (ctx.request.ipAddress) {\n event.ipAddress = ctx.request.ipAddress\n }\n if (ctx.request.userAgent) {\n event.userAgent = ctx.request.userAgent\n }\n }\n\n // Build context\n const context = this.buildContext(ctx, tableConfig, options?.context)\n if (context !== undefined) {\n event.context = context\n }\n\n return event\n }\n\n /**\n * Build context object with filtering\n */\n private buildContext(\n ctx: RLSContext | null,\n tableConfig: TableAuditConfig,\n additionalContext?: Record<string, unknown>\n ): Record<string, unknown> | undefined {\n const context: Record<string, unknown> = {}\n\n // Add roles\n if (ctx?.auth.roles && ctx.auth.roles.length > 0) {\n context['roles'] = ctx.auth.roles\n }\n\n // Add organization IDs if present\n if (ctx?.auth.organizationIds && ctx.auth.organizationIds.length > 0) {\n context['organizationIds'] = ctx.auth.organizationIds\n }\n\n // Add meta if present\n if (ctx?.meta && typeof ctx.meta === 'object') {\n Object.assign(context, ctx.meta)\n }\n\n // Add additional context\n if (additionalContext) {\n Object.assign(context, additionalContext)\n }\n\n // Apply include/exclude filters\n let filteredContext = context\n\n if (tableConfig.includeContext && tableConfig.includeContext.length > 0) {\n filteredContext = {}\n for (const key of tableConfig.includeContext) {\n if (key in context) {\n filteredContext[key] = context[key]\n }\n }\n }\n\n if (tableConfig.excludeContext && tableConfig.excludeContext.length > 0) {\n for (const key of tableConfig.excludeContext) {\n // Use destructuring to avoid dynamic delete\n const { [key]: _, ...rest } = filteredContext\n filteredContext = rest\n }\n }\n\n return Object.keys(filteredContext).length > 0 ? filteredContext : undefined\n }\n\n /**\n * Log event to buffer or directly\n */\n private async logEvent(event: RLSAuditEvent): Promise<void> {\n if (this.config.async && this.config.bufferSize > 0) {\n // Buffered async logging\n this.buffer.push(event)\n\n if (this.buffer.length >= this.config.bufferSize) {\n // Buffer full, flush now\n await this.flush()\n }\n } else if (this.config.async) {\n // Async fire-and-forget\n this.adapter.log(event).catch((error: unknown) => {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), [event])\n })\n } else {\n // Synchronous logging\n try {\n await this.adapter.log(event)\n } catch (error) {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), [event])\n }\n }\n }\n\n /**\n * Start the flush timer\n */\n private startFlushTimer(): void {\n this.flushTimer = setInterval(() => {\n this.flush().catch((error: unknown) => {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), [...this.buffer])\n })\n }, this.config.flushInterval)\n\n // Don't block process exit\n if (this.flushTimer.unref) {\n this.flushTimer.unref()\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create an audit logger\n */\nexport function createAuditLogger(config: AuditConfig): AuditLogger {\n return new AuditLogger(config)\n}\n","/**\n * Policy Testing Utilities\n *\n * Provides tools for unit testing RLS policies without a database.\n *\n * @module @kysera/rls/testing\n */\n\nimport type {\n RLSSchema,\n PolicyEvaluationContext,\n Operation,\n RLSAuthContext,\n CompiledPolicy\n} from '../policy/types.js'\nimport { PolicyRegistry } from '../policy/registry.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of policy evaluation\n */\nexport interface PolicyEvaluationResult {\n /**\n * Whether the operation is allowed\n */\n allowed: boolean\n\n /**\n * Name of the policy that made the decision\n */\n policyName?: string\n\n /**\n * Type of decision\n */\n decisionType: 'allow' | 'deny' | 'default'\n\n /**\n * Reason for the decision\n */\n reason?: string\n\n /**\n * All policies that were evaluated\n */\n evaluatedPolicies: {\n name: string\n type: 'allow' | 'deny' | 'validate'\n result: boolean\n }[]\n}\n\n/**\n * Result of filter evaluation\n */\nexport interface FilterEvaluationResult {\n /**\n * Generated filter conditions\n */\n conditions: Record<string, unknown>\n\n /**\n * Names of all filters applied\n */\n appliedFilters: string[]\n}\n\n/**\n * Test context for policy evaluation\n */\nexport interface TestContext<TRow = Record<string, unknown>> {\n /**\n * Auth context\n */\n auth: RLSAuthContext\n\n /**\n * Row data (for read/update/delete operations)\n */\n row?: TRow\n\n /**\n * Mutation data (for create/update operations)\n */\n data?: Record<string, unknown>\n\n /**\n * Additional metadata\n */\n meta?: Record<string, unknown>\n}\n\n// ============================================================================\n// Policy Tester\n// ============================================================================\n\n/**\n * Policy Tester\n *\n * Test RLS policies without a database connection.\n *\n * @example\n * ```typescript\n * const tester = createPolicyTester(rlsSchema);\n *\n * describe('Post RLS Policies', () => {\n * it('should allow owner to update their post', async () => {\n * const result = await tester.evaluate('posts', 'update', {\n * auth: { userId: 'user-1', roles: ['user'] },\n * row: { id: 'post-1', author_id: 'user-1', status: 'draft' }\n * });\n *\n * expect(result.allowed).toBe(true);\n * });\n *\n * it('should deny non-owner update', async () => {\n * const result = await tester.evaluate('posts', 'update', {\n * auth: { userId: 'user-2', roles: ['user'] },\n * row: { id: 'post-1', author_id: 'user-1', status: 'draft' }\n * });\n *\n * expect(result.allowed).toBe(false);\n * expect(result.reason).toContain('not owner');\n * });\n *\n * it('should apply filters correctly', async () => {\n * const filters = await tester.getFilters('posts', 'read', {\n * auth: { userId: 'user-1', tenantId: 'tenant-1', roles: [] }\n * });\n *\n * expect(filters.conditions).toEqual({\n * tenant_id: 'tenant-1',\n * deleted_at: null\n * });\n * });\n * });\n * ```\n */\nexport class PolicyTester<DB = unknown> {\n private registry: PolicyRegistry<DB>\n\n constructor(schema: RLSSchema<DB>) {\n this.registry = new PolicyRegistry<DB>(schema)\n }\n\n /**\n * Evaluate policies for an operation\n *\n * @param table - Table name\n * @param operation - Operation to test\n * @param context - Test context\n * @returns Evaluation result\n */\n async evaluate(\n table: string,\n operation: Operation,\n context: TestContext\n ): Promise<PolicyEvaluationResult> {\n const evaluatedPolicies: PolicyEvaluationResult['evaluatedPolicies'] = []\n\n // Check if table is registered\n if (!this.registry.hasTable(table)) {\n return {\n allowed: true,\n decisionType: 'default',\n reason: 'Table has no RLS policies',\n evaluatedPolicies\n }\n }\n\n // Check system user bypass\n if (context.auth.isSystem) {\n return {\n allowed: true,\n decisionType: 'allow',\n reason: 'System user bypasses RLS',\n evaluatedPolicies\n }\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => context.auth.roles.includes(role))) {\n return {\n allowed: true,\n decisionType: 'allow',\n reason: `Role bypass: ${skipFor.find(r => context.auth.roles.includes(r))}`,\n evaluatedPolicies\n }\n }\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: context.auth,\n row: context.row,\n data: context.data,\n table,\n operation,\n ...(context.meta !== undefined && { meta: context.meta })\n }\n\n // Evaluate deny policies first\n const denies = this.registry.getDenies(table, operation)\n for (const deny of denies) {\n const result = await this.evaluatePolicy(deny, evalCtx)\n evaluatedPolicies.push({\n name: deny.name,\n type: 'deny',\n result\n })\n\n if (result) {\n return {\n allowed: false,\n policyName: deny.name,\n decisionType: 'deny',\n reason: `Denied by policy: ${deny.name}`,\n evaluatedPolicies\n }\n }\n }\n\n // Evaluate validate policies (for create/update)\n if ((operation === 'create' || operation === 'update') && context.data) {\n const validates = this.registry.getValidates(table, operation)\n for (const validate of validates) {\n const result = await this.evaluatePolicy(validate, evalCtx)\n evaluatedPolicies.push({\n name: validate.name,\n type: 'validate',\n result\n })\n\n if (!result) {\n return {\n allowed: false,\n policyName: validate.name,\n decisionType: 'deny',\n reason: `Validation failed: ${validate.name}`,\n evaluatedPolicies\n }\n }\n }\n }\n\n // Evaluate allow policies\n const allows = this.registry.getAllows(table, operation)\n const defaultDeny = this.registry.hasDefaultDeny(table)\n\n if (defaultDeny && allows.length === 0) {\n return {\n allowed: false,\n decisionType: 'default',\n reason: 'No allow policies defined (default deny)',\n evaluatedPolicies\n }\n }\n\n for (const allow of allows) {\n const result = await this.evaluatePolicy(allow, evalCtx)\n evaluatedPolicies.push({\n name: allow.name,\n type: 'allow',\n result\n })\n\n if (result) {\n return {\n allowed: true,\n policyName: allow.name,\n decisionType: 'allow',\n reason: `Allowed by policy: ${allow.name}`,\n evaluatedPolicies\n }\n }\n }\n\n // No allow policy matched\n if (defaultDeny) {\n return {\n allowed: false,\n decisionType: 'default',\n reason: 'No allow policies matched (default deny)',\n evaluatedPolicies\n }\n }\n\n return {\n allowed: true,\n decisionType: 'default',\n reason: 'No policies matched (default allow)',\n evaluatedPolicies\n }\n }\n\n /**\n * Get filter conditions for read operations\n *\n * @param table - Table name\n * @param operation - Must be 'read'\n * @param context - Test context\n * @returns Filter conditions\n */\n getFilters(\n table: string,\n _operation: 'read',\n context: Pick<TestContext, 'auth' | 'meta'>\n ): FilterEvaluationResult {\n const conditions: Record<string, unknown> = {}\n const appliedFilters: string[] = []\n\n // Check if table is registered\n if (!this.registry.hasTable(table)) {\n return { conditions, appliedFilters }\n }\n\n // Check system user bypass\n if (context.auth.isSystem) {\n return { conditions, appliedFilters }\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => context.auth.roles.includes(role))) {\n return { conditions, appliedFilters }\n }\n\n // Get filters\n const filters = this.registry.getFilters(table)\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: context.auth,\n ...(context.meta !== undefined && { meta: context.meta })\n }\n\n // Evaluate each filter\n for (const filter of filters) {\n const filterConditions = filter.getConditions(evalCtx)\n Object.assign(conditions, filterConditions)\n appliedFilters.push(filter.name)\n }\n\n return { conditions, appliedFilters }\n }\n\n /**\n * Test if a specific policy allows the operation\n *\n * @param table - Table name\n * @param policyName - Name of the policy to test\n * @param context - Test context\n * @returns True if policy allows\n */\n async testPolicy(\n table: string,\n policyName: string,\n context: TestContext\n ): Promise<{ found: boolean; result?: boolean }> {\n // Search in all policy types\n const operations: Operation[] = ['read', 'create', 'update', 'delete']\n\n for (const op of operations) {\n // Build evaluation context once per operation\n const evalCtx: PolicyEvaluationContext = {\n auth: context.auth,\n row: context.row,\n data: context.data,\n table,\n operation: op,\n ...(context.meta !== undefined && { meta: context.meta })\n }\n\n // Check allows\n const allows = this.registry.getAllows(table, op)\n const allow = allows.find(p => p.name === policyName)\n if (allow) {\n const result = await this.evaluatePolicy(allow, evalCtx)\n return { found: true, result }\n }\n\n // Check denies\n const denies = this.registry.getDenies(table, op)\n const deny = denies.find(p => p.name === policyName)\n if (deny) {\n const result = await this.evaluatePolicy(deny, evalCtx)\n return { found: true, result }\n }\n\n // Check validates\n const validates = this.registry.getValidates(table, op)\n const validate = validates.find(p => p.name === policyName)\n if (validate) {\n const result = await this.evaluatePolicy(validate, evalCtx)\n return { found: true, result }\n }\n }\n\n return { found: false }\n }\n\n /**\n * List all policies for a table\n */\n listPolicies(table: string): {\n allows: string[]\n denies: string[]\n filters: string[]\n validates: string[]\n } {\n const operations: Operation[] = ['read', 'create', 'update', 'delete']\n const allowSet = new Set<string>()\n const denySet = new Set<string>()\n const validateSet = new Set<string>()\n\n for (const op of operations) {\n this.registry.getAllows(table, op).forEach(p => allowSet.add(p.name))\n this.registry.getDenies(table, op).forEach(p => denySet.add(p.name))\n this.registry.getValidates(table, op).forEach(p => validateSet.add(p.name))\n }\n\n return {\n allows: Array.from(allowSet),\n denies: Array.from(denySet),\n filters: this.registry.getFilters(table).map(f => f.name),\n validates: Array.from(validateSet)\n }\n }\n\n /**\n * Get all registered tables\n */\n getTables(): string[] {\n return this.registry.getTables()\n }\n\n /**\n * Evaluate a single policy\n */\n private async evaluatePolicy(\n policy: CompiledPolicy,\n ctx: PolicyEvaluationContext\n ): Promise<boolean> {\n try {\n const result = policy.evaluate(ctx)\n return result instanceof Promise ? await result : result\n } catch {\n return false // Fail closed\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a policy tester\n *\n * @param schema - RLS schema to test\n * @returns PolicyTester instance\n */\nexport function createPolicyTester<DB = unknown>(schema: RLSSchema<DB>): PolicyTester<DB> {\n return new PolicyTester<DB>(schema)\n}\n\n// ============================================================================\n// Test Helpers\n// ============================================================================\n\n/**\n * Create a test auth context\n *\n * @param overrides - Values to override\n * @returns RLSAuthContext for testing\n */\nexport function createTestAuthContext(\n overrides: Partial<RLSAuthContext> & { userId: string | number }\n): RLSAuthContext {\n return {\n roles: [],\n isSystem: false,\n ...overrides\n }\n}\n\n/**\n * Create a test row\n *\n * @param data - Row data\n * @returns Row object\n */\nexport function createTestRow<T extends Record<string, unknown>>(data: T): T {\n return { ...data }\n}\n\n/**\n * Assertion helpers for policy testing\n */\nexport const policyAssertions = {\n /**\n * Assert that the result is allowed\n */\n assertAllowed(result: PolicyEvaluationResult, message?: string): void {\n if (!result.allowed) {\n throw new Error(\n message ?? `Expected policy to allow, but was denied: ${result.reason}`\n )\n }\n },\n\n /**\n * Assert that the result is denied\n */\n assertDenied(result: PolicyEvaluationResult, message?: string): void {\n if (result.allowed) {\n throw new Error(\n message ?? `Expected policy to deny, but was allowed: ${result.reason}`\n )\n }\n },\n\n /**\n * Assert that a specific policy made the decision\n */\n assertPolicyUsed(result: PolicyEvaluationResult, policyName: string, message?: string): void {\n if (result.policyName !== policyName) {\n throw new Error(\n message ?? `Expected policy \"${policyName}\" but was \"${result.policyName}\"`\n )\n }\n },\n\n /**\n * Assert that filters include expected conditions\n */\n assertFiltersInclude(\n result: FilterEvaluationResult,\n expected: Record<string, unknown>,\n message?: string\n ): void {\n for (const [key, value] of Object.entries(expected)) {\n if (result.conditions[key] !== value) {\n throw new Error(\n message ??\n `Expected filter condition ${key}=${JSON.stringify(value)} but got ${JSON.stringify(result.conditions[key])}`\n )\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/policy/schema.ts","../src/policy/builder.ts","../src/policy/registry.ts","../src/context/storage.ts","../src/context/manager.ts","../src/utils/type-utils.ts","../src/transformer/select.ts","../src/transformer/mutation.ts","../src/version.ts","../src/plugin.ts","../src/utils/helpers.ts","../src/resolvers/types.ts","../src/resolvers/manager.ts","../src/rebac/types.ts","../src/rebac/registry.ts","../src/rebac/transformer.ts","../src/field-access/types.ts","../src/field-access/registry.ts","../src/field-access/processor.ts","../src/composition/builder.ts","../src/audit/types.ts","../src/audit/logger.ts","../src/testing/index.ts"],"names":["allow","deny","validate","filter","silentLogger","sql"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * RLS Error Classes\n *\n * This module provides specialized error classes for Row-Level Security operations.\n * All errors extend base error classes from @kysera/core for consistency across\n * the Kysera ecosystem.\n *\n * @module @kysera/rls/errors\n */\n\nimport { DatabaseError } from '@kysera/core'\nimport type { ErrorCode } from '@kysera/core'\n\n// ============================================================================\n// RLS Error Codes\n// ============================================================================\n\n/**\n * RLS-specific error codes\n *\n * These codes extend the unified error codes from @kysera/core with\n * RLS-specific error conditions.\n */\nexport const RLSErrorCodes = {\n /** RLS context is missing or not set */\n RLS_CONTEXT_MISSING: 'RLS_CONTEXT_MISSING' as ErrorCode,\n /** RLS policy violation occurred */\n RLS_POLICY_VIOLATION: 'RLS_POLICY_VIOLATION' as ErrorCode,\n /** RLS policy definition is invalid */\n RLS_POLICY_INVALID: 'RLS_POLICY_INVALID' as ErrorCode,\n /** RLS schema definition is invalid */\n RLS_SCHEMA_INVALID: 'RLS_SCHEMA_INVALID' as ErrorCode,\n /** RLS context validation failed */\n RLS_CONTEXT_INVALID: 'RLS_CONTEXT_INVALID' as ErrorCode,\n /** RLS policy evaluation threw an error */\n RLS_POLICY_EVALUATION_ERROR: 'RLS_POLICY_EVALUATION_ERROR' as ErrorCode\n} as const\n\n/**\n * Type for RLS error codes\n */\nexport type RLSErrorCode = (typeof RLSErrorCodes)[keyof typeof RLSErrorCodes]\n\n// ============================================================================\n// Base RLS Error\n// ============================================================================\n\n/**\n * Base class for all RLS-related errors\n *\n * Extends DatabaseError from @kysera/core for consistency with other Kysera packages.\n * Provides common error functionality including error codes and JSON serialization.\n *\n * @example\n * ```typescript\n * throw new RLSError('Something went wrong', RLSErrorCodes.RLS_POLICY_INVALID);\n * ```\n */\nexport class RLSError extends DatabaseError {\n /**\n * Creates a new RLS error\n *\n * @param message - Error message\n * @param code - RLS error code\n */\n constructor(message: string, code: RLSErrorCode) {\n super(message, code)\n this.name = 'RLSError'\n }\n}\n\n// ============================================================================\n// Context Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS context is missing\n *\n * This error occurs when an operation requiring RLS context is executed\n * outside of a context scope (i.e., without calling withRLSContext()).\n *\n * @example\n * ```typescript\n * // This will throw RLSContextError\n * const result = await db.selectFrom('posts').execute();\n *\n * // Correct usage with context\n * await withRLSContext(rlsContext, async () => {\n * const result = await db.selectFrom('posts').execute();\n * });\n * ```\n */\nexport class RLSContextError extends RLSError {\n /**\n * Creates a new RLS context error\n *\n * @param message - Error message (defaults to standard message)\n */\n constructor(message = 'No RLS context found. Ensure code runs within withRLSContext()') {\n super(message, RLSErrorCodes.RLS_CONTEXT_MISSING)\n this.name = 'RLSContextError'\n }\n}\n\n/**\n * Error thrown when RLS context validation fails\n *\n * Extends RLSError as context validation failures are RLS-specific errors.\n *\n * This error occurs when the provided RLS context is invalid or missing\n * required fields.\n *\n * @example\n * ```typescript\n * // Missing required userId field\n * const invalidContext = {\n * auth: {\n * roles: ['user']\n * // userId is missing!\n * },\n * timestamp: new Date()\n * };\n *\n * // This will throw RLSContextValidationError\n * validateRLSContext(invalidContext);\n * ```\n */\nexport class RLSContextValidationError extends RLSError {\n public readonly field: string\n\n /**\n * Creates a new context validation error\n *\n * @param message - Error message\n * @param field - Field that failed validation\n */\n constructor(message: string, field: string) {\n super(message, RLSErrorCodes.RLS_CONTEXT_INVALID)\n this.name = 'RLSContextValidationError'\n this.field = field\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n field: this.field\n }\n }\n}\n\n// ============================================================================\n// Policy Errors\n// ============================================================================\n\n/**\n * Error thrown when an RLS policy violation occurs\n *\n * This error is thrown when a database operation is denied by RLS policies.\n * It provides detailed information about the violation including the operation,\n * table, and reason for denial.\n *\n * @example\n * ```typescript\n * // User tries to update a post they don't own\n * throw new RLSPolicyViolation(\n * 'update',\n * 'posts',\n * 'User does not own this post',\n * 'ownership_policy'\n * );\n * ```\n */\nexport class RLSPolicyViolation extends RLSError {\n public readonly operation: string\n public readonly table: string\n public readonly reason: string\n public readonly policyName?: string\n\n /**\n * Creates a new policy violation error\n *\n * @param operation - Database operation that was denied (read, create, update, delete)\n * @param table - Table name where violation occurred\n * @param reason - Reason for the policy violation\n * @param policyName - Name of the policy that denied access (optional)\n */\n constructor(operation: string, table: string, reason: string, policyName?: string) {\n super(\n `RLS policy violation: ${operation} on ${table} - ${reason}`,\n RLSErrorCodes.RLS_POLICY_VIOLATION\n )\n this.name = 'RLSPolicyViolation'\n this.operation = operation\n this.table = table\n this.reason = reason\n if (policyName !== undefined) {\n this.policyName = policyName\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n ...super.toJSON(),\n operation: this.operation,\n table: this.table,\n reason: this.reason\n }\n if (this.policyName !== undefined) {\n json['policyName'] = this.policyName\n }\n return json\n }\n}\n\n// ============================================================================\n// Policy Evaluation Errors\n// ============================================================================\n\n/**\n * Error thrown when a policy condition throws an error during evaluation\n *\n * This error is distinct from RLSPolicyViolation - it indicates a bug in the\n * policy condition function itself, not a legitimate access denial.\n *\n * @example\n * ```typescript\n * // A policy with a bug\n * allow('read', ctx => {\n * return ctx.row.someField.value; // Throws if someField is undefined\n * });\n *\n * // This will throw RLSPolicyEvaluationError, not RLSPolicyViolation\n * ```\n */\nexport class RLSPolicyEvaluationError extends RLSError {\n public readonly operation: string\n public readonly table: string\n public readonly policyName?: string\n public readonly originalError?: Error\n\n /**\n * Creates a new policy evaluation error\n *\n * @param operation - Database operation being performed\n * @param table - Table name where error occurred\n * @param message - Error message from the policy\n * @param policyName - Name of the policy that threw\n * @param originalError - The original error thrown by the policy\n */\n constructor(\n operation: string,\n table: string,\n message: string,\n policyName?: string,\n originalError?: Error\n ) {\n super(\n `RLS policy evaluation error during ${operation} on ${table}: ${message}`,\n RLSErrorCodes.RLS_POLICY_EVALUATION_ERROR\n )\n this.name = 'RLSPolicyEvaluationError'\n this.operation = operation\n this.table = table\n if (policyName !== undefined) {\n this.policyName = policyName\n }\n if (originalError !== undefined) {\n this.originalError = originalError\n // Preserve the original stack trace for debugging\n if (originalError.stack) {\n this.stack = `${this.stack}\\n\\nCaused by:\\n${originalError.stack}`\n }\n }\n }\n\n override toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n ...super.toJSON(),\n operation: this.operation,\n table: this.table\n }\n if (this.policyName !== undefined) {\n json['policyName'] = this.policyName\n }\n if (this.originalError !== undefined) {\n json['originalError'] = {\n name: this.originalError.name,\n message: this.originalError.message\n }\n }\n return json\n }\n}\n\n// ============================================================================\n// Schema Errors\n// ============================================================================\n\n/**\n * Error thrown when RLS schema validation fails\n *\n * Extends RLSError as schema validation failures are RLS-specific errors.\n *\n * This error occurs when the RLS schema definition is invalid or contains\n * configuration errors.\n *\n * @example\n * ```typescript\n * // Invalid policy definition\n * const invalidSchema = {\n * posts: {\n * policies: [\n * {\n * type: 'invalid-type', // Invalid policy type!\n * operation: 'read',\n * condition: (ctx) => true\n * }\n * ]\n * }\n * };\n *\n * // This will throw RLSSchemaError\n * validateRLSSchema(invalidSchema);\n * ```\n */\nexport class RLSSchemaError extends RLSError {\n public readonly details: Record<string, unknown>\n\n /**\n * Creates a new schema validation error\n *\n * @param message - Error message\n * @param details - Additional details about the validation failure\n */\n constructor(message: string, details: Record<string, unknown> = {}) {\n super(message, RLSErrorCodes.RLS_SCHEMA_INVALID)\n this.name = 'RLSSchemaError'\n this.details = details\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n details: this.details\n }\n }\n}\n","/**\n * RLS schema definition and validation\n *\n * Provides functions to define, validate, and merge RLS schemas.\n */\n\nimport type { RLSSchema, TableRLSConfig, PolicyDefinition } from './types.js'\nimport { RLSSchemaError } from '../errors.js'\n\n/**\n * Define RLS schema with full type safety\n *\n * @example\n * ```typescript\n * interface Database {\n * users: { id: number; email: string; tenant_id: number };\n * posts: { id: number; user_id: number; tenant_id: number };\n * }\n *\n * const schema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * // Users can read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * // Filter by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Admins bypass all checks\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * posts: {\n * policies: [\n * // Filter posts by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Users can only edit their own posts\n * allow(['update', 'delete'], ctx => ctx.auth.userId === ctx.row.user_id),\n * // Validate new posts belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * defaultDeny: true, // Require explicit allow\n * },\n * });\n * ```\n */\nexport function defineRLSSchema<DB>(schema: RLSSchema<DB>): RLSSchema<DB> {\n // Validate schema\n validateSchema(schema)\n return schema\n}\n\n/**\n * Validate RLS schema\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validateSchema<DB>(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n\n const tableConfig = config as TableRLSConfig\n\n if (!Array.isArray(tableConfig.policies)) {\n throw new RLSSchemaError(`Invalid policies for table \"${table}\": must be an array`, { table })\n }\n\n // Validate each policy\n for (let i = 0; i < tableConfig.policies.length; i++) {\n const policy = tableConfig.policies[i]\n if (policy !== undefined) {\n validatePolicy(policy, table, i)\n }\n }\n\n // Validate skipFor if present (array of role names that bypass RLS)\n if (tableConfig.skipFor !== undefined) {\n if (!Array.isArray(tableConfig.skipFor)) {\n throw new RLSSchemaError(\n `Invalid skipFor for table \"${table}\": must be an array of role names`,\n { table }\n )\n }\n\n // skipFor contains role names (strings), not operations\n for (const role of tableConfig.skipFor) {\n if (typeof role !== 'string' || role.trim() === '') {\n throw new RLSSchemaError(\n `Invalid role in skipFor for table \"${table}\": must be a non-empty string`,\n { table }\n )\n }\n }\n }\n\n // Validate defaultDeny if present\n if (tableConfig.defaultDeny !== undefined && typeof tableConfig.defaultDeny !== 'boolean') {\n throw new RLSSchemaError(`Invalid defaultDeny for table \"${table}\": must be a boolean`, {\n table\n })\n }\n }\n}\n\n/**\n * Validate a single policy\n * Throws RLSSchemaError if validation fails\n *\n * @internal\n */\nfunction validatePolicy(policy: PolicyDefinition, table: string, index: number): void {\n if (!policy.type) {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" missing type`, { table, index })\n }\n\n const validTypes = ['allow', 'deny', 'filter', 'validate']\n if (!validTypes.includes(policy.type)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid type: ${policy.type}`,\n { table, index, type: policy.type }\n )\n }\n\n if (!policy.operation) {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" missing operation`, {\n table,\n index\n })\n }\n\n const validOps = ['read', 'create', 'update', 'delete', 'all']\n const ops = Array.isArray(policy.operation) ? policy.operation : [policy.operation]\n\n for (const op of ops) {\n if (!validOps.includes(op)) {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" has invalid operation: ${op}`,\n { table, index, operation: op }\n )\n }\n }\n\n if (policy.condition === undefined || policy.condition === null) {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" missing condition`, {\n table,\n index\n })\n }\n\n if (typeof policy.condition !== 'function' && typeof policy.condition !== 'string') {\n throw new RLSSchemaError(\n `Policy ${index} for table \"${table}\" condition must be a function or string`,\n { table, index }\n )\n }\n\n // Validate priority if present\n if (policy.priority !== undefined && typeof policy.priority !== 'number') {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" priority must be a number`, {\n table,\n index\n })\n }\n\n // Validate name if present\n if (policy.name !== undefined && typeof policy.name !== 'string') {\n throw new RLSSchemaError(`Policy ${index} for table \"${table}\" name must be a string`, {\n table,\n index\n })\n }\n}\n\n/**\n * Merge multiple RLS schemas\n * Later schemas override earlier ones for the same table\n *\n * @example\n * ```typescript\n * const baseSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * },\n * });\n *\n * const adminSchema = defineRLSSchema<Database>({\n * users: {\n * policies: [\n * allow('all', ctx => ctx.auth.roles.includes('admin')),\n * ],\n * },\n * });\n *\n * // Merged schema will have both filters and admin allow\n * const merged = mergeRLSSchemas(baseSchema, adminSchema);\n * ```\n */\nexport function mergeRLSSchemas<DB>(...schemas: RLSSchema<DB>[]): RLSSchema<DB> {\n const merged: RLSSchema<DB> = {}\n\n for (const schema of schemas) {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n\n const existingConfig = merged[table as keyof DB]\n const newConfig = config as TableRLSConfig\n\n if (existingConfig) {\n // Merge policies (append new policies)\n existingConfig.policies = [...existingConfig.policies, ...newConfig.policies]\n\n // Merge skipFor (combine arrays and deduplicate)\n if (newConfig.skipFor) {\n const existingSkipFor = existingConfig.skipFor ?? []\n const combinedSkipFor = [...existingSkipFor, ...newConfig.skipFor]\n existingConfig.skipFor = Array.from(new Set(combinedSkipFor))\n }\n\n // Override defaultDeny if explicitly set in new config\n if (newConfig.defaultDeny !== undefined) {\n existingConfig.defaultDeny = newConfig.defaultDeny\n }\n } else {\n // Deep copy the config to avoid mutation\n // Type cast necessary: TypeScript cannot infer that the spread object matches\n // the TableRLSConfig type exactly due to optional properties and type narrowing.\n // Runtime safety: We've validated the schema structure via validateSchema(),\n // and we're creating a proper TableRLSConfig from validated components.\n\n merged[table as keyof DB] = {\n policies: [...newConfig.policies],\n skipFor: newConfig.skipFor ? [...newConfig.skipFor] : undefined,\n defaultDeny: newConfig.defaultDeny\n } as TableRLSConfig\n }\n }\n }\n\n // Validate merged schema\n validateSchema(merged)\n\n return merged\n}\n","/**\n * Fluent policy builders for Row-Level Security\n *\n * Provides intuitive builder functions for creating RLS policies:\n * - allow: Grants access when condition is true\n * - deny: Blocks access when condition is true (overrides allow)\n * - filter: Adds WHERE conditions to SELECT queries\n * - validate: Validates mutation data before execution\n */\n\nimport type {\n Operation,\n PolicyCondition,\n FilterCondition,\n PolicyHints,\n PolicyActivationCondition,\n ConditionalPolicyDefinition\n} from './types.js'\n\n/**\n * Options for policy definitions\n */\nexport interface PolicyOptions {\n /** Policy name for debugging and identification */\n name?: string\n /** Priority (higher runs first, deny policies default to 100) */\n priority?: number\n /** Performance optimization hints */\n hints?: PolicyHints\n /**\n * Condition that determines if this policy is active\n * The policy will only be evaluated if this returns true\n *\n * @example\n * ```typescript\n * // Only apply in production\n * allow('read', () => true, {\n * condition: ctx => ctx.meta?.environment === 'production'\n * })\n *\n * // Feature-gated policy\n * filter('read', ctx => ({ strict: true }), {\n * condition: ctx => ctx.meta?.features?.strictMode\n * })\n * ```\n */\n condition?: PolicyActivationCondition\n}\n\n/**\n * Create an allow policy\n * Grants access when condition evaluates to true\n *\n * @example\n * ```typescript\n * // Allow users to read their own records\n * allow('read', ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Allow admins to do everything\n * allow('all', ctx => ctx.auth.roles.includes('admin'))\n *\n * // Allow with multiple operations\n * allow(['read', 'update'], ctx => ctx.auth.userId === ctx.row.userId)\n *\n * // Named policy with priority\n * allow('read', ctx => ctx.auth.roles.includes('verified'), {\n * name: 'verified-users-only',\n * priority: 10\n * })\n * ```\n */\nexport function allow(\n operation: Operation | Operation[],\n condition: PolicyCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const policy: ConditionalPolicyDefinition = {\n type: 'allow',\n operation,\n condition: condition,\n priority: options?.priority ?? 0\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n/**\n * Create a deny policy\n * Blocks access when condition evaluates to true (overrides allow)\n * If no condition is provided, always denies\n *\n * @example\n * ```typescript\n * // Deny access to banned users\n * deny('all', ctx => ctx.auth.attributes?.banned === true)\n *\n * // Deny deletions on archived records\n * deny('delete', ctx => ctx.row.archived === true)\n *\n * // Deny all access to sensitive table\n * deny('all')\n *\n * // Named deny with high priority\n * deny('all', ctx => ctx.auth.attributes?.suspended === true, {\n * name: 'block-suspended-users',\n * priority: 200\n * })\n * ```\n */\nexport function deny(\n operation: Operation | Operation[],\n condition?: PolicyCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const policy: ConditionalPolicyDefinition = {\n type: 'deny',\n operation,\n condition: condition ?? (() => true),\n priority: options?.priority ?? 100 // Deny policies run first by default\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n/**\n * Create a filter policy\n * Adds WHERE conditions to SELECT queries\n *\n * **IMPORTANT**: Filter conditions must be synchronous functions.\n * Async filter policies are not currently supported because filters are applied\n * directly to query builders at query construction time.\n *\n * @example\n * ```typescript\n * // ✅ CORRECT: Filter by tenant (synchronous)\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n *\n * // ✅ CORRECT: Filter by organization with soft delete\n * filter('read', ctx => ({\n * organization_id: ctx.auth.organizationIds?.[0],\n * deleted_at: null\n * }))\n *\n * // ❌ WRONG: Async filter (not supported)\n * // filter('read', async ctx => {\n * // const tenantId = await fetchTenantId(ctx.auth.userId)\n * // return { tenant_id: tenantId }\n * // })\n *\n * // ✅ WORKAROUND: Fetch data before creating context\n * // const tenantId = await fetchTenantId(userId)\n * // const ctx = createRLSContext({ auth: { userId, tenantId, roles: [] } })\n * // filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n *\n * // Named filter\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }), {\n * name: 'tenant-filter'\n * })\n * ```\n */\nexport function filter(\n operation: 'read' | 'all',\n condition: FilterCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const policy: ConditionalPolicyDefinition = {\n type: 'filter',\n operation: operation === 'all' ? 'read' : operation,\n condition: condition as unknown as PolicyCondition,\n priority: options?.priority ?? 0\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n/**\n * Create a validate policy\n * Validates mutation data before execution\n *\n * @example\n * ```typescript\n * // Validate user can only set their own user_id\n * validate('create', ctx => ctx.data.userId === ctx.auth.userId)\n *\n * // Validate status transitions\n * validate('update', ctx => {\n * const { status } = ctx.data;\n * return !status || ['draft', 'published'].includes(status);\n * })\n *\n * // Apply to both create and update\n * validate('all', ctx => ctx.data.price >= 0)\n *\n * // Named validation\n * validate('create', ctx => validateEmail(ctx.data.email), {\n * name: 'validate-email'\n * })\n * ```\n */\nexport function validate(\n operation: 'create' | 'update' | 'all',\n condition: PolicyCondition,\n options?: PolicyOptions\n): ConditionalPolicyDefinition {\n const ops: Operation[] = operation === 'all' ? ['create', 'update'] : [operation]\n\n const policy: ConditionalPolicyDefinition = {\n type: 'validate',\n operation: ops,\n condition: condition,\n priority: options?.priority ?? 0\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.hints !== undefined) {\n policy.hints = options.hints\n }\n\n if (options?.condition !== undefined) {\n policy.activationCondition = options.condition\n }\n\n return policy\n}\n\n// ============================================================================\n// Conditional Policy Helpers\n// ============================================================================\n\n/**\n * Create a policy that is only active in specific environments\n *\n * @param environments - Environments where the policy is active\n * @param policyFn - Function that creates the policy\n * @returns Policy with environment condition\n *\n * @example\n * ```typescript\n * // Policy only active in production\n * const prodPolicy = whenEnvironment(['production'], () =>\n * allow('read', () => true, { name: 'prod-read' })\n * );\n *\n * // Policy active in staging and production\n * const nonDevPolicy = whenEnvironment(['staging', 'production'], () =>\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }))\n * );\n * ```\n */\nexport function whenEnvironment(\n environments: string[],\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n const existingCondition = policy.activationCondition\n policy.activationCondition = ctx => {\n const envMatch = environments.includes(ctx.environment ?? '')\n if (!envMatch) return false\n // If there was an existing condition (from inner wrapper), it must also pass\n return existingCondition ? existingCondition(ctx) : true\n }\n return policy\n}\n\n/**\n * Create a policy that is only active when a feature flag is enabled\n *\n * @param feature - Feature flag name\n * @param policyFn - Function that creates the policy\n * @returns Policy with feature flag condition\n *\n * @example\n * ```typescript\n * // Policy only active when 'strict_rls' feature is enabled\n * const strictPolicy = whenFeature('strict_rls', () =>\n * deny('delete', () => true, { name: 'strict-no-delete' })\n * );\n * ```\n */\nexport function whenFeature(\n feature: string,\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n const existingCondition = policy.activationCondition\n policy.activationCondition = ctx => {\n let featureEnabled = false\n if (Array.isArray(ctx.features)) {\n featureEnabled = ctx.features.includes(feature)\n } else if (ctx.features && typeof ctx.features === 'object' && 'has' in ctx.features) {\n // Support Set<string>\n featureEnabled = (ctx.features as Set<string>).has(feature)\n } else if (ctx.features && typeof ctx.features === 'object') {\n // Support object-style features: { feature_name: boolean }\n featureEnabled = !!(ctx.features as Record<string, unknown>)[feature]\n }\n if (!featureEnabled) return false\n // If there was an existing condition (from inner wrapper), it must also pass\n return existingCondition ? existingCondition(ctx) : true\n }\n return policy\n}\n\n/**\n * Create a policy that is only active during specific hours\n *\n * @param startHour - Start hour (0-23)\n * @param endHour - End hour (0-23)\n * @param policyFn - Function that creates the policy\n * @returns Policy with time-based condition\n *\n * @example\n * ```typescript\n * // Policy only active during business hours (9 AM - 5 PM)\n * const businessHoursPolicy = whenTimeRange(9, 17, () =>\n * allow('update', () => true, { name: 'business-hours-update' })\n * );\n * ```\n */\nexport function whenTimeRange(\n startHour: number,\n endHour: number,\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n const existingCondition = policy.activationCondition\n policy.activationCondition = ctx => {\n const hour = (ctx.timestamp ?? new Date()).getHours()\n let inRange: boolean\n // Handle midnight crossing (e.g., 22:00 to 06:00)\n if (startHour > endHour) {\n inRange = hour >= startHour || hour < endHour\n } else {\n inRange = hour >= startHour && hour < endHour\n }\n if (!inRange) return false\n // If there was an existing condition (from inner wrapper), it must also pass\n return existingCondition ? existingCondition(ctx) : true\n }\n return policy\n}\n\n/**\n * Create a policy that is only active when a custom condition is met\n *\n * @param condition - Custom activation condition\n * @param policyFn - Function that creates the policy\n * @returns Policy with custom condition\n *\n * @example\n * ```typescript\n * // Policy only active when user is in beta program\n * const betaPolicy = whenCondition(\n * ctx => ctx.meta?.betaUser === true,\n * () => allow('read', () => true, { name: 'beta-read' })\n * );\n * ```\n */\nexport function whenCondition(\n condition: PolicyActivationCondition,\n policyFn: () => ConditionalPolicyDefinition\n): ConditionalPolicyDefinition {\n const policy = policyFn()\n policy.activationCondition = condition\n return policy\n}\n","/**\n * Policy Registry\n * Central registry for managing RLS policies across all tables\n *\n * The PolicyRegistry compiles and stores RLS policies for efficient runtime lookup.\n * It categorizes policies by type (allow/deny/filter/validate) and operation,\n * and provides methods to query policies for specific tables and operations.\n */\n\nimport type {\n Operation,\n PolicyDefinition,\n FilterCondition,\n RLSSchema,\n TableRLSConfig,\n CompiledPolicy,\n CompiledFilterPolicy,\n PolicyEvaluationContext\n} from './types.js'\nimport { RLSSchemaError } from '../errors.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\n\n/**\n * Internal compiled policy with operations as Set for efficient lookup\n */\ninterface InternalCompiledPolicy {\n name: string\n operations: Set<Operation>\n type: 'allow' | 'deny' | 'validate'\n evaluate: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n priority: number\n}\n\n/**\n * Table policy configuration\n */\ninterface TablePolicyConfig {\n allows: InternalCompiledPolicy[]\n denies: InternalCompiledPolicy[]\n filters: CompiledFilterPolicy[]\n validates: InternalCompiledPolicy[]\n skipFor: string[] // Role names that bypass RLS\n defaultDeny: boolean\n}\n\n/**\n * Policy Registry\n * Manages and provides access to RLS policies\n */\nexport class PolicyRegistry<DB = unknown> {\n private tables = new Map<string, TablePolicyConfig>()\n private compiled = false\n private logger: KyseraLogger\n\n constructor(schema?: RLSSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger\n if (schema) {\n this.loadSchema(schema)\n }\n }\n\n /**\n * Load and compile policies from schema\n *\n * @example\n * ```typescript\n * const registry = new PolicyRegistry<Database>();\n * registry.loadSchema({\n * users: {\n * policies: [\n * allow('read', ctx => ctx.auth.userId === ctx.row.id),\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * ],\n * defaultDeny: true,\n * },\n * });\n * ```\n */\n loadSchema(schema: RLSSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n this.registerTable(table, config as TableRLSConfig)\n }\n this.compiled = true\n }\n\n /**\n * Register policies for a single table\n *\n * @param table - Table name\n * @param config - Table RLS configuration\n */\n registerTable(table: string, config: TableRLSConfig): void {\n const tableConfig: TablePolicyConfig = {\n allows: [],\n denies: [],\n filters: [],\n validates: [],\n skipFor: config.skipFor ?? [],\n defaultDeny: config.defaultDeny ?? true\n }\n\n // Compile and categorize policies\n for (let i = 0; i < config.policies.length; i++) {\n const policy = config.policies[i]\n if (!policy) continue\n\n const policyName = policy.name ?? `${table}_policy_${i}`\n\n try {\n if (policy.type === 'filter') {\n const compiled = this.compileFilterPolicy(policy, policyName)\n tableConfig.filters.push(compiled)\n } else {\n const compiled = this.compilePolicy(policy, policyName)\n\n switch (policy.type) {\n case 'allow':\n tableConfig.allows.push(compiled)\n break\n case 'deny':\n tableConfig.denies.push(compiled)\n break\n case 'validate':\n tableConfig.validates.push(compiled)\n break\n }\n }\n } catch (error) {\n throw new RLSSchemaError(\n `Failed to compile policy \"${policyName}\" for table \"${table}\": ${error instanceof Error ? error.message : String(error)}`,\n { table, policy: policyName }\n )\n }\n }\n\n // Sort by priority (higher priority first)\n tableConfig.allows.sort((a, b) => b.priority - a.priority)\n tableConfig.denies.sort((a, b) => b.priority - a.priority)\n tableConfig.validates.sort((a, b) => b.priority - a.priority)\n\n this.tables.set(table, tableConfig)\n }\n\n /**\n * Register policies - supports both schema and table-based registration\n *\n * @overload Register a full schema\n * @overload Register policies for a single table (deprecated)\n */\n register(schemaOrTable: RLSSchema<DB>): void\n register(\n schemaOrTable: keyof DB & string,\n policies: PolicyDefinition[],\n options?: {\n skipFor?: string[]\n defaultDeny?: boolean\n }\n ): void\n register(\n schemaOrTable: RLSSchema<DB> | (keyof DB & string),\n policies?: PolicyDefinition[],\n options?: {\n skipFor?: string[] // Role names that bypass RLS\n defaultDeny?: boolean\n }\n ): void {\n // If first argument is an object with policies, treat as schema\n if (typeof schemaOrTable === 'object' && schemaOrTable !== null) {\n this.loadSchema(schemaOrTable)\n return\n }\n\n // Otherwise, treat as table-based registration\n const table = schemaOrTable\n if (!policies) {\n throw new RLSSchemaError('Policies are required when registering by table name', { table })\n }\n\n const config: TableRLSConfig = {\n policies\n }\n\n if (options?.skipFor !== undefined) {\n config.skipFor = options.skipFor\n }\n\n if (options?.defaultDeny !== undefined) {\n config.defaultDeny = options.defaultDeny\n }\n\n this.registerTable(table, config)\n }\n\n /**\n * Compile a policy definition into an internal compiled policy\n *\n * @param policy - Policy definition to compile\n * @param name - Policy name for debugging\n * @returns Compiled policy ready for evaluation\n */\n private compilePolicy(policy: PolicyDefinition, name: string): InternalCompiledPolicy {\n const operations = Array.isArray(policy.operation) ? policy.operation : [policy.operation]\n\n // Expand 'all' to all operations\n const expandedOps = operations.flatMap(op =>\n op === 'all' ? (['read', 'create', 'update', 'delete'] as const) : [op]\n ) as Operation[]\n\n return {\n name,\n operations: new Set(expandedOps),\n type: policy.type as 'allow' | 'deny' | 'validate',\n evaluate: policy.condition as (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n priority: policy.priority ?? (policy.type === 'deny' ? 100 : 0)\n }\n }\n\n /**\n * Compile a filter policy\n *\n * @param policy - Filter policy definition\n * @param name - Policy name for debugging\n * @returns Compiled filter policy\n */\n private compileFilterPolicy(policy: PolicyDefinition, name: string): CompiledFilterPolicy {\n const condition = policy.condition as unknown as FilterCondition\n\n return {\n operation: 'read',\n getConditions: condition as (ctx: PolicyEvaluationContext) => Record<string, unknown>,\n name\n }\n }\n\n /**\n * Convert internal compiled policy to public CompiledPolicy\n */\n private toCompiledPolicy(internal: InternalCompiledPolicy): CompiledPolicy {\n return {\n name: internal.name,\n type: internal.type,\n operation: Array.from(internal.operations),\n evaluate: internal.evaluate,\n priority: internal.priority\n }\n }\n\n /**\n * Get allow policies for a table and operation\n */\n getAllows(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.allows.filter(p => p.operations.has(operation)).map(p => this.toCompiledPolicy(p))\n }\n\n /**\n * Get deny policies for a table and operation\n */\n getDenies(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.denies.filter(p => p.operations.has(operation)).map(p => this.toCompiledPolicy(p))\n }\n\n /**\n * Get validate policies for a table and operation\n */\n getValidates(table: string, operation: Operation): CompiledPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.validates\n .filter(p => p.operations.has(operation))\n .map(p => this.toCompiledPolicy(p))\n }\n\n /**\n * Get filter policies for a table\n */\n getFilters(table: string): CompiledFilterPolicy[] {\n const config = this.tables.get(table)\n return config?.filters ?? []\n }\n\n /**\n * Get roles that skip RLS for a table\n */\n getSkipFor(table: string): string[] {\n const config = this.tables.get(table)\n return config?.skipFor ?? []\n }\n\n /**\n * Check if table has default deny\n */\n hasDefaultDeny(table: string): boolean {\n const config = this.tables.get(table)\n return config?.defaultDeny ?? true\n }\n\n /**\n * Check if a table is registered\n */\n hasTable(table: string): boolean {\n return this.tables.has(table)\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys())\n }\n\n /**\n * Check if registry is compiled\n */\n isCompiled(): boolean {\n return this.compiled\n }\n\n /**\n * Validate that all policies are properly defined\n *\n * This method checks for common issues:\n * - Tables with no policies and defaultDeny=false (warns)\n * - Tables with skipFor operations but no corresponding policies\n */\n validate(): void {\n for (const [table, config] of this.tables) {\n // Check that at least one operation has policies\n const hasPolicy =\n config.allows.length > 0 ||\n config.denies.length > 0 ||\n config.filters.length > 0 ||\n config.validates.length > 0\n\n if (!hasPolicy && !config.defaultDeny) {\n // Warning: table has no policies and defaultDeny is false\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has no policies and defaultDeny is false. ` +\n `All operations will be allowed.`\n )\n }\n\n // Warn if skipFor includes operations that have policies\n if (config.skipFor.length > 0) {\n const opsWithPolicies = new Set<Operation>()\n\n for (const allow of config.allows) {\n allow.operations.forEach(op => opsWithPolicies.add(op))\n }\n for (const deny of config.denies) {\n deny.operations.forEach(op => opsWithPolicies.add(op))\n }\n for (const validate of config.validates) {\n validate.operations.forEach(op => opsWithPolicies.add(op))\n }\n if (config.filters.length > 0) {\n opsWithPolicies.add('read')\n }\n\n const skippedOpsWithPolicies = config.skipFor.filter(op => {\n // 'all' means skip all operations\n if (op === 'all') return opsWithPolicies.size > 0\n // Check if this is an operation name (for backwards compatibility)\n return opsWithPolicies.has(op as Operation)\n })\n\n if (skippedOpsWithPolicies.length > 0) {\n this.logger.warn?.(\n `[RLS] Table \"${table}\" has skipFor operations that also have policies: ${skippedOpsWithPolicies.join(', ')}. ` +\n `The policies will be ignored for these operations.`\n )\n }\n }\n }\n }\n\n /**\n * Clear all policies\n */\n clear(): void {\n this.tables.clear()\n this.compiled = false\n }\n\n /**\n * Remove policies for a specific table\n */\n remove(table: string): void {\n this.tables.delete(table)\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RLSContext } from './types.js'\n\n/**\n * AsyncLocalStorage instance for RLS context\n * Provides automatic context propagation across async boundaries\n */\nexport const rlsStorage = new AsyncLocalStorage<RLSContext>()\n","import { rlsStorage } from './storage.js'\nimport type { RLSContext, RLSAuthContext, RLSRequestContext } from './types.js'\nimport { RLSContextError, RLSContextValidationError } from '../errors.js'\n\n/**\n * Options for creating RLS context\n */\nexport interface CreateRLSContextOptions<TUser = unknown, TMeta = unknown> {\n auth: RLSAuthContext<TUser>\n request?: Partial<RLSRequestContext>\n meta?: TMeta\n}\n\n/**\n * Create a new RLS context\n */\nexport function createRLSContext<TUser = unknown, TMeta = unknown>(\n options: CreateRLSContextOptions<TUser, TMeta>\n): RLSContext<TUser, TMeta> {\n validateAuthContext(options.auth)\n\n const context: RLSContext<TUser, TMeta> = {\n auth: {\n ...options.auth,\n isSystem: options.auth.isSystem ?? false // Default to false if not provided\n },\n timestamp: new Date()\n }\n\n if (options.request) {\n context.request = {\n ...options.request,\n timestamp: options.request.timestamp ?? new Date()\n } as RLSRequestContext\n }\n\n if (options.meta !== undefined) {\n context.meta = options.meta\n }\n\n return context\n}\n\n/**\n * Validate auth context\n */\nfunction validateAuthContext(auth: RLSAuthContext): void {\n if (auth.userId === undefined || auth.userId === null) {\n throw new RLSContextValidationError('userId is required in auth context', 'userId')\n }\n\n if (!Array.isArray(auth.roles)) {\n throw new RLSContextValidationError('roles must be an array', 'roles')\n }\n}\n\n/**\n * RLS Context Manager\n * Manages RLS context using AsyncLocalStorage for automatic propagation\n */\nclass RLSContextManager {\n /**\n * Run a synchronous function within an RLS context\n */\n run<T>(context: RLSContext, fn: () => T): T {\n return rlsStorage.run(context, fn)\n }\n\n /**\n * Run an async function within an RLS context\n */\n async runAsync<T>(context: RLSContext, fn: () => Promise<T>): Promise<T> {\n return await rlsStorage.run(context, fn)\n }\n\n /**\n * Get current RLS context\n * @throws RLSContextError if no context is set\n */\n getContext(): RLSContext {\n const ctx = rlsStorage.getStore()\n if (!ctx) {\n throw new RLSContextError()\n }\n return ctx\n }\n\n /**\n * Get current RLS context or null if not set\n */\n getContextOrNull(): RLSContext | null {\n return rlsStorage.getStore() ?? null\n }\n\n /**\n * Check if running within RLS context\n */\n hasContext(): boolean {\n return rlsStorage.getStore() !== undefined\n }\n\n /**\n * Get current auth context\n * @throws RLSContextError if no context is set\n */\n getAuth(): RLSAuthContext {\n return this.getContext().auth\n }\n\n /**\n * Get current user ID\n * @throws RLSContextError if no context is set\n */\n getUserId(): string | number {\n return this.getAuth().userId\n }\n\n /**\n * Get current tenant ID\n * @throws RLSContextError if no context is set\n */\n getTenantId(): string | number | undefined {\n return this.getAuth().tenantId\n }\n\n /**\n * Check if current user has a specific role\n */\n hasRole(role: string): boolean {\n const ctx = this.getContextOrNull()\n return ctx?.auth.roles.includes(role) ?? false\n }\n\n /**\n * Check if current user has a specific permission\n */\n hasPermission(permission: string): boolean {\n const ctx = this.getContextOrNull()\n return ctx?.auth.permissions?.includes(permission) ?? false\n }\n\n /**\n * Check if current context is a system context (bypasses RLS)\n */\n isSystem(): boolean {\n const ctx = this.getContextOrNull()\n return ctx?.auth.isSystem ?? false\n }\n\n /**\n * Create a system context for operations that should bypass RLS\n */\n asSystem<T>(fn: () => T): T {\n const currentCtx = this.getContextOrNull()\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context')\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true }\n }\n\n return this.run(systemCtx, fn)\n }\n\n /**\n * Create a system context for async operations\n */\n async asSystemAsync<T>(fn: () => Promise<T>): Promise<T> {\n const currentCtx = this.getContextOrNull()\n if (!currentCtx) {\n throw new RLSContextError('Cannot create system context without existing context')\n }\n\n const systemCtx: RLSContext = {\n ...currentCtx,\n auth: { ...currentCtx.auth, isSystem: true }\n }\n\n return await this.runAsync(systemCtx, fn)\n }\n}\n\n// Export singleton instance\nexport const rlsContext = new RLSContextManager()\n\n/**\n * Convenience function to run code within RLS context\n */\nexport function withRLSContext<T>(context: RLSContext, fn: () => T): T {\n return rlsContext.run(context, fn)\n}\n\n/**\n * Convenience function to run async code within RLS context\n */\nexport async function withRLSContextAsync<T>(\n context: RLSContext,\n fn: () => Promise<T>\n): Promise<T> {\n return await rlsContext.runAsync(context, fn)\n}\n","/**\n * Type utilities for RLS plugin\n *\n * These utilities provide type-safe wrappers around dynamic operations\n * that require runtime flexibility beyond TypeScript's compile-time constraints.\n *\n * NOTE: This file intentionally uses `any` types to bridge the gap between\n * Kysely's compile-time type system and RLS's runtime dynamic requirements.\n * All `any` usage is documented and justified with runtime safety guarantees.\n *\n * @module @kysera/rls/utils/type-utils\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { SelectQueryBuilder, Kysely, RawBuilder } from 'kysely'\nimport { sql } from 'kysely'\n\n/**\n * Type-safe wrapper for dynamic column references in WHERE clauses\n *\n * Kysely's type system requires compile-time known column names, but RLS policies\n * work with dynamic column names at runtime. This utility provides a type-safe\n * boundary for this conversion.\n *\n * Type safety is maintained through:\n * 1. Column names come from validated policy definitions (developer-controlled)\n * 2. Values are type-checked by policy condition functions\n * 3. Runtime validation during policy registration\n *\n * @param table - Table name (from validated policy schema)\n * @param column - Column name (from validated policy definition)\n * @returns Type-safe column reference for Kysely query builder\n */\nexport function createQualifiedColumn(table: string, column: string): string {\n return `${table}.${column}`\n}\n\n/**\n * Type-safe wrapper for applying WHERE conditions from RLS filters\n *\n * This function encapsulates the type boundary between runtime policy conditions\n * and Kysely's compile-time type system.\n *\n * @param qb - Query builder to modify\n * @param column - Qualified column name (table.column)\n * @param operator - Comparison operator\n * @param value - Value to compare against\n * @returns Modified query builder\n */\nexport function applyWhereCondition<DB, TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n column: string,\n operator: 'is' | '=' | 'in',\n value: unknown\n): SelectQueryBuilder<DB, TB, O> {\n return qb.where(column as any, operator as any, value as any)\n}\n\n/**\n * Type-safe wrapper for raw SQL expressions\n *\n * @param expression - SQL expression (e.g., 'FALSE' for impossible conditions)\n * @returns Type-safe raw builder for WHERE clauses\n */\nexport function createRawCondition(expression: string): RawBuilder<boolean> {\n return sql`${sql.raw(expression)}`\n}\n\n/**\n * Type-safe wrapper for dynamic table queries (used in raw db queries)\n *\n * This is used by plugins to bypass RLS filtering when fetching existing rows\n * for mutation validation. The table name comes from repository configuration\n * and is validated during repository creation.\n *\n * @param db - Kysely database instance\n * @param table - Table name (from repository config)\n * @returns Query builder for the table\n */\nexport function selectFromDynamicTable<DB>(\n db: Kysely<DB>,\n table: string\n): SelectQueryBuilder<Record<string, unknown>, string, Record<string, unknown>> {\n return db.selectFrom(table as any).selectAll() as any\n}\n\n/**\n * Add WHERE clause for primary key equality.\n * Supports custom primary key column names.\n *\n * @param qb - Select query builder\n * @param id - Primary key value\n * @param primaryKeyColumn - Primary key column name (default: 'id')\n * @returns Query builder with ID filter\n */\nexport function whereIdEquals(\n qb: SelectQueryBuilder<any, any, any>,\n id: unknown,\n primaryKeyColumn = 'id'\n): SelectQueryBuilder<any, any, any> {\n return qb.where(primaryKeyColumn as any, '=', id as any)\n}\n\n/**\n * Type-safe wrapper for transforming query builders in plugin interceptors\n *\n * Used when plugins need to transform a generic query builder (QB) to a specific\n * type (e.g., SelectQueryBuilder) and back. This is necessary because the executor's\n * interceptQuery hook receives unconstrained QB types to preserve type inference.\n *\n * @param qb - Generic query builder from interceptor\n * @param operation - Operation type (for runtime validation)\n * @param transform - Transformation function\n * @returns Transformed query builder\n */\nexport function transformQueryBuilder<QB>(\n qb: QB,\n operation: string,\n transform: (\n qb: SelectQueryBuilder<Record<string, unknown>, string, Record<string, unknown>>\n ) => SelectQueryBuilder<Record<string, unknown>, string, Record<string, unknown>>\n): QB {\n if (operation !== 'select') {\n return qb\n }\n\n const transformed = transform(qb as any)\n return transformed as QB\n}\n\n/**\n * Type guard to check if an executor has a raw db instance\n *\n * @param executor - Kysely executor (may have __rawDb property)\n * @returns True if executor has __rawDb property\n */\nexport function hasRawDb<DB>(\n executor: Kysely<DB>\n): executor is Kysely<DB> & { __rawDb: Kysely<DB> } {\n return '__rawDb' in executor && (executor as any).__rawDb !== undefined\n}\n\n/**\n * Type-safe wrapper to get raw db from executor\n *\n * @param executor - Kysely executor with optional __rawDb\n * @returns Raw db instance or original executor\n */\nexport function getRawDbSafe<DB>(executor: Kysely<DB>): Kysely<DB> {\n if (hasRawDb(executor)) {\n return executor.__rawDb\n }\n return executor\n}\n","/**\n * SELECT Query Transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\n\nimport type { SelectQueryBuilder } from 'kysely'\nimport type { PolicyRegistry } from '../policy/registry.js'\nimport type { PolicyEvaluationContext } from '../policy/types.js'\nimport type { RLSContext } from '../context/types.js'\nimport { rlsContext } from '../context/manager.js'\nimport { RLSError, RLSErrorCodes } from '../errors.js'\nimport {\n createQualifiedColumn,\n applyWhereCondition,\n createRawCondition\n} from '../utils/type-utils.js'\n\n/**\n * SELECT query transformer\n * Applies filter policies to SELECT queries by adding WHERE conditions\n */\nexport class SelectTransformer<DB = unknown> {\n constructor(private registry: PolicyRegistry<DB>) {}\n\n /**\n * Transform a SELECT query by applying filter policies\n *\n * @param qb - The query builder to transform\n * @param table - Table name being queried\n * @returns Transformed query builder with RLS filters applied\n *\n * @example\n * ```typescript\n * const transformer = new SelectTransformer(registry);\n * let query = db.selectFrom('posts').selectAll();\n * query = transformer.transform(query, 'posts');\n * // Query now includes WHERE conditions from RLS policies\n * ```\n */\n transform<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n // Check for context\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n // SECURITY FIX (H-11): This should never happen as plugin.interceptQuery\n // now handles missing context. If we reach here, apply defensive WHERE FALSE\n // to prevent unfiltered queries from leaking through.\n // This is a defense-in-depth measure.\n return applyWhereCondition(\n qb,\n createRawCondition('FALSE') as unknown as string,\n '=',\n true\n ) as SelectQueryBuilder<DB, TB, O>\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n return qb\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return qb\n }\n\n // Get filter policies for this table\n const filters = this.registry.getFilters(table)\n if (filters.length === 0) {\n return qb\n }\n\n // Apply each filter as WHERE condition\n let result = qb\n for (const filter of filters) {\n const conditions = this.evaluateFilter(filter, ctx, table)\n result = this.applyConditions(result, conditions, table)\n }\n\n return result\n }\n\n /**\n * Evaluate a filter policy to get WHERE conditions\n *\n * @param filter - The filter policy to evaluate\n * @param ctx - RLS context\n * @param table - Table name\n * @returns WHERE clause conditions as key-value pairs\n */\n private evaluateFilter(\n filter: {\n name: string\n getConditions: (\n ctx: PolicyEvaluationContext\n ) => Record<string, unknown> | Promise<Record<string, unknown>>\n },\n ctx: RLSContext,\n table: string\n ): Record<string, unknown> {\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n\n const result = filter.getConditions(evalCtx)\n\n // Note: If async filters are needed, this method signature would need to change\n // For now, we assume synchronous filter evaluation\n if (result instanceof Promise) {\n throw new RLSError(\n `Async filter policies are not supported in SELECT transformers. ` +\n `Filter '${filter.name}' on table '${table}' returned a Promise. ` +\n `Use synchronous conditions for filter policies.`,\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n return result\n }\n\n /**\n * Apply filter conditions to query builder\n *\n * Uses type-safe wrappers from utils/type-utils.ts to encapsulate the boundary\n * between runtime policy conditions and Kysely's compile-time type system.\n *\n * Type safety is maintained through:\n * 1. Policy conditions are validated during schema registration\n * 2. Column names come from policy definitions (developer-controlled)\n * 3. Values are type-checked by the policy condition functions\n *\n * @param qb - Query builder to modify\n * @param conditions - WHERE clause conditions\n * @param table - Table name (for qualified column names)\n * @returns Modified query builder\n */\n private applyConditions<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n conditions: Record<string, unknown>,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n let result = qb\n\n for (const [column, value] of Object.entries(conditions)) {\n // Use table-qualified column name to avoid ambiguity in joins\n const qualifiedColumn = createQualifiedColumn(table, column)\n\n if (value === null) {\n // NULL check\n result = applyWhereCondition(result, qualifiedColumn, 'is', null)\n } else if (value === undefined) {\n // Skip undefined values\n continue\n } else if (Array.isArray(value)) {\n if (value.length === 0) {\n // Empty array means no matches - add impossible condition using SQL FALSE\n // This ensures the query returns no rows without using magic strings\n // that could potentially match actual data\n result = applyWhereCondition(\n result,\n createRawCondition('FALSE') as unknown as string,\n '=',\n true\n )\n } else {\n // IN clause for array values\n result = applyWhereCondition(result, qualifiedColumn, 'in', value)\n }\n } else {\n // Equality check\n result = applyWhereCondition(result, qualifiedColumn, '=', value)\n }\n }\n\n return result\n }\n}\n","/**\n * Mutation Guard\n * Validates CREATE, UPDATE, DELETE operations against RLS policies\n */\n\nimport type { PolicyRegistry } from '../policy/registry.js'\nimport type { PolicyEvaluationContext, Operation } from '../policy/types.js'\nimport type { RLSContext } from '../context/types.js'\nimport { rlsContext } from '../context/manager.js'\nimport { RLSPolicyViolation, RLSPolicyEvaluationError } from '../errors.js'\n\n/**\n * Default chunk size for parallel row filtering\n */\nconst DEFAULT_CHUNK_SIZE = 100\n\n/**\n * Mutation guard\n * Validates mutations (CREATE, UPDATE, DELETE) against allow/deny/validate policies\n */\nexport class MutationGuard<DB = unknown> {\n constructor(private registry: PolicyRegistry<DB>) {}\n\n /**\n * Check if CREATE operation is allowed\n *\n * @param table - Table name\n * @param data - Data being inserted\n * @throws RLSPolicyViolation if access is denied\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * await guard.checkCreate('posts', { title: 'Hello', tenant_id: 1 });\n * ```\n */\n async checkCreate(table: string, data: Record<string, unknown>): Promise<void> {\n await this.checkMutation(table, 'create', undefined, data)\n }\n\n /**\n * Check if an UPDATE operation is allowed by RLS policies.\n *\n * IMPORTANT: To prevent TOCTOU race conditions, always call this method\n * within the same transaction as the actual update operation. The existingRow\n * should be fetched with SELECT FOR UPDATE within the transaction.\n *\n * Without proper transaction isolation, the existingRow could be modified by\n * a concurrent operation between the time it was fetched and the time this\n * check runs, leading to policy decisions based on stale data.\n *\n * @param table - Target table name\n * @param existingRow - Current row data (should be fetched within same transaction)\n * @param data - New data being applied\n * @throws RLSPolicyViolation if the operation is not allowed\n *\n * @example\n * ```typescript\n * // RECOMMENDED: Use within a transaction with row locking\n * await db.transaction().execute(async (trx) => {\n * const existingPost = await trx\n * .selectFrom('posts')\n * .where('id', '=', 1)\n * .forUpdate()\n * .selectAll()\n * .executeTakeFirst();\n *\n * await guard.checkUpdate('posts', existingPost, { title: 'Updated' });\n * await trx.updateTable('posts').set({ title: 'Updated' }).where('id', '=', 1).execute();\n * });\n * ```\n */\n async checkUpdate(\n table: string,\n existingRow: Record<string, unknown>,\n data: Record<string, unknown>\n ): Promise<void> {\n await this.checkMutation(table, 'update', existingRow, data)\n }\n\n /**\n * Check if a DELETE operation is allowed by RLS policies.\n *\n * IMPORTANT: To prevent TOCTOU race conditions, always call this method\n * within the same transaction as the actual delete operation. The existingRow\n * should be fetched with SELECT FOR UPDATE within the transaction.\n *\n * Without proper transaction isolation, the existingRow could be modified by\n * a concurrent operation between the time it was fetched and the time this\n * check runs, leading to policy decisions based on stale data (e.g., a row's\n * ownership could change, allowing an unauthorized delete).\n *\n * @param table - Target table name\n * @param existingRow - Current row data (should be fetched within same transaction)\n * @throws RLSPolicyViolation if the operation is not allowed\n *\n * @example\n * ```typescript\n * // RECOMMENDED: Use within a transaction with row locking\n * await db.transaction().execute(async (trx) => {\n * const existingPost = await trx\n * .selectFrom('posts')\n * .where('id', '=', 1)\n * .forUpdate()\n * .selectAll()\n * .executeTakeFirst();\n *\n * await guard.checkDelete('posts', existingPost);\n * await trx.deleteFrom('posts').where('id', '=', 1).execute();\n * });\n * ```\n */\n async checkDelete(table: string, existingRow: Record<string, unknown>): Promise<void> {\n await this.checkMutation(table, 'delete', existingRow)\n }\n\n /**\n * Check if READ operation is allowed on a specific row\n *\n * @param table - Table name\n * @param row - Row to check access for\n * @returns true if access is allowed\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * const post = await db.selectFrom('posts').where('id', '=', 1).selectAll().executeTakeFirst();\n * const canRead = await guard.checkRead('posts', post);\n * ```\n */\n async checkRead(table: string, row: Record<string, unknown>): Promise<boolean> {\n try {\n await this.checkMutation(table, 'read', row)\n return true\n } catch (error) {\n // Both policy violations and evaluation errors result in denial\n if (error instanceof RLSPolicyViolation || error instanceof RLSPolicyEvaluationError) {\n return false\n }\n throw error\n }\n }\n\n /**\n * Generic check for any operation (helper for testing)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @returns true if access is allowed, false otherwise\n */\n async canMutate(\n operation: Operation,\n table: string,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<boolean> {\n try {\n await this.checkMutation(table, operation, row, data)\n return true\n } catch (error) {\n // Both policy violations and evaluation errors result in denial\n if (error instanceof RLSPolicyViolation || error instanceof RLSPolicyEvaluationError) {\n return false\n }\n throw error\n }\n }\n\n /**\n * Validate mutation data (for validate policies)\n *\n * @param operation - Operation type\n * @param table - Table name\n * @param data - New data (for CREATE/UPDATE)\n * @param row - Existing row (for UPDATE)\n * @returns true if valid, false otherwise\n */\n async validateMutation(\n operation: Operation,\n table: string,\n data: Record<string, unknown>,\n row?: Record<string, unknown>\n ): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n return false\n }\n\n // System users bypass validation\n if (ctx.auth.isSystem) {\n return true\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true\n }\n\n // Get validate policies for this operation\n const validates = this.registry.getValidates(table, operation)\n if (validates.length === 0) {\n return true\n }\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: ctx.auth,\n row: row,\n data: data,\n table: table,\n operation: operation,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n\n // All validate policies must pass\n for (const validate of validates) {\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx, validate.name)\n if (!result) {\n return false\n }\n }\n\n return true\n }\n\n /**\n * Check mutation against RLS policies\n *\n * @param table - Table name\n * @param operation - Operation type\n * @param row - Existing row (for UPDATE/DELETE/READ)\n * @param data - New data (for CREATE/UPDATE)\n * @throws RLSPolicyViolation if access is denied\n */\n private async checkMutation(\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): Promise<void> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n throw new RLSPolicyViolation(operation, table, 'No RLS context available')\n }\n\n // System users bypass all checks\n if (ctx.auth.isSystem) {\n return\n }\n\n // Check if user role should skip RLS\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => ctx.auth.roles.includes(role))) {\n return\n }\n\n // Evaluate deny policies first (they override allows)\n const denies = this.registry.getDenies(table, operation)\n for (const deny of denies) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data)\n const result = await this.evaluatePolicy(deny.evaluate, evalCtx, deny.name)\n\n if (result) {\n throw new RLSPolicyViolation(operation, table, `Denied by policy: ${deny.name}`)\n }\n }\n\n // Evaluate validate policies (for CREATE/UPDATE)\n if ((operation === 'create' || operation === 'update') && data) {\n const validates = this.registry.getValidates(table, operation)\n for (const validate of validates) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data)\n const result = await this.evaluatePolicy(validate.evaluate, evalCtx, validate.name)\n\n if (!result) {\n throw new RLSPolicyViolation(operation, table, `Validation failed: ${validate.name}`)\n }\n }\n }\n\n // Evaluate allow policies\n const allows = this.registry.getAllows(table, operation)\n const defaultDeny = this.registry.hasDefaultDeny(table)\n\n if (defaultDeny && allows.length === 0) {\n throw new RLSPolicyViolation(operation, table, 'No allow policies defined (default deny)')\n }\n\n if (allows.length > 0) {\n // At least one allow policy must pass\n let allowed = false\n\n for (const allow of allows) {\n const evalCtx = this.createEvalContext(ctx, table, operation, row, data)\n const result = await this.evaluatePolicy(allow.evaluate, evalCtx, allow.name)\n\n if (result) {\n allowed = true\n break\n }\n }\n\n if (!allowed) {\n throw new RLSPolicyViolation(operation, table, 'No allow policies matched')\n }\n }\n }\n\n /**\n * Create policy evaluation context\n */\n private createEvalContext(\n ctx: RLSContext,\n table: string,\n operation: Operation,\n row?: Record<string, unknown>,\n data?: Record<string, unknown>\n ): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n row,\n data,\n table,\n operation,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n }\n\n /**\n * Evaluate a policy condition\n *\n * @param condition - Policy condition function\n * @param evalCtx - Policy evaluation context\n * @param policyName - Name of the policy being evaluated (for error reporting)\n * @returns Boolean result of policy evaluation\n * @throws RLSPolicyEvaluationError if the policy throws an error\n */\n private async evaluatePolicy(\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n evalCtx: PolicyEvaluationContext,\n policyName?: string\n ): Promise<boolean> {\n try {\n const result = condition(evalCtx)\n return result instanceof Promise ? await result : result\n } catch (error) {\n // Distinguish between policy evaluation errors and policy violations\n // RLSPolicyEvaluationError indicates a bug in the policy, not a legitimate denial\n const originalError = error instanceof Error ? error : undefined\n throw new RLSPolicyEvaluationError(\n evalCtx.operation ?? 'unknown',\n evalCtx.table ?? 'unknown',\n error instanceof Error ? error.message : 'Unknown error',\n policyName,\n originalError\n )\n }\n }\n\n /**\n * Filter rows based on read policies.\n * Uses parallel processing with chunking for performance.\n *\n * @param table - Table name\n * @param rows - Rows to filter\n * @param chunkSize - Number of rows to process in parallel (default: 100)\n * @returns Filtered array containing only accessible rows\n *\n * @example\n * ```typescript\n * const guard = new MutationGuard(registry);\n * const allPosts = await db.selectFrom('posts').selectAll().execute();\n * const accessiblePosts = await guard.filterRows('posts', allPosts);\n *\n * // With custom chunk size for large datasets\n * const accessiblePosts = await guard.filterRows('posts', allPosts, 50);\n * ```\n */\n async filterRows<T extends Record<string, unknown>>(\n table: string,\n rows: T[],\n chunkSize: number = DEFAULT_CHUNK_SIZE\n ): Promise<T[]> {\n if (rows.length === 0) return []\n\n const results: T[] = []\n\n // Process in chunks to avoid overwhelming the event loop\n for (let i = 0; i < rows.length; i += chunkSize) {\n const chunk = rows.slice(i, i + chunkSize)\n\n // Process chunk in parallel\n const chunkResults = await Promise.all(\n chunk.map(async (row) => {\n const allowed = await this.checkRead(table, row)\n return allowed ? row : null\n })\n )\n\n // Filter out nulls and add to results\n for (const row of chunkResults) {\n if (row !== null) {\n results.push(row)\n }\n }\n }\n\n return results\n }\n}\n","/**\n * Package version - injected at build time by tsup\n * Falls back to development version if not replaced\n * @internal\n */\nconst RAW_VERSION = '__VERSION__'\nexport const VERSION = RAW_VERSION.startsWith('__') ? '0.0.0-dev' : RAW_VERSION\n","/**\n * RLS Plugin for Kysera Repository\n *\n * Implements Row-Level Security as a Kysera plugin, providing:\n * - Automatic query filtering for SELECT operations\n * - Policy enforcement for CREATE, UPDATE, DELETE operations\n * - Repository method extensions for RLS-aware operations\n * - System context bypass for privileged operations\n *\n * @module @kysera/rls\n */\n\nimport type { Plugin, QueryBuilderContext, BaseRepositoryLike } from '@kysera/executor'\nimport { getRawDb, isRepositoryLike } from '@kysera/executor'\nimport type { Kysely } from 'kysely'\nimport { z } from 'zod'\nimport type { RLSSchema, Operation } from './policy/types.js'\nimport { PolicyRegistry } from './policy/registry.js'\nimport { SelectTransformer } from './transformer/select.js'\nimport { MutationGuard } from './transformer/mutation.js'\nimport { rlsContext } from './context/manager.js'\nimport { VERSION } from './version.js'\nimport { RLSContextError, RLSPolicyViolation, RLSError, RLSErrorCodes } from './errors.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\nimport {\n transformQueryBuilder,\n selectFromDynamicTable,\n whereIdEquals,\n hasRawDb as hasRawDbUtil,\n applyWhereCondition,\n createRawCondition\n} from './utils/type-utils.js'\n\n/**\n * RLS Plugin configuration options\n */\nexport interface RLSPluginOptions<DB = unknown> {\n /** RLS policy schema */\n schema: RLSSchema<DB>\n\n /**\n * Tables to exclude from RLS (always bypass policies)\n * @default []\n */\n excludeTables?: string[]\n\n /** Roles that bypass RLS entirely (e.g., ['admin', 'superuser']) */\n bypassRoles?: string[]\n\n /** Logger instance for RLS operations */\n logger?: KyseraLogger\n\n /**\n * Require RLS context for all operations (throws if missing)\n *\n * **Security**: Defaults to `true` for secure-by-default behavior.\n * When `true`, missing RLS context throws RLSContextError, preventing\n * unfiltered database access which could expose sensitive data.\n *\n * Only set to `false` if you explicitly want to allow queries without\n * RLS context (not recommended in production).\n *\n * @default true\n * @see allowUnfilteredQueries for explicit unfiltered query control\n */\n requireContext?: boolean\n\n /**\n * Allow unfiltered queries when RLS context is missing\n *\n * **SECURITY WARNING**: Setting this to `true` allows database queries\n * to execute without RLS filtering when context is missing. This can\n * expose sensitive data across tenant boundaries or user permissions.\n *\n * Only enable this if you:\n * 1. Understand the security implications\n * 2. Have other security controls in place\n * 3. Are running background jobs or system operations that don't have user context\n *\n * When both `requireContext: false` and `allowUnfilteredQueries: false`:\n * - Missing context logs a warning and returns empty results\n *\n * @default false (secure-by-default)\n */\n allowUnfilteredQueries?: boolean\n\n /** Enable audit logging of policy decisions */\n auditDecisions?: boolean\n\n /** Custom error handler for policy violations */\n onViolation?: (violation: RLSPolicyViolation) => void\n\n /**\n * Primary key column name for row lookups.\n * @default 'id'\n */\n primaryKeyColumn?: string\n}\n\n/**\n * Zod schema for RLSPluginOptions\n * Used for validation and configuration in the kysera-cli.\n * Note: 'schema' and 'onViolation' are not included as they are complex runtime objects.\n */\nexport const RLSPluginOptionsSchema = z.object({\n excludeTables: z.array(z.string()).optional(),\n bypassRoles: z.array(z.string()).optional(),\n requireContext: z.boolean().optional(),\n allowUnfilteredQueries: z.boolean().optional(),\n auditDecisions: z.boolean().optional(),\n primaryKeyColumn: z.string().optional()\n})\n\n/**\n * Base repository interface for type safety.\n * Type alias for BaseRepositoryLike from @kysera/executor with concrete DB type.\n * @internal\n */\ntype BaseRepository = BaseRepositoryLike<Record<string, unknown>>\n\n/**\n * Create RLS plugin for Kysera\n *\n * The RLS plugin provides declarative row-level security for your database operations.\n * It automatically filters SELECT queries and validates mutations (CREATE, UPDATE, DELETE)\n * against your policy schema.\n *\n * @example\n * ```typescript\n * import { rlsPlugin, defineRLSSchema, allow, filter } from '@kysera/rls';\n * import { createORM } from '@kysera/repository';\n *\n * // Define your RLS schema\n * const schema = defineRLSSchema<Database>({\n * resources: {\n * policies: [\n * // Filter reads by tenant\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId })),\n * // Allow updates for resource owners\n * allow('update', ctx => ctx.auth.userId === ctx.row.owner_id),\n * // Validate creates belong to user's tenant\n * validate('create', ctx => ctx.data.tenant_id === ctx.auth.tenantId),\n * ],\n * },\n * });\n *\n * // Create repository with RLS plugin\n * const orm = await createORM(db, [\n * rlsPlugin({ schema }),\n * ]);\n *\n * // Use within RLS context\n * await rlsContext.runAsync(\n * {\n * auth: { userId: 1, tenantId: 100, roles: ['user'], isSystem: false },\n * timestamp: new Date(),\n * },\n * async () => {\n * // All queries automatically filtered by tenant_id\n * const resources = await orm.resources.findAll();\n * }\n * );\n * ```\n *\n * @param options - Plugin configuration options\n * @returns Kysera plugin instance\n */\n// eslint-disable-next-line max-lines-per-function\nexport function rlsPlugin<DB>(options: RLSPluginOptions<DB>): Plugin {\n const {\n schema,\n excludeTables = [],\n bypassRoles = [],\n logger = silentLogger,\n requireContext = true, // SECURITY: Changed to true for secure-by-default (CRIT-2 fix)\n allowUnfilteredQueries = false, // SECURITY: Explicit opt-in for unfiltered queries\n auditDecisions = false,\n onViolation,\n primaryKeyColumn = 'id'\n } = options\n\n // Registry and transformers (initialized in onInit)\n let registry: PolicyRegistry<DB>\n let selectTransformer: SelectTransformer<DB>\n let mutationGuard: MutationGuard<DB>\n\n return {\n name: '@kysera/rls',\n version: VERSION,\n\n // Run after soft-delete (priority 0), before audit\n priority: 50,\n\n // No dependencies by default\n dependencies: [],\n\n /**\n * Initialize plugin - compile policies\n */\n onInit<TDB>(_executor: Kysely<TDB>): void {\n logger.info?.('[RLS] Initializing RLS plugin', {\n tables: Object.keys(schema).length,\n excludeTables: excludeTables.length,\n bypassRoles: bypassRoles.length\n })\n\n // Create and compile registry\n // Type assertion: The plugin is configured with a specific DB schema,\n // but onInit receives a generic TDB. We use the schema's DB type.\n registry = new PolicyRegistry<DB>(schema)\n registry.validate()\n\n // Create transformers\n selectTransformer = new SelectTransformer<DB>(registry)\n mutationGuard = new MutationGuard<DB>(registry)\n\n logger.info?.('[RLS] RLS plugin initialized successfully')\n },\n\n /**\n * Cleanup resources when executor is destroyed\n */\n onDestroy(): Promise<void> {\n // Clear registry to free up memory\n registry.clear()\n logger.info?.('[RLS] RLS plugin destroyed, cleared policy registry')\n return Promise.resolve()\n },\n\n /**\n * Intercept queries to apply RLS filtering\n *\n * This hook is called for every query builder operation. For SELECT queries,\n * it applies filter policies as WHERE conditions. For mutations, it marks\n * that RLS validation is required (performed in extendRepository).\n */\n interceptQuery<QB>(qb: QB, context: QueryBuilderContext): QB {\n const { operation, table, metadata } = context\n\n // Skip if table is excluded\n if (excludeTables.includes(table)) {\n logger.debug?.(`[RLS] Skipping RLS for excluded table: ${table}`)\n return qb\n }\n\n // Skip if explicitly disabled via metadata\n if (metadata['skipRLS'] === true) {\n logger.debug?.(`[RLS] Skipping RLS (explicit skip): ${table}`)\n return qb\n }\n\n // Check for context\n const ctx = rlsContext.getContextOrNull()\n\n if (!ctx) {\n // SECURITY FIX (CRIT-2): Secure-by-default behavior for missing context\n if (requireContext) {\n throw new RLSContextError(\n `RLS context required but not found for ${operation} on ${table}. ` +\n `This prevents unfiltered database access. ` +\n `Either provide RLS context or set 'requireContext: false' with 'allowUnfilteredQueries: true' if intentional.`\n )\n }\n\n if (!allowUnfilteredQueries) {\n // Log warning and return safe empty result\n logger.warn?.(\n `[RLS] Missing context for ${operation} on ${table}. ` +\n `Queries will return empty results for security. ` +\n `Set 'allowUnfilteredQueries: true' to allow unfiltered access (not recommended).`\n )\n // For SELECT, apply impossible condition to return no rows\n if (operation === 'select') {\n return transformQueryBuilder(qb, operation, selectQb => {\n // Apply WHERE FALSE to ensure no rows are returned\n return applyWhereCondition(\n selectQb,\n createRawCondition('FALSE') as unknown as string,\n '=',\n true\n ) as typeof selectQb\n })\n }\n // For mutations, we'll let them through but log warning\n // The extendRepository will handle mutation checks\n return qb\n }\n\n // allowUnfilteredQueries is true - allow but log warning\n logger.warn?.(\n `[RLS] No context for ${operation} on ${table}. ` +\n `Allowing unfiltered query due to 'allowUnfilteredQueries: true'. ` +\n `This may expose sensitive data.`\n )\n return qb\n }\n\n // Check if system user (bypass RLS)\n if (ctx.auth.isSystem) {\n logger.debug?.(`[RLS] Bypassing RLS (system user): ${table}`)\n return qb\n }\n\n // Check bypass roles\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) {\n logger.debug?.(`[RLS] Bypassing RLS (bypass role): ${table}`)\n return qb\n }\n\n // Apply SELECT filtering\n if (operation === 'select') {\n try {\n const transformed = transformQueryBuilder(\n qb,\n operation,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n selectQb => selectTransformer.transform(selectQb as any, table) as any\n )\n\n if (auditDecisions) {\n logger.info?.('[RLS] Filter applied', {\n table,\n operation,\n userId: ctx.auth.userId\n })\n }\n\n return transformed\n } catch (error) {\n logger.error?.('[RLS] Error applying filter', { table, error })\n throw error\n }\n }\n\n // For mutations, mark that RLS check is needed (done in extendRepository)\n if (operation === 'insert' || operation === 'update' || operation === 'delete') {\n metadata['__rlsRequired'] = true\n metadata['__rlsTable'] = table\n }\n\n return qb\n },\n\n /**\n * Extend repository with RLS-aware methods\n *\n * Wraps create, update, and delete methods to enforce RLS policies.\n * Also adds utility methods for bypassing RLS and checking access.\n */\n extendRepository<T extends object>(repo: T): T {\n // Use the shared type guard from @kysera/executor\n if (!isRepositoryLike(repo)) {\n return repo\n }\n\n const baseRepo = repo as unknown as BaseRepository\n\n const table = baseRepo.tableName\n\n // Skip excluded tables\n if (excludeTables.includes(table)) {\n logger.debug?.(`[RLS] Skipping repository extension for excluded table: ${table}`)\n return repo\n }\n\n // Skip if table not in schema\n if (!registry.hasTable(table)) {\n logger.debug?.(`[RLS] Table \"${table}\" not in RLS schema, skipping`)\n return repo\n }\n\n logger.debug?.(`[RLS] Extending repository for table: ${table}`)\n\n // Store original methods\n const originalCreate = baseRepo.create?.bind(baseRepo)\n const originalUpdate = baseRepo.update?.bind(baseRepo)\n const originalDelete = baseRepo.delete?.bind(baseRepo)\n const originalFindById = baseRepo.findById?.bind(baseRepo)\n\n // Get raw db for internal queries that need to bypass RLS\n // If executor doesn't have __rawDb (e.g., in tests), we'll use originalFindById\n const rawDb = getRawDb(baseRepo.executor)\n const hasRawDbInstance = hasRawDbUtil(baseRepo.executor)\n\n const extendedRepo = {\n ...baseRepo,\n\n /**\n * Wrapped create with RLS check\n */\n async create(data: unknown): Promise<unknown> {\n if (!originalCreate) {\n throw new RLSError(\n 'Repository does not support create operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n const ctx = rlsContext.getContextOrNull()\n\n // Check RLS if context exists and not system/bypass\n if (\n ctx &&\n !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))\n ) {\n try {\n await mutationGuard.checkCreate(table, data as Record<string, unknown>)\n\n if (auditDecisions) {\n logger.info?.('[RLS] Create allowed', { table, userId: ctx.auth.userId })\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error)\n if (auditDecisions) {\n logger.warn?.('[RLS] Create denied', {\n table,\n userId: ctx.auth.userId,\n reason: error.reason\n })\n }\n }\n throw error\n }\n }\n\n return await originalCreate(data)\n },\n\n /**\n * Wrapped update with RLS check.\n *\n * WARNING (TOCTOU): The existing row is fetched before the policy check.\n * In concurrent environments, the row could be modified between fetch and\n * check. For safety, call this method within a transaction. The underlying\n * MutationGuard.checkUpdate documents this in detail.\n */\n async update(id: unknown, data: unknown): Promise<unknown> {\n if (!originalUpdate) {\n throw new RLSError(\n 'Repository does not support update operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n const ctx = rlsContext.getContextOrNull()\n\n if (\n ctx &&\n !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))\n ) {\n // Fetch existing row for policy evaluation\n // Use raw db if available to bypass RLS filtering and prevent self-interception\n let existingRow: unknown\n\n if (hasRawDbInstance) {\n // Use raw db to bypass RLS filtering\n const query = selectFromDynamicTable(rawDb, table)\n existingRow = await whereIdEquals(query, id, primaryKeyColumn).executeTakeFirst()\n } else if (originalFindById) {\n // Fallback to originalFindById for tests/mocks\n existingRow = await originalFindById(id)\n } else {\n throw new RLSError(\n 'Repository does not support update operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n if (!existingRow) {\n // Let the original method handle not found\n return await originalUpdate(id, data)\n }\n\n try {\n await mutationGuard.checkUpdate(\n table,\n existingRow as Record<string, unknown>,\n data as Record<string, unknown>\n )\n\n if (auditDecisions) {\n logger.info?.('[RLS] Update allowed', { table, id, userId: ctx.auth.userId })\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error)\n if (auditDecisions) {\n logger.warn?.('[RLS] Update denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n })\n }\n }\n throw error\n }\n }\n\n return await originalUpdate(id, data)\n },\n\n /**\n * Wrapped delete with RLS check.\n *\n * WARNING (TOCTOU): The existing row is fetched before the policy check.\n * In concurrent environments, the row could be modified between fetch and\n * check. For safety, call this method within a transaction. The underlying\n * MutationGuard.checkDelete documents this in detail.\n */\n async delete(id: unknown): Promise<unknown> {\n if (!originalDelete) {\n throw new RLSError(\n 'Repository does not support delete operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n const ctx = rlsContext.getContextOrNull()\n\n if (\n ctx &&\n !ctx.auth.isSystem &&\n !bypassRoles.some(role => ctx.auth.roles.includes(role))\n ) {\n // Fetch existing row for policy evaluation\n // Use raw db if available to bypass RLS filtering and prevent self-interception\n let existingRow: unknown\n\n if (hasRawDbInstance) {\n // Use raw db to bypass RLS filtering\n const query = selectFromDynamicTable(rawDb, table)\n existingRow = await whereIdEquals(query, id, primaryKeyColumn).executeTakeFirst()\n } else if (originalFindById) {\n // Fallback to originalFindById for tests/mocks\n existingRow = await originalFindById(id)\n } else {\n throw new RLSError(\n 'Repository does not support delete operation',\n RLSErrorCodes.RLS_POLICY_INVALID\n )\n }\n\n if (!existingRow) {\n // Let the original method handle not found\n return await originalDelete(id)\n }\n\n try {\n await mutationGuard.checkDelete(table, existingRow as Record<string, unknown>)\n\n if (auditDecisions) {\n logger.info?.('[RLS] Delete allowed', { table, id, userId: ctx.auth.userId })\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n onViolation?.(error)\n if (auditDecisions) {\n logger.warn?.('[RLS] Delete denied', {\n table,\n id,\n userId: ctx.auth.userId,\n reason: error.reason\n })\n }\n }\n throw error\n }\n }\n\n return await originalDelete(id)\n },\n\n /**\n * Bypass RLS for specific operation\n * Requires existing context\n *\n * @example\n * ```typescript\n * // Perform operation as system user\n * const result = await repo.withoutRLS(async () => {\n * return repo.findAll(); // No RLS filtering\n * });\n * ```\n */\n async withoutRLS<R>(fn: () => Promise<R>): Promise<R> {\n return await rlsContext.asSystemAsync(fn)\n },\n\n /**\n * Check if current user can perform operation on a row\n *\n * @example\n * ```typescript\n * const post = await repo.findById(1);\n * const canUpdate = await repo.canAccess('update', post);\n * if (canUpdate) {\n * await repo.update(1, { title: 'New title' });\n * }\n * ```\n */\n async canAccess(operation: Operation, row: Record<string, unknown>): Promise<boolean> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) return false\n if (ctx.auth.isSystem) return true\n if (bypassRoles.some(role => ctx.auth.roles.includes(role))) return true\n\n try {\n switch (operation) {\n case 'read':\n return await mutationGuard.checkRead(table, row)\n case 'create':\n await mutationGuard.checkCreate(table, row)\n return true\n case 'update':\n await mutationGuard.checkUpdate(table, row, {})\n return true\n case 'delete':\n await mutationGuard.checkDelete(table, row)\n return true\n default:\n return false\n }\n } catch (error) {\n logger.debug?.('[RLS] Access check failed', {\n table,\n operation,\n error: error instanceof Error ? error.message : String(error)\n })\n return false\n }\n }\n }\n\n return extendedRepo as T\n }\n }\n}\n","/**\n * Utility helper functions for RLS\n */\n\nimport type { RLSContext, PolicyEvaluationContext, Operation } from '../policy/types.js'\n\n/**\n * Create a policy evaluation context from RLS context\n */\nexport function createEvaluationContext<TRow = unknown, TData = unknown>(\n rlsCtx: RLSContext,\n options?: {\n row?: TRow\n data?: TData\n }\n): PolicyEvaluationContext<unknown, TRow, TData> {\n const ctx: PolicyEvaluationContext<unknown, TRow, TData> = {\n auth: rlsCtx.auth\n }\n\n if (options?.row !== undefined) {\n ctx.row = options.row\n }\n\n if (options?.data !== undefined) {\n ctx.data = options.data\n }\n\n if (rlsCtx.request !== undefined) {\n ctx.request = rlsCtx.request\n }\n\n if (rlsCtx.meta !== undefined) {\n ctx.meta = rlsCtx.meta as Record<string, unknown>\n }\n\n return ctx\n}\n\n/**\n * Check if a condition function is async\n *\n * NOTE: This function checks both constructor.name (for native async functions)\n * and return type (for transpiled code that returns Promise).\n * Transpilers often convert async functions to regular functions that return Promise.\n */\nexport function isAsyncFunction(fn: unknown): fn is (...args: unknown[]) => Promise<unknown> {\n if (!(fn instanceof Function)) {\n return false\n }\n\n // Check constructor name for native async functions\n if (fn.constructor.name === 'AsyncFunction') {\n return true\n }\n\n // For transpiled code: call the function with empty args and check if it returns a Promise\n // This is safe because policy conditions should be pure functions\n try {\n const result = (fn as Function)()\n return result instanceof Promise\n } catch {\n // If calling with no args throws, assume it's not async\n // (async functions that require args should be wrapped in the policy definition)\n return false\n }\n}\n\n/**\n * Safely evaluate a policy condition\n */\nexport async function safeEvaluate<T>(fn: () => T | Promise<T>, defaultValue: T): Promise<T> {\n try {\n const result = fn()\n if (result instanceof Promise) {\n return await result\n }\n return result\n } catch (_error) {\n // Expected failure during policy evaluation - return default value\n // Logger not available in this utility function, error is handled gracefully\n return defaultValue\n }\n}\n\n/**\n * Deep merge two objects\n */\nexport function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T {\n const result = { ...target }\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceValue = source[key]\n const targetValue = result[key]\n\n if (\n sourceValue !== undefined &&\n typeof sourceValue === 'object' &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n ) as T[keyof T]\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as T[keyof T]\n }\n }\n\n return result\n}\n\n/**\n * Create a simple hash for cache keys\n */\nexport function hashString(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32bit integer\n }\n return hash.toString(36)\n}\n\n/**\n * Normalize operations to array format\n */\nexport function normalizeOperations(operation: Operation | Operation[]): Operation[] {\n if (Array.isArray(operation)) {\n if (operation.includes('all')) {\n return ['read', 'create', 'update', 'delete']\n }\n return operation\n }\n\n if (operation === 'all') {\n return ['read', 'create', 'update', 'delete']\n }\n\n return [operation]\n}\n","/**\n * Context Resolver Types\n *\n * Provides infrastructure for pre-resolving async data before RLS policy evaluation.\n * This allows synchronous filters to access data that would otherwise require async lookups.\n *\n * @module @kysera/rls/resolvers/types\n */\n\nimport type { RLSAuthContext, RLSContext } from '../policy/types.js'\n\n// ============================================================================\n// Resolved Data Types\n// ============================================================================\n\n/**\n * Base interface for resolved data that can be added to RLS context\n *\n * @example\n * ```typescript\n * interface MyResolvedData extends ResolvedData {\n * organizationIds: string[];\n * permissions: Set<string>;\n * employeeRoles: Map<string, string[]>;\n * }\n * ```\n */\nexport interface ResolvedData {\n /**\n * Timestamp when data was resolved\n * Used for cache validation\n */\n resolvedAt: Date\n\n /**\n * Cache key used for this resolution (if cached)\n */\n cacheKey?: string\n}\n\n/**\n * Extended auth context with pre-resolved data\n *\n * @typeParam TUser - Custom user type\n * @typeParam TResolved - Type of pre-resolved data\n *\n * @example\n * ```typescript\n * interface OrgPermissions extends ResolvedData {\n * organizationIds: string[];\n * orgPermissions: Map<string, Set<string>>;\n * isOrgOwner: (orgId: string) => boolean;\n * hasOrgPermission: (orgId: string, permission: string) => boolean;\n * }\n *\n * type EnhancedAuth = EnhancedRLSAuthContext<User, OrgPermissions>;\n *\n * // Use in policy\n * filter('read', ctx => ({\n * organization_id: ctx.auth.resolved.organizationIds\n * }));\n * ```\n */\nexport interface EnhancedRLSAuthContext<TUser = unknown, TResolved extends ResolvedData = ResolvedData>\n extends RLSAuthContext<TUser> {\n /**\n * Pre-resolved data available synchronously in policies\n *\n * This data is populated by ContextResolvers before entering the RLS context.\n * Use this for async data lookups that policies need synchronously.\n */\n resolved: TResolved\n}\n\n/**\n * Extended RLS context with enhanced auth containing resolved data\n *\n * @typeParam TUser - Custom user type\n * @typeParam TResolved - Type of pre-resolved data\n * @typeParam TMeta - Custom metadata type\n */\nexport interface EnhancedRLSContext<\n TUser = unknown,\n TResolved extends ResolvedData = ResolvedData,\n TMeta = unknown\n> extends Omit<RLSContext<TUser, TMeta>, 'auth'> {\n auth: EnhancedRLSAuthContext<TUser, TResolved>\n}\n\n// ============================================================================\n// Context Resolver Interface\n// ============================================================================\n\n/**\n * Base context for resolver input (before resolution)\n */\nexport interface BaseResolverContext {\n auth: {\n userId: string | number\n roles: string[]\n tenantId?: string | number\n organizationIds?: (string | number)[]\n permissions?: string[]\n attributes?: Record<string, unknown>\n isSystem?: boolean\n }\n timestamp: Date\n meta?: unknown\n}\n\n/**\n * Context resolver that enriches base context with pre-resolved data\n *\n * Resolvers are responsible for fetching async data and making it available\n * synchronously in policy evaluation contexts.\n *\n * @typeParam TResolved - Type of resolved data this resolver produces\n *\n * @example\n * ```typescript\n * const orgPermissionResolver: ContextResolver<OrgPermissions> = {\n * name: 'org-permissions',\n *\n * async resolve(base) {\n * const employments = await db.selectFrom('employees')\n * .where('user_id', '=', base.auth.userId)\n * .where('status', '=', 'active')\n * .execute();\n *\n * const orgPermissions = new Map<string, Set<string>>();\n * // ... resolve permissions ...\n *\n * return {\n * resolvedAt: new Date(),\n * organizationIds: employments.map(e => e.organization_id),\n * orgPermissions,\n * isOrgOwner: (orgId) => employments.some(e => e.organization_id === orgId && e.is_owner),\n * hasOrgPermission: (orgId, permission) => {\n * const perms = orgPermissions.get(orgId);\n * return perms?.has('*') || perms?.has(permission) || false;\n * }\n * };\n * },\n *\n * cacheKey: (base) => `rls:org-perms:${base.auth.userId}`,\n * cacheTtl: 300 // 5 minutes\n * };\n * ```\n */\nexport interface ContextResolver<TResolved extends ResolvedData = ResolvedData> {\n /**\n * Unique name for this resolver\n * Used for logging and debugging\n */\n name: string\n\n /**\n * Resolve async data for the context\n *\n * @param base - Base context with user info\n * @returns Pre-resolved data to be added to context\n */\n resolve(base: BaseResolverContext): Promise<TResolved>\n\n /**\n * Generate cache key for this context\n * Return undefined to disable caching for this resolver\n *\n * @param base - Base context\n * @returns Cache key string or undefined\n */\n cacheKey?(base: BaseResolverContext): string | undefined\n\n /**\n * Cache TTL in seconds\n * @default 300 (5 minutes)\n */\n cacheTtl?: number\n\n /**\n * Whether this resolver is required\n * If true, resolution failure will throw an error\n * If false, the resolver will be skipped on failure\n *\n * @default true\n */\n required?: boolean\n\n /**\n * Dependencies on other resolvers (by name)\n * This resolver will wait for dependencies to complete first\n */\n dependsOn?: string[]\n\n /**\n * Priority for resolver execution order (higher = earlier)\n * @default 0\n */\n priority?: number\n}\n\n/**\n * Combined result of multiple resolvers\n *\n * @typeParam T - Union type of all resolved data types\n */\nexport interface CompositeResolvedData<T extends Record<string, ResolvedData>> extends ResolvedData {\n /**\n * Individual resolver results keyed by resolver name\n */\n resolvers: T\n}\n\n// ============================================================================\n// Resolver Manager Options\n// ============================================================================\n\n/**\n * Cache provider interface for storing resolved context data\n */\nexport interface ResolverCacheProvider {\n /**\n * Get cached data\n * @param key - Cache key\n * @returns Cached data or null if not found/expired\n */\n get<T>(key: string): Promise<T | null>\n\n /**\n * Set cached data\n * @param key - Cache key\n * @param value - Data to cache\n * @param ttlSeconds - Time to live in seconds\n */\n set<T>(key: string, value: T, ttlSeconds: number): Promise<void>\n\n /**\n * Delete cached data\n * @param key - Cache key\n */\n delete(key: string): Promise<void>\n\n /**\n * Delete all cached data matching a pattern\n * @param pattern - Pattern to match (e.g., \"rls:org-perms:*\")\n */\n deletePattern?(pattern: string): Promise<void>\n}\n\n/**\n * In-memory cache provider implementation\n *\n * Suitable for single-instance deployments or testing.\n * For distributed systems, use a Redis-based provider.\n */\nexport class InMemoryCacheProvider implements ResolverCacheProvider {\n private cache = new Map<string, { value: unknown; expiresAt: number }>()\n\n get<T>(key: string): Promise<T | null> {\n const entry = this.cache.get(key)\n if (!entry) return Promise.resolve(null)\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key)\n return Promise.resolve(null)\n }\n return Promise.resolve(entry.value as T)\n }\n\n set<T>(key: string, value: T, ttlSeconds: number): Promise<void> {\n this.cache.set(key, {\n value,\n expiresAt: Date.now() + ttlSeconds * 1000\n })\n return Promise.resolve()\n }\n\n delete(key: string): Promise<void> {\n this.cache.delete(key)\n return Promise.resolve()\n }\n\n deletePattern(pattern: string): Promise<void> {\n // Simple pattern matching: * at end matches any suffix\n const prefix = pattern.endsWith('*') ? pattern.slice(0, -1) : pattern\n for (const key of this.cache.keys()) {\n if (key.startsWith(prefix)) {\n this.cache.delete(key)\n }\n }\n return Promise.resolve()\n }\n\n /**\n * Clear all cached entries\n */\n clear(): void {\n this.cache.clear()\n }\n\n /**\n * Get current cache size\n */\n get size(): number {\n return this.cache.size\n }\n}\n\n/**\n * Options for ResolverManager\n */\nexport interface ResolverManagerOptions {\n /**\n * Cache provider for storing resolved data\n * @default InMemoryCacheProvider\n */\n cacheProvider?: ResolverCacheProvider\n\n /**\n * Default cache TTL in seconds\n * @default 300 (5 minutes)\n */\n defaultCacheTtl?: number\n\n /**\n * Whether to run resolvers in parallel when possible\n * @default true\n */\n parallelResolution?: boolean\n\n /**\n * Maximum time (ms) to wait for a single resolver\n * @default 5000 (5 seconds)\n */\n resolverTimeout?: number\n\n /**\n * Logger for resolver operations\n */\n logger?: {\n debug?: (message: string, context?: Record<string, unknown>) => void\n info?: (message: string, context?: Record<string, unknown>) => void\n warn?: (message: string, context?: Record<string, unknown>) => void\n error?: (message: string, context?: Record<string, unknown>) => void\n }\n}\n\n// ============================================================================\n// Common Resolved Data Patterns\n// ============================================================================\n\n/**\n * Common resolved data for organization-based permissions\n *\n * Pre-built pattern for multi-organization systems where users can\n * belong to multiple organizations with different roles/permissions.\n */\nexport interface OrganizationResolvedData extends ResolvedData {\n /**\n * List of organization IDs the user belongs to\n */\n organizationIds: (string | number)[]\n\n /**\n * Map of organization ID to user's permissions in that org\n */\n orgPermissions: Map<string | number, Set<string>>\n\n /**\n * Map of organization ID to user's roles in that org\n */\n orgRoles: Map<string | number, string[]>\n\n /**\n * Check if user is owner of an organization\n * @param orgId - Organization ID\n */\n isOrgOwner(orgId: string | number): boolean\n\n /**\n * Check if user has a specific permission in an organization\n * @param orgId - Organization ID\n * @param permission - Permission to check\n */\n hasOrgPermission(orgId: string | number, permission: string): boolean\n\n /**\n * Check if user has a specific role in an organization\n * @param orgId - Organization ID\n * @param role - Role to check\n */\n hasOrgRole(orgId: string | number, role: string): boolean\n}\n\n/**\n * Common resolved data for tenant-based systems\n */\nexport interface TenantResolvedData extends ResolvedData {\n /**\n * Current tenant ID (resolved from user context)\n */\n tenantId: string | number\n\n /**\n * Tenant-specific settings/restrictions\n */\n tenantSettings?: Record<string, unknown>\n\n /**\n * Tenant-specific feature flags\n */\n tenantFeatures?: Set<string>\n}\n\n/**\n * Common resolved data for hierarchical permissions\n *\n * For systems with resource hierarchies (e.g., team -> project -> task)\n */\nexport interface HierarchyResolvedData extends ResolvedData {\n /**\n * Resources the user has direct access to\n */\n directAccess: Set<string>\n\n /**\n * Resources the user has inherited access to (through hierarchy)\n */\n inheritedAccess: Set<string>\n\n /**\n * Check if user can access a resource (direct or inherited)\n * @param resourceId - Resource ID\n */\n canAccess(resourceId: string): boolean\n\n /**\n * Get the access level for a resource\n * @param resourceId - Resource ID\n * @returns Access level or null if no access\n */\n getAccessLevel(resourceId: string): string | null\n}\n\n/**\n * Combined resolved data type for common use cases\n */\nexport type CommonResolvedData = OrganizationResolvedData & TenantResolvedData\n","/**\n * Context Resolver Manager\n *\n * Orchestrates the resolution of context data from multiple resolvers,\n * handling caching, dependencies, and parallel execution.\n *\n * @module @kysera/rls/resolvers/manager\n */\n\nimport type {\n ContextResolver,\n ResolvedData,\n BaseResolverContext,\n ResolverManagerOptions,\n ResolverCacheProvider,\n EnhancedRLSContext\n} from './types.js'\nimport { InMemoryCacheProvider } from './types.js'\nimport { RLSError, RLSErrorCodes } from '../errors.js'\n\n// ============================================================================\n// Resolver Manager\n// ============================================================================\n\n/**\n * Manages context resolvers and orchestrates context resolution\n *\n * The ResolverManager is responsible for:\n * - Registering and organizing resolvers\n * - Resolving context data in the correct order (respecting dependencies)\n * - Caching resolved data\n * - Handling resolver failures\n *\n * @example\n * ```typescript\n * const manager = new ResolverManager({\n * cacheProvider: new RedisCacheProvider(redis),\n * defaultCacheTtl: 300,\n * parallelResolution: true\n * });\n *\n * // Register resolvers\n * manager.register(orgPermissionResolver);\n * manager.register(tenantSettingsResolver);\n *\n * // Resolve context\n * const enhancedCtx = await manager.resolve({\n * auth: { userId: '123', roles: ['user'] },\n * timestamp: new Date()\n * });\n *\n * // Use in RLS\n * await rlsContext.runAsync(enhancedCtx, async () => {\n * // Policies can access resolved data synchronously\n * });\n * ```\n */\nexport class ResolverManager<TResolved extends ResolvedData = ResolvedData> {\n private resolvers = new Map<string, ContextResolver>()\n private cacheProvider: ResolverCacheProvider\n private defaultCacheTtl: number\n private parallelResolution: boolean\n private resolverTimeout: number\n private logger: ResolverManagerOptions['logger']\n\n constructor(options: ResolverManagerOptions = {}) {\n this.cacheProvider = options.cacheProvider ?? new InMemoryCacheProvider()\n this.defaultCacheTtl = options.defaultCacheTtl ?? 300\n this.parallelResolution = options.parallelResolution ?? true\n this.resolverTimeout = options.resolverTimeout ?? 5000\n this.logger = options.logger\n }\n\n /**\n * Register a context resolver\n *\n * @param resolver - Resolver to register\n * @throws RLSError if resolver with same name already exists\n */\n register<T extends ResolvedData>(resolver: ContextResolver<T>): void {\n if (this.resolvers.has(resolver.name)) {\n throw new RLSError(\n `Resolver \"${resolver.name}\" is already registered`,\n RLSErrorCodes.RLS_SCHEMA_INVALID\n )\n }\n\n // Validate dependencies exist\n if (resolver.dependsOn) {\n for (const dep of resolver.dependsOn) {\n if (dep === resolver.name) {\n throw new RLSError(\n `Resolver \"${resolver.name}\" cannot depend on itself`,\n RLSErrorCodes.RLS_SCHEMA_INVALID\n )\n }\n }\n }\n\n this.resolvers.set(resolver.name, resolver as ContextResolver)\n this.logger?.debug?.(`[ResolverManager] Registered resolver: ${resolver.name}`)\n }\n\n /**\n * Unregister a context resolver\n *\n * @param name - Name of resolver to unregister\n * @returns true if resolver was removed, false if it didn't exist\n */\n unregister(name: string): boolean {\n const removed = this.resolvers.delete(name)\n if (removed) {\n this.logger?.debug?.(`[ResolverManager] Unregistered resolver: ${name}`)\n }\n return removed\n }\n\n /**\n * Check if a resolver is registered\n *\n * @param name - Resolver name\n */\n hasResolver(name: string): boolean {\n return this.resolvers.has(name)\n }\n\n /**\n * Get all registered resolver names\n */\n getResolverNames(): string[] {\n return Array.from(this.resolvers.keys())\n }\n\n /**\n * Resolve context data using all registered resolvers\n *\n * @param baseContext - Base context to resolve\n * @returns Enhanced context with resolved data\n *\n * @example\n * ```typescript\n * const baseCtx = {\n * auth: { userId: '123', roles: ['user'], tenantId: 'acme' },\n * timestamp: new Date()\n * };\n *\n * const enhancedCtx = await manager.resolve(baseCtx);\n * // enhancedCtx.auth.resolved contains all resolved data\n * ```\n */\n async resolve(baseContext: BaseResolverContext): Promise<EnhancedRLSContext<unknown, TResolved>> {\n const startTime = Date.now()\n const resolverOrder = this.getResolverOrder()\n\n this.logger?.debug?.(`[ResolverManager] Starting resolution for user ${baseContext.auth.userId}`, {\n resolverCount: resolverOrder.length,\n resolvers: resolverOrder.map(r => r.name)\n })\n\n const results = new Map<string, ResolvedData>()\n\n if (this.parallelResolution) {\n await this.resolveParallel(baseContext, resolverOrder, results)\n } else {\n await this.resolveSequential(baseContext, resolverOrder, results)\n }\n\n // Merge all resolved data\n const mergedResolved = this.mergeResolvedData(results)\n\n const enhancedContext: EnhancedRLSContext<unknown, TResolved> = {\n auth: {\n ...baseContext.auth,\n resolved: mergedResolved as TResolved\n },\n timestamp: baseContext.timestamp\n }\n\n if (baseContext.meta !== undefined) {\n enhancedContext.meta = baseContext.meta\n }\n\n const duration = Date.now() - startTime\n this.logger?.info?.(`[ResolverManager] Resolution completed`, {\n userId: baseContext.auth.userId,\n durationMs: duration,\n resolverCount: results.size\n })\n\n return enhancedContext\n }\n\n /**\n * Resolve a single resolver (useful for partial updates)\n *\n * @param name - Resolver name\n * @param baseContext - Base context\n * @returns Resolved data from the specific resolver\n */\n async resolveOne<T extends ResolvedData>(\n name: string,\n baseContext: BaseResolverContext\n ): Promise<T | null> {\n const resolver = this.resolvers.get(name)\n if (!resolver) {\n this.logger?.warn?.(`[ResolverManager] Resolver not found: ${name}`)\n return null\n }\n\n return (await this.resolveWithCache(resolver, baseContext)) as T | null\n }\n\n /**\n * Invalidate cached data for a user\n *\n * @param userId - User ID whose cache should be invalidated\n * @param resolverName - Optional specific resolver to invalidate\n */\n async invalidateCache(userId: string | number, resolverName?: string): Promise<void> {\n if (resolverName) {\n const resolver = this.resolvers.get(resolverName)\n if (resolver?.cacheKey) {\n const key = resolver.cacheKey({ auth: { userId, roles: [] }, timestamp: new Date() })\n if (key) {\n await this.cacheProvider.delete(key)\n this.logger?.debug?.(`[ResolverManager] Invalidated cache for ${resolverName}: ${key}`)\n }\n }\n } else {\n // Invalidate all resolvers for this user\n const pattern = `rls:*:${userId}:*`\n if (this.cacheProvider.deletePattern) {\n await this.cacheProvider.deletePattern(pattern)\n }\n this.logger?.debug?.(`[ResolverManager] Invalidated all cache for user ${userId}`)\n }\n }\n\n /**\n * Clear all cached data\n */\n async clearCache(): Promise<void> {\n if (this.cacheProvider instanceof InMemoryCacheProvider) {\n this.cacheProvider.clear()\n } else if (this.cacheProvider.deletePattern) {\n await this.cacheProvider.deletePattern('rls:*')\n }\n this.logger?.info?.('[ResolverManager] Cleared all cache')\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Get resolvers in dependency order (topological sort)\n */\n private getResolverOrder(): ContextResolver[] {\n const ordered: ContextResolver[] = []\n const visited = new Set<string>()\n const visiting = new Set<string>()\n\n const visit = (name: string): void => {\n if (visited.has(name)) return\n if (visiting.has(name)) {\n throw new RLSError(\n `Circular dependency detected in resolvers involving \"${name}\"`,\n RLSErrorCodes.RLS_SCHEMA_INVALID\n )\n }\n\n const resolver = this.resolvers.get(name)\n if (!resolver) return\n\n visiting.add(name)\n\n // Visit dependencies first\n if (resolver.dependsOn) {\n for (const dep of resolver.dependsOn) {\n visit(dep)\n }\n }\n\n visiting.delete(name)\n visited.add(name)\n ordered.push(resolver)\n }\n\n // Visit all resolvers\n for (const name of this.resolvers.keys()) {\n visit(name)\n }\n\n // Sort by priority within dependency constraints\n // Higher priority = earlier execution\n return ordered.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n }\n\n /**\n * Resolve resolvers sequentially\n */\n private async resolveSequential(\n baseContext: BaseResolverContext,\n resolvers: ContextResolver[],\n results: Map<string, ResolvedData>\n ): Promise<void> {\n for (const resolver of resolvers) {\n const data = await this.resolveWithCache(resolver, baseContext)\n if (data) {\n results.set(resolver.name, data)\n }\n }\n }\n\n /**\n * Resolve resolvers in parallel (respecting dependencies)\n */\n private async resolveParallel(\n baseContext: BaseResolverContext,\n resolvers: ContextResolver[],\n results: Map<string, ResolvedData>\n ): Promise<void> {\n // Group resolvers by their dependency depth\n const levels: ContextResolver[][] = []\n const assigned = new Set<string>()\n\n const getLevel = (resolver: ContextResolver): number => {\n if (!resolver.dependsOn || resolver.dependsOn.length === 0) {\n return 0\n }\n let maxDepLevel = 0\n for (const dep of resolver.dependsOn) {\n const depResolver = this.resolvers.get(dep)\n if (depResolver) {\n maxDepLevel = Math.max(maxDepLevel, getLevel(depResolver) + 1)\n }\n }\n return maxDepLevel\n }\n\n // Assign resolvers to levels\n for (const resolver of resolvers) {\n const level = getLevel(resolver)\n while (levels.length <= level) {\n levels.push([])\n }\n levels[level]!.push(resolver)\n assigned.add(resolver.name)\n }\n\n // Execute level by level\n for (const level of levels) {\n await Promise.all(\n level.map(async resolver => {\n const data = await this.resolveWithCache(resolver, baseContext)\n if (data) {\n results.set(resolver.name, data)\n }\n })\n )\n }\n }\n\n /**\n * Resolve a single resolver with caching\n */\n private async resolveWithCache(\n resolver: ContextResolver,\n baseContext: BaseResolverContext\n ): Promise<ResolvedData | null> {\n const startTime = Date.now()\n\n try {\n // Check cache first\n if (resolver.cacheKey) {\n const cacheKey = resolver.cacheKey(baseContext)\n if (cacheKey) {\n const cached = await this.cacheProvider.get<ResolvedData>(cacheKey)\n if (cached) {\n this.logger?.debug?.(`[ResolverManager] Cache hit for ${resolver.name}`, { cacheKey })\n return cached\n }\n }\n }\n\n // Resolve with timeout\n const data = await this.withTimeout(\n resolver.resolve(baseContext),\n this.resolverTimeout,\n `Resolver \"${resolver.name}\" timed out after ${this.resolverTimeout}ms`\n )\n\n // Cache the result\n if (resolver.cacheKey) {\n const cacheKey = resolver.cacheKey(baseContext)\n if (cacheKey) {\n const ttl = resolver.cacheTtl ?? this.defaultCacheTtl\n await this.cacheProvider.set(cacheKey, data, ttl)\n this.logger?.debug?.(`[ResolverManager] Cached ${resolver.name}`, { cacheKey, ttl })\n }\n }\n\n const duration = Date.now() - startTime\n this.logger?.debug?.(`[ResolverManager] Resolved ${resolver.name}`, { durationMs: duration })\n\n return data\n } catch (error) {\n const duration = Date.now() - startTime\n this.logger?.error?.(`[ResolverManager] Failed to resolve ${resolver.name}`, {\n error: error instanceof Error ? error.message : String(error),\n durationMs: duration\n })\n\n if (resolver.required !== false) {\n throw new RLSError(\n `Required resolver \"${resolver.name}\" failed: ${error instanceof Error ? error.message : String(error)}`,\n RLSErrorCodes.RLS_POLICY_EVALUATION_ERROR\n )\n }\n\n return null\n }\n }\n\n /**\n * Execute a promise with timeout\n */\n private async withTimeout<T>(promise: Promise<T>, timeoutMs: number, message: string): Promise<T> {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => setTimeout(() => { reject(new Error(message)); }, timeoutMs))\n ])\n }\n\n /**\n * Merge resolved data from multiple resolvers\n */\n private mergeResolvedData(results: Map<string, ResolvedData>): ResolvedData {\n const merged: ResolvedData & Record<string, unknown> = {\n resolvedAt: new Date()\n }\n\n for (const [name, data] of results) {\n // Add resolver data under its name\n merged[name] = data\n\n // Also spread properties to root level for convenience\n for (const [key, value] of Object.entries(data)) {\n if (key !== 'resolvedAt' && key !== 'cacheKey') {\n if (merged[key] === undefined) {\n merged[key] = value\n }\n }\n }\n }\n\n return merged\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a context resolver manager with common defaults\n *\n * @param options - Manager options\n * @returns Configured ResolverManager\n */\nexport function createResolverManager<TResolved extends ResolvedData = ResolvedData>(\n options?: ResolverManagerOptions\n): ResolverManager<TResolved> {\n return new ResolverManager<TResolved>(options)\n}\n\n/**\n * Helper to create a context resolver\n *\n * @param config - Resolver configuration\n * @returns ContextResolver instance\n *\n * @example\n * ```typescript\n * const resolver = createResolver({\n * name: 'org-permissions',\n * resolve: async (base) => {\n * const orgs = await getEmployeeOrganizations(base.auth.userId);\n * return {\n * resolvedAt: new Date(),\n * organizationIds: orgs.map(o => o.id)\n * };\n * },\n * cacheKey: (base) => `rls:org:${base.auth.userId}`,\n * cacheTtl: 300\n * });\n * ```\n */\nexport function createResolver<TResolved extends ResolvedData>(\n config: ContextResolver<TResolved>\n): ContextResolver<TResolved> {\n return {\n required: true,\n priority: 0,\n ...config\n }\n}\n","/**\n * ReBAC (Relationship-Based Access Control) Types\n *\n * Provides type definitions for relationship-based filtering in RLS policies.\n * ReBAC allows policies to be defined based on relationships between entities\n * in the database, enabling complex access control patterns like\n * \"show products if user is employee of product's shop's organization\".\n *\n * @module @kysera/rls/rebac/types\n */\n\nimport type { PolicyEvaluationContext, PolicyDefinition } from '../policy/types.js'\n\n// ============================================================================\n// Relationship Definition Types\n// ============================================================================\n\n/**\n * A single step in a relationship path\n *\n * Defines how to join from one table to another.\n *\n * @example\n * ```typescript\n * // Simple join: products.shop_id -> shops.id\n * const step: RelationshipStep = {\n * from: 'products',\n * to: 'shops',\n * fromColumn: 'shop_id',\n * toColumn: 'id'\n * };\n * ```\n */\nexport interface RelationshipStep {\n /**\n * Source table name\n */\n from: string\n\n /**\n * Target table name\n */\n to: string\n\n /**\n * Column in source table for the join\n * @default 'id' on target table side, '{to}_id' on source side\n */\n fromColumn?: string\n\n /**\n * Column in target table for the join\n * @default 'id'\n */\n toColumn?: string\n\n /**\n * Optional alias for the target table in the join\n * Useful when joining the same table multiple times\n */\n alias?: string\n\n /**\n * Join type\n * @default 'inner'\n */\n joinType?: 'inner' | 'left' | 'right'\n\n /**\n * Additional conditions for this join step\n * @example { 'shops.deleted_at': null, 'shops.status': 'active' }\n */\n additionalConditions?: Record<string, unknown>\n}\n\n/**\n * Complete relationship path definition\n *\n * Defines a chain of relationships from a source table to a target.\n *\n * @example\n * ```typescript\n * // Path: products -> shops -> organizations -> employees\n * const path: RelationshipPath = {\n * name: 'orgEmployee',\n * steps: [\n * { from: 'products', to: 'shops', fromColumn: 'shop_id' },\n * { from: 'shops', to: 'organizations', fromColumn: 'organization_id' },\n * { from: 'organizations', to: 'employees', toColumn: 'organization_id' }\n * ]\n * };\n * ```\n */\nexport interface RelationshipPath {\n /**\n * Unique name for this relationship path\n * Used in policy definitions to reference this path\n */\n name: string\n\n /**\n * Steps in the relationship chain\n */\n steps: RelationshipStep[]\n\n /**\n * Optional description for documentation\n */\n description?: string\n}\n\n/**\n * Condition to apply at the end of a relationship path\n *\n * @typeParam TCtx - Policy evaluation context type\n */\nexport type RelationshipCondition<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> =\n | ((ctx: TCtx) => Record<string, unknown>)\n | Record<string, unknown>\n\n/**\n * ReBAC policy definition\n *\n * Extends standard policy definition with relationship-based filtering.\n */\nexport interface ReBAcPolicyDefinition<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext>\n extends Omit<PolicyDefinition, 'condition'> {\n /**\n * Name of the relationship path to use (defined in relationships config)\n */\n relationshipPath: string\n\n /**\n * Conditions to apply at the end of the relationship\n * These conditions filter the final table in the relationship chain.\n *\n * @example\n * ```typescript\n * // Filter employees table at end of relationship\n * endCondition: ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'active'\n * })\n * ```\n */\n endCondition: RelationshipCondition<TCtx>\n\n /**\n * Whether this is a permissive or restrictive policy\n * - 'allow': Row is accessible if relationship exists\n * - 'deny': Row is NOT accessible if relationship exists\n * @default 'allow'\n */\n policyType?: 'allow' | 'deny'\n}\n\n// ============================================================================\n// Table ReBAC Configuration\n// ============================================================================\n\n/**\n * ReBAC configuration for a single table\n */\nexport interface TableReBAcConfig {\n /**\n * Relationship paths available for this table\n */\n relationships: RelationshipPath[]\n\n /**\n * ReBAC policies for this table\n */\n policies: ReBAcPolicyDefinition[]\n}\n\n/**\n * Complete ReBAC schema for all tables\n *\n * @typeParam DB - Database schema type\n */\nexport type ReBAcSchema<DB> = {\n [K in keyof DB]?: TableReBAcConfig\n}\n\n// ============================================================================\n// Compiled ReBAC Types\n// ============================================================================\n\n/**\n * Compiled relationship path ready for query generation\n */\nexport interface CompiledRelationshipPath {\n /**\n * Path name\n */\n name: string\n\n /**\n * Compiled join steps with defaults filled in\n */\n steps: Required<RelationshipStep>[]\n\n /**\n * Source table (first table in the chain)\n */\n sourceTable: string\n\n /**\n * Target table (final table in the chain)\n */\n targetTable: string\n}\n\n/**\n * Compiled ReBAC policy ready for evaluation\n */\nexport interface CompiledReBAcPolicy<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {\n /**\n * Policy name\n */\n name: string\n\n /**\n * Policy type (allow/deny)\n */\n type: 'allow' | 'deny'\n\n /**\n * Operations this policy applies to\n */\n operations: Set<string>\n\n /**\n * Compiled relationship path\n */\n relationshipPath: CompiledRelationshipPath\n\n /**\n * Function to get end conditions\n */\n getEndConditions: (ctx: TCtx) => Record<string, unknown>\n\n /**\n * Priority for policy evaluation\n */\n priority: number\n}\n\n// ============================================================================\n// Query Generation Types\n// ============================================================================\n\n/**\n * Generated EXISTS subquery for ReBAC filtering\n */\nexport interface ReBAcSubquery {\n /**\n * SQL for the EXISTS subquery\n */\n sql: string\n\n /**\n * Parameter values for the subquery\n */\n parameters: unknown[]\n\n /**\n * Whether this is an allow (EXISTS) or deny (NOT EXISTS) check\n */\n isNegated: boolean\n}\n\n/**\n * Options for ReBAC query generation\n */\nexport interface ReBAcQueryOptions {\n /**\n * Table alias for the main query table\n * @default table name\n */\n mainTableAlias?: string\n\n /**\n * Whether to use qualified column names\n * @default true\n */\n qualifyColumns?: boolean\n\n /**\n * Database dialect for query generation\n * @default 'postgres'\n */\n dialect?: 'postgres' | 'mysql' | 'sqlite'\n}\n\n// ============================================================================\n// Predefined Relationship Patterns\n// ============================================================================\n\n/**\n * Common relationship pattern: Resource belongs to organization via owner\n *\n * @param resourceTable - Table containing the resource\n * @param organizationColumn - Column linking to organization\n *\n * @example\n * ```typescript\n * const path = orgMembershipPath('products', 'organization_id');\n * // Creates path: products -> organizations -> employees\n * ```\n */\nexport function orgMembershipPath(\n resourceTable: string,\n organizationColumn = 'organization_id'\n): RelationshipPath {\n return {\n name: `${resourceTable}_org_membership`,\n description: `Access ${resourceTable} through organization membership`,\n steps: [\n {\n from: resourceTable,\n to: 'organizations',\n fromColumn: organizationColumn,\n toColumn: 'id'\n },\n {\n from: 'organizations',\n to: 'employees',\n fromColumn: 'id',\n toColumn: 'organization_id'\n }\n ]\n }\n}\n\n/**\n * Common relationship pattern: Resource belongs to shop's organization\n *\n * @param resourceTable - Table containing the resource\n * @param shopColumn - Column linking to shop\n *\n * @example\n * ```typescript\n * const path = shopOrgMembershipPath('products', 'shop_id');\n * // Creates path: products -> shops -> organizations -> employees\n * ```\n */\nexport function shopOrgMembershipPath(\n resourceTable: string,\n shopColumn = 'shop_id'\n): RelationshipPath {\n return {\n name: `${resourceTable}_shop_org_membership`,\n description: `Access ${resourceTable} through shop's organization membership`,\n steps: [\n {\n from: resourceTable,\n to: 'shops',\n fromColumn: shopColumn,\n toColumn: 'id'\n },\n {\n from: 'shops',\n to: 'organizations',\n fromColumn: 'organization_id',\n toColumn: 'id'\n },\n {\n from: 'organizations',\n to: 'employees',\n fromColumn: 'id',\n toColumn: 'organization_id'\n }\n ]\n }\n}\n\n/**\n * Common relationship pattern: Hierarchical team access\n *\n * @param resourceTable - Table containing the resource\n * @param teamColumn - Column linking to team\n *\n * @example\n * ```typescript\n * const path = teamHierarchyPath('tasks', 'team_id');\n * // Creates path: tasks -> teams -> team_members\n * ```\n */\nexport function teamHierarchyPath(\n resourceTable: string,\n teamColumn = 'team_id'\n): RelationshipPath {\n return {\n name: `${resourceTable}_team_access`,\n description: `Access ${resourceTable} through team membership`,\n steps: [\n {\n from: resourceTable,\n to: 'teams',\n fromColumn: teamColumn,\n toColumn: 'id'\n },\n {\n from: 'teams',\n to: 'team_members',\n fromColumn: 'id',\n toColumn: 'team_id'\n }\n ]\n }\n}\n","/**\n * ReBAC Policy Registry\n *\n * Manages relationship definitions and ReBAC policies for RLS.\n *\n * @module @kysera/rls/rebac/registry\n */\n\nimport type {\n RelationshipPath,\n RelationshipStep,\n ReBAcPolicyDefinition,\n ReBAcSchema,\n TableReBAcConfig,\n CompiledRelationshipPath,\n CompiledReBAcPolicy\n} from './types.js'\nimport type { PolicyEvaluationContext, Operation } from '../policy/types.js'\nimport { RLSSchemaError } from '../errors.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\n\n// ============================================================================\n// ReBAC Registry\n// ============================================================================\n\n/**\n * Internal compiled table configuration\n */\ninterface TableReBAcCompiled {\n relationships: Map<string, CompiledRelationshipPath>\n policies: CompiledReBAcPolicy[]\n}\n\n/**\n * ReBAC Registry\n *\n * Manages relationship paths and ReBAC policies across tables.\n *\n * @example\n * ```typescript\n * const registry = new ReBAcRegistry();\n *\n * // Register relationship paths and policies\n * registry.loadSchema({\n * products: {\n * relationships: [\n * shopOrgMembershipPath('products', 'shop_id')\n * ],\n * policies: [\n * {\n * type: 'filter',\n * operation: 'read',\n * relationshipPath: 'products_shop_org_membership',\n * endCondition: ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'active'\n * })\n * }\n * ]\n * }\n * });\n *\n * // Get policies for a table\n * const policies = registry.getPolicies('products', 'read');\n * ```\n */\nexport class ReBAcRegistry<DB = unknown> {\n private tables = new Map<string, TableReBAcCompiled>()\n private globalRelationships = new Map<string, CompiledRelationshipPath>()\n private logger: KyseraLogger\n\n constructor(schema?: ReBAcSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger\n if (schema) {\n this.loadSchema(schema)\n }\n }\n\n /**\n * Load ReBAC schema\n */\n loadSchema(schema: ReBAcSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n this.registerTable(table, config as TableReBAcConfig)\n }\n }\n\n /**\n * Register ReBAC configuration for a single table\n */\n registerTable(table: string, config: TableReBAcConfig): void {\n const compiled: TableReBAcCompiled = {\n relationships: new Map(),\n policies: []\n }\n\n // Compile relationships\n for (const rel of config.relationships) {\n const compiledPath = this.compileRelationshipPath(rel, table)\n compiled.relationships.set(rel.name, compiledPath)\n // Also register globally for cross-table references\n this.globalRelationships.set(rel.name, compiledPath)\n }\n\n // Compile policies\n for (let i = 0; i < config.policies.length; i++) {\n const policy = config.policies[i]\n if (!policy) continue\n\n const policyName = policy.name ?? `${table}_rebac_policy_${i}`\n const compiledPolicy = this.compilePolicy(policy, policyName, table, compiled.relationships)\n compiled.policies.push(compiledPolicy)\n }\n\n // Sort by priority\n compiled.policies.sort((a, b) => b.priority - a.priority)\n\n this.tables.set(table, compiled)\n this.logger.info?.(`[ReBAC] Registered table: ${table}`, {\n relationships: config.relationships.length,\n policies: config.policies.length\n })\n }\n\n /**\n * Register a global relationship path (available to all tables)\n */\n registerRelationship(path: RelationshipPath): void {\n if (!path.steps.length) {\n throw new RLSSchemaError(`Relationship path \"${path.name}\" has no steps`, {\n path: path.name\n })\n }\n\n const compiled = this.compileRelationshipPath(path, path.steps[0]!.from)\n this.globalRelationships.set(path.name, compiled)\n }\n\n /**\n * Get ReBAC policies for a table and operation\n */\n getPolicies(table: string, operation: Operation): CompiledReBAcPolicy[] {\n const config = this.tables.get(table)\n if (!config) return []\n\n return config.policies.filter(p => p.operations.has(operation) || p.operations.has('all'))\n }\n\n /**\n * Get a specific relationship path\n */\n getRelationship(name: string, table?: string): CompiledRelationshipPath | undefined {\n // Check table-specific first\n if (table) {\n const tableConfig = this.tables.get(table)\n const tablePath = tableConfig?.relationships.get(name)\n if (tablePath) return tablePath\n }\n\n // Fall back to global\n return this.globalRelationships.get(name)\n }\n\n /**\n * Check if table has ReBAC configuration\n */\n hasTable(table: string): boolean {\n return this.tables.has(table)\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys())\n }\n\n /**\n * Clear all registrations\n */\n clear(): void {\n this.tables.clear()\n this.globalRelationships.clear()\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Compile a relationship path definition\n */\n private compileRelationshipPath(path: RelationshipPath, sourceTable: string): CompiledRelationshipPath {\n if (path.steps.length === 0) {\n throw new RLSSchemaError(`Relationship path \"${path.name}\" must have at least one step`, {\n path: path.name\n })\n }\n\n const compiledSteps: Required<RelationshipStep>[] = path.steps.map((step, index) => {\n // Validate step\n if (!step.from || !step.to) {\n throw new RLSSchemaError(\n `Relationship step ${index} in \"${path.name}\" must have 'from' and 'to' tables`,\n { path: path.name, step: index }\n )\n }\n\n // Fill defaults\n return {\n from: step.from,\n to: step.to,\n fromColumn: step.fromColumn ?? `${step.to}_id`,\n toColumn: step.toColumn ?? 'id',\n alias: step.alias ?? step.to,\n joinType: step.joinType ?? 'inner',\n additionalConditions: step.additionalConditions ?? {}\n }\n })\n\n // Validate chain continuity\n for (let i = 1; i < compiledSteps.length; i++) {\n const prevStep = compiledSteps[i - 1]!\n const currentStep = compiledSteps[i]!\n\n // Each step's 'from' should match previous step's 'to'\n if (currentStep.from !== prevStep.to && currentStep.from !== prevStep.alias) {\n throw new RLSSchemaError(\n `Relationship path \"${path.name}\" has broken chain at step ${i}: ` +\n `expected '${prevStep.to}' but got '${currentStep.from}'`,\n { path: path.name, step: i }\n )\n }\n }\n\n const lastStep = compiledSteps[compiledSteps.length - 1]!\n\n return {\n name: path.name,\n steps: compiledSteps,\n sourceTable,\n targetTable: lastStep.to\n }\n }\n\n /**\n * Compile a ReBAC policy definition\n */\n private compilePolicy(\n policy: ReBAcPolicyDefinition,\n name: string,\n table: string,\n tableRelationships: Map<string, CompiledRelationshipPath>\n ): CompiledReBAcPolicy {\n // Get relationship path\n const relationshipPath =\n tableRelationships.get(policy.relationshipPath) ??\n this.globalRelationships.get(policy.relationshipPath)\n\n if (!relationshipPath) {\n throw new RLSSchemaError(\n `ReBAC policy \"${name}\" references unknown relationship path \"${policy.relationshipPath}\"`,\n { policy: name, table, relationshipPath: policy.relationshipPath }\n )\n }\n\n // Normalize operations\n const ops = Array.isArray(policy.operation) ? policy.operation : [policy.operation]\n const expandedOps = ops.flatMap(op =>\n op === 'all' ? ['read', 'create', 'update', 'delete'] : [op]\n )\n\n // Compile end condition\n const getEndConditions =\n typeof policy.endCondition === 'function'\n ? policy.endCondition\n : () => policy.endCondition as Record<string, unknown>\n\n return {\n name,\n type: policy.policyType ?? 'allow',\n operations: new Set(expandedOps),\n relationshipPath,\n getEndConditions: getEndConditions as (ctx: PolicyEvaluationContext) => Record<string, unknown>,\n priority: policy.priority ?? 0\n }\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a ReBAC registry\n */\nexport function createReBAcRegistry<DB = unknown>(\n schema?: ReBAcSchema<DB>,\n options?: { logger?: KyseraLogger }\n): ReBAcRegistry<DB> {\n return new ReBAcRegistry<DB>(schema, options)\n}\n","/**\n * ReBAC Query Transformer\n *\n * Transforms queries to apply relationship-based access control policies.\n * Generates EXISTS subqueries that filter rows based on relationship chains.\n *\n * @module @kysera/rls/rebac/transformer\n */\n\nimport type { SelectQueryBuilder } from 'kysely'\nimport { sql } from 'kysely'\nimport type { ReBAcRegistry } from './registry.js'\nimport type { CompiledReBAcPolicy, ReBAcQueryOptions, ReBAcPolicyDefinition } from './types.js'\nimport type { PolicyEvaluationContext, Operation, RLSContext } from '../policy/types.js'\nimport { rlsContext } from '../context/manager.js'\n\n// ============================================================================\n// ReBAC Transformer\n// ============================================================================\n\n/**\n * ReBAC query transformer\n *\n * Applies relationship-based access control to SELECT queries by generating\n * EXISTS subqueries that follow relationship paths.\n *\n * @example\n * ```typescript\n * const transformer = new ReBAcTransformer(registry);\n *\n * // Transform query\n * let query = db.selectFrom('products').selectAll();\n * query = transformer.transform(query, 'products', 'read');\n *\n * // Generated SQL includes EXISTS subquery:\n * // SELECT * FROM products p\n * // WHERE EXISTS (\n * // SELECT 1 FROM shops s\n * // JOIN organizations o ON s.organization_id = o.id\n * // JOIN employees e ON e.organization_id = o.id\n * // WHERE s.id = p.shop_id\n * // AND e.user_id = $1\n * // AND e.status = 'active'\n * // )\n * ```\n */\nexport class ReBAcTransformer<DB = unknown> {\n constructor(\n private registry: ReBAcRegistry<DB>,\n private options: ReBAcQueryOptions = {}\n ) {\n this.options = {\n qualifyColumns: true,\n dialect: 'postgres',\n ...options\n }\n }\n\n /**\n * Transform a SELECT query by applying ReBAC policies\n *\n * @param qb - Query builder to transform\n * @param table - Table being queried\n * @param operation - Operation being performed\n * @returns Transformed query builder\n */\n transform<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n table: string,\n operation: Operation = 'read'\n ): SelectQueryBuilder<DB, TB, O> {\n const ctx = rlsContext.getContextOrNull()\n if (!ctx) {\n // No context - handled by main RLS plugin\n return qb\n }\n\n // System users bypass ReBAC\n if (ctx.auth.isSystem) {\n return qb\n }\n\n // Get applicable ReBAC policies\n const policies = this.registry.getPolicies(table, operation)\n if (policies.length === 0) {\n return qb\n }\n\n // Apply each policy\n let result = qb\n for (const policy of policies) {\n result = this.applyPolicy(result, policy, ctx, table)\n }\n\n return result\n }\n\n /**\n * Generate EXISTS condition SQL for a policy\n *\n * This method can be used to get the raw SQL for debugging or manual query building.\n *\n * @param policy - ReBAC policy to generate SQL for\n * @param ctx - RLS context\n * @param mainTable - Main query table\n * @param mainTableAlias - Alias for main table\n * @returns SQL string and parameters\n */\n generateExistsSql(\n policy: CompiledReBAcPolicy,\n ctx: RLSContext,\n mainTable: string,\n mainTableAlias?: string\n ): { sql: string; params: unknown[] } {\n const { relationshipPath } = policy\n const evalCtx = this.createEvalContext(ctx, mainTable)\n const endConditions = policy.getEndConditions(evalCtx)\n\n const alias = mainTableAlias ?? mainTable\n const params: unknown[] = []\n let paramIndex = 1\n\n // Build the EXISTS subquery\n const steps = relationshipPath.steps\n if (steps.length === 0) {\n return { sql: 'TRUE', params: [] }\n }\n\n // Start with first join target\n const firstStep = steps[0]!\n let sql = `SELECT 1 FROM ${this.quote(firstStep.to)}`\n if (firstStep.alias !== firstStep.to) {\n sql += ` AS ${this.quote(firstStep.alias)}`\n }\n\n // Add joins for remaining steps\n for (let i = 1; i < steps.length; i++) {\n const step = steps[i]!\n const joinType = step.joinType === 'left' ? 'LEFT JOIN' : step.joinType === 'right' ? 'RIGHT JOIN' : 'JOIN'\n\n sql += ` ${joinType} ${this.quote(step.to)}`\n if (step.alias !== step.to) {\n sql += ` AS ${this.quote(step.alias)}`\n }\n\n // Join condition\n const prevStep = steps[i - 1]!\n const prevAlias = prevStep.alias\n sql += ` ON ${this.quote(prevAlias)}.${this.quote(step.fromColumn)} = ${this.quote(step.alias)}.${this.quote(step.toColumn)}`\n\n // Additional conditions for this step\n if (Object.keys(step.additionalConditions).length > 0) {\n for (const [col, val] of Object.entries(step.additionalConditions)) {\n if (val === null) {\n sql += ` AND ${this.quote(step.alias)}.${this.quote(col)} IS NULL`\n } else {\n sql += ` AND ${this.quote(step.alias)}.${this.quote(col)} = ${this.param(paramIndex++)}`\n params.push(val)\n }\n }\n }\n }\n\n // WHERE clause connecting to main table\n sql += ` WHERE ${this.quote(firstStep.alias)}.${this.quote(firstStep.toColumn)} = ${this.quote(alias)}.${this.quote(firstStep.fromColumn)}`\n\n // Additional conditions from first step\n if (Object.keys(firstStep.additionalConditions).length > 0) {\n for (const [col, val] of Object.entries(firstStep.additionalConditions)) {\n if (val === null) {\n sql += ` AND ${this.quote(firstStep.alias)}.${this.quote(col)} IS NULL`\n } else {\n sql += ` AND ${this.quote(firstStep.alias)}.${this.quote(col)} = ${this.param(paramIndex++)}`\n params.push(val)\n }\n }\n }\n\n // End conditions (applied to the final table in the chain)\n const lastStep = steps[steps.length - 1]!\n for (const [col, val] of Object.entries(endConditions)) {\n if (val === null) {\n sql += ` AND ${this.quote(lastStep.alias)}.${this.quote(col)} IS NULL`\n } else if (val === undefined) {\n // Skip undefined\n continue\n } else if (Array.isArray(val)) {\n if (val.length === 0) {\n sql += ` AND FALSE`\n } else {\n const placeholders = val.map(() => this.param(paramIndex++)).join(', ')\n sql += ` AND ${this.quote(lastStep.alias)}.${this.quote(col)} IN (${placeholders})`\n params.push(...val)\n }\n } else {\n sql += ` AND ${this.quote(lastStep.alias)}.${this.quote(col)} = ${this.param(paramIndex++)}`\n params.push(val)\n }\n }\n\n // Wrap in EXISTS or NOT EXISTS based on policy type\n const existsExpr = policy.type === 'deny' ? `NOT EXISTS (${sql})` : `EXISTS (${sql})`\n\n return { sql: existsExpr, params }\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Apply a single ReBAC policy to a query\n *\n * NOTE: Uses type casting for dynamic SQL because Kysely's type system\n * requires compile-time known types, but ReBAC policies work with\n * runtime-generated EXISTS clauses.\n */\n private applyPolicy<TB extends keyof DB & string, O>(\n qb: SelectQueryBuilder<DB, TB, O>,\n policy: CompiledReBAcPolicy,\n ctx: RLSContext,\n table: string\n ): SelectQueryBuilder<DB, TB, O> {\n const { sql: existsSql, params } = this.generateExistsSql(policy, ctx, table, this.options.mainTableAlias)\n\n // Build the SQL template parts for parameterization\n // Replace $N placeholders with sql template placeholders\n const sqlParts = existsSql.split(/\\$\\d+/)\n\n // Use Kysely's sql template function with tagged template literal\n // Build a raw sql expression with proper parameter binding\n const rawBuilder = sql.join(\n sqlParts.map((part, i) => {\n if (i < params.length) {\n return sql`${sql.raw(part)}${params[i]}`\n }\n return sql.raw(part)\n })\n )\n\n // Add the EXISTS/NOT EXISTS condition to the WHERE clause\n // Type cast is necessary because sql.join returns RawBuilder<unknown>\n // but where() requires ExpressionOrFactory<SqlBool>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return qb.where(rawBuilder as any) as SelectQueryBuilder<DB, TB, O>\n }\n\n /**\n * Create evaluation context for policy conditions\n */\n private createEvalContext(ctx: RLSContext, table: string): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n table,\n operation: 'read',\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n }\n\n /**\n * Quote an identifier for the target dialect\n */\n private quote(identifier: string): string {\n switch (this.options.dialect) {\n case 'mysql':\n return `\\`${identifier}\\``\n case 'sqlite':\n return `\"${identifier}\"`\n case 'postgres':\n default:\n return `\"${identifier}\"`\n }\n }\n\n /**\n * Generate parameter placeholder for the target dialect\n */\n private param(index: number): string {\n switch (this.options.dialect) {\n case 'mysql':\n case 'sqlite':\n return '?'\n case 'postgres':\n default:\n return `$${index}`\n }\n }\n}\n\n// ============================================================================\n// Policy Builder Functions\n// ============================================================================\n\n/**\n * Create a ReBAC allow policy\n *\n * Rows are accessible if the relationship EXISTS with the given end conditions.\n *\n * @param operation - Operation(s) this policy applies to\n * @param relationshipPath - Name of the relationship path to use\n * @param endCondition - Conditions to apply at the end of the relationship\n * @param options - Additional policy options\n *\n * @example\n * ```typescript\n * // Allow read if user is employee of product's shop's organization\n * allowRelation('read', 'products_shop_org_membership', ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'active'\n * }))\n * ```\n */\nexport function allowRelation(\n operation: Operation | Operation[],\n relationshipPath: string,\n endCondition: ((ctx: PolicyEvaluationContext) => Record<string, unknown>) | Record<string, unknown>,\n options?: { name?: string; priority?: number }\n): ReBAcPolicyDefinition {\n const policy: ReBAcPolicyDefinition = {\n type: 'filter',\n operation,\n relationshipPath,\n endCondition,\n policyType: 'allow'\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n if (options?.priority !== undefined) {\n policy.priority = options.priority\n }\n\n return policy\n}\n\n/**\n * Create a ReBAC deny policy\n *\n * Rows are NOT accessible if the relationship EXISTS with the given conditions.\n *\n * @param operation - Operation(s) this policy applies to\n * @param relationshipPath - Name of the relationship path to use\n * @param endCondition - Conditions to apply at the end of the relationship\n * @param options - Additional policy options\n *\n * @example\n * ```typescript\n * // Deny access if user is blocked in the organization\n * denyRelation('all', 'products_shop_org_membership', ctx => ({\n * user_id: ctx.auth.userId,\n * status: 'blocked'\n * }))\n * ```\n */\nexport function denyRelation(\n operation: Operation | Operation[],\n relationshipPath: string,\n endCondition: ((ctx: PolicyEvaluationContext) => Record<string, unknown>) | Record<string, unknown>,\n options?: { name?: string; priority?: number }\n): ReBAcPolicyDefinition {\n const policy: ReBAcPolicyDefinition = {\n type: 'filter',\n operation,\n relationshipPath,\n endCondition,\n policyType: 'deny',\n priority: options?.priority ?? 100 // Higher priority for deny\n }\n\n if (options?.name !== undefined) {\n policy.name = options.name\n }\n\n return policy\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a ReBAC transformer\n */\nexport function createReBAcTransformer<DB = unknown>(\n registry: ReBAcRegistry<DB>,\n options?: ReBAcQueryOptions\n): ReBAcTransformer<DB> {\n return new ReBAcTransformer<DB>(registry, options)\n}\n","/**\n * Field-Level Access Control Types\n *\n * Provides type definitions for controlling access to individual columns\n * based on context. This allows hiding sensitive fields from unauthorized users.\n *\n * @module @kysera/rls/field-access/types\n */\n\nimport type { PolicyEvaluationContext } from '../policy/types.js'\n\n// ============================================================================\n// Field Access Types\n// ============================================================================\n\n/**\n * Operations that can be controlled at field level\n */\nexport type FieldOperation = 'read' | 'write'\n\n/**\n * Field access condition function\n *\n * Returns true if the field is accessible, false otherwise.\n *\n * @typeParam TCtx - Policy evaluation context type\n */\nexport type FieldAccessCondition<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> = (\n ctx: TCtx\n) => boolean | Promise<boolean>\n\n/**\n * Configuration for a single field's access control\n *\n * @example\n * ```typescript\n * const emailConfig: FieldAccessConfig = {\n * read: ctx => ctx.auth.userId === ctx.row.id || ctx.auth.roles.includes('admin'),\n * write: ctx => ctx.auth.userId === ctx.row.id\n * };\n * ```\n */\nexport interface FieldAccessConfig<TCtx extends PolicyEvaluationContext = PolicyEvaluationContext> {\n /**\n * Condition for read access\n * If undefined, uses table default\n */\n read?: FieldAccessCondition<TCtx>\n\n /**\n * Condition for write access\n * If undefined, uses table default\n */\n write?: FieldAccessCondition<TCtx>\n\n /**\n * Value to use when field is not readable\n * @default null\n */\n maskedValue?: unknown\n\n /**\n * Whether to completely omit the field when not readable\n * @default false (uses maskedValue instead)\n */\n omitWhenHidden?: boolean\n}\n\n/**\n * Table field access configuration\n *\n * @typeParam TRow - Type of the database row\n * @typeParam TCtx - Policy evaluation context type\n *\n * @example\n * ```typescript\n * const usersFieldAccess: TableFieldAccessConfig<User> = {\n * default: 'allow',\n * fields: {\n * email: {\n * read: ctx => ctx.auth.userId === ctx.row.id || ctx.auth.roles.includes('admin')\n * },\n * password_hash: {\n * read: () => false,\n * write: () => false\n * },\n * mfa_totp_secret: {\n * read: ctx => ctx.auth.userId === ctx.row.id,\n * omitWhenHidden: true\n * }\n * }\n * };\n * ```\n */\nexport interface TableFieldAccessConfig<\n TRow = unknown,\n TCtx extends PolicyEvaluationContext = PolicyEvaluationContext\n> {\n /**\n * Default access policy for fields not explicitly configured\n * - 'allow': All fields are accessible by default\n * - 'deny': Only explicitly allowed fields are accessible\n * @default 'allow'\n */\n default?: 'allow' | 'deny'\n\n /**\n * Field-specific access configurations\n */\n fields: {\n [K in keyof TRow]?: FieldAccessConfig<TCtx>\n }\n\n /**\n * Roles that bypass field access control\n */\n skipFor?: string[]\n}\n\n/**\n * Complete field access schema for all tables\n *\n * @typeParam DB - Database schema type\n */\nexport type FieldAccessSchema<DB> = {\n [K in keyof DB]?: TableFieldAccessConfig<DB[K]>\n}\n\n// ============================================================================\n// Compiled Field Access Types\n// ============================================================================\n\n/**\n * Compiled field access configuration ready for evaluation\n */\nexport interface CompiledFieldAccess {\n /**\n * Field name\n */\n field: string\n\n /**\n * Compiled read condition\n * Returns true if field is readable\n */\n canRead: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n\n /**\n * Compiled write condition\n * Returns true if field is writable\n */\n canWrite: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n\n /**\n * Value to use when field is masked\n */\n maskedValue: unknown\n\n /**\n * Whether to omit the field entirely when hidden\n */\n omitWhenHidden: boolean\n}\n\n/**\n * Compiled table field access configuration\n */\nexport interface CompiledTableFieldAccess {\n /**\n * Table name\n */\n table: string\n\n /**\n * Default access policy\n */\n defaultAccess: 'allow' | 'deny'\n\n /**\n * Roles that bypass field access\n */\n skipFor: string[]\n\n /**\n * Field-specific configurations\n */\n fields: Map<string, CompiledFieldAccess>\n}\n\n// ============================================================================\n// Field Masking Result Types\n// ============================================================================\n\n/**\n * Result of field access evaluation\n */\nexport interface FieldAccessResult {\n /**\n * Whether the field is accessible\n */\n accessible: boolean\n\n /**\n * If not accessible, the reason\n */\n reason?: string\n\n /**\n * Value to use (original or masked)\n */\n value: unknown\n\n /**\n * Whether the field should be omitted entirely\n */\n omit: boolean\n}\n\n/**\n * Result of applying field access to a row\n */\nexport interface MaskedRow<T = Record<string, unknown>> {\n /**\n * The row with field access applied\n */\n data: Partial<T>\n\n /**\n * Fields that were masked\n */\n maskedFields: string[]\n\n /**\n * Fields that were omitted\n */\n omittedFields: string[]\n}\n\n// ============================================================================\n// Field Access Options\n// ============================================================================\n\n/**\n * Options for field access processing\n */\nexport interface FieldAccessOptions {\n /**\n * Whether to throw an error when accessing a denied field\n * @default false (returns masked value instead)\n */\n throwOnDenied?: boolean\n\n /**\n * Whether to include metadata about masked fields in the result\n * @default false\n */\n includeMetadata?: boolean\n\n /**\n * Fields to explicitly include (whitelist)\n * If specified, only these fields are processed\n */\n includeFields?: string[]\n\n /**\n * Fields to explicitly exclude (blacklist)\n * These fields are never included regardless of access\n */\n excludeFields?: string[]\n}\n\n// ============================================================================\n// Predefined Field Patterns\n// ============================================================================\n\n/**\n * Always deny access to a field\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * password_hash: neverAccessible(),\n * api_secret: neverAccessible()\n * }\n * };\n * ```\n */\nexport function neverAccessible(): FieldAccessConfig {\n return {\n read: () => false,\n write: () => false,\n omitWhenHidden: true\n }\n}\n\n/**\n * Only the resource owner can access this field\n *\n * @param ownerField - Field name containing the owner ID\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * email: ownerOnly('user_id'),\n * phone: ownerOnly('user_id')\n * }\n * };\n * ```\n */\nexport function ownerOnly(ownerField = 'id'): FieldAccessConfig {\n return {\n read: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n // Convert both to strings for comparison to handle number/string mismatches\n return String(ctx.auth.userId) === String(rowValue)\n },\n write: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n return String(ctx.auth.userId) === String(rowValue)\n }\n }\n}\n\n/**\n * Owner or users with specific roles can access this field\n *\n * @param roles - Roles that can access besides owner\n * @param ownerField - Field name containing the owner ID\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * email: ownerOrRoles(['admin', 'support'], 'user_id'),\n * address: ownerOrRoles(['admin'], 'user_id')\n * }\n * };\n * ```\n */\nexport function ownerOrRoles(roles: string[], ownerField = 'id'): FieldAccessConfig {\n return {\n read: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n return String(ctx.auth.userId) === String(rowValue) || roles.some(r => ctx.auth.roles.includes(r))\n },\n write: ctx => {\n const rowValue = (ctx.row as Record<string, unknown>)?.[ownerField]\n return String(ctx.auth.userId) === String(rowValue) || roles.some(r => ctx.auth.roles.includes(r))\n }\n }\n}\n\n/**\n * Only users with specific roles can access this field\n *\n * @param roles - Roles that can access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * internal_notes: rolesOnly(['admin', 'moderator']),\n * audit_log: rolesOnly(['admin'])\n * }\n * };\n * ```\n */\nexport function rolesOnly(roles: string[]): FieldAccessConfig {\n return {\n read: ctx => roles.some(r => ctx.auth.roles.includes(r)),\n write: ctx => roles.some(r => ctx.auth.roles.includes(r))\n }\n}\n\n/**\n * Field is read-only (no write access)\n *\n * @param readCondition - Optional condition for read access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * created_at: readOnly(),\n * version: readOnly()\n * }\n * };\n * ```\n */\nexport function readOnly(readCondition?: FieldAccessCondition): FieldAccessConfig {\n return {\n read: readCondition ?? (() => true),\n write: () => false\n }\n}\n\n/**\n * Field has public read access but restricted write\n *\n * @param writeCondition - Condition for write access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * display_name: publicReadRestrictedWrite(ctx => ctx.auth.userId === ctx.row.id),\n * bio: publicReadRestrictedWrite(ctx => ctx.auth.userId === ctx.row.id)\n * }\n * };\n * ```\n */\nexport function publicReadRestrictedWrite(writeCondition: FieldAccessCondition): FieldAccessConfig {\n return {\n read: () => true,\n write: writeCondition\n }\n}\n\n/**\n * Mask field value with custom masking function\n *\n * @param maskFn - Function to mask the value\n * @param readCondition - Condition for full read access\n *\n * @example\n * ```typescript\n * const config = {\n * fields: {\n * email: maskedField(\n * value => value.replace(/(.{2}).*@/, '$1***@'),\n * ctx => ctx.auth.userId === ctx.row.id\n * ),\n * phone: maskedField(\n * value => value.replace(/\\d(?=\\d{4})/g, '*'),\n * ctx => ctx.auth.userId === ctx.row.id\n * )\n * }\n * };\n * ```\n */\nexport function maskedField(\n maskFn: (value: unknown) => unknown,\n readCondition: FieldAccessCondition\n): FieldAccessConfig & { maskFn: (value: unknown) => unknown } {\n return {\n read: readCondition,\n write: readCondition,\n maskedValue: undefined, // Will be computed by maskFn\n maskFn\n }\n}\n","/**\n * Field Access Registry\n *\n * Manages field-level access control configurations across tables.\n *\n * @module @kysera/rls/field-access/registry\n */\n\nimport type {\n FieldAccessSchema,\n TableFieldAccessConfig,\n FieldAccessConfig,\n CompiledTableFieldAccess,\n CompiledFieldAccess\n} from './types.js'\nimport type { PolicyEvaluationContext } from '../policy/types.js'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\n\n// ============================================================================\n// Field Access Registry\n// ============================================================================\n\n/**\n * Field Access Registry\n *\n * Manages field-level access control configurations for all tables.\n *\n * @example\n * ```typescript\n * const registry = new FieldAccessRegistry();\n *\n * registry.loadSchema<Database>({\n * users: {\n * default: 'allow',\n * fields: {\n * email: ownerOrRoles(['admin'], 'id'),\n * password_hash: neverAccessible(),\n * mfa_secret: ownerOnly('id')\n * }\n * }\n * });\n *\n * // Check if field is accessible\n * const canRead = await registry.canReadField('users', 'email', evalCtx);\n * ```\n */\nexport class FieldAccessRegistry<DB = unknown> {\n private tables = new Map<string, CompiledTableFieldAccess>()\n private logger: KyseraLogger\n\n constructor(schema?: FieldAccessSchema<DB>, options?: { logger?: KyseraLogger }) {\n this.logger = options?.logger ?? silentLogger\n if (schema) {\n this.loadSchema(schema)\n }\n }\n\n /**\n * Load field access schema\n */\n loadSchema(schema: FieldAccessSchema<DB>): void {\n for (const [table, config] of Object.entries(schema)) {\n if (!config) continue\n this.registerTable(table, config as TableFieldAccessConfig)\n }\n }\n\n /**\n * Register field access configuration for a table\n */\n registerTable(table: string, config: TableFieldAccessConfig): void {\n const compiled: CompiledTableFieldAccess = {\n table,\n defaultAccess: config.default ?? 'allow',\n skipFor: config.skipFor ?? [],\n fields: new Map()\n }\n\n // Compile field configurations\n for (const [field, fieldConfig] of Object.entries(config.fields)) {\n if (!fieldConfig) continue\n\n const compiledField = this.compileFieldConfig(field, fieldConfig as FieldAccessConfig)\n compiled.fields.set(field, compiledField)\n }\n\n this.tables.set(table, compiled)\n this.logger.info?.(`[FieldAccess] Registered table: ${table}`, {\n fields: compiled.fields.size,\n defaultAccess: compiled.defaultAccess\n })\n }\n\n /**\n * Check if a field is readable in the current context\n *\n * @param table - Table name\n * @param field - Field name\n * @param ctx - Evaluation context\n * @returns True if field is readable\n */\n async canReadField(table: string, field: string, ctx: PolicyEvaluationContext): Promise<boolean> {\n const config = this.tables.get(table)\n if (!config) {\n // No field access config = all fields readable\n return true\n }\n\n // Check skipFor roles\n if (config.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true\n }\n\n // System user bypasses field access\n if (ctx.auth.isSystem) {\n return true\n }\n\n const fieldConfig = config.fields.get(field)\n if (!fieldConfig) {\n // Use default policy\n return config.defaultAccess === 'allow'\n }\n\n try {\n const result = fieldConfig.canRead(ctx)\n return result instanceof Promise ? await result : result\n } catch (error) {\n this.logger.error?.(`[FieldAccess] Error checking read access for ${table}.${field}`, {\n error: error instanceof Error ? error.message : String(error)\n })\n return false // Fail closed\n }\n }\n\n /**\n * Check if a field is writable in the current context\n *\n * @param table - Table name\n * @param field - Field name\n * @param ctx - Evaluation context\n * @returns True if field is writable\n */\n async canWriteField(table: string, field: string, ctx: PolicyEvaluationContext): Promise<boolean> {\n const config = this.tables.get(table)\n if (!config) {\n return true\n }\n\n // Check skipFor roles\n if (config.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return true\n }\n\n // System user bypasses field access\n if (ctx.auth.isSystem) {\n return true\n }\n\n const fieldConfig = config.fields.get(field)\n if (!fieldConfig) {\n return config.defaultAccess === 'allow'\n }\n\n try {\n const result = fieldConfig.canWrite(ctx)\n return result instanceof Promise ? await result : result\n } catch (error) {\n this.logger.error?.(`[FieldAccess] Error checking write access for ${table}.${field}`, {\n error: error instanceof Error ? error.message : String(error)\n })\n return false\n }\n }\n\n /**\n * Get field configuration\n *\n * @param table - Table name\n * @param field - Field name\n * @returns Compiled field access config or undefined\n */\n getFieldConfig(table: string, field: string): CompiledFieldAccess | undefined {\n return this.tables.get(table)?.fields.get(field)\n }\n\n /**\n * Get table configuration\n *\n * @param table - Table name\n * @returns Compiled table field access config or undefined\n */\n getTableConfig(table: string): CompiledTableFieldAccess | undefined {\n return this.tables.get(table)\n }\n\n /**\n * Check if table has field access configuration\n */\n hasTable(table: string): boolean {\n return this.tables.has(table)\n }\n\n /**\n * Get all registered table names\n */\n getTables(): string[] {\n return Array.from(this.tables.keys())\n }\n\n /**\n * Get all fields with explicit configuration for a table\n *\n * @param table - Table name\n * @returns Array of field names\n */\n getConfiguredFields(table: string): string[] {\n const config = this.tables.get(table)\n return config ? Array.from(config.fields.keys()) : []\n }\n\n /**\n * Clear all configurations\n */\n clear(): void {\n this.tables.clear()\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Compile a field access configuration\n */\n private compileFieldConfig(field: string, config: FieldAccessConfig): CompiledFieldAccess {\n return {\n field,\n canRead: config.read ?? (() => true),\n canWrite: config.write ?? (() => true),\n maskedValue: config.maskedValue ?? null,\n omitWhenHidden: config.omitWhenHidden ?? false\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a field access registry\n */\nexport function createFieldAccessRegistry<DB = unknown>(\n schema?: FieldAccessSchema<DB>,\n options?: { logger?: KyseraLogger }\n): FieldAccessRegistry<DB> {\n return new FieldAccessRegistry<DB>(schema, options)\n}\n","/**\n * Field Access Processor\n *\n * Applies field-level access control to database rows and mutation data.\n *\n * @module @kysera/rls/field-access/processor\n */\n\nimport type { FieldAccessRegistry } from './registry.js'\nimport type {\n MaskedRow,\n FieldAccessOptions,\n FieldAccessResult,\n CompiledFieldAccess\n} from './types.js'\nimport type { PolicyEvaluationContext, RLSContext } from '../policy/types.js'\nimport { rlsContext } from '../context/manager.js'\nimport { RLSPolicyViolation } from '../errors.js'\n\n// ============================================================================\n// Field Access Processor\n// ============================================================================\n\n/**\n * Field Access Processor\n *\n * Applies field-level access control rules to rows and mutation data.\n *\n * @example\n * ```typescript\n * const processor = new FieldAccessProcessor(registry);\n *\n * // Mask fields in a row\n * const result = await processor.maskRow('users', user, {\n * includeMetadata: true\n * });\n *\n * console.log(result.data); // Row with masked fields\n * console.log(result.maskedFields); // ['email', 'phone']\n * console.log(result.omittedFields); // ['mfa_secret']\n *\n * // Validate write access\n * await processor.validateWrite('users', { email: 'new@example.com' });\n * ```\n */\nexport class FieldAccessProcessor<DB = unknown> {\n constructor(\n private registry: FieldAccessRegistry<DB>,\n private defaultMaskValue: unknown = null\n ) {}\n\n /**\n * Apply field access control to a single row\n *\n * @param table - Table name\n * @param row - Row data\n * @param options - Processing options\n * @returns Masked row with metadata\n */\n async maskRow<T extends Record<string, unknown>>(\n table: string,\n row: T,\n options: FieldAccessOptions = {}\n ): Promise<MaskedRow<T>> {\n const ctx = this.getContext()\n if (!ctx) {\n // No context - return original row\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n // System user sees everything\n if (ctx.auth.isSystem) {\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n // No field access config - return original\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return {\n data: row,\n maskedFields: [],\n omittedFields: []\n }\n }\n\n const evalCtx = this.createEvalContext(ctx, row, table)\n const result: Partial<T> = {}\n const maskedFields: string[] = []\n const omittedFields: string[] = []\n\n // Process each field\n for (const [field, value] of Object.entries(row)) {\n // Check explicit include/exclude\n if (options.excludeFields?.includes(field)) {\n continue\n }\n if (options.includeFields && !options.includeFields.includes(field)) {\n continue\n }\n\n const fieldResult = await this.evaluateFieldAccess(\n tableConfig,\n field,\n value,\n evalCtx,\n options\n )\n\n if (fieldResult.omit) {\n omittedFields.push(field)\n } else if (!fieldResult.accessible) {\n maskedFields.push(field)\n ;(result as Record<string, unknown>)[field] = fieldResult.value\n } else {\n ;(result as Record<string, unknown>)[field] = value\n }\n }\n\n return {\n data: result,\n maskedFields,\n omittedFields\n }\n }\n\n /**\n * Apply field access control to multiple rows\n *\n * @param table - Table name\n * @param rows - Array of rows\n * @param options - Processing options\n * @returns Array of masked rows\n */\n async maskRows<T extends Record<string, unknown>>(\n table: string,\n rows: T[],\n options: FieldAccessOptions = {}\n ): Promise<MaskedRow<T>[]> {\n return await Promise.all(rows.map(row => this.maskRow(table, row, options)))\n }\n\n /**\n * Validate that all fields in mutation data are writable\n *\n * @param table - Table name\n * @param data - Mutation data\n * @param existingRow - Existing row (for update operations)\n * @throws RLSPolicyViolation if any field is not writable\n */\n async validateWrite(\n table: string,\n data: Record<string, unknown>,\n existingRow?: Record<string, unknown>\n ): Promise<void> {\n const ctx = this.getContext()\n if (!ctx) {\n return // No context = no validation\n }\n\n if (ctx.auth.isSystem) {\n return // System user can write anything\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return // No field access config\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return\n }\n\n const evalCtx = this.createEvalContext(ctx, existingRow ?? {}, table, data)\n\n // Check each field being written\n const unwritableFields: string[] = []\n\n for (const field of Object.keys(data)) {\n const canWrite = await this.registry.canWriteField(table, field, evalCtx)\n if (!canWrite) {\n unwritableFields.push(field)\n }\n }\n\n if (unwritableFields.length > 0) {\n throw new RLSPolicyViolation(\n 'write',\n table,\n `Cannot write to protected fields: ${unwritableFields.join(', ')}`\n )\n }\n }\n\n /**\n * Filter mutation data to only include writable fields\n *\n * @param table - Table name\n * @param data - Mutation data\n * @param existingRow - Existing row (for update operations)\n * @returns Filtered data with only writable fields\n */\n async filterWritableFields(\n table: string,\n data: Record<string, unknown>,\n existingRow?: Record<string, unknown>\n ): Promise<{ data: Record<string, unknown>; removedFields: string[] }> {\n const ctx = this.getContext()\n if (!ctx) {\n return { data, removedFields: [] }\n }\n\n if (ctx.auth.isSystem) {\n return { data, removedFields: [] }\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return { data, removedFields: [] }\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return { data, removedFields: [] }\n }\n\n const evalCtx = this.createEvalContext(ctx, existingRow ?? {}, table, data)\n const result: Record<string, unknown> = {}\n const removedFields: string[] = []\n\n for (const [field, value] of Object.entries(data)) {\n const canWrite = await this.registry.canWriteField(table, field, evalCtx)\n if (canWrite) {\n result[field] = value\n } else {\n removedFields.push(field)\n }\n }\n\n return { data: result, removedFields }\n }\n\n /**\n * Get list of readable fields for a table\n *\n * @param table - Table name\n * @param row - Row data (for context-dependent fields)\n * @returns Array of readable field names\n */\n async getReadableFields(table: string, row: Record<string, unknown>): Promise<string[]> {\n const ctx = this.getContext()\n if (!ctx || ctx.auth.isSystem) {\n return Object.keys(row)\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return Object.keys(row)\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return Object.keys(row)\n }\n\n const evalCtx = this.createEvalContext(ctx, row, table)\n const readable: string[] = []\n\n for (const field of Object.keys(row)) {\n const canRead = await this.registry.canReadField(table, field, evalCtx)\n if (canRead) {\n readable.push(field)\n }\n }\n\n return readable\n }\n\n /**\n * Get list of writable fields for a table\n *\n * @param table - Table name\n * @param row - Existing row data (for context-dependent fields)\n * @returns Array of writable field names\n */\n async getWritableFields(table: string, row: Record<string, unknown>): Promise<string[]> {\n const ctx = this.getContext()\n if (!ctx || ctx.auth.isSystem) {\n return Object.keys(row)\n }\n\n const tableConfig = this.registry.getTableConfig(table)\n if (!tableConfig) {\n return Object.keys(row)\n }\n\n // Check skipFor roles\n if (tableConfig.skipFor.some(role => ctx.auth.roles.includes(role))) {\n return Object.keys(row)\n }\n\n const evalCtx = this.createEvalContext(ctx, row, table)\n const writable: string[] = []\n\n for (const field of Object.keys(row)) {\n const canWrite = await this.registry.canWriteField(table, field, evalCtx)\n if (canWrite) {\n writable.push(field)\n }\n }\n\n return writable\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Get current RLS context\n */\n private getContext(): RLSContext | null {\n return rlsContext.getContextOrNull()\n }\n\n /**\n * Create evaluation context\n */\n private createEvalContext(\n ctx: RLSContext,\n row: Record<string, unknown>,\n table: string,\n data?: Record<string, unknown>\n ): PolicyEvaluationContext {\n return {\n auth: ctx.auth,\n row,\n data,\n table,\n ...(ctx.meta !== undefined && { meta: ctx.meta as Record<string, unknown> })\n }\n }\n\n /**\n * Evaluate field access for a specific field\n */\n private async evaluateFieldAccess(\n tableConfig: {\n defaultAccess: 'allow' | 'deny'\n fields: Map<string, CompiledFieldAccess>\n },\n field: string,\n value: unknown,\n ctx: PolicyEvaluationContext,\n options: FieldAccessOptions\n ): Promise<FieldAccessResult> {\n const fieldConfig = tableConfig.fields.get(field)\n\n if (!fieldConfig) {\n // Use default access policy\n const accessible = tableConfig.defaultAccess === 'allow'\n return {\n accessible,\n value: accessible ? value : this.defaultMaskValue,\n omit: !accessible && options.throwOnDenied !== true\n }\n }\n\n try {\n const canRead = await fieldConfig.canRead(ctx)\n\n if (canRead) {\n return {\n accessible: true,\n value\n } as FieldAccessResult\n }\n\n if (options.throwOnDenied) {\n throw new RLSPolicyViolation('read', ctx.table ?? 'unknown', `Cannot read field: ${field}`)\n }\n\n // Check if there's a mask function\n const configWithMask = fieldConfig as CompiledFieldAccess & {\n maskFn?: (value: unknown) => unknown\n }\n const maskedValue = configWithMask.maskFn\n ? configWithMask.maskFn(value)\n : fieldConfig.maskedValue ?? this.defaultMaskValue\n\n return {\n accessible: false,\n reason: `Field \"${field}\" is not accessible`,\n value: maskedValue,\n omit: fieldConfig.omitWhenHidden\n }\n } catch (error) {\n if (error instanceof RLSPolicyViolation) {\n throw error\n }\n\n // Log error and fail closed\n return {\n accessible: false,\n reason: `Error evaluating access: ${error instanceof Error ? error.message : String(error)}`,\n value: this.defaultMaskValue,\n omit: true\n }\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a field access processor\n */\nexport function createFieldAccessProcessor<DB = unknown>(\n registry: FieldAccessRegistry<DB>,\n defaultMaskValue?: unknown\n): FieldAccessProcessor<DB> {\n return new FieldAccessProcessor<DB>(registry, defaultMaskValue)\n}\n","/**\n * Policy Composition Builder\n *\n * Factory functions for creating reusable, composable RLS policies.\n *\n * @module @kysera/rls/composition/builder\n */\n\nimport type {\n ReusablePolicy,\n ReusablePolicyConfig,\n TenantIsolationConfig,\n OwnershipConfig,\n SoftDeleteConfig,\n StatusAccessConfig\n} from './types.js'\nimport type { PolicyDefinition, PolicyEvaluationContext, Operation } from '../policy/types.js'\nimport { allow, deny, filter, validate } from '../policy/builder.js'\n\n// ============================================================================\n// Core Policy Builder\n// ============================================================================\n\n/**\n * Create a reusable policy template\n *\n * @param config - Policy configuration\n * @param policies - Array of policy definitions\n * @returns Reusable policy template\n *\n * @example\n * ```typescript\n * const tenantPolicy = definePolicy(\n * {\n * name: 'tenantIsolation',\n * description: 'Filter by tenant_id',\n * tags: ['multi-tenant']\n * },\n * [\n * filter('read', ctx => ({ tenant_id: ctx.auth.tenantId }), {\n * priority: 1000,\n * name: 'tenant-filter'\n * }),\n * validate('create', ctx => ctx.data?.tenant_id === ctx.auth.tenantId, {\n * name: 'tenant-validate'\n * })\n * ]\n * );\n * ```\n */\nexport function definePolicy(\n config: ReusablePolicyConfig,\n policies: PolicyDefinition[]\n): ReusablePolicy {\n const result: ReusablePolicy = {\n name: config.name,\n policies\n }\n\n if (config.description !== undefined) {\n result.description = config.description\n }\n\n if (config.tags !== undefined) {\n result.tags = config.tags\n }\n\n return result\n}\n\n/**\n * Create a filter-only policy\n *\n * @param name - Policy name\n * @param filterFn - Filter condition\n * @param options - Additional options\n * @returns Reusable filter policy\n */\nexport function defineFilterPolicy(\n name: string,\n filterFn: (ctx: PolicyEvaluationContext) => Record<string, unknown>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n filter('read', filterFn, {\n name: `${name}-filter`,\n ...(options?.priority !== undefined && { priority: options.priority })\n })\n ]\n }\n}\n\n/**\n * Create an allow-based policy\n *\n * @param name - Policy name\n * @param operation - Operations to allow\n * @param condition - Allow condition\n * @param options - Additional options\n * @returns Reusable allow policy\n */\nexport function defineAllowPolicy(\n name: string,\n operation: Operation | Operation[],\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n allow(operation, condition, {\n name: `${name}-allow`,\n ...(options?.priority !== undefined && { priority: options.priority })\n })\n ]\n }\n}\n\n/**\n * Create a deny-based policy\n *\n * @param name - Policy name\n * @param operation - Operations to deny\n * @param condition - Deny condition (optional - if not provided, always denies)\n * @param options - Additional options\n * @returns Reusable deny policy\n */\nexport function defineDenyPolicy(\n name: string,\n operation: Operation | Operation[],\n condition?: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n deny(operation, condition, {\n name: `${name}-deny`,\n priority: options?.priority ?? 100\n })\n ]\n }\n}\n\n/**\n * Create a validation policy\n *\n * @param name - Policy name\n * @param operation - Operations to validate\n * @param condition - Validation condition\n * @param options - Additional options\n * @returns Reusable validate policy\n */\nexport function defineValidatePolicy(\n name: string,\n operation: 'create' | 'update' | 'all',\n condition: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>,\n options?: { priority?: number }\n): ReusablePolicy {\n return {\n name,\n policies: [\n validate(operation, condition, {\n name: `${name}-validate`,\n ...(options?.priority !== undefined && { priority: options.priority })\n })\n ]\n }\n}\n\n/**\n * Create a combined policy with multiple types\n *\n * @param name - Policy name\n * @param config - Policy configurations\n * @returns Reusable combined policy\n */\nexport function defineCombinedPolicy(\n name: string,\n config: {\n filter?: (ctx: PolicyEvaluationContext) => Record<string, unknown>\n allow?: Record<string, (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>>\n deny?: Record<string, (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>>\n validate?: {\n create?: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n update?: (ctx: PolicyEvaluationContext) => boolean | Promise<boolean>\n }\n }\n): ReusablePolicy {\n const policies: PolicyDefinition[] = []\n\n // Add filter policy\n if (config.filter) {\n policies.push(\n filter('read', config.filter, {\n name: `${name}-filter`\n })\n )\n }\n\n // Add allow policies\n if (config.allow) {\n for (const [op, condition] of Object.entries(config.allow)) {\n if (condition) {\n policies.push(\n allow(op as Operation, condition, {\n name: `${name}-allow-${op}`\n })\n )\n }\n }\n }\n\n // Add deny policies\n if (config.deny) {\n for (const [op, condition] of Object.entries(config.deny)) {\n if (condition) {\n policies.push(\n deny(op as Operation, condition, {\n name: `${name}-deny-${op}`,\n priority: 100\n })\n )\n }\n }\n }\n\n // Add validate policies\n if (config.validate) {\n if (config.validate.create) {\n policies.push(\n validate('create', config.validate.create, {\n name: `${name}-validate-create`\n })\n )\n }\n if (config.validate.update) {\n policies.push(\n validate('update', config.validate.update, {\n name: `${name}-validate-update`\n })\n )\n }\n }\n\n return {\n name,\n policies\n }\n}\n\n// ============================================================================\n// Common Policy Patterns\n// ============================================================================\n\n/**\n * Create a tenant isolation policy\n *\n * Automatically filters by tenant_id and validates mutations.\n *\n * @param config - Tenant isolation configuration\n * @returns Reusable tenant isolation policy\n */\nexport function createTenantIsolationPolicy(config: TenantIsolationConfig = {}): ReusablePolicy {\n const { tenantColumn = 'tenant_id', validateOnMutation = true } = config\n\n const policies: PolicyDefinition[] = [\n // Filter reads by tenant\n filter('read', ctx => ({ [tenantColumn]: ctx.auth.tenantId }), {\n name: 'tenant-isolation-filter',\n priority: 1000\n })\n ]\n\n // Validate tenant on mutations\n if (validateOnMutation) {\n policies.push(\n validate('create', ctx => {\n const data = ctx.data as Record<string, unknown> | undefined\n return data?.[tenantColumn] === ctx.auth.tenantId\n }, {\n name: 'tenant-isolation-validate-create'\n }),\n validate('update', ctx => {\n const data = ctx.data as Record<string, unknown> | undefined\n // Cannot change tenant on update\n if (data?.[tenantColumn] !== undefined) {\n return data[tenantColumn] === ctx.auth.tenantId\n }\n return true\n }, {\n name: 'tenant-isolation-validate-update'\n })\n )\n }\n\n return {\n name: 'tenantIsolation',\n description: `Filter by ${tenantColumn} for multi-tenancy`,\n policies,\n tags: ['multi-tenant', 'isolation']\n }\n}\n\n/**\n * Create an ownership policy\n *\n * Allows owners to read/update/delete their own resources.\n *\n * @param config - Ownership configuration\n * @returns Reusable ownership policy\n */\nexport function createOwnershipPolicy(config: OwnershipConfig = {}): ReusablePolicy {\n const { ownerColumn = 'owner_id', ownerOperations = ['read', 'update', 'delete'], canDelete = true } = config\n\n const policies: PolicyDefinition[] = []\n\n // Filter ops to only those allowed\n const ops = ownerOperations.filter(op => op !== 'delete' || canDelete)\n\n if (ops.length > 0) {\n policies.push(\n allow(ops, ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return ctx.auth.userId === row?.[ownerColumn]\n }, {\n name: 'ownership-allow'\n })\n )\n }\n\n // Explicit deny for delete if not allowed\n if (!canDelete && ownerOperations.includes('delete')) {\n policies.push(\n deny('delete', () => true, {\n name: 'ownership-no-delete',\n priority: 150\n })\n )\n }\n\n return {\n name: 'ownership',\n description: `Owner access via ${ownerColumn}`,\n policies,\n tags: ['ownership']\n }\n}\n\n/**\n * Create a soft delete policy\n *\n * Filters out soft-deleted rows and optionally prevents hard deletes.\n *\n * @param config - Soft delete configuration\n * @returns Reusable soft delete policy\n */\nexport function createSoftDeletePolicy(config: SoftDeleteConfig = {}): ReusablePolicy {\n const { deletedColumn = 'deleted_at', filterOnRead = true, preventHardDelete = true } = config\n\n const policies: PolicyDefinition[] = []\n\n // Filter soft-deleted rows\n if (filterOnRead) {\n policies.push(\n filter('read', () => ({ [deletedColumn]: null }), {\n name: 'soft-delete-filter',\n priority: 900\n })\n )\n }\n\n // Prevent hard deletes\n if (preventHardDelete) {\n policies.push(\n deny('delete', () => true, {\n name: 'soft-delete-no-hard-delete',\n priority: 150\n })\n )\n }\n\n return {\n name: 'softDelete',\n description: `Soft delete via ${deletedColumn}`,\n policies,\n tags: ['soft-delete']\n }\n}\n\n/**\n * Create a status-based access policy\n *\n * Controls access based on resource status.\n *\n * @param config - Status access configuration\n * @returns Reusable status policy\n */\nexport function createStatusAccessPolicy(config: StatusAccessConfig): ReusablePolicy {\n const { statusColumn = 'status', publicStatuses = [], editableStatuses = [], deletableStatuses = [] } = config\n\n const policies: PolicyDefinition[] = []\n\n // Allow public read for certain statuses\n if (publicStatuses.length > 0) {\n policies.push(\n allow('read', ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return publicStatuses.includes(row?.[statusColumn] as string)\n }, {\n name: 'status-public-read'\n })\n )\n }\n\n // Restrict updates to certain statuses\n if (editableStatuses.length > 0) {\n policies.push(\n deny('update', ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return !editableStatuses.includes(row?.[statusColumn] as string)\n }, {\n name: 'status-restrict-update',\n priority: 100\n })\n )\n }\n\n // Restrict deletes to certain statuses\n if (deletableStatuses.length > 0) {\n policies.push(\n deny('delete', ctx => {\n const row = ctx.row as Record<string, unknown> | undefined\n return !deletableStatuses.includes(row?.[statusColumn] as string)\n }, {\n name: 'status-restrict-delete',\n priority: 100\n })\n )\n }\n\n return {\n name: 'statusAccess',\n description: `Status-based access via ${statusColumn}`,\n policies,\n tags: ['status']\n }\n}\n\n/**\n * Create an admin bypass policy\n *\n * Allows admin roles to perform all operations.\n *\n * @param roles - Roles that have admin access\n * @returns Reusable admin policy\n */\nexport function createAdminPolicy(roles: string[]): ReusablePolicy {\n return {\n name: 'adminBypass',\n description: `Admin access for roles: ${roles.join(', ')}`,\n policies: [\n allow('all', ctx => roles.some(r => ctx.auth.roles.includes(r)), {\n name: 'admin-bypass',\n priority: 500\n })\n ],\n tags: ['admin']\n }\n}\n\n// ============================================================================\n// Policy Composition Functions\n// ============================================================================\n\n/**\n * Compose multiple reusable policies into one\n *\n * @param name - Name for the composed policy\n * @param policies - Policies to compose\n * @returns Composed policy\n */\nexport function composePolicies(name: string, policies: ReusablePolicy[]): ReusablePolicy {\n const allPolicies: PolicyDefinition[] = []\n const allTags = new Set<string>()\n\n for (const policy of policies) {\n allPolicies.push(...policy.policies)\n policy.tags?.forEach(tag => allTags.add(tag))\n }\n\n return {\n name,\n description: `Composed from: ${policies.map(p => p.name).join(', ')}`,\n policies: allPolicies,\n tags: Array.from(allTags)\n }\n}\n\n/**\n * Extend a reusable policy with additional policies\n *\n * @param base - Base policy to extend\n * @param additional - Additional policies to add\n * @returns Extended policy\n */\nexport function extendPolicy(base: ReusablePolicy, additional: PolicyDefinition[]): ReusablePolicy {\n const result: ReusablePolicy = {\n name: `${base.name}_extended`,\n policies: [...base.policies, ...additional]\n }\n\n if (base.description !== undefined) {\n result.description = base.description\n }\n\n if (base.tags !== undefined) {\n result.tags = base.tags\n }\n\n return result\n}\n\n/**\n * Override policies from a base with new conditions\n *\n * @param base - Base policy\n * @param overrides - Policy name to new policy mapping\n * @returns Policy with overrides applied\n */\nexport function overridePolicy(\n base: ReusablePolicy,\n overrides: Record<string, PolicyDefinition>\n): ReusablePolicy {\n const newPolicies = base.policies.map(policy => {\n const override = policy.name ? overrides[policy.name] : undefined\n return override ?? policy\n })\n\n const result: ReusablePolicy = {\n name: `${base.name}_overridden`,\n policies: newPolicies\n }\n\n if (base.description !== undefined) {\n result.description = base.description\n }\n\n if (base.tags !== undefined) {\n result.tags = base.tags\n }\n\n return result\n}\n","/**\n * Audit Trail Types\n *\n * Provides type definitions for auditing RLS policy decisions.\n *\n * @module @kysera/rls/audit/types\n */\n\nimport type { Operation } from '../policy/types.js'\n\n// ============================================================================\n// Audit Event Types\n// ============================================================================\n\n/**\n * RLS policy decision result\n */\nexport type AuditDecision = 'allow' | 'deny' | 'filter'\n\n/**\n * RLS audit event\n *\n * Represents a single policy evaluation event for audit logging.\n *\n * @example\n * ```typescript\n * const event: RLSAuditEvent = {\n * timestamp: new Date(),\n * userId: '123',\n * operation: 'update',\n * table: 'posts',\n * policyName: 'ownership-allow',\n * decision: 'allow',\n * context: { rowId: '456', tenantId: 'acme' }\n * };\n * ```\n */\nexport interface RLSAuditEvent {\n /**\n * Timestamp of the event\n */\n timestamp: Date\n\n /**\n * User ID who performed the action\n */\n userId: string | number\n\n /**\n * Tenant ID (if multi-tenant)\n */\n tenantId?: string | number\n\n /**\n * Database operation\n */\n operation: Operation\n\n /**\n * Table name\n */\n table: string\n\n /**\n * Name of the policy that made the decision\n */\n policyName?: string\n\n /**\n * Decision result\n */\n decision: AuditDecision\n\n /**\n * Reason for the decision (especially for denials)\n */\n reason?: string\n\n /**\n * Additional context about the event\n */\n context?: Record<string, unknown>\n\n /**\n * Row ID(s) affected\n */\n rowIds?: (string | number)[]\n\n /**\n * Hash of the query (for grouping similar queries)\n */\n queryHash?: string\n\n /**\n * Request ID for tracing\n */\n requestId?: string\n\n /**\n * IP address of the requester\n */\n ipAddress?: string\n\n /**\n * User agent string\n */\n userAgent?: string\n\n /**\n * Duration of policy evaluation in milliseconds\n */\n durationMs?: number\n\n /**\n * Whether this event was filtered from logging\n * (set by filtering rules but still available for debugging)\n */\n filtered?: boolean\n}\n\n// ============================================================================\n// Audit Adapter Interface\n// ============================================================================\n\n/**\n * Adapter for persisting audit events\n *\n * Implement this interface to store audit events in your preferred backend.\n *\n * @example\n * ```typescript\n * class DatabaseAuditAdapter implements RLSAuditAdapter {\n * constructor(private db: Kysely<AuditDB>) {}\n *\n * async log(event: RLSAuditEvent): Promise<void> {\n * await this.db.insertInto('rls_audit_log')\n * .values({\n * user_id: event.userId,\n * operation: event.operation,\n * table_name: event.table,\n * decision: event.decision,\n * context: JSON.stringify(event.context),\n * created_at: event.timestamp\n * })\n * .execute();\n * }\n *\n * async logBatch(events: RLSAuditEvent[]): Promise<void> {\n * await this.db.insertInto('rls_audit_log')\n * .values(events.map(e => ({\n * user_id: e.userId,\n * operation: e.operation,\n * table_name: e.table,\n * decision: e.decision,\n * context: JSON.stringify(e.context),\n * created_at: e.timestamp\n * })))\n * .execute();\n * }\n * }\n * ```\n */\nexport interface RLSAuditAdapter {\n /**\n * Log a single audit event\n *\n * @param event - Event to log\n */\n log(event: RLSAuditEvent): Promise<void>\n\n /**\n * Log multiple audit events (for batch processing)\n *\n * @param events - Events to log\n */\n logBatch?(events: RLSAuditEvent[]): Promise<void>\n\n /**\n * Flush any buffered events\n */\n flush?(): Promise<void>\n\n /**\n * Close the adapter and release resources\n */\n close?(): Promise<void>\n}\n\n// ============================================================================\n// Audit Configuration\n// ============================================================================\n\n/**\n * Configuration for table-specific audit settings\n */\nexport interface TableAuditConfig {\n /**\n * Whether audit is enabled for this table\n * @default true (if audit is globally enabled)\n */\n enabled?: boolean\n\n /**\n * Log allowed decisions\n * @default false\n */\n logAllowed?: boolean\n\n /**\n * Log denied decisions\n * @default true\n */\n logDenied?: boolean\n\n /**\n * Log filter applications\n * @default false\n */\n logFilters?: boolean\n\n /**\n * Context fields to include in audit logs\n * If empty, includes all available context\n */\n includeContext?: string[]\n\n /**\n * Context fields to exclude from audit logs\n */\n excludeContext?: string[]\n\n /**\n * Whether to include row data in audit logs\n * @default false (for privacy)\n */\n includeRowData?: boolean\n\n /**\n * Whether to include mutation data in audit logs\n * @default false (for privacy)\n */\n includeMutationData?: boolean\n\n /**\n * Custom filter function to determine if an event should be logged\n */\n filter?: (event: RLSAuditEvent) => boolean\n}\n\n/**\n * Global audit configuration\n */\nexport interface AuditConfig {\n /**\n * Audit adapter for persisting events\n */\n adapter: RLSAuditAdapter\n\n /**\n * Whether audit is enabled globally\n * @default true\n */\n enabled?: boolean\n\n /**\n * Default settings for all tables\n */\n defaults?: Omit<TableAuditConfig, 'enabled'>\n\n /**\n * Table-specific audit configurations\n */\n tables?: Record<string, TableAuditConfig>\n\n /**\n * Buffer size for batch logging\n * Events are batched until this size is reached\n * @default 100\n */\n bufferSize?: number\n\n /**\n * Maximum time to buffer events before flushing (ms)\n * @default 5000 (5 seconds)\n */\n flushInterval?: number\n\n /**\n * Whether to log asynchronously (fire-and-forget)\n * @default true (for performance)\n */\n async?: boolean\n\n /**\n * Error handler for audit failures\n */\n onError?: (error: Error, events: RLSAuditEvent[]) => void\n\n /**\n * Sample rate for audit logging (0.0 to 1.0)\n * Use for high-traffic systems to reduce log volume\n * @default 1.0 (log all)\n */\n sampleRate?: number\n}\n\n// ============================================================================\n// Audit Query Types\n// ============================================================================\n\n/**\n * Query parameters for retrieving audit events\n */\nexport interface AuditQueryParams {\n /**\n * Filter by user ID\n */\n userId?: string | number\n\n /**\n * Filter by tenant ID\n */\n tenantId?: string | number\n\n /**\n * Filter by table name\n */\n table?: string\n\n /**\n * Filter by operation\n */\n operation?: Operation\n\n /**\n * Filter by decision\n */\n decision?: AuditDecision\n\n /**\n * Start timestamp (inclusive)\n */\n startTime?: Date\n\n /**\n * End timestamp (exclusive)\n */\n endTime?: Date\n\n /**\n * Filter by request ID\n */\n requestId?: string\n\n /**\n * Maximum results to return\n */\n limit?: number\n\n /**\n * Offset for pagination\n */\n offset?: number\n}\n\n/**\n * Aggregated audit statistics\n */\nexport interface AuditStats {\n /**\n * Total number of events\n */\n totalEvents: number\n\n /**\n * Events by decision type\n */\n byDecision: Record<AuditDecision, number>\n\n /**\n * Events by operation\n */\n byOperation: Record<Operation, number>\n\n /**\n * Events by table\n */\n byTable: Record<string, number>\n\n /**\n * Top denied users\n */\n topDeniedUsers?: { userId: string | number; count: number }[]\n\n /**\n * Time range of stats\n */\n timeRange: {\n start: Date\n end: Date\n }\n}\n\n// ============================================================================\n// Console Audit Adapter\n// ============================================================================\n\n/**\n * Simple console-based audit adapter for development/testing\n *\n * @example\n * ```typescript\n * const adapter = new ConsoleAuditAdapter({\n * format: 'json',\n * colors: true\n * });\n * ```\n */\nexport interface ConsoleAuditAdapterOptions {\n /**\n * Output format\n * @default 'text'\n */\n format?: 'text' | 'json'\n\n /**\n * Use colors in output (for text format)\n * @default true\n */\n colors?: boolean\n\n /**\n * Include timestamp in output\n * @default true\n */\n includeTimestamp?: boolean\n}\n\n/**\n * Console audit adapter implementation\n */\nexport class ConsoleAuditAdapter implements RLSAuditAdapter {\n private options: Required<ConsoleAuditAdapterOptions>\n\n constructor(options: ConsoleAuditAdapterOptions = {}) {\n this.options = {\n format: options.format ?? 'text',\n colors: options.colors ?? true,\n includeTimestamp: options.includeTimestamp ?? true\n }\n }\n\n log(event: RLSAuditEvent): Promise<void> {\n if (this.options.format === 'json') {\n // eslint-disable-next-line no-console\n console.log(JSON.stringify(event))\n } else {\n const prefix = this.getPrefix(event.decision)\n const timestamp = this.options.includeTimestamp ? `[${event.timestamp.toISOString()}] ` : ''\n // eslint-disable-next-line no-console\n console.log(\n `${timestamp}${prefix} RLS ${event.decision.toUpperCase()}: ${event.operation} on ${event.table}` +\n (event.policyName ? ` (policy: ${event.policyName})` : '') +\n (event.reason ? ` - ${event.reason}` : '') +\n (event.userId ? ` [user: ${event.userId}]` : '')\n )\n }\n return Promise.resolve()\n }\n\n async logBatch(events: RLSAuditEvent[]): Promise<void> {\n for (const event of events) {\n await this.log(event)\n }\n }\n\n private getPrefix(decision: AuditDecision): string {\n if (!this.options.colors) {\n return decision === 'allow' ? '✓' : decision === 'deny' ? '✗' : '~'\n }\n\n switch (decision) {\n case 'allow':\n return '\\x1b[32m✓\\x1b[0m' // Green\n case 'deny':\n return '\\x1b[31m✗\\x1b[0m' // Red\n case 'filter':\n return '\\x1b[33m~\\x1b[0m' // Yellow\n default:\n return '?'\n }\n }\n}\n\n// ============================================================================\n// In-Memory Audit Adapter\n// ============================================================================\n\n/**\n * In-memory audit adapter for testing\n *\n * Stores events in memory for later retrieval and assertion.\n */\nexport class InMemoryAuditAdapter implements RLSAuditAdapter {\n private events: RLSAuditEvent[] = []\n private maxSize: number\n\n constructor(maxSize = 10000) {\n this.maxSize = maxSize\n }\n\n log(event: RLSAuditEvent): Promise<void> {\n this.events.push(event)\n // Trim if exceeds max size\n if (this.events.length > this.maxSize) {\n this.events = this.events.slice(-this.maxSize)\n }\n return Promise.resolve()\n }\n\n logBatch(events: RLSAuditEvent[]): Promise<void> {\n this.events.push(...events)\n if (this.events.length > this.maxSize) {\n this.events = this.events.slice(-this.maxSize)\n }\n return Promise.resolve()\n }\n\n /**\n * Get all logged events\n */\n getEvents(): RLSAuditEvent[] {\n return [...this.events]\n }\n\n /**\n * Query events\n */\n query(params: AuditQueryParams): RLSAuditEvent[] {\n let results = [...this.events]\n\n if (params.userId !== undefined) {\n results = results.filter(e => e.userId === params.userId)\n }\n if (params.tenantId !== undefined) {\n results = results.filter(e => e.tenantId === params.tenantId)\n }\n if (params.table) {\n results = results.filter(e => e.table === params.table)\n }\n if (params.operation) {\n results = results.filter(e => e.operation === params.operation)\n }\n if (params.decision) {\n results = results.filter(e => e.decision === params.decision)\n }\n if (params.startTime) {\n results = results.filter(e => e.timestamp >= params.startTime!)\n }\n if (params.endTime) {\n results = results.filter(e => e.timestamp < params.endTime!)\n }\n if (params.requestId) {\n results = results.filter(e => e.requestId === params.requestId)\n }\n\n if (params.offset) {\n results = results.slice(params.offset)\n }\n if (params.limit) {\n results = results.slice(0, params.limit)\n }\n\n return results\n }\n\n /**\n * Get statistics\n */\n getStats(params?: Pick<AuditQueryParams, 'startTime' | 'endTime'>): AuditStats {\n let events = this.events\n\n if (params?.startTime) {\n events = events.filter(e => e.timestamp >= params.startTime!)\n }\n if (params?.endTime) {\n events = events.filter(e => e.timestamp < params.endTime!)\n }\n\n const byDecision: Record<AuditDecision, number> = { allow: 0, deny: 0, filter: 0 }\n const byOperation: Record<Operation, number> = { read: 0, create: 0, update: 0, delete: 0, all: 0 }\n const byTable: Record<string, number> = {}\n\n for (const event of events) {\n byDecision[event.decision]++\n byOperation[event.operation]++\n byTable[event.table] = (byTable[event.table] ?? 0) + 1\n }\n\n return {\n totalEvents: events.length,\n byDecision,\n byOperation,\n byTable,\n timeRange: {\n start: events[0]?.timestamp ?? new Date(),\n end: events[events.length - 1]?.timestamp ?? new Date()\n }\n }\n }\n\n /**\n * Clear all events\n */\n clear(): void {\n this.events = []\n }\n\n /**\n * Get event count\n */\n get size(): number {\n return this.events.length\n }\n}\n","/**\n * Audit Logger\n *\n * Manages audit event logging with buffering and filtering.\n *\n * @module @kysera/rls/audit/logger\n */\n\nimport type {\n RLSAuditEvent,\n RLSAuditAdapter,\n AuditConfig,\n TableAuditConfig,\n AuditDecision\n} from './types.js'\nimport type { Operation, RLSContext } from '../policy/types.js'\nimport { rlsContext } from '../context/manager.js'\n\n// ============================================================================\n// Audit Logger\n// ============================================================================\n\n/**\n * Audit Logger\n *\n * Manages RLS audit event logging with buffering, filtering, and sampling.\n *\n * @example\n * ```typescript\n * const logger = new AuditLogger({\n * adapter: new DatabaseAuditAdapter(db),\n * bufferSize: 50,\n * flushInterval: 5000,\n * defaults: {\n * logAllowed: false,\n * logDenied: true,\n * logFilters: false\n * },\n * tables: {\n * sensitive_data: {\n * logAllowed: true,\n * includeContext: ['requestId', 'ipAddress']\n * }\n * }\n * });\n *\n * // Log an event\n * await logger.logDecision('update', 'posts', 'allow', 'ownership-allow');\n *\n * // Ensure all events are flushed\n * await logger.flush();\n * ```\n */\nexport class AuditLogger {\n private adapter: RLSAuditAdapter\n private config: Required<Omit<AuditConfig, 'adapter' | 'tables' | 'onError'>> & {\n tables: Record<string, TableAuditConfig>\n onError?: (error: Error, events: RLSAuditEvent[]) => void\n }\n private buffer: RLSAuditEvent[] = []\n private flushTimer: NodeJS.Timeout | null = null\n private isShuttingDown = false\n\n constructor(config: AuditConfig) {\n this.adapter = config.adapter\n const baseConfig = {\n enabled: config.enabled ?? true,\n defaults: config.defaults ?? {\n logAllowed: false,\n logDenied: true,\n logFilters: false\n },\n tables: config.tables ?? {},\n bufferSize: config.bufferSize ?? 100,\n flushInterval: config.flushInterval ?? 5000,\n async: config.async ?? true,\n sampleRate: config.sampleRate ?? 1.0\n }\n\n this.config = config.onError !== undefined\n ? { ...baseConfig, onError: config.onError }\n : baseConfig\n\n // Start flush timer\n if (this.config.flushInterval > 0) {\n this.startFlushTimer()\n }\n }\n\n /**\n * Log a policy decision\n *\n * @param operation - Database operation\n * @param table - Table name\n * @param decision - Decision result\n * @param policyName - Name of the policy\n * @param options - Additional options\n */\n async logDecision(\n operation: Operation,\n table: string,\n decision: AuditDecision,\n policyName?: string,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n queryHash?: string\n durationMs?: number\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n if (!this.config.enabled || this.isShuttingDown) {\n return\n }\n\n // Check sampling\n if (this.config.sampleRate < 1.0 && Math.random() > this.config.sampleRate) {\n return\n }\n\n // Get table config\n const tableConfig = this.getTableConfig(table)\n\n // Check if this decision type should be logged\n if (!this.shouldLog(decision, tableConfig)) {\n return\n }\n\n // Get current RLS context\n const ctx = rlsContext.getContextOrNull()\n\n // Build event\n const event = this.buildEvent(operation, table, decision, policyName, ctx, tableConfig, options)\n\n // Apply custom filter if present\n if (tableConfig.filter && !tableConfig.filter(event)) {\n event.filtered = true\n return\n }\n\n // Log the event\n await this.logEvent(event)\n }\n\n /**\n * Log an allow decision\n */\n async logAllow(\n operation: Operation,\n table: string,\n policyName?: string,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n await this.logDecision(operation, table, 'allow', policyName, options)\n }\n\n /**\n * Log a deny decision\n */\n async logDeny(\n operation: Operation,\n table: string,\n policyName?: string,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n await this.logDecision(operation, table, 'deny', policyName, options)\n }\n\n /**\n * Log a filter application\n */\n async logFilter(\n table: string,\n policyName?: string,\n options?: {\n context?: Record<string, unknown>\n }\n ): Promise<void> {\n await this.logDecision('read', table, 'filter', policyName, options)\n }\n\n /**\n * Flush buffered events\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) {\n return\n }\n\n const eventsToFlush = [...this.buffer]\n this.buffer = []\n\n try {\n if (this.adapter.logBatch) {\n await this.adapter.logBatch(eventsToFlush)\n } else {\n for (const event of eventsToFlush) {\n await this.adapter.log(event)\n }\n }\n } catch (error) {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), eventsToFlush)\n }\n }\n\n /**\n * Close the logger\n */\n async close(): Promise<void> {\n this.isShuttingDown = true\n\n if (this.flushTimer) {\n clearInterval(this.flushTimer)\n this.flushTimer = null\n }\n\n await this.flush()\n await this.adapter.flush?.()\n await this.adapter.close?.()\n }\n\n /**\n * Get buffer size\n */\n get bufferSize(): number {\n return this.buffer.length\n }\n\n /**\n * Check if logger is enabled\n */\n get enabled(): boolean {\n return this.config.enabled\n }\n\n /**\n * Enable or disable logging\n */\n setEnabled(enabled: boolean): void {\n this.config.enabled = enabled\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n /**\n * Get table-specific config with defaults\n */\n private getTableConfig(table: string): TableAuditConfig {\n const tableOverride = this.config.tables[table]\n return {\n ...this.config.defaults,\n ...tableOverride,\n enabled: tableOverride?.enabled ?? true\n }\n }\n\n /**\n * Check if decision should be logged\n */\n private shouldLog(decision: AuditDecision, tableConfig: TableAuditConfig): boolean {\n if (!tableConfig.enabled) {\n return false\n }\n\n switch (decision) {\n case 'allow':\n return tableConfig.logAllowed ?? false\n case 'deny':\n return tableConfig.logDenied ?? true\n case 'filter':\n return tableConfig.logFilters ?? false\n default:\n return false\n }\n }\n\n /**\n * Build audit event\n */\n private buildEvent(\n operation: Operation,\n table: string,\n decision: AuditDecision,\n policyName: string | undefined,\n ctx: RLSContext | null,\n tableConfig: TableAuditConfig,\n options?: {\n reason?: string\n rowIds?: (string | number)[]\n queryHash?: string\n durationMs?: number\n context?: Record<string, unknown>\n }\n ): RLSAuditEvent {\n const event: RLSAuditEvent = {\n timestamp: new Date(),\n userId: ctx?.auth.userId ?? 'anonymous',\n operation,\n table,\n decision\n }\n\n // Add tenant ID if present\n if (ctx?.auth.tenantId !== undefined) {\n event.tenantId = ctx.auth.tenantId\n }\n\n // Add policy name\n if (policyName) {\n event.policyName = policyName\n }\n\n // Add options\n if (options?.reason) {\n event.reason = options.reason\n }\n if (options?.rowIds && options.rowIds.length > 0) {\n event.rowIds = options.rowIds\n }\n if (options?.queryHash) {\n event.queryHash = options.queryHash\n }\n if (options?.durationMs !== undefined) {\n event.durationMs = options.durationMs\n }\n\n // Add request context\n if (ctx?.request) {\n if (ctx.request.requestId) {\n event.requestId = ctx.request.requestId\n }\n if (ctx.request.ipAddress) {\n event.ipAddress = ctx.request.ipAddress\n }\n if (ctx.request.userAgent) {\n event.userAgent = ctx.request.userAgent\n }\n }\n\n // Build context\n const context = this.buildContext(ctx, tableConfig, options?.context)\n if (context !== undefined) {\n event.context = context\n }\n\n return event\n }\n\n /**\n * Build context object with filtering\n */\n private buildContext(\n ctx: RLSContext | null,\n tableConfig: TableAuditConfig,\n additionalContext?: Record<string, unknown>\n ): Record<string, unknown> | undefined {\n const context: Record<string, unknown> = {}\n\n // Add roles\n if (ctx?.auth.roles && ctx.auth.roles.length > 0) {\n context['roles'] = ctx.auth.roles\n }\n\n // Add organization IDs if present\n if (ctx?.auth.organizationIds && ctx.auth.organizationIds.length > 0) {\n context['organizationIds'] = ctx.auth.organizationIds\n }\n\n // Add meta if present\n if (ctx?.meta && typeof ctx.meta === 'object') {\n Object.assign(context, ctx.meta)\n }\n\n // Add additional context\n if (additionalContext) {\n Object.assign(context, additionalContext)\n }\n\n // Apply include/exclude filters\n let filteredContext = context\n\n if (tableConfig.includeContext && tableConfig.includeContext.length > 0) {\n filteredContext = {}\n for (const key of tableConfig.includeContext) {\n if (key in context) {\n filteredContext[key] = context[key]\n }\n }\n }\n\n if (tableConfig.excludeContext && tableConfig.excludeContext.length > 0) {\n for (const key of tableConfig.excludeContext) {\n // Use destructuring to avoid dynamic delete\n const { [key]: _, ...rest } = filteredContext\n filteredContext = rest\n }\n }\n\n return Object.keys(filteredContext).length > 0 ? filteredContext : undefined\n }\n\n /**\n * Log event to buffer or directly\n */\n private async logEvent(event: RLSAuditEvent): Promise<void> {\n if (this.config.async && this.config.bufferSize > 0) {\n // Buffered async logging\n this.buffer.push(event)\n\n if (this.buffer.length >= this.config.bufferSize) {\n // Buffer full, flush now\n await this.flush()\n }\n } else if (this.config.async) {\n // Async fire-and-forget\n this.adapter.log(event).catch((error: unknown) => {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), [event])\n })\n } else {\n // Synchronous logging\n try {\n await this.adapter.log(event)\n } catch (error) {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), [event])\n }\n }\n }\n\n /**\n * Start the flush timer\n */\n private startFlushTimer(): void {\n this.flushTimer = setInterval(() => {\n this.flush().catch((error: unknown) => {\n this.config.onError?.(error instanceof Error ? error : new Error(String(error)), [...this.buffer])\n })\n }, this.config.flushInterval)\n\n // Don't block process exit\n if (this.flushTimer.unref) {\n this.flushTimer.unref()\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create an audit logger\n */\nexport function createAuditLogger(config: AuditConfig): AuditLogger {\n return new AuditLogger(config)\n}\n","/**\n * Policy Testing Utilities\n *\n * Provides tools for unit testing RLS policies without a database.\n *\n * @module @kysera/rls/testing\n */\n\nimport type {\n RLSSchema,\n PolicyEvaluationContext,\n Operation,\n RLSAuthContext,\n CompiledPolicy\n} from '../policy/types.js'\nimport { PolicyRegistry } from '../policy/registry.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of policy evaluation\n */\nexport interface PolicyEvaluationResult {\n /**\n * Whether the operation is allowed\n */\n allowed: boolean\n\n /**\n * Name of the policy that made the decision\n */\n policyName?: string\n\n /**\n * Type of decision\n */\n decisionType: 'allow' | 'deny' | 'default'\n\n /**\n * Reason for the decision\n */\n reason?: string\n\n /**\n * All policies that were evaluated\n */\n evaluatedPolicies: {\n name: string\n type: 'allow' | 'deny' | 'validate'\n result: boolean\n }[]\n}\n\n/**\n * Result of filter evaluation\n */\nexport interface FilterEvaluationResult {\n /**\n * Generated filter conditions\n */\n conditions: Record<string, unknown>\n\n /**\n * Names of all filters applied\n */\n appliedFilters: string[]\n}\n\n/**\n * Test context for policy evaluation\n */\nexport interface TestContext<TRow = Record<string, unknown>> {\n /**\n * Auth context\n */\n auth: RLSAuthContext\n\n /**\n * Row data (for read/update/delete operations)\n */\n row?: TRow\n\n /**\n * Mutation data (for create/update operations)\n */\n data?: Record<string, unknown>\n\n /**\n * Additional metadata\n */\n meta?: Record<string, unknown>\n}\n\n// ============================================================================\n// Policy Tester\n// ============================================================================\n\n/**\n * Policy Tester\n *\n * Test RLS policies without a database connection.\n *\n * @example\n * ```typescript\n * const tester = createPolicyTester(rlsSchema);\n *\n * describe('Post RLS Policies', () => {\n * it('should allow owner to update their post', async () => {\n * const result = await tester.evaluate('posts', 'update', {\n * auth: { userId: 'user-1', roles: ['user'] },\n * row: { id: 'post-1', author_id: 'user-1', status: 'draft' }\n * });\n *\n * expect(result.allowed).toBe(true);\n * });\n *\n * it('should deny non-owner update', async () => {\n * const result = await tester.evaluate('posts', 'update', {\n * auth: { userId: 'user-2', roles: ['user'] },\n * row: { id: 'post-1', author_id: 'user-1', status: 'draft' }\n * });\n *\n * expect(result.allowed).toBe(false);\n * expect(result.reason).toContain('not owner');\n * });\n *\n * it('should apply filters correctly', async () => {\n * const filters = await tester.getFilters('posts', 'read', {\n * auth: { userId: 'user-1', tenantId: 'tenant-1', roles: [] }\n * });\n *\n * expect(filters.conditions).toEqual({\n * tenant_id: 'tenant-1',\n * deleted_at: null\n * });\n * });\n * });\n * ```\n */\nexport class PolicyTester<DB = unknown> {\n private registry: PolicyRegistry<DB>\n\n constructor(schema: RLSSchema<DB>) {\n this.registry = new PolicyRegistry<DB>(schema)\n }\n\n /**\n * Evaluate policies for an operation\n *\n * @param table - Table name\n * @param operation - Operation to test\n * @param context - Test context\n * @returns Evaluation result\n */\n async evaluate(\n table: string,\n operation: Operation,\n context: TestContext\n ): Promise<PolicyEvaluationResult> {\n const evaluatedPolicies: PolicyEvaluationResult['evaluatedPolicies'] = []\n\n // Check if table is registered\n if (!this.registry.hasTable(table)) {\n return {\n allowed: true,\n decisionType: 'default',\n reason: 'Table has no RLS policies',\n evaluatedPolicies\n }\n }\n\n // Check system user bypass\n if (context.auth.isSystem) {\n return {\n allowed: true,\n decisionType: 'allow',\n reason: 'System user bypasses RLS',\n evaluatedPolicies\n }\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => context.auth.roles.includes(role))) {\n return {\n allowed: true,\n decisionType: 'allow',\n reason: `Role bypass: ${skipFor.find(r => context.auth.roles.includes(r))}`,\n evaluatedPolicies\n }\n }\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: context.auth,\n row: context.row,\n data: context.data,\n table,\n operation,\n ...(context.meta !== undefined && { meta: context.meta })\n }\n\n // Evaluate deny policies first\n const denies = this.registry.getDenies(table, operation)\n for (const deny of denies) {\n const result = await this.evaluatePolicy(deny, evalCtx)\n evaluatedPolicies.push({\n name: deny.name,\n type: 'deny',\n result\n })\n\n if (result) {\n return {\n allowed: false,\n policyName: deny.name,\n decisionType: 'deny',\n reason: `Denied by policy: ${deny.name}`,\n evaluatedPolicies\n }\n }\n }\n\n // Evaluate validate policies (for create/update)\n if ((operation === 'create' || operation === 'update') && context.data) {\n const validates = this.registry.getValidates(table, operation)\n for (const validate of validates) {\n const result = await this.evaluatePolicy(validate, evalCtx)\n evaluatedPolicies.push({\n name: validate.name,\n type: 'validate',\n result\n })\n\n if (!result) {\n return {\n allowed: false,\n policyName: validate.name,\n decisionType: 'deny',\n reason: `Validation failed: ${validate.name}`,\n evaluatedPolicies\n }\n }\n }\n }\n\n // Evaluate allow policies\n const allows = this.registry.getAllows(table, operation)\n const defaultDeny = this.registry.hasDefaultDeny(table)\n\n if (defaultDeny && allows.length === 0) {\n return {\n allowed: false,\n decisionType: 'default',\n reason: 'No allow policies defined (default deny)',\n evaluatedPolicies\n }\n }\n\n for (const allow of allows) {\n const result = await this.evaluatePolicy(allow, evalCtx)\n evaluatedPolicies.push({\n name: allow.name,\n type: 'allow',\n result\n })\n\n if (result) {\n return {\n allowed: true,\n policyName: allow.name,\n decisionType: 'allow',\n reason: `Allowed by policy: ${allow.name}`,\n evaluatedPolicies\n }\n }\n }\n\n // No allow policy matched\n if (defaultDeny) {\n return {\n allowed: false,\n decisionType: 'default',\n reason: 'No allow policies matched (default deny)',\n evaluatedPolicies\n }\n }\n\n return {\n allowed: true,\n decisionType: 'default',\n reason: 'No policies matched (default allow)',\n evaluatedPolicies\n }\n }\n\n /**\n * Get filter conditions for read operations\n *\n * @param table - Table name\n * @param operation - Must be 'read'\n * @param context - Test context\n * @returns Filter conditions\n */\n getFilters(\n table: string,\n _operation: 'read',\n context: Pick<TestContext, 'auth' | 'meta'>\n ): FilterEvaluationResult {\n const conditions: Record<string, unknown> = {}\n const appliedFilters: string[] = []\n\n // Check if table is registered\n if (!this.registry.hasTable(table)) {\n return { conditions, appliedFilters }\n }\n\n // Check system user bypass\n if (context.auth.isSystem) {\n return { conditions, appliedFilters }\n }\n\n // Check skipFor roles\n const skipFor = this.registry.getSkipFor(table)\n if (skipFor.some(role => context.auth.roles.includes(role))) {\n return { conditions, appliedFilters }\n }\n\n // Get filters\n const filters = this.registry.getFilters(table)\n\n // Build evaluation context\n const evalCtx: PolicyEvaluationContext = {\n auth: context.auth,\n ...(context.meta !== undefined && { meta: context.meta })\n }\n\n // Evaluate each filter\n for (const filter of filters) {\n const filterConditions = filter.getConditions(evalCtx)\n Object.assign(conditions, filterConditions)\n appliedFilters.push(filter.name)\n }\n\n return { conditions, appliedFilters }\n }\n\n /**\n * Test if a specific policy allows the operation\n *\n * @param table - Table name\n * @param policyName - Name of the policy to test\n * @param context - Test context\n * @returns True if policy allows\n */\n async testPolicy(\n table: string,\n policyName: string,\n context: TestContext\n ): Promise<{ found: boolean; result?: boolean }> {\n // Search in all policy types\n const operations: Operation[] = ['read', 'create', 'update', 'delete']\n\n for (const op of operations) {\n // Build evaluation context once per operation\n const evalCtx: PolicyEvaluationContext = {\n auth: context.auth,\n row: context.row,\n data: context.data,\n table,\n operation: op,\n ...(context.meta !== undefined && { meta: context.meta })\n }\n\n // Check allows\n const allows = this.registry.getAllows(table, op)\n const allow = allows.find(p => p.name === policyName)\n if (allow) {\n const result = await this.evaluatePolicy(allow, evalCtx)\n return { found: true, result }\n }\n\n // Check denies\n const denies = this.registry.getDenies(table, op)\n const deny = denies.find(p => p.name === policyName)\n if (deny) {\n const result = await this.evaluatePolicy(deny, evalCtx)\n return { found: true, result }\n }\n\n // Check validates\n const validates = this.registry.getValidates(table, op)\n const validate = validates.find(p => p.name === policyName)\n if (validate) {\n const result = await this.evaluatePolicy(validate, evalCtx)\n return { found: true, result }\n }\n }\n\n return { found: false }\n }\n\n /**\n * List all policies for a table\n */\n listPolicies(table: string): {\n allows: string[]\n denies: string[]\n filters: string[]\n validates: string[]\n } {\n const operations: Operation[] = ['read', 'create', 'update', 'delete']\n const allowSet = new Set<string>()\n const denySet = new Set<string>()\n const validateSet = new Set<string>()\n\n for (const op of operations) {\n this.registry.getAllows(table, op).forEach(p => allowSet.add(p.name))\n this.registry.getDenies(table, op).forEach(p => denySet.add(p.name))\n this.registry.getValidates(table, op).forEach(p => validateSet.add(p.name))\n }\n\n return {\n allows: Array.from(allowSet),\n denies: Array.from(denySet),\n filters: this.registry.getFilters(table).map(f => f.name),\n validates: Array.from(validateSet)\n }\n }\n\n /**\n * Get all registered tables\n */\n getTables(): string[] {\n return this.registry.getTables()\n }\n\n /**\n * Evaluate a single policy\n */\n private async evaluatePolicy(\n policy: CompiledPolicy,\n ctx: PolicyEvaluationContext\n ): Promise<boolean> {\n try {\n const result = policy.evaluate(ctx)\n return result instanceof Promise ? await result : result\n } catch {\n return false // Fail closed\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a policy tester\n *\n * @param schema - RLS schema to test\n * @returns PolicyTester instance\n */\nexport function createPolicyTester<DB = unknown>(schema: RLSSchema<DB>): PolicyTester<DB> {\n return new PolicyTester<DB>(schema)\n}\n\n// ============================================================================\n// Test Helpers\n// ============================================================================\n\n/**\n * Create a test auth context\n *\n * @param overrides - Values to override\n * @returns RLSAuthContext for testing\n */\nexport function createTestAuthContext(\n overrides: Partial<RLSAuthContext> & { userId: string | number }\n): RLSAuthContext {\n return {\n roles: [],\n isSystem: false,\n ...overrides\n }\n}\n\n/**\n * Create a test row\n *\n * @param data - Row data\n * @returns Row object\n */\nexport function createTestRow<T extends Record<string, unknown>>(data: T): T {\n return { ...data }\n}\n\n/**\n * Assertion helpers for policy testing\n */\nexport const policyAssertions = {\n /**\n * Assert that the result is allowed\n */\n assertAllowed(result: PolicyEvaluationResult, message?: string): void {\n if (!result.allowed) {\n throw new Error(\n message ?? `Expected policy to allow, but was denied: ${result.reason}`\n )\n }\n },\n\n /**\n * Assert that the result is denied\n */\n assertDenied(result: PolicyEvaluationResult, message?: string): void {\n if (result.allowed) {\n throw new Error(\n message ?? `Expected policy to deny, but was allowed: ${result.reason}`\n )\n }\n },\n\n /**\n * Assert that a specific policy made the decision\n */\n assertPolicyUsed(result: PolicyEvaluationResult, policyName: string, message?: string): void {\n if (result.policyName !== policyName) {\n throw new Error(\n message ?? `Expected policy \"${policyName}\" but was \"${result.policyName}\"`\n )\n }\n },\n\n /**\n * Assert that filters include expected conditions\n */\n assertFiltersInclude(\n result: FilterEvaluationResult,\n expected: Record<string, unknown>,\n message?: string\n ): void {\n for (const [key, value] of Object.entries(expected)) {\n if (result.conditions[key] !== value) {\n throw new Error(\n message ??\n `Expected filter condition ${key}=${JSON.stringify(value)} but got ${JSON.stringify(result.conditions[key])}`\n )\n }\n }\n }\n}\n"]}