{"version":3,"sources":["../src/schema/base.ts","../src/schema/fields.ts","../src/schema/view.ts","../src/utils/permission-templates.ts"],"names":["z","baseSchema"],"mappings":";;;;;AAOO,IAAM,UAAA,GAAa;AAAA,EACxB,EAAA,EAAIA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,WAAW,CAAA;AAAA,EACnC,YAAA,EAAcA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,eAAe,CAAA;AAAA,EACjD,cAAA,EAAgBA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,iBAAiB,CAAA;AAAA,EACrD,MAAA,EAAQA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,EAAO,EAAGA,KAAA,CAAE,GAAA,EAAK,CAAA,CAAE,QAAA,CAAS,mBAAmB,CAAA;AAAA,EAClE,OAAA,EAASA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,oBAAoB,CAAA;AAAA,EACjD,OAAA,EAASA,KAAA,CAAE,MAAA,EAAO,CAAE,SAAS,uBAAuB;AACtD;AAuDA,IAAM,qBAAA,GAAwB,yBAAA;AA0BvB,SAAS,cAAc,MAAA,EAAwB;AACpD,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,qBAAqB,GAAG;AAAA,MACvB,IAAA,EAAM,QAAA;AAAA,MACN,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,aAAA,EAAe,OAAO,aAAA,IAAiB,KAAA;AAAA,MACvC,SAAA,EAAW,CAAA;AAAA,MACX,SAAA,EAAW,CAAA;AAAA,MACX,aAAA,EAAe,OAAO,aAAA,IAAiB;AAAA;AACzC,GACF;AAEA,EAAA,OAAOA,MAAE,MAAA,EAAO,CAAE,SAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACrD;AA8BO,SAAS,eAAe,MAAA,EAAyB;AACtD,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,qBAAqB,GAAG;AAAA,MACvB,IAAA,EAAM,UAAA;AAAA,MACN,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,aAAA,EAAe,OAAO,aAAA,IAAiB,KAAA;AAAA,MACvC,SAAA,EAAW,OAAO,SAAA,IAAa,GAAA;AAAA,MAC/B,SAAA,EAAW,OAAO,SAAA,IAAa,CAAA;AAAA,MAC/B,aAAA,EAAe,OAAO,aAAA,IAAiB;AAAA;AACzC,GACF;AAEA,EAAA,IAAI,MAAA,GAASA,KAAA,CAAE,KAAA,CAAMA,KAAA,CAAE,QAAQ,CAAA;AAG/B,EAAA,IAAI,MAAA,CAAO,cAAc,MAAA,EAAW;AAClC,IAAA,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,MAAA,CAAO,SAAS,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,MAAA,CAAO,cAAc,MAAA,EAAW;AAClC,IAAA,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,MAAA,CAAO,SAAS,CAAA;AAAA,EACtC;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;AASO,SAAS,wBAAwB,WAAA,EAO/B;AACP,EAAA,IAAI,CAAC,aAAa,OAAO,IAAA;AAEzB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA;AACrC,IAAA,IAAI,MAAA,CAAO,qBAAqB,CAAA,EAAG;AACjC,MAAA,OAAO,OAAO,qBAAqB,CAAA;AAAA,IACrC;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,OAAO,IAAA;AACT;AAiIO,SAAS,iBAAiB,MAAA,EAA4C;AAC3E,EAAA,MAAM,EAAE,cAAA,EAAgB,MAAA,EAAQ,aAAa,OAAA,EAAS,IAAA,EAAM,WAAU,GAAI,MAAA;AAG1E,EAAA,MAAM,QAAA,GAAgB;AAAA,IACpB;AAAA,GACF;AAGA,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,QAAA,CAAS,IAAA,GAAO,IAAA;AAAA,EAClB;AAGA,EAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,IAAA,QAAA,CAAS,SAAA,GAAY,SAAA;AAAA,EACvB;AAGA,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,QAAA,CAAS,WAAA,GAAc,WAAA;AAAA,EACzB;AAGA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,QAAA,CAAS,OAAA,GAAU,OAAA;AAAA,EACrB;AAGA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;ACnVO,IAAM,kBAAA,GAAqB;AAyC3B,SAAS,qBAAqB,WAAA,EAAuD;AAC1F,EAAA,IAAI,CAAC,aAAa,OAAO,IAAA;AAEzB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA;AACrC,IAAA,IAAI,MAAA,CAAO,kBAAkB,CAAA,EAAG;AAC9B,MAAA,OAAO,OAAO,kBAAkB,CAAA;AAAA,IAClC;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,OAAO,IAAA;AACT;AAkMA,IAAM,mBAAA,GAAsB,CAAA,GAAI,IAAA,GAAO,IAAA,GAAO,IAAA;AAO9C,IAAM,sBAAsB,MAAA,CAAO,gBAAA;AAEnC,SAAS,oBAAA,CACP,OACA,OAAA,EACA,KAAA,GAA0C,EAAE,KAAA,EAAO,mBAAA,EAAqB,KAAA,EAAO,IAAA,EAAK,EAC5E;AACR,EAAA,IAAI,KAAA;AAEJ,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,0CAAA,CAA4C,CAAA;AAAA,IACxE;AACA,IAAA,KAAA,GAAQ,IAAA,CAAK,MAAM,KAAK,CAAA;AAAA,EAC1B,CAAA,MAAO;AACL,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,IAAA,MAAM,KAAA,GAAQ,8BAAA,CAA+B,IAAA,CAAK,OAAO,CAAA;AACzD,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,qEAAA,CAAuE,CAAA;AAAA,IACnG;AAEA,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA;AAC9B,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,CAAE,WAAA,EAAY;AAElC,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,gCAAA,CAAkC,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,UAAA,GAAa,SAAS,GAAA,GAAM,IAAA,GAAO,SAAS,GAAA,GAAM,IAAA,GAAO,IAAA,GAAO,IAAA,GAAO,IAAA,GAAO,IAAA;AACpF,IAAA,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,UAAU,CAAA;AAAA,EACxC;AAEA,EAAA,IAAI,QAAQ,CAAA,EAAG;AACb,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,sBAAA,CAAwB,CAAA;AAAA,EACpD;AAEA,EAAA,IAAI,KAAA,GAAQ,MAAM,KAAA,EAAO;AACvB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,wBAAA,EAA2B,MAAM,KAAK,CAAA,EAAA,EAAK,KAAA,CAAM,KAAK,CAAA,OAAA,CAAS,CAAA;AAAA,EAC3F;AAEA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,yBAAA,CACP,SACA,OAAA,EAC8B;AAC9B,EAAA,IAAI,CAAC,SAAS,OAAO,OAAA;AACrB,EAAA,IAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,EAAW,OAAO,OAAA;AAE1C,EAAA,OAAO;AAAA,IACL,GAAG,OAAA;AAAA;AAAA,IAEH,OAAA,EAAS,oBAAA,CAAqB,OAAA,CAAQ,OAAA,EAAS,OAAO;AAAA,GACxD;AACF;AAEA,SAAS,yBAAA,CACP,SACA,OAAA,EAC8B;AAC9B,EAAA,IAAI,CAAC,SAAS,OAAO,OAAA;AACrB,EAAA,IAAI,OAAA,CAAQ,OAAA,KAAY,MAAA,EAAW,OAAO,OAAA;AAE1C,EAAA,OAAO;AAAA,IACL,GAAG,OAAA;AAAA,IACH,OAAA,EAAS,oBAAA,CAAqB,OAAA,CAAQ,OAAA,EAAS,OAAA,EAAS;AAAA,MACtD,KAAA,EAAO,mBAAA;AAAA,MACP,KAAA,EAAO;AAAA,KACR;AAAA,GACH;AACF;AAkBO,SAAS,SAAA,GAA0B;AACxC,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM;AAAA;AACR,GACF;AAEA,EAAA,OAAOA,MAAE,OAAA,EAAQ,CAAE,SAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACtD;AAuBO,SAAS,YAAY,OAAA,EAA2C;AAErE,EAAA,IAAI,OAAA,EAAS,GAAA,KAAQ,MAAA,IAAa,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC5D,IAAA,IAAI,OAAA,CAAQ,GAAA,GAAM,OAAA,CAAQ,GAAA,EAAK;AAC7B,MAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,IAC/D;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,GAASA,MAAE,MAAA,EAAO;AAGtB,EAAA,IAAI,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC9B,IAAA,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAAA,EACjC;AACA,EAAA,IAAI,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC9B,IAAA,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAAA,EACjC;AAGA,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS,WAAW;AAAC;AACvB,GACF;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;AAgBO,SAAS,UAAU,OAAA,EAAyC;AAEjE,EAAA,IAAI,OAAA,EAAS,GAAA,KAAQ,MAAA,IAAa,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC5D,IAAA,IAAI,OAAA,CAAQ,GAAA,GAAM,OAAA,CAAQ,GAAA,EAAK;AAC7B,MAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,IAC7D;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,GAASA,MAAE,MAAA,EAAO;AAGtB,EAAA,IAAI,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC9B,IAAA,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAAA,EACjC;AACA,EAAA,IAAI,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC9B,IAAA,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAAA,EACjC;AACA,EAAA,IAAI,OAAA,EAAS,YAAY,MAAA,EAAW;AAClC,IAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,YAAmB,MAAA,GAAS,QAAQ,OAAA,GAAU,IAAI,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA;AAChG,IAAA,MAAA,GAAS,MAAA,CAAO,MAAM,OAAO,CAAA;AAAA,EAC/B;AAQA,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,MAAA;AAAA,MACN,SAAS,OAAA,GACL,EAAE,GAAG,OAAA,EAAS,GAAI,QAAQ,OAAA,YAAmB,MAAA,GAAS,EAAE,OAAA,EAAS,QAAQ,OAAA,CAAQ,MAAA,KAAW,EAAC,KAC7F;AAAC;AACP,GACF;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;AAcO,SAAS,UAAA,GAA0B;AACxC,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM;AAAA;AACR,GACF;AAEA,EAAA,OAAOA,KAAAA,CAAE,QAAO,CAAE,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAC7D;AAcO,SAAS,QAAA,GAAwB;AACtC,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM;AAAA;AACR,GACF;AAEA,EAAA,OAAOA,KAAAA,CAAE,QAAO,CAAE,GAAA,GAAM,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAC3D;AAcO,SAAS,WAAA,GAA2B;AACzC,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM;AAAA;AACR,GACF;AAEA,EAAA,OAAOA,MAAE,MAAA,EAAO,CAAE,SAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACrD;AAgBO,SAAS,UAAU,OAAA,EAAyC;AAEjE,EAAA,IAAI,OAAA,EAAS,GAAA,KAAQ,MAAA,IAAa,OAAA,EAAS,QAAQ,MAAA,EAAW;AAC5D,IAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,GAAA,KAAQ,QAAA,GAAW,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAA;AAClF,IAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,GAAA,KAAQ,QAAA,GAAW,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAA;AAClF,IAAA,IAAI,UAAU,OAAA,EAAS;AACrB,MAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,IAC7D;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAASA,MAAE,MAAA,EAAO;AAGxB,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,WAAW;AAAC;AACvB,GACF;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;AAgBO,SAAS,cAAc,OAAA,EAA6C;AACzE,EAAA,MAAM,MAAA,GAASA,MAAE,MAAA,EAAO;AAGxB,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,UAAA;AAAA,MACN,OAAA,EAAS,WAAW;AAAC;AACvB,GACF;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;AAqCO,SAAS,WAAA,CACd,QACA,OAAA,EACiD;AACjD,EAAA,MAAM,SAAA,GAAY,SAAS,SAAA,IAAa,CAAA;AAExC,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAAA,EACvD;AAEA,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS;AAAA,QACP,MAAA;AAAA,QACA;AAAA;AACF;AACF,GACF;AAEA,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,OAAOA,KAAAA,CAAE,KAAA,CAAMA,KAAAA,CAAE,IAAA,CAAK,MAAM,CAAC,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,EAClE;AAEA,EAAA,OAAOA,KAAAA,CAAE,KAAK,MAAM,CAAA,CAAE,SAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACzD;AAmBO,SAAS,UAAU,OAAA,EAA8D;AAGtF,EAAA,MAAM,MAAA,GAASA,KAAAA,CAAE,UAAA,CAAW,CAAC,GAAA,KAAQ;AAGnC,IAAA,OAAO,GAAA,YAAe,IAAA,GAAO,GAAA,CAAI,IAAA,IAAQ,EAAA,GAAK,GAAA;AAAA,EAChD,CAAA,EAAGA,KAAAA,CAAE,MAAA,EAAQ,CAAA;AAEb,EAAA,MAAM,iBAAA,GAAoB,yBAAA,CAA0B,OAAA,EAAS,WAAW,CAAA;AAGxE,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,qBAAqB;AAAC;AACjC,GACF;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;AAmBO,SAAS,WAAW,OAAA,EAAqE;AAE9F,EAAA,IAAI,OAAA,EAAS,SAAA,KAAc,MAAA,IAAa,OAAA,EAAS,cAAc,MAAA,EAAW;AACxE,IAAA,IAAI,OAAA,CAAQ,SAAA,GAAY,OAAA,CAAQ,SAAA,EAAW;AACzC,MAAA,MAAM,IAAI,MAAM,wDAAwD,CAAA;AAAA,IAC1E;AAAA,EACF;AAIA,EAAA,IAAI,eAAA,GAAkBA,KAAAA,CAAE,KAAA,CAAMA,KAAAA,CAAE,QAAQ,CAAA;AAGxC,EAAA,IAAI,OAAA,EAAS,cAAc,MAAA,EAAW;AACpC,IAAA,eAAA,GAAkB,eAAA,CAAgB,GAAA,CAAI,OAAA,CAAQ,SAAS,CAAA;AAAA,EACzD;AACA,EAAA,IAAI,OAAA,EAAS,cAAc,MAAA,EAAW;AACpC,IAAA,eAAA,GAAkB,eAAA,CAAgB,GAAA,CAAI,OAAA,CAAQ,SAAS,CAAA;AAAA,EACzD;AAEA,EAAA,MAAM,MAAA,GAASA,KAAAA,CAAE,UAAA,CAAW,CAAC,GAAA,KAAQ;AAEnC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,MAAA,OAAO,GAAA,CAAI,IAAI,CAAC,IAAA,KAAU,gBAAgB,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAA,GAAK,IAAK,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,GAAA;AAAA,EACT,GAAG,eAAe,CAAA;AAElB,EAAA,MAAM,iBAAA,GAAoB,yBAAA,CAA0B,OAAA,EAAS,YAAY,CAAA;AAGzE,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,qBAAqB;AAAC;AACjC,GACF;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;AAQA,SAAS,YAAY,KAAA,EAAuC;AAC1D,EAAA,IAAI,KAAA,YAAiBA,MAAE,OAAA,EAAS;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OACE,OAAO,KAAA,KAAU,QAAA,IACjB,KAAA,KAAU,IAAA,IACV,OAAQ,KAAA,CAA8B,KAAA,KAAU,UAAA,IAChD,OAAQ,KAAA,CAAkC,SAAA,KAAc,UAAA;AAE5D;AAmCO,SAAS,SAAA,CACd,iBACA,YAAA,EACwC;AACxC,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,eAAe,CAAA,GAAI,eAAA,GAAkB,MAAA;AAIhE,EAAA,MAAM,OAAA,GAAU,MAAA,GAAS,YAAA,GAAiB,eAAA,IAAoD,YAAA;AAE9F,EAAA,MAAMC,WAAAA,GAAa,UAAUD,KAAAA,CAAE,MAAA,CAAOA,MAAE,MAAA,EAAO,EAAGA,KAAAA,CAAE,GAAA,EAAK,CAAA;AACzD,EAAA,MAAM,iBAAA,GAAoB,yBAAA,CAA0B,OAAA,EAAS,WAAW,CAAA;AAIxE,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM,MAAA;AAAA,MACN,GAAI,iBAAA,IAAqB,MAAA,CAAO,IAAA,CAAK,iBAAiB,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,EAAE,OAAA,EAAS,iBAAA,EAAkB,GAAI;AAAC;AACzG,GACF;AAEA,EAAA,OAAOC,WAAAA,CAAW,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACrD;AAcO,SAAS,aAAA,GAGb;AACD,EAAA,MAAM,MAAA,GAASD,MAAE,MAAA,CAAO;AAAA,IACtB,GAAA,EAAKA,MAAE,MAAA,EAAO;AAAA,IACd,GAAA,EAAKA,MAAE,MAAA;AAAO,GACf,CAAA;AAGD,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,CAAC,kBAAkB,GAAG;AAAA,MACpB,IAAA,EAAM;AAAA;AACR,GACF;AAEA,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AACjD;ACtyBO,SAAS,UAAU,KAAA,EAAuB;AAC/C,EAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,SAAS,IAAI,CAAA,CAAE,MAAM,IAAI,CAAA;AAGrD,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,OAAW,EAAA,EAAI;AACjD,IAAA,KAAA,CAAM,KAAA,EAAM;AAAA,EACd;AACA,EAAA,OAAO,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,SAAS,CAAC,CAAA,CAAE,IAAA,EAAK,KAAM,EAAA,EAAI;AAChE,IAAA,KAAA,CAAM,GAAA,EAAI;AAAA,EACZ;AAEA,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,EAAA;AAAA,EACT;AAGA,EAAA,IAAI,SAAA,GAAY,QAAA;AAChB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,IAAA,CAAK,IAAA,EAAK,KAAM,EAAA,EAAI;AACxB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,WAAU,CAAE,MAAA;AAC9C,IAAA,IAAI,SAAS,SAAA,EAAW;AACtB,MAAA,SAAA,GAAY,MAAA;AAAA,IACd;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,IAAK,cAAc,CAAA,EAAG;AAClD,IAAA,OAAO,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,KAAK,OAAA,EAAS,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,EACtD;AAEA,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AACvE;AAgBO,SAAS,GAAA,CAAI,YAAkC,MAAA,EAAwC;AAC5F,EAAA,IAAI,MAAA,GAAS,EAAA;AAEb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,IAAA,MAAA,IAAU,QAAQ,CAAC,CAAA;AACnB,IAAA,IAAI,CAAA,GAAI,OAAO,MAAA,EAAQ;AACrB,MAAA,MAAA,IAAU,MAAA,CAAO,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAC5B;AAAA,EACF;AAEA,EAAA,OAAO,UAAU,MAAM,CAAA;AACzB;AAQA,SAAS,qBAAqB,KAAA,EAAuB;AACnD,EAAA,IAAI,SAAA,GAAY,MAAM,IAAA,EAAK;AAG3B,EAAA,OAAO,SAAA,CAAU,SAAS,CAAA,EAAG;AAC3B,IAAA,IAAI,SAAA,CAAU,UAAA,CAAW,IAAI,CAAA,EAAG;AAC9B,MAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AACtC,MAAA,SAAA,GAAY,OAAA,KAAY,KAAK,EAAA,GAAK,SAAA,CAAU,MAAM,OAAA,GAAU,CAAC,EAAE,IAAA,EAAK;AACpE,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAA,CAAU,UAAA,CAAW,IAAI,CAAA,EAAG;AAC9B,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAClC,MAAA,SAAA,GAAY,GAAA,KAAQ,KAAK,EAAA,GAAK,SAAA,CAAU,MAAM,GAAA,GAAM,CAAC,EAAE,IAAA,EAAK;AAC5D,MAAA;AAAA,IACF;AAEA,IAAA;AAAA,EACF;AAEA,EAAA,OAAO,SAAA;AACT;AAQO,SAAS,iBAAA,CAAkB,gBAAwB,SAAA,EAAiD;AACzG,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,IAAY,SAAA,CAAU,IAAA,OAAW,EAAA,EAAI;AAC5D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,oBAAoB,cAAc,CAAA,oFAAA;AAAA,KAEpC;AAAA,EACF;AAEA,EAAA,MAAM,IAAA,GAAO,qBAAqB,SAAS,CAAA;AAC3C,EAAA,IAAI,CAAC,mBAAA,CAAoB,IAAA,CAAK,IAAI,CAAA,EAAG;AACnC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iBAAA,EAAoB,cAAc,CAAA,yEAAA,EACnB,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,IAAA,CAAK,MAAA,GAAS,EAAA,GAAK,QAAQ,EAAE,CAAA;AAAA,KAClE;AAAA,EACF;AACF;AAwCO,SAAS,WAAW,MAAA,EAAgD;AACzE,EAAA,MAAM,EAAE,cAAA,EAAgB,MAAA,EAAQ,SAAA,EAAW,aAAY,GAAI,MAAA;AAE3D,EAAA,iBAAA,CAAkB,gBAAgB,SAAS,CAAA;AAE3C,EAAA,OAAO,gBAAA,CAAiB;AAAA,IACtB,cAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA,EAAM,MAAA;AAAA,IACN,SAAA;AAAA;AAAA,IAEA,WAAA,EAAa;AAAA,MACX,QAAA,EAAU,aAAa,QAAA,IAAY,IAAA;AAAA,MACnC,QAAA,EAAU,aAAa,QAAA,IAAY,IAAA;AAAA,MACnC,UAAA,EAAY,IAAA;AAAA,MACZ,UAAA,EAAY,IAAA;AAAA,MACZ,UAAA,EAAY;AAAA;AACd,GACD,CAAA;AACH;;;AChOO,IAAM,mBAAA,GAAsB;AAAA;AAAA;AAAA;AAAA,EAIjC,QAAQ,OAAyB;AAAA,IAC/B,QAAA,EAAU,EAAA;AAAA,IACV,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY,EAAA;AAAA,IACZ,UAAA,EAAY,EAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACd,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,OAAyB;AAAA,IACtC,QAAA,EAAU,wBAAA;AAAA,IACV,QAAA,EAAU,wBAAA;AAAA,IACV,UAAA,EAAY,wBAAA;AAAA,IACZ,UAAA,EAAY,wBAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACd,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAA,EAAW,CAAC,UAAA,GAAqB,MAAA,MAA8B;AAAA,IAC7D,QAAA,EAAU,6BAA6B,UAAU,CAAA,mBAAA,CAAA;AAAA,IACjD,QAAA,EAAU,6BAA6B,UAAU,CAAA,mBAAA,CAAA;AAAA,IACjD,UAAA,EAAY,wBAAA;AAAA,IACZ,UAAA,EAAY,6BAA6B,UAAU,CAAA,mBAAA,CAAA;AAAA,IACnD,UAAA,EAAY,6BAA6B,UAAU,CAAA,mBAAA;AAAA,GACrD,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAA,EAAW,CAAC,SAAA,GAAoB,MAAA,MAA8B;AAAA,IAC5D,QAAA,EAAU,2CAA2C,SAAS,CAAA,UAAA,CAAA;AAAA,IAC9D,QAAA,EAAU,2CAA2C,SAAS,CAAA,UAAA,CAAA;AAAA,IAC9D,UAAA,EAAY,2CAA2C,SAAS,CAAA,UAAA,CAAA;AAAA,IAChE,UAAA,EAAY,2CAA2C,SAAS,CAAA,UAAA,CAAA;AAAA,IAChE,UAAA,EAAY,2CAA2C,SAAS,CAAA,UAAA;AAAA,GAClE,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,OAAyB;AAAA,IACnC,QAAA,EAAU,EAAA;AAAA,IACV,QAAA,EAAU,EAAA;AAAA,IACV,UAAA,EAAY,wBAAA;AAAA,IACZ,UAAA,EAAY,wBAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACd,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,OAAyB;AAAA,IAC/B,QAAA,EAAU,IAAA;AAAA,IACV,QAAA,EAAU,IAAA;AAAA,IACV,UAAA,EAAY,IAAA;AAAA,IACZ,UAAA,EAAY,IAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACd,CAAA;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuB,OAAyB;AAAA,IAC9C,QAAA,EAAU,wBAAA;AAAA,IACV,QAAA,EAAU,wBAAA;AAAA,IACV,UAAA,EAAY,IAAA;AAAA,IACZ,UAAA,EAAY,IAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACd;AACF;AAOO,SAAS,gBAAgB,MAAA,EAAoD;AAClF,EAAA,IAAI,SAAA;AAEJ,EAAA,QAAQ,OAAO,QAAA;AAAU,IACvB,KAAK,QAAA;AACH,MAAA,SAAA,GAAY,oBAAoB,MAAA,EAAO;AACvC,MAAA;AAAA,IACF,KAAK,eAAA;AACH,MAAA,SAAA,GAAY,oBAAoB,aAAA,EAAc;AAC9C,MAAA;AAAA,IACF,KAAK,YAAA;AACH,MAAA,SAAA,GAAY,mBAAA,CAAoB,SAAA,CAAU,MAAA,CAAO,UAAU,CAAA;AAC3D,MAAA;AAAA,IACF,KAAK,YAAA;AACH,MAAA,SAAA,GAAY,mBAAA,CAAoB,SAAA,CAAU,MAAA,CAAO,SAAS,CAAA;AAC1D,MAAA;AAAA,IACF,KAAK,aAAA;AACH,MAAA,SAAA,GAAY,oBAAoB,UAAA,EAAW;AAC3C,MAAA;AAAA,IACF,KAAK,QAAA;AACH,MAAA,SAAA,GAAY,EAAC;AACb,MAAA;AAAA,IACF,SAAS;AAEP,MAAA,MAAM,cAAqB,MAAA,CAAO,QAAA;AAClC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,WAAW,CAAA,CAAE,CAAA;AAAA,IACzD;AAAA;AAIF,EAAA,OAAO;AAAA,IACL,GAAG,SAAA;AAAA,IACH,GAAG,MAAA,CAAO;AAAA,GACZ;AACF","file":"index.cjs","sourcesContent":["import { z } from \"zod\";\nimport type { PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\n\n/**\n * Base schema fields that PocketBase automatically adds to all records\n * These fields are managed by PocketBase and should not be set manually\n */\nexport const baseSchema = {\n  id: z.string().describe(\"unique id\"),\n  collectionId: z.string().describe(\"collection id\"),\n  collectionName: z.string().describe(\"collection name\"),\n  expand: z.record(z.string(), z.any()).describe(\"expandable fields\"),\n  created: z.string().describe(\"creation timestamp\"),\n  updated: z.string().describe(\"last update timestamp\"),\n};\n\n// ============================================================================\n// Common PocketBase Field Type Patterns\n// ============================================================================\n// Note: Field type helpers are now exported from ./fields.ts with PascalCase names\n// (e.g., TextField, EmailField, JSONField, etc.) to ensure consistent naming.\n\n// ============================================================================\n// Relation Field Helpers - Explicit Relationship Definitions\n// ============================================================================\n\n/**\n * Relation field configuration options\n */\nexport interface RelationConfig {\n  /**\n   * Target collection name (e.g., 'users', 'posts', 'tags')\n   * This is the PocketBase collection that the relation points to\n   */\n  collection: string;\n\n  /**\n   * Whether to cascade delete related records when this record is deleted\n   * @default false\n   */\n  cascadeDelete?: boolean;\n\n  /**\n   * Fields to display in the admin UI\n   */\n  displayFields?: string[] | null;\n}\n\n/**\n * Multiple relation field configuration options\n */\nexport interface RelationsConfig extends RelationConfig {\n  /**\n   * Minimum number of relations required\n   * @default 0\n   */\n  minSelect?: number;\n\n  /**\n   * Maximum number of relations allowed\n   * @default 999\n   */\n  maxSelect?: number;\n}\n\n/**\n * Internal marker for relation metadata\n * Used by the analyzer to detect explicit relation definitions\n */\nconst RELATION_METADATA_KEY = \"__pocketbase_relation__\";\n\n/**\n * Creates a single relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect=1\n *\n * This is the recommended way to define relations - it's explicit and doesn't\n * rely on naming conventions.\n *\n * @param config - Relation configuration with target collection\n * @returns Zod string schema with relation metadata\n *\n * @example\n * // Single relation to users collection\n * const PostSchema = z.object({\n *   title: z.string(),\n *   author: RelationField({ collection: 'users' }),\n * });\n *\n * @example\n * // Relation with cascade delete\n * const CommentSchema = z.object({\n *   content: z.string(),\n *   post: RelationField({ collection: 'posts', cascadeDelete: true }),\n * });\n */\nexport function RelationField(config: RelationConfig) {\n  const metadata = {\n    [RELATION_METADATA_KEY]: {\n      type: \"single\",\n      collection: config.collection,\n      cascadeDelete: config.cascadeDelete ?? false,\n      maxSelect: 1,\n      minSelect: 0,\n      displayFields: config.displayFields ?? null,\n    },\n  };\n\n  return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple relation field schema with explicit collection target\n * Maps to PocketBase 'relation' field type with maxSelect>1\n *\n * This is the recommended way to define multi-relations - it's explicit and\n * doesn't rely on naming conventions.\n *\n * @param config - Relations configuration with target collection and limits\n * @returns Zod array of strings schema with relation metadata\n *\n * @example\n * // Multiple relations to tags collection\n * const PostSchema = z.object({\n *   title: z.string(),\n *   tags: RelationsField({ collection: 'tags' }),\n * });\n *\n * @example\n * // Relations with min/max constraints\n * const ProjectSchema = z.object({\n *   title: z.string(),\n *   collaborators: RelationsField({\n *     collection: 'users',\n *     minSelect: 1,\n *     maxSelect: 10,\n *   }),\n * });\n */\nexport function RelationsField(config: RelationsConfig) {\n  const metadata = {\n    [RELATION_METADATA_KEY]: {\n      type: \"multiple\",\n      collection: config.collection,\n      cascadeDelete: config.cascadeDelete ?? false,\n      maxSelect: config.maxSelect ?? 999,\n      minSelect: config.minSelect ?? 0,\n      displayFields: config.displayFields ?? null,\n    },\n  };\n\n  let schema = z.array(z.string());\n\n  // Apply array constraints for Zod validation\n  if (config.minSelect !== undefined) {\n    schema = schema.min(config.minSelect);\n  }\n  if (config.maxSelect !== undefined) {\n    schema = schema.max(config.maxSelect);\n  }\n\n  return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Extracts relation metadata from a Zod type's description\n * Used internally by the analyzer to detect explicit relation definitions\n *\n * @param description - The Zod type's description string\n * @returns Relation metadata if present, null otherwise\n */\nexport function extractRelationMetadata(description: string | undefined): {\n  type: \"single\" | \"multiple\";\n  collection: string;\n  cascadeDelete: boolean;\n  maxSelect: number;\n  minSelect: number;\n  displayFields?: string[] | null;\n} | null {\n  if (!description) return null;\n\n  try {\n    const parsed = JSON.parse(description);\n    if (parsed[RELATION_METADATA_KEY]) {\n      return parsed[RELATION_METADATA_KEY];\n    }\n  } catch {\n    // Not JSON, ignore\n  }\n\n  return null;\n}\n\n/**\n * Configuration options for defining a collection\n */\nexport interface CollectionConfig {\n  /**\n   * The name of the PocketBase collection\n   * This will be used when generating migrations\n   */\n  collectionName: string;\n\n  /**\n   * The Zod schema definition for the collection\n   */\n  schema: z.ZodObject<any>;\n\n  /**\n   * Optional permission configuration\n   * Can be a template-based config or custom permission rules\n   */\n  permissions?: PermissionTemplateConfig | PermissionSchema;\n\n  /**\n   * Optional array of index SQL statements\n   * Example: ['CREATE UNIQUE INDEX idx_users_email ON users (email)']\n   */\n  indexes?: string[];\n\n  /**\n   * Optional collection type\n   * - \"base\": Standard collection (default)\n   * - \"auth\": Authentication collection with system auth fields\n   * - \"view\": Read-only collection backed by a SQL query (requires viewQuery)\n   *\n   * Defaults to \"base\". Auth collections must set type: \"auth\" explicitly.\n   *\n   * Prefer defineView() over type: \"view\" - it enforces the constraints\n   * PocketBase places on view collections at compile time.\n   */\n  type?: \"base\" | \"auth\" | \"view\";\n\n  /**\n   * SQL SELECT statement backing a view collection\n   *\n   * Only valid when type is \"view\", where it is required. PocketBase derives\n   * the collection's fields by running this query, so the Zod schema is used\n   * for TypeScript types only.\n   */\n  viewQuery?: string;\n}\n\n/**\n * High-level wrapper for defining a PocketBase collection with all metadata\n *\n * This is the recommended way to define collections as it provides a single\n * entry point for collection name, schema, permissions, indexes, and future features.\n *\n * @param config - Collection configuration object\n * @returns The schema with all metadata attached\n *\n * @example\n * // Recommended: Use default export for clarity\n * const PostCollection = defineCollection({\n *   collectionName: \"posts\",\n *   schema: z.object({\n *     title: z.string(),\n *     content: z.string(),\n *     author: RelationField({ collection: \"users\" }),\n *   }),\n *   permissions: {\n *     template: \"owner-only\",\n *     ownerField: \"author\",\n *   },\n * });\n * export default PostCollection;\n *\n * @example\n * // Also supported: Named export (backward compatible)\n * export const PostCollection = defineCollection({\n *   collectionName: \"posts\",\n *   schema: z.object({\n *     title: z.string(),\n *     content: z.string(),\n *     author: RelationField({ collection: \"users\" }),\n *   }),\n *   permissions: {\n *     template: \"owner-only\",\n *     ownerField: \"author\",\n *   },\n * });\n *\n * @example\n * // Collection with permissions and indexes\n * export const UserSchema = defineCollection({\n *   collectionName: \"users\",\n *   schema: z.object({\n *     name: z.string(),\n *     email: z.string().email(),\n *   }),\n *   permissions: {\n *     listRule: \"id = @request.auth.id\",\n *     viewRule: \"id = @request.auth.id\",\n *     createRule: \"\",\n *     updateRule: \"id = @request.auth.id\",\n *     deleteRule: \"id = @request.auth.id\",\n *   },\n *   indexes: [\n *     \"CREATE UNIQUE INDEX idx_users_email ON users (email)\",\n *   ],\n * });\n *\n * @example\n * // Collection with template and custom rule overrides\n * export const ProjectSchema = defineCollection({\n *   collectionName: \"projects\",\n *   schema: z.object({\n *     title: z.string(),\n *     owner: RelationField({ collection: \"users\" }),\n *   }),\n *   permissions: {\n *     template: \"owner-only\",\n *     ownerField: \"owner\",\n *     customRules: {\n *       listRule: '@request.auth.id != \"\"',\n *     },\n *   },\n * });\n */\nexport function defineCollection(config: CollectionConfig): z.ZodObject<any> {\n  const { collectionName, schema, permissions, indexes, type, viewQuery } = config;\n\n  // Build metadata object\n  const metadata: any = {\n    collectionName,\n  };\n\n  // Add type if provided\n  if (type) {\n    metadata.type = type;\n  }\n\n  // Add the SQL query backing a view collection\n  if (viewQuery !== undefined) {\n    metadata.viewQuery = viewQuery;\n  }\n\n  // Add permissions if provided\n  if (permissions) {\n    metadata.permissions = permissions;\n  }\n\n  // Add indexes if provided\n  if (indexes) {\n    metadata.indexes = indexes;\n  }\n\n  // Attach all metadata to schema using Zod's describe() method\n  return schema.describe(JSON.stringify(metadata)) as z.ZodObject<any>;\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Field Metadata System\n// ============================================================================\n\n/**\n * Internal marker for field metadata\n * Used by the migration generator to detect explicit field type definitions\n */\nexport const FIELD_METADATA_KEY = \"__pocketbase_field__\";\n\n/**\n * PocketBase field types\n */\nexport type PocketBaseFieldType =\n  | \"text\"\n  | \"email\"\n  | \"url\"\n  | \"editor\"\n  | \"number\"\n  | \"bool\"\n  | \"date\"\n  | \"autodate\"\n  | \"select\"\n  | \"relation\"\n  | \"file\"\n  | \"json\"\n  | \"geoPoint\"\n  | \"password\";\n\n/**\n * Field metadata structure embedded in Zod schema descriptions\n */\nexport interface FieldMetadata {\n  type: PocketBaseFieldType;\n  options?: Record<string, any>;\n}\n\n/**\n * Extracts field metadata from a Zod type's description\n * Used by the migration generator to detect explicit field type definitions\n *\n * @param description - The Zod type's description string\n * @returns Field metadata if present, null otherwise\n *\n * @example\n * const schema = TextField({ min: 1, max: 100 });\n * const metadata = extractFieldMetadata(schema.description);\n * // Returns: { type: \"text\", options: { min: 1, max: 100 } }\n */\nexport function extractFieldMetadata(description: string | undefined): FieldMetadata | null {\n  if (!description) return null;\n\n  try {\n    const parsed = JSON.parse(description);\n    if (parsed[FIELD_METADATA_KEY]) {\n      return parsed[FIELD_METADATA_KEY];\n    }\n  } catch {\n    // Not JSON, ignore\n  }\n\n  return null;\n}\n\n// ============================================================================\n// Field Options Interfaces\n// ============================================================================\n\n/**\n * Text field configuration options\n */\nexport interface TextFieldOptions {\n  /**\n   * Minimum length constraint\n   */\n  min?: number;\n\n  /**\n   * Maximum length constraint\n   */\n  max?: number;\n\n  /**\n   * Pattern constraint (regex)\n   */\n  pattern?: RegExp | string;\n\n  /**\n   * Auto-generate pattern for automatic value generation\n   * Example: \"[A-Z]{3}-[0-9]{6}\" generates values like \"ABC-123456\"\n   */\n  autogeneratePattern?: string;\n}\n\n/**\n * Number field configuration options\n */\nexport interface NumberFieldOptions {\n  /**\n   * Minimum value constraint\n   */\n  min?: number;\n\n  /**\n   * Maximum value constraint\n   */\n  max?: number;\n\n  /**\n   * Whether to disallow decimal values (integers only)\n   */\n  noDecimal?: boolean;\n\n  /**\n   * Whether the field is required\n   * @default false\n   *\n   * Note: In PocketBase, `required: true` for number fields means the value must be non-zero.\n   * If you want to allow zero values (e.g., for progress: 0-100), keep this as `false`.\n   * Set to `true` only if you want to enforce non-zero values.\n   */\n  required?: boolean;\n}\n\n/**\n * Date field configuration options\n */\nexport interface DateFieldOptions {\n  /**\n   * Minimum date constraint\n   */\n  min?: Date | string;\n\n  /**\n   * Maximum date constraint\n   */\n  max?: Date | string;\n}\n\n/**\n * Autodate field configuration options\n */\nexport interface AutodateFieldOptions {\n  /**\n   * Set date automatically on record creation\n   * @default false\n   */\n  onCreate?: boolean;\n\n  /**\n   * Update date automatically on record update\n   * @default false\n   */\n  onUpdate?: boolean;\n}\n\n/**\n * Select field configuration options\n */\nexport interface SelectFieldOptions {\n  /**\n   * Maximum number of selections allowed\n   * If > 1, enables multiple selection\n   * @default 1\n   */\n  maxSelect?: number;\n}\n\nexport type EnumFromArray<T extends readonly [string, ...string[]]> = z.ZodEnum<z.core.util.ToEnum<T[number]>>;\n\n/**\n * Human-friendly byte size input.\n *\n * - Use a number for raw bytes (e.g. `5242880`)\n * - Use a string with unit suffix for kibibytes/mebibytes/gibibytes (e.g. `\"5M\"`, `\"1G\"`)\n *\n * Supported suffixes: `K`, `M`, `G` (case-insensitive).\n */\nexport type ByteSize = number | `${number}${\"K\" | \"M\" | \"G\" | \"k\" | \"m\" | \"g\"}`;\n\n/**\n * File field configuration options\n */\nexport interface FileFieldOptions {\n  /**\n   * Allowed MIME types\n   * Example: [\"image/*\", \"application/pdf\"]\n   */\n  mimeTypes?: string[];\n\n  /**\n   * Maximum file size.\n   *\n   * - Provide a number for raw bytes\n   * - Or use a string with `K`, `M`, `G` suffix (case-insensitive)\n   *\n   * Max allowed is `8G`.\n   *\n   * @example\n   * maxSize: 5242880\n   * maxSize: \"5M\"\n   * maxSize: \"1G\"\n   */\n  maxSize?: ByteSize;\n\n  /**\n   * Thumbnail sizes to generate\n   * Example: [\"100x100\", \"200x200\"]\n   * Set to null to explicitly disable thumbnails\n   */\n  thumbs?: string[];\n\n  /**\n   * Whether the file is protected (requires auth to access)\n   * @default false\n   */\n  protected?: boolean;\n}\n\n/**\n * Multiple files field configuration options\n */\nexport interface FilesFieldOptions extends FileFieldOptions {\n  /**\n   * Minimum number of files required\n   */\n  minSelect?: number;\n\n  /**\n   * Maximum number of files allowed\n   */\n  maxSelect?: number;\n}\n\n/**\n * JSON field configuration options\n */\nexport interface JSONFieldOptions {\n  /**\n   * Maximum size of the serialized JSON value.\n   *\n   * - Provide a number for raw bytes\n   * - Or use a string with `K`, `M`, `G` suffix (case-insensitive)\n   *\n   * PocketBase applies a **1MB** default when this is unset (or `0`), so a field\n   * holding anything larger has to declare its own limit. The maximum PocketBase\n   * accepts is 2^53-1 bytes.\n   *\n   * @example\n   * maxSize: 5242880\n   * maxSize: \"5M\"\n   * maxSize: \"200K\"\n   */\n  maxSize?: ByteSize;\n}\n\nconst MAX_FILE_SIZE_BYTES = 8 * 1024 * 1024 * 1024; // 8G\n\n/**\n * PocketBase validates a json field's `maxSize` against `maxSafeJSONInt`\n * (2^53-1) — the field is stored as a JS-safe integer, not a file size, so the\n * file ceiling does not apply here.\n */\nconst MAX_JSON_SIZE_BYTES = Number.MAX_SAFE_INTEGER; // 2^53 - 1\n\nfunction parseByteSizeToBytes(\n  value: ByteSize,\n  context: string,\n  limit: { bytes: number; label: string } = { bytes: MAX_FILE_SIZE_BYTES, label: \"8G\" }\n): number {\n  let bytes: number;\n\n  if (typeof value === \"number\") {\n    if (!Number.isFinite(value)) {\n      throw new Error(`${context}: maxSize must be a finite number of bytes`);\n    }\n    bytes = Math.round(value);\n  } else {\n    const trimmed = value.trim();\n    const match = /^(\\d+(?:\\.\\d+)?)\\s*([KMG])$/i.exec(trimmed);\n    if (!match) {\n      throw new Error(`${context}: maxSize string must be like \"10K\", \"5M\", or \"1G\" (case-insensitive)`);\n    }\n\n    const amount = Number(match[1]);\n    const unit = match[2].toUpperCase() as \"K\" | \"M\" | \"G\";\n\n    if (!Number.isFinite(amount)) {\n      throw new Error(`${context}: maxSize must be a valid number`);\n    }\n\n    const multiplier = unit === \"K\" ? 1024 : unit === \"M\" ? 1024 * 1024 : 1024 * 1024 * 1024;\n    bytes = Math.round(amount * multiplier);\n  }\n\n  if (bytes < 0) {\n    throw new Error(`${context}: maxSize must be >= 0`);\n  }\n\n  if (bytes > limit.bytes) {\n    throw new Error(`${context}: maxSize cannot exceed ${limit.label} (${limit.bytes} bytes)`);\n  }\n\n  return bytes;\n}\n\nfunction normalizeFileFieldOptions(\n  options: FileFieldOptions | undefined,\n  context: string\n): FileFieldOptions | undefined {\n  if (!options) return options;\n  if (options.maxSize === undefined) return options;\n\n  return {\n    ...options,\n    // PocketBase expects bytes; normalize any human-friendly inputs to bytes here.\n    maxSize: parseByteSizeToBytes(options.maxSize, context),\n  };\n}\n\nfunction normalizeJSONFieldOptions(\n  options: JSONFieldOptions | undefined,\n  context: string\n): JSONFieldOptions | undefined {\n  if (!options) return options;\n  if (options.maxSize === undefined) return options;\n\n  return {\n    ...options,\n    maxSize: parseByteSizeToBytes(options.maxSize, context, {\n      bytes: MAX_JSON_SIZE_BYTES,\n      label: \"2^53-1\",\n    }),\n  };\n}\n\n// ============================================================================\n// Field Helper Functions\n// ============================================================================\n\n/**\n * Creates a boolean field schema\n * Maps to PocketBase 'bool' field type\n *\n * @returns Zod boolean schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n *   active: BoolField(),\n *   featured: BoolField().optional(),\n * });\n */\nexport function BoolField(): z.ZodBoolean {\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"bool\" as const,\n    },\n  };\n\n  return z.boolean().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a number field schema with optional constraints\n * Maps to PocketBase 'number' field type\n *\n * @param options - Optional constraints for the number field\n * @returns Zod number schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n *   price: NumberField({ min: 0 }),\n *   quantity: NumberField({ min: 0, noDecimal: true }),\n *   rating: NumberField({ min: 0, max: 5 }),\n *   progress: NumberField({ min: 0, max: 100 }), // required defaults to false, allowing zero\n *   score: NumberField({ min: 1, max: 10, required: true }), // requires non-zero value\n * });\n *\n * @remarks\n * By default, number fields are not required (`required: false`), which allows zero values.\n * In PocketBase, `required: true` for number fields means the value must be non-zero.\n * If you set `min: 0` and want to allow zero, keep `required: false` (the default).\n */\nexport function NumberField(options?: NumberFieldOptions): z.ZodNumber {\n  // Validate options\n  if (options?.min !== undefined && options?.max !== undefined) {\n    if (options.min > options.max) {\n      throw new Error(\"NumberField: min cannot be greater than max\");\n    }\n  }\n\n  // Create base schema\n  let schema = z.number();\n\n  // Apply Zod validations\n  if (options?.min !== undefined) {\n    schema = schema.min(options.min);\n  }\n  if (options?.max !== undefined) {\n    schema = schema.max(options.max);\n  }\n\n  // Build metadata\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"number\" as const,\n      options: options || {},\n    },\n  };\n\n  return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a text field schema with optional constraints\n * Maps to PocketBase 'text' field type\n *\n * @param options - Optional constraints for the text field\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n *   name: TextField({ min: 1, max: 200 }),\n *   sku: TextField({ autogeneratePattern: \"[A-Z]{3}-[0-9]{6}\" }),\n *   description: TextField({ max: 1000 }),\n * });\n */\nexport function TextField(options?: TextFieldOptions): z.ZodString {\n  // Validate options\n  if (options?.min !== undefined && options?.max !== undefined) {\n    if (options.min > options.max) {\n      throw new Error(\"TextField: min cannot be greater than max\");\n    }\n  }\n\n  // Create base schema\n  let schema = z.string();\n\n  // Apply Zod validations\n  if (options?.min !== undefined) {\n    schema = schema.min(options.min);\n  }\n  if (options?.max !== undefined) {\n    schema = schema.max(options.max);\n  }\n  if (options?.pattern !== undefined) {\n    const pattern = options.pattern instanceof RegExp ? options.pattern : new RegExp(options.pattern);\n    schema = schema.regex(pattern);\n  }\n\n  // Build metadata\n  //\n  // The metadata travels as JSON in the description, and `JSON.stringify` turns\n  // a RegExp into `{}` — the pattern would be silently lost between here and\n  // the analyzer. PocketBase stores the pattern as a string anyway, so a RegExp\n  // is recorded as its source.\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"text\" as const,\n      options: options\n        ? { ...options, ...(options.pattern instanceof RegExp ? { pattern: options.pattern.source } : {}) }\n        : {},\n    },\n  };\n\n  return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an email field schema\n * Maps to PocketBase 'email' field type\n *\n * @returns Zod string schema with email validation and PocketBase metadata\n *\n * @example\n * const UserSchema = z.object({\n *   email: EmailField(),\n *   alternateEmail: EmailField().optional(),\n * });\n */\nexport function EmailField(): z.ZodString {\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"email\" as const,\n    },\n  };\n\n  return z.string().email().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a URL field schema\n * Maps to PocketBase 'url' field type\n *\n * @returns Zod string schema with URL validation and PocketBase metadata\n *\n * @example\n * const ProductSchema = z.object({\n *   website: URLField(),\n *   documentation: URLField().optional(),\n * });\n */\nexport function URLField(): z.ZodString {\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"url\" as const,\n    },\n  };\n\n  return z.string().url().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a rich text editor field schema\n * Maps to PocketBase 'editor' field type\n *\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n *   content: EditorField(),\n *   summary: EditorField().optional(),\n * });\n */\nexport function EditorField(): z.ZodString {\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"editor\" as const,\n    },\n  };\n\n  return z.string().describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a date field schema with optional constraints\n * Maps to PocketBase 'date' field type\n *\n * @param options - Optional date constraints\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const EventSchema = z.object({\n *   startDate: DateField(),\n *   endDate: DateField({ min: new Date('2024-01-01') }),\n *   releaseDate: DateField().optional(),\n * });\n */\nexport function DateField(options?: DateFieldOptions): z.ZodString {\n  // Validate options\n  if (options?.min !== undefined && options?.max !== undefined) {\n    const minDate = typeof options.min === \"string\" ? new Date(options.min) : options.min;\n    const maxDate = typeof options.max === \"string\" ? new Date(options.max) : options.max;\n    if (minDate > maxDate) {\n      throw new Error(\"DateField: min cannot be greater than max\");\n    }\n  }\n\n  // Create base schema\n  const schema = z.string();\n\n  // Build metadata\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"date\" as const,\n      options: options || {},\n    },\n  };\n\n  return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates an autodate field schema with automatic timestamp management\n * Maps to PocketBase 'autodate' field type\n *\n * @param options - Optional autodate configuration\n * @returns Zod string schema with PocketBase metadata\n *\n * @example\n * const PostSchema = z.object({\n *   createdAt: AutodateField({ onCreate: true }),\n *   updatedAt: AutodateField({ onUpdate: true }),\n *   publishedAt: AutodateField({ onCreate: true, onUpdate: false }),\n * });\n */\nexport function AutodateField(options?: AutodateFieldOptions): z.ZodString {\n  const schema = z.string();\n\n  // Build metadata\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"autodate\" as const,\n      options: options || {},\n    },\n  };\n\n  return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a select field schema from enum values\n * Maps to PocketBase 'select' field type\n *\n * A `maxSelect` of 1 (or no options) produces a single-select enum schema;\n * `maxSelect` greater than 1 produces a multi-select array schema.\n *\n * Pass `maxSelect` as a literal so the overloads can pick the right return\n * type — a widened `number` variable resolves to the array overload even when\n * its runtime value is 1.\n *\n * @param values - Array of allowed string values\n * @param options - Optional select configuration\n * @returns Zod enum schema (single select) or array schema (multiple select) with PocketBase metadata\n *\n * @example\n * // Single select\n * const PostSchema = z.object({\n *   status: SelectField([\"draft\", \"published\", \"archived\"]),\n * });\n *\n * @example\n * // Multiple select\n * const ProductSchema = z.object({\n *   categories: SelectField([\"electronics\", \"clothing\", \"food\"], { maxSelect: 3 }),\n * });\n */\nexport function SelectField<const T extends readonly [string, ...string[]]>(\n  values: T,\n  options?: { maxSelect?: 1 }\n): EnumFromArray<T>;\nexport function SelectField<const T extends readonly [string, ...string[]]>(\n  values: T,\n  options: { maxSelect: number }\n): z.ZodArray<EnumFromArray<T>>;\nexport function SelectField<const T extends readonly [string, ...string[]]>(\n  values: T,\n  options?: SelectFieldOptions\n): EnumFromArray<T> | z.ZodArray<EnumFromArray<T>> {\n  const maxSelect = options?.maxSelect ?? 1;\n\n  if (maxSelect < 1) {\n    throw new Error(\"SelectField: maxSelect must be >= 1\");\n  }\n\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"select\" as const,\n      options: {\n        values,\n        maxSelect,\n      },\n    },\n  };\n\n  if (maxSelect > 1) {\n    return z.array(z.enum(values)).describe(JSON.stringify(metadata)) as z.ZodArray<EnumFromArray<T>>;\n  }\n\n  return z.enum(values).describe(JSON.stringify(metadata)) as EnumFromArray<T>;\n}\n\n/**\n * Creates a single file field schema\n * Maps to PocketBase 'file' field type with maxSelect=1\n *\n * @param options - Optional file constraints\n * @returns Zod schema that accepts File on input and returns string when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n *   thumbnail: FileField({ mimeTypes: [\"image/*\"], maxSize: 5242880 }),\n *   document: FileField({ mimeTypes: [\"application/pdf\"] }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File objects\n * - When reading from PocketBase: returns string (filename)\n */\nexport function FileField(options?: FileFieldOptions): z.ZodType<string, File | string> {\n  // Accept File for input (when creating/updating) or string (when reading from DB)\n  // Output is always string (as returned by PocketBase)\n  const schema = z.preprocess((val) => {\n    // If it's a File, return its name (or empty string if no name)\n    // If it's already a string (from DB), return as-is\n    return val instanceof File ? val.name || \"\" : val;\n  }, z.string()) as z.ZodType<string, File | string>;\n\n  const normalizedOptions = normalizeFileFieldOptions(options, \"FileField\");\n\n  // Build metadata\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"file\" as const,\n      options: normalizedOptions || {},\n    },\n  };\n\n  return schema.describe(JSON.stringify(metadata));\n}\n\n/**\n * Creates a multiple files field schema\n * Maps to PocketBase 'file' field type with maxSelect>1\n *\n * @param options - Optional file constraints\n * @returns Zod array schema that accepts File[] on input and returns string[] when reading from database\n *\n * @example\n * const ProductSchema = z.object({\n *   images: FilesField({ mimeTypes: [\"image/*\"], maxSelect: 5 }),\n *   attachments: FilesField({ minSelect: 1, maxSelect: 10 }),\n * });\n *\n * @remarks\n * - When creating/updating records: accepts File[]\n * - When reading from PocketBase: returns string[] (filenames)\n */\nexport function FilesField(options?: FilesFieldOptions): z.ZodType<string[], (File | string)[]> {\n  // Validate options\n  if (options?.minSelect !== undefined && options?.maxSelect !== undefined) {\n    if (options.minSelect > options.maxSelect) {\n      throw new Error(\"FilesField: minSelect cannot be greater than maxSelect\");\n    }\n  }\n\n  // Accept File[] for input (when creating/updating) or string[] (when reading from DB)\n  // Output is always string[] (as returned by PocketBase)\n  let baseArraySchema = z.array(z.string());\n\n  // Apply Zod validations first\n  if (options?.minSelect !== undefined) {\n    baseArraySchema = baseArraySchema.min(options.minSelect);\n  }\n  if (options?.maxSelect !== undefined) {\n    baseArraySchema = baseArraySchema.max(options.maxSelect);\n  }\n\n  const schema = z.preprocess((val) => {\n    // Handle array of Files or strings\n    if (Array.isArray(val)) {\n      return val.map((item) => (item instanceof File ? item.name || \"\" : item));\n    }\n    return val;\n  }, baseArraySchema);\n\n  const normalizedOptions = normalizeFileFieldOptions(options, \"FilesField\");\n\n  // Build metadata\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"file\" as const,\n      options: normalizedOptions || {},\n    },\n  };\n\n  return schema.describe(JSON.stringify(metadata)) as z.ZodType<string[], (File | string)[]>;\n}\n\n/**\n * Distinguishes `JSONField(schema)` from `JSONField(options)`.\n *\n * Both arguments are plain objects at runtime, so the Zod schema is identified\n * by its parse surface rather than by shape.\n */\nfunction isZodSchema(value: unknown): value is z.ZodTypeAny {\n  if (value instanceof z.ZodType) {\n    return true;\n  }\n\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    typeof (value as { parse?: unknown }).parse === \"function\" &&\n    typeof (value as { safeParse?: unknown }).safeParse === \"function\"\n  );\n}\n\n/**\n * Creates a JSON field schema with optional inner schema validation\n * Maps to PocketBase 'json' field type\n *\n * @param schema - Optional Zod schema for the JSON structure\n * @param options - Optional PocketBase constraints (`maxSize`)\n * @returns Zod schema with PocketBase metadata\n *\n * @example\n * // Any JSON\n * const ProductSchema = z.object({\n *   metadata: JSONField(),\n * });\n *\n * @example\n * // Typed JSON\n * const ProductSchema = z.object({\n *   settings: JSONField(z.object({\n *     theme: z.string(),\n *     notifications: z.boolean(),\n *   })),\n * });\n *\n * @example\n * // A payload larger than PocketBase's 1MB default needs its own limit\n * const TimelineSchema = z.object({\n *   timelineData: JSONField({ maxSize: \"5M\" }),\n *   outputSettings: JSONField(z.object({ fps: z.number() }), { maxSize: \"200K\" }),\n * });\n */\nexport function JSONField(options?: JSONFieldOptions): z.ZodRecord<z.ZodString, z.ZodAny>;\nexport function JSONField(schema: undefined, options?: JSONFieldOptions): z.ZodRecord<z.ZodString, z.ZodAny>;\nexport function JSONField<T extends z.ZodTypeAny>(schema: T, options?: JSONFieldOptions): T;\nexport function JSONField<T extends z.ZodTypeAny>(\n  schemaOrOptions?: T | JSONFieldOptions,\n  maybeOptions?: JSONFieldOptions\n): T | z.ZodRecord<z.ZodString, z.ZodAny> {\n  const schema = isZodSchema(schemaOrOptions) ? schemaOrOptions : undefined;\n  // A caller passing the schema conditionally (`JSONField(shape ?? undefined,\n  // { maxSize })`) leaves the options in the second slot, so both are read —\n  // otherwise the size cap would be dropped without a word\n  const options = schema ? maybeOptions : ((schemaOrOptions as JSONFieldOptions | undefined) ?? maybeOptions);\n\n  const baseSchema = schema ?? z.record(z.string(), z.any());\n  const normalizedOptions = normalizeJSONFieldOptions(options, \"JSONField\");\n\n  // Build metadata — `options` is omitted when the field carries no constraint,\n  // so an unconstrained JSONField serializes exactly as it always has\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"json\" as const,\n      ...(normalizedOptions && Object.keys(normalizedOptions).length > 0 ? { options: normalizedOptions } : {}),\n    },\n  };\n\n  return baseSchema.describe(JSON.stringify(metadata)) as T | z.ZodRecord<z.ZodString, z.ZodAny>;\n}\n\n/**\n * Creates a geographic point field schema\n * Maps to PocketBase 'geoPoint' field type\n *\n * @returns Zod object schema with lon/lat fields and PocketBase metadata\n *\n * @example\n * const LocationSchema = z.object({\n *   coordinates: GeoPointField(),\n *   homeLocation: GeoPointField().optional(),\n * });\n */\nexport function GeoPointField(): z.ZodObject<{\n  lon: z.ZodNumber;\n  lat: z.ZodNumber;\n}> {\n  const schema = z.object({\n    lon: z.number(),\n    lat: z.number(),\n  });\n\n  // Build metadata\n  const metadata = {\n    [FIELD_METADATA_KEY]: {\n      type: \"geoPoint\" as const,\n    },\n  };\n\n  return schema.describe(JSON.stringify(metadata));\n}\n","import { z } from \"zod\";\nimport type { RuleExpression } from \"../utils/permissions\";\nimport { defineCollection } from \"./base\";\n\n/**\n * Permission rules that apply to a view collection\n *\n * View collections are read-only: PocketBase rejects createRule, updateRule,\n * deleteRule and manageRule on them, so only the two read rules are accepted.\n */\nexport interface ViewPermissionSchema {\n  /** Controls who can list/query the view's rows */\n  listRule?: RuleExpression;\n\n  /** Controls who can view an individual row */\n  viewRule?: RuleExpression;\n}\n\n/**\n * Configuration options for defining a view collection\n */\nexport interface ViewCollectionConfig {\n  /**\n   * The name of the PocketBase collection\n   */\n  collectionName: string;\n\n  /**\n   * The Zod schema describing the shape of a row\n   *\n   * For views this is used for TypeScript type generation and application-side\n   * parsing only - PocketBase derives the collection's actual fields from the\n   * SQL query when the collection is saved.\n   */\n  schema: z.ZodObject<any>;\n\n  /**\n   * The SQL SELECT statement backing the view\n   *\n   * Use the `sql` tagged template for consistent formatting.\n   */\n  viewQuery: string;\n\n  /**\n   * Optional read permissions (listRule / viewRule)\n   */\n  permissions?: ViewPermissionSchema;\n}\n\n/**\n * Removes the common leading indentation from a multi-line string and trims\n * blank leading/trailing lines\n *\n * Keeps generated migrations stable when a query is re-indented in the source\n * file, since only the relative indentation is preserved. Also used when\n * reading a query back out of a migration file, where the generator has\n * indented it to fit the surrounding code.\n *\n * @param value - Raw multi-line string\n * @returns Dedented string\n */\nexport function dedentSql(value: string): string {\n  const lines = value.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n\n  // Drop leading and trailing blank lines\n  while (lines.length > 0 && lines[0].trim() === \"\") {\n    lines.shift();\n  }\n  while (lines.length > 0 && lines[lines.length - 1].trim() === \"\") {\n    lines.pop();\n  }\n\n  if (lines.length === 0) {\n    return \"\";\n  }\n\n  // Find the smallest indentation across all non-blank lines\n  let minIndent = Infinity;\n  for (const line of lines) {\n    if (line.trim() === \"\") continue;\n    const indent = line.length - line.trimStart().length;\n    if (indent < minIndent) {\n      minIndent = indent;\n    }\n  }\n\n  if (!Number.isFinite(minIndent) || minIndent === 0) {\n    return lines.map((line) => line.trimEnd()).join(\"\\n\");\n  }\n\n  return lines.map((line) => line.slice(minIndent).trimEnd()).join(\"\\n\");\n}\n\n/**\n * Tagged template for SQL view queries\n *\n * Interpolates values, strips the common leading indentation and trims blank\n * leading/trailing lines. Returns a plain string, so a regular string literal\n * works anywhere `sql` does.\n *\n * @example\n * const query = sql`\n *   SELECT p.id AS id, p.title AS title\n *     FROM Projects p\n * `;\n * // \"SELECT p.id AS id, p.title AS title\\n  FROM Projects p\"\n */\nexport function sql(strings: TemplateStringsArray, ...values: Array<string | number>): string {\n  let result = \"\";\n\n  for (let i = 0; i < strings.length; i++) {\n    result += strings[i];\n    if (i < values.length) {\n      result += String(values[i]);\n    }\n  }\n\n  return dedentSql(result);\n}\n\n/**\n * Strips SQL comments and leading whitespace so the first real token can be checked\n *\n * @param query - The SQL query\n * @returns The query with leading comments and whitespace removed\n */\nfunction stripLeadingComments(query: string): string {\n  let remaining = query.trim();\n\n  // Repeatedly strip line comments (-- ...) and block comments (/* ... */)\n  while (remaining.length > 0) {\n    if (remaining.startsWith(\"--\")) {\n      const newline = remaining.indexOf(\"\\n\");\n      remaining = newline === -1 ? \"\" : remaining.slice(newline + 1).trim();\n      continue;\n    }\n\n    if (remaining.startsWith(\"/*\")) {\n      const end = remaining.indexOf(\"*/\");\n      remaining = end === -1 ? \"\" : remaining.slice(end + 2).trim();\n      continue;\n    }\n\n    break;\n  }\n\n  return remaining;\n}\n\n/**\n * Validates a view query, throwing with an actionable message when it can't work\n *\n * @param collectionName - Collection name, used in error messages\n * @param viewQuery - The SQL query to validate\n */\nexport function validateViewQuery(collectionName: string, viewQuery: unknown): asserts viewQuery is string {\n  if (typeof viewQuery !== \"string\" || viewQuery.trim() === \"\") {\n    throw new Error(\n      `View collection \"${collectionName}\" requires a non-empty viewQuery. ` +\n        `Provide the SQL SELECT statement backing the view.`\n    );\n  }\n\n  const body = stripLeadingComments(viewQuery);\n  if (!/^(select|with)\\b/i.test(body)) {\n    throw new Error(\n      `View collection \"${collectionName}\" has an invalid viewQuery: it must start with SELECT or WITH. ` +\n        `Received: ${body.slice(0, 40)}${body.length > 40 ? \"...\" : \"\"}`\n    );\n  }\n}\n\n/**\n * Defines a read-only PocketBase view collection backed by a SQL query\n *\n * PocketBase derives the collection's fields by running the query, so the Zod\n * schema only describes the shape for TypeScript types and application-side\n * parsing. Views cannot have indexes and only support listRule / viewRule.\n *\n * The generated migration creates the collection with `type: \"view\"` and the\n * query; changing the SQL later produces an in-place `viewQuery` update, which\n * keeps the collection id stable.\n *\n * @param config - View collection configuration\n * @returns The schema with view metadata attached\n *\n * @example\n * export default defineView({\n *   collectionName: \"ProjectStats\",\n *   schema: ProjectStatsSchema,\n *   viewQuery: sql`\n *     SELECT p.OwnerUser AS id,\n *            p.OwnerUser AS OwnerUser,\n *            COUNT(*)    AS projectCount\n *       FROM Projects p\n *      GROUP BY p.OwnerUser\n *   `,\n *   permissions: {\n *     listRule: \"OwnerUser = @request.auth.id\",\n *     viewRule: \"OwnerUser = @request.auth.id\",\n *   },\n * });\n *\n * @example\n * // Requirements PocketBase places on the query:\n * // - the outermost SELECT must expose an `id` column\n * // - a relation column must be selected bare (e.g. `p.OwnerUser AS OwnerUser`)\n * //   from the outer table for PocketBase to infer it as a relation field\n * // - no top-level UNION (wrap unions in a subquery)\n */\nexport function defineView(config: ViewCollectionConfig): z.ZodObject<any> {\n  const { collectionName, schema, viewQuery, permissions } = config;\n\n  validateViewQuery(collectionName, viewQuery);\n\n  return defineCollection({\n    collectionName,\n    schema,\n    type: \"view\",\n    viewQuery,\n    // Write rules are always locked for views - PocketBase rejects anything else\n    permissions: {\n      listRule: permissions?.listRule ?? null,\n      viewRule: permissions?.viewRule ?? null,\n      createRule: null,\n      updateRule: null,\n      deleteRule: null,\n    },\n  });\n}\n","import type { PermissionSchema, PermissionTemplateConfig } from \"../utils/permissions\";\n\n/**\n * Predefined permission templates for common access control patterns\n */\nexport const PermissionTemplates = {\n  /**\n   * Public access - anyone can perform all operations\n   */\n  public: (): PermissionSchema => ({\n    listRule: \"\",\n    viewRule: \"\",\n    createRule: \"\",\n    updateRule: \"\",\n    deleteRule: \"\",\n  }),\n\n  /**\n   * Authenticated users only - requires valid authentication for all operations\n   */\n  authenticated: (): PermissionSchema => ({\n    listRule: '@request.auth.id != \"\"',\n    viewRule: '@request.auth.id != \"\"',\n    createRule: '@request.auth.id != \"\"',\n    updateRule: '@request.auth.id != \"\"',\n    deleteRule: '@request.auth.id != \"\"',\n  }),\n\n  /**\n   * Owner-only access - users can only manage their own records\n   * @param ownerField - Name of the relation field pointing to user (default: 'User')\n   */\n  ownerOnly: (ownerField: string = \"User\"): PermissionSchema => ({\n    listRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n    viewRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n    createRule: '@request.auth.id != \"\"',\n    updateRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n    deleteRule: `@request.auth.id != \"\" && ${ownerField} = @request.auth.id`,\n  }),\n\n  /**\n   * Admin/superuser only access\n   * Assumes a 'role' field exists with 'admin' value\n   * @param roleField - Name of the role field (default: 'role')\n   */\n  adminOnly: (roleField: string = \"role\"): PermissionSchema => ({\n    listRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n    viewRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n    createRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n    updateRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n    deleteRule: `@request.auth.id != \"\" && @request.auth.${roleField} = \"admin\"`,\n  }),\n\n  /**\n   * Public read, authenticated write\n   * Anyone can list/view, but only authenticated users can create/update/delete\n   */\n  readPublic: (): PermissionSchema => ({\n    listRule: \"\",\n    viewRule: \"\",\n    createRule: '@request.auth.id != \"\"',\n    updateRule: '@request.auth.id != \"\"',\n    deleteRule: '@request.auth.id != \"\"',\n  }),\n\n  /**\n   * Locked access - only superusers can perform operations\n   * All rules are set to null (locked)\n   */\n  locked: (): PermissionSchema => ({\n    listRule: null,\n    viewRule: null,\n    createRule: null,\n    updateRule: null,\n    deleteRule: null,\n  }),\n\n  /**\n   * Read-only authenticated - authenticated users can read, no write access\n   */\n  readOnlyAuthenticated: (): PermissionSchema => ({\n    listRule: '@request.auth.id != \"\"',\n    viewRule: '@request.auth.id != \"\"',\n    createRule: null,\n    updateRule: null,\n    deleteRule: null,\n  }),\n};\n\n/**\n * Resolve template configuration to concrete permission schema\n * @param config - Template configuration or direct permission schema\n * @returns Resolved permission schema with all rules defined\n */\nexport function resolveTemplate(config: PermissionTemplateConfig): PermissionSchema {\n  let baseRules: PermissionSchema;\n\n  switch (config.template) {\n    case \"public\":\n      baseRules = PermissionTemplates.public();\n      break;\n    case \"authenticated\":\n      baseRules = PermissionTemplates.authenticated();\n      break;\n    case \"owner-only\":\n      baseRules = PermissionTemplates.ownerOnly(config.ownerField);\n      break;\n    case \"admin-only\":\n      baseRules = PermissionTemplates.adminOnly(config.roleField);\n      break;\n    case \"read-public\":\n      baseRules = PermissionTemplates.readPublic();\n      break;\n    case \"custom\":\n      baseRules = {};\n      break;\n    default: {\n      // Exhaustive check - TypeScript will error if we miss a template type\n      const _exhaustive: never = config.template;\n      throw new Error(`Unknown template type: ${_exhaustive}`);\n    }\n  }\n\n  // Merge with custom rules if provided (custom rules override template rules)\n  return {\n    ...baseRules,\n    ...config.customRules,\n  };\n}\n\n"]}