@fayz-ai/core 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/access/index.js.map +1 -1
- package/dist/chunk-BEGXYHS4.js +566 -0
- package/dist/chunk-BEGXYHS4.js.map +1 -0
- package/dist/chunk-ED6NBH6U.js +348 -0
- package/dist/chunk-ED6NBH6U.js.map +1 -0
- package/dist/chunk-EWKX4VUM.js +429 -0
- package/dist/chunk-EWKX4VUM.js.map +1 -0
- package/dist/chunk-LARZWDHA.js +319 -0
- package/dist/chunk-LARZWDHA.js.map +1 -0
- package/dist/chunk-OXQGRJZT.js +125 -0
- package/dist/chunk-OXQGRJZT.js.map +1 -0
- package/dist/chunk-RRYFXUQX.js +1247 -0
- package/dist/chunk-RRYFXUQX.js.map +1 -0
- package/dist/{chunk-5RJVUC6J.js → chunk-TDI6F6PT.js} +373 -25
- package/dist/chunk-TDI6F6PT.js.map +1 -0
- package/dist/{chunk-V2MSAUHO.js → chunk-UVKH6RDX.js} +211 -335
- package/dist/chunk-UVKH6RDX.js.map +1 -0
- package/dist/chunk-V53GR4UT.js +289 -0
- package/dist/chunk-V53GR4UT.js.map +1 -0
- package/dist/connector-runtime/index.d.ts +15 -0
- package/dist/connector-runtime/index.d.ts.map +1 -0
- package/dist/connector-runtime/index.js +3 -0
- package/dist/connector-runtime/index.js.map +1 -0
- package/dist/data/archetype.d.ts.map +1 -1
- package/dist/data/backend-env.d.ts +38 -0
- package/dist/data/backend-env.d.ts.map +1 -0
- package/dist/data/bulk.d.ts +24 -0
- package/dist/data/bulk.d.ts.map +1 -1
- package/dist/data/cached.d.ts.map +1 -1
- package/dist/data/custom-fields.d.ts +5 -0
- package/dist/data/custom-fields.d.ts.map +1 -0
- package/dist/data/index.d.ts +2 -1
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +3 -1
- package/dist/data/mock.d.ts.map +1 -1
- package/dist/data/platform-api.d.ts.map +1 -1
- package/dist/data/resolve.d.ts.map +1 -1
- package/dist/data/supabase.d.ts.map +1 -1
- package/dist/data/types.d.ts +8 -0
- package/dist/data/types.d.ts.map +1 -1
- package/dist/entity/events.d.ts +14 -0
- package/dist/entity/events.d.ts.map +1 -0
- package/dist/events/envelope.d.ts +31 -0
- package/dist/events/envelope.d.ts.map +1 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/log.d.ts +44 -0
- package/dist/events/log.d.ts.map +1 -0
- package/dist/events/types.d.ts +40 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/fields/store.d.ts +45 -0
- package/dist/fields/store.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +10 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/shell-translations.en.d.ts.map +1 -1
- package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
- package/dist/index.d.ts +45 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +543 -56
- package/dist/index.js.map +1 -1
- package/dist/integrations/events.d.ts +7 -0
- package/dist/integrations/events.d.ts.map +1 -0
- package/dist/integrations/index.d.ts +533 -29
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +3 -1
- package/dist/integrations/permissions.d.ts +132 -0
- package/dist/integrations/permissions.d.ts.map +1 -0
- package/dist/integrations/request.d.ts +170 -0
- package/dist/integrations/request.d.ts.map +1 -0
- package/dist/integrations/runtime-token.d.ts +33 -0
- package/dist/integrations/runtime-token.d.ts.map +1 -0
- package/dist/integrations/runtime.d.ts +398 -0
- package/dist/integrations/runtime.d.ts.map +1 -0
- package/dist/integrations/settings.d.ts +102 -0
- package/dist/integrations/settings.d.ts.map +1 -0
- package/dist/integrations/store.d.ts +145 -0
- package/dist/integrations/store.d.ts.map +1 -0
- package/dist/{address/index.d.ts → lib/address.d.ts} +1 -1
- package/dist/{address/index.d.ts.map → lib/address.d.ts.map} +1 -1
- package/dist/{phone/index.d.ts → lib/phone.d.ts} +1 -1
- package/dist/lib/phone.d.ts.map +1 -0
- package/dist/{seo/index.d.ts → lib/seo.d.ts} +18 -1
- package/dist/lib/seo.d.ts.map +1 -0
- package/dist/{tenant/index.d.ts → lib/tenant.d.ts} +1 -1
- package/dist/lib/tenant.d.ts.map +1 -0
- package/dist/manifest/index.d.ts +1 -1
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/messaging/index.d.ts +3 -0
- package/dist/messaging/index.d.ts.map +1 -0
- package/dist/messaging/registry.d.ts +35 -0
- package/dist/messaging/registry.d.ts.map +1 -0
- package/dist/messaging/types.d.ts +67 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/plugin/index.js +3 -1
- package/dist/plugin/runtime.d.ts +17 -0
- package/dist/plugin/runtime.d.ts.map +1 -1
- package/dist/registry/block-catalog.d.ts +78 -0
- package/dist/registry/block-catalog.d.ts.map +1 -0
- package/dist/registry/block-constraints.d.ts +64 -0
- package/dist/registry/block-constraints.d.ts.map +1 -0
- package/dist/registry/block-schema.d.ts +69 -0
- package/dist/registry/block-schema.d.ts.map +1 -0
- package/dist/registry/blocks.d.ts +84 -0
- package/dist/registry/blocks.d.ts.map +1 -0
- package/dist/registry/entities.d.ts +179 -0
- package/dist/registry/entities.d.ts.map +1 -0
- package/dist/registry/extension-points.d.ts +117 -0
- package/dist/registry/extension-points.d.ts.map +1 -0
- package/dist/registry/handles.d.ts +41 -0
- package/dist/registry/handles.d.ts.map +1 -0
- package/dist/registry/index.d.ts +41 -41
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/loaders.d.ts +55 -0
- package/dist/registry/loaders.d.ts.map +1 -0
- package/dist/registry/registry-class.d.ts +157 -0
- package/dist/registry/registry-class.d.ts.map +1 -0
- package/dist/registry/schema-check.d.ts +14 -0
- package/dist/registry/schema-check.d.ts.map +1 -0
- package/dist/router/index.d.ts +78 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +1 -1
- package/dist/{shell-translations.pt-br-2GWRQRRP.js → shell-translations.pt-br-BM5ZFSKJ.js} +72 -3
- package/dist/shell-translations.pt-br-BM5ZFSKJ.js.map +1 -0
- package/dist/telemetry/errors.d.ts +87 -0
- package/dist/telemetry/errors.d.ts.map +1 -0
- package/dist/testing/index.js +4 -1
- package/dist/{testing/index.d.ts → testing.d.ts} +5 -3
- package/dist/testing.d.ts.map +1 -0
- package/dist/types/analytics.d.ts +213 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/crud.d.ts +37 -3
- package/dist/types/crud.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +138 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +9 -17
- package/dist/blocks/index.d.ts +0 -25
- package/dist/blocks/index.d.ts.map +0 -1
- package/dist/chunk-5RJVUC6J.js.map +0 -1
- package/dist/chunk-L4TLMYGC.js +0 -42
- package/dist/chunk-L4TLMYGC.js.map +0 -1
- package/dist/chunk-V2MSAUHO.js.map +0 -1
- package/dist/chunk-X5THHG6T.js +0 -77
- package/dist/chunk-X5THHG6T.js.map +0 -1
- package/dist/chunk-Y2C2FBQP.js +0 -35
- package/dist/chunk-Y2C2FBQP.js.map +0 -1
- package/dist/chunk-YH25Y4FW.js +0 -311
- package/dist/chunk-YH25Y4FW.js.map +0 -1
- package/dist/phone/index.d.ts.map +0 -1
- package/dist/seo/index.d.ts.map +0 -1
- package/dist/shell-translations.pt-br-2GWRQRRP.js.map +0 -1
- package/dist/tenant/index.d.ts.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/src/access/denial.ts +0 -33
- package/src/access/engine.test.ts +0 -48
- package/src/access/engine.ts +0 -136
- package/src/access/index.ts +0 -14
- package/src/access/limits.ts +0 -18
- package/src/address/index.ts +0 -188
- package/src/app/render.tsx +0 -69
- package/src/blocks/index.tsx +0 -68
- package/src/data/archetype.ts +0 -255
- package/src/data/bulk.ts +0 -35
- package/src/data/cached.ts +0 -55
- package/src/data/count.test.ts +0 -152
- package/src/data/count.ts +0 -131
- package/src/data/filters.test.ts +0 -70
- package/src/data/filters.ts +0 -90
- package/src/data/index.ts +0 -11
- package/src/data/mock.ts +0 -90
- package/src/data/platform-api.ts +0 -209
- package/src/data/refresh.ts +0 -115
- package/src/data/resolve.ts +0 -126
- package/src/data/supabase.ts +0 -230
- package/src/data/types.ts +0 -50
- package/src/entity/index.ts +0 -2
- package/src/entity/registry.ts +0 -49
- package/src/events/index.tsx +0 -82
- package/src/i18n/index.ts +0 -476
- package/src/i18n/shell-translations.en.ts +0 -875
- package/src/i18n/shell-translations.pt-br.ts +0 -873
- package/src/index.ts +0 -217
- package/src/integrations/index.ts +0 -237
- package/src/lib/cache.ts +0 -118
- package/src/lib/csv.ts +0 -54
- package/src/lib/format.ts +0 -58
- package/src/manifest/app-manifest.schema.json +0 -676
- package/src/manifest/index.ts +0 -518
- package/src/manifest/serialize.ts +0 -52
- package/src/phone/index.ts +0 -85
- package/src/plugin/createSafeDataProvider.ts +0 -30
- package/src/plugin/index.ts +0 -1
- package/src/plugin/runtime.ts +0 -331
- package/src/registry/index.ts +0 -163
- package/src/router/history.ts +0 -86
- package/src/router/index.ts +0 -29
- package/src/runtime/index.ts +0 -15
- package/src/runtime/oauth.ts +0 -219
- package/src/search/engine.ts +0 -559
- package/src/search/index.ts +0 -25
- package/src/search/text.ts +0 -206
- package/src/search/types.ts +0 -75
- package/src/seo/index.ts +0 -128
- package/src/tenant/index.ts +0 -38
- package/src/testing/index.ts +0 -116
- package/src/types/auth.ts +0 -41
- package/src/types/billing.ts +0 -39
- package/src/types/crud.ts +0 -184
- package/src/types/entities.ts +0 -142
- package/src/types/entitlements.ts +0 -45
- package/src/types/i18n.ts +0 -7
- package/src/types/index.ts +0 -11
- package/src/types/org.ts +0 -137
- package/src/types/payment.ts +0 -44
- package/src/types/permissions.ts +0 -32
- package/src/types/plugins.ts +0 -480
- package/src/types/theme.ts +0 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/registry/registry-class.ts","../src/registry/entities.ts"],"names":[],"mappings":";AAsKO,IAAM,WAAN,MAAkB;AAAA,EAGvB,YAAqB,IAAA,EAAc;AAAd,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAFrB,IAAA,IAAA,CAAiB,OAAA,uBAAc,GAAA,EAA8B;AAAA,EAEzB;AAAA,EAEpC,QAAA,CAAS,EAAA,EAAY,KAAA,EAAU,IAAA,GAAqB,EAAC,EAAS;AAG5D,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,KAAA;AACjC,IAAA,IAAA,CAAK,QAAQ,GAAA,CAAI,EAAA,EAAI,EAAE,EAAA,EAAI,OAAO,IAAA,EAAM,KAAA,KAAU,MAAA,GAAY,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,OAAO,KAAA,EAAO,KAAA,IAAS,CAAA;AAAA,EACzG;AAAA,EAEA,IAAI,EAAA,EAA2B;AAC7B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG,KAAA;AAAA,EAC/B;AAAA,EAEA,SAAS,EAAA,EAA0C;AACjD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,EAAA,EAAqB;AACvB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAA,GAA2B;AACzB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA;AAAA,EACzC;AAAA,EAEA,GAAA,GAAgB;AACd,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAA,GAAsC;AACpC,IAAA,OAAO,IAAA,CAAK,MAAK,CACd,GAAA,CAAI,CAAC,EAAE,EAAA,EAAI,MAAK,MAAO;AAAA,MACtB,EAAA;AAAA,MACA,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,KAAA;AAAA,MAC1B,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,QAAQ,IAAA,CAAK,WAAA;AAAA,MACb,SAAA,EAAW,KAAK,SAAA,IAAa,QAAA;AAAA,MAC7B,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,UAAU,IAAA,CAAK;AAAA,KACjB,CAAE,CAAA,CACD,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,EAC5C;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AACF;AAGO,SAAS,WAAW,EAAA,EAAqB;AAC9C,EAAA,OAAO,EAAA,CAAG,WAAW,SAAS,CAAA;AAChC;;;ACnLO,IAAM,kBAAA,GAAqB;AAAA,EAChC,MAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF;AA2FO,IAAM,oBAAA,GAAuB;AAGpC,IAAM,aAAA,GAAgB,mBAAA;AACtB,IAAM,aAAA,GAAgB,mBAAA;AAGf,IAAM,yBAAyB,CAAC,IAAA,EAAM,QAAQ,QAAA,EAAU,WAAA,EAAa,cAAc,YAAY;AAE/F,IAAM,yBAAA,GAA4B,IAAI,QAAA,CAA4B,QAAQ;AAEjF,SAAS,IAAA,CAAK,SAAiB,KAAA,EAAkC;AAC/D,EAAA,MAAM,IAAI,KAAA,CAAM,KAAA,EAAO,MAAA,GAAS,CAAA,EAAG,OAAO,CAAA,QAAA,EAAW,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,OAAO,CAAA;AACpF;AAEA,SAAS,oBAAA,CAAqB,KAAa,KAAA,EAAkD;AAC3F,EAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,GAAG,CAAA,EAAG;AAC5B,IAAA,IAAA,CAAK,CAAA,eAAA,EAAkB,GAAG,CAAA,wDAAA,EAAsD,aAAa,CAAA,EAAA,CAAI,CAAA;AAAA,EACnG;AACA,EAAA,MAAM,aAAa,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,MAAA,IAAU,EAAE,CAAA;AACjD,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,IAAA,CAAK,CAAA,cAAA,EAAiB,GAAG,CAAA,0CAAA,CAA4C,CAAA;AAAA,EACvE;AACA,EAAA,KAAA,MAAW,CAAC,MAAM,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA,EAAG;AACxD,IAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG;AAC7B,MAAA,IAAA,CAAK,iBAAiB,GAAG,CAAA,KAAA,EAAQ,IAAI,CAAA,0DAAA,EAAwD,aAAa,CAAA,EAAA,CAAI,CAAA;AAAA,IAChH;AACA,IAAA,IAAK,sBAAA,CAA6C,QAAA,CAAS,IAAI,CAAA,EAAG;AAChE,MAAA,IAAA,CAAK,CAAA,cAAA,EAAiB,GAAG,CAAA,KAAA,EAAQ,IAAI,mEAAmE,sBAAsB,CAAA;AAAA,IAChI;AACA,IAAA,IAAI,CAAE,kBAAA,CAAyC,QAAA,CAAS,KAAA,EAAO,IAAc,CAAA,EAAG;AAC9E,MAAA,IAAA,CAAK,CAAA,cAAA,EAAiB,GAAG,CAAA,WAAA,EAAc,IAAI,CAAA,oBAAA,EAAuB,OAAO,KAAA,EAAO,IAAI,CAAC,CAAA,EAAA,CAAA,EAAM,kBAAkB,CAAA;AAAA,IAC/G;AACA,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,KAAA,IAAS,CAAC,MAAM,MAAA,EAAQ;AACzC,MAAA,IAAA,CAAK,CAAA,cAAA,EAAiB,GAAG,CAAA,eAAA,EAAkB,IAAI,CAAA,uEAAA,CAAyE,CAAA;AAAA,IAC1H;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,EAAc,KAAA,KAAwB;AACnD,IAAA,IAAI,CAAC,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA,EAAG;AAC9B,MAAA,IAAA,CAAK,iBAAiB,GAAG,CAAA,IAAA,EAAO,KAAK,CAAA,8BAAA,EAAiC,IAAI,MAAM,UAAU,CAAA;AAAA,IAC5F;AAAA,EACF,CAAA;AACA,EAAA,KAAA,MAAW,KAAA,IAAS,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG;AACvC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,KAAA,CAAM,IAAA,EAAM,UAAU,CAAA;AAAA,EAClD;AACA,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,KAAA,CAAM,KAAA,CAAM,YAAY,YAAY,CAAA;AAC1D,EAAA,KAAA,MAAW,QAAQ,KAAA,CAAM,aAAA,IAAiB,EAAC,EAAG,KAAA,CAAM,MAAM,eAAe,CAAA;AAEzE,EAAA,MAAM,UAAA,GACJ,KAAA,CAAM,UAAA,IAAc,UAAA,CAAW,IAAA,CAAK,CAAC,IAAA,KAAS,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA,CAAG,IAAA,KAAS,MAAM,CAAA;AACnF,EAAA,MAAM,aAAA,GACJ,KAAA,CAAM,aAAA,IAAiB,UAAA,CAAW,MAAA,CAAO,CAAC,IAAA,KAAS,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA,CAAG,IAAA,KAAS,MAAM,CAAA;AAExF,EAAA,OAAO;AAAA,IACL,GAAA;AAAA,IACA,KAAA,EAAO,MAAM,KAAA,IAAS,GAAA;AAAA,IACtB,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,KAAA,EAAO,MAAM,KAAA,IAAS,QAAA;AAAA,IACtB,MAAA,EAAQ,EAAE,IAAA,EAAM,KAAA,CAAM,QAAQ,IAAA,IAAQ,OAAA,EAAS,OAAO,OAAA,EAAQ;AAAA,IAC9D,OAAA,EAAS,KAAA,CAAM,OAAA,IAAW,EAAC;AAAA,IAC3B,UAAA;AAAA,IACA,aAAA;AAAA,IACA,OAAA,EAAS,EAAE,IAAA,EAAM,SAAA,EAAW,OAAO,oBAAA;AAAqB,GAC1D;AACF;AAQO,SAAS,YAAA,CACd,GAAA,EACA,KAAA,EACA,IAAA,GAAuE,EAAC,EACrD;AACnB,EAAA,MAAM,WAAA,GAAc,oBAAA,CAAqB,GAAA,EAAK,KAAK,CAAA;AACnD,EAAA,yBAAA,CAA0B,QAAA,CAAS,KAAK,WAAA,EAAa;AAAA,IACnD,OAAO,WAAA,CAAY,KAAA;AAAA,IACnB,aAAa,WAAA,CAAY,WAAA;AAAA,IACzB,WAAA,EAAa,mBAAmB,WAAW,CAAA;AAAA,IAC3C,MAAA,EAAQ,KAAK,MAAA,IAAU,KAAA;AAAA,IACvB,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,OAAO,IAAA,CAAK;AAAA,GACb,CAAA;AACD,EAAA,OAAO,WAAA;AACT;AAEA,SAAS,mBAAA,GAA8B;AACrC,EAAA,MAAM,GAAA,GAAM,yBAAA,CAA0B,GAAA,EAAI,CAAE,IAAA,EAAK;AACjD,EAAA,OAAO,IAAI,MAAA,GACP,CAAA,mBAAA,EAAsB,IAAI,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACpC,4EAAA;AACN;AAGO,SAAS,yBAAyB,GAAA,EAAgC;AACvE,EAAA,MAAM,WAAA,GAAc,yBAAA,CAA0B,GAAA,CAAI,GAAG,CAAA;AACrD,EAAA,IAAI,CAAC,WAAA,EAAa,MAAM,IAAI,KAAA,CAAM,mBAAmB,GAAG,CAAA,GAAA,EAAM,mBAAA,EAAqB,CAAA,CAAE,CAAA;AACrF,EAAA,OAAO,WAAA;AACT;AAEO,SAAS,qBAAqB,GAAA,EAAsB;AACzD,EAAA,OAAO,yBAAA,CAA0B,IAAI,GAAG,CAAA;AAC1C;AAGO,SAAS,sBAAA,GAAmC;AACjD,EAAA,OAAO,yBAAA,CAA0B,GAAA,EAAI,CAAE,IAAA,EAAK;AAC9C;AAGO,SAAS,uBAAA,GAAgC;AAC9C,EAAA,yBAAA,CAA0B,KAAA,EAAM;AAClC;AAIA,IAAM,YAAA,GAAyD;AAAA,EAC7D,KAAA,EAAO,KAAA;AAAA,EACP,GAAA,EAAK,KAAA;AAAA,EACL,IAAA,EAAM,MAAA;AAAA,EACN,QAAA,EAAU;AACZ,CAAA;AAIA,SAAS,eAAA,CAAgB,MAAkB,KAAA,EAA0B;AACnE,EAAA,MAAM,IAAI,KAAA,CAAM,UAAA;AAChB,EAAA,IAAI,CAAC,CAAA,EAAG;AACR,EAAA,IAAI,KAAA,CAAM,SAAS,QAAA,EAAU;AAC3B,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,MAAA,EAAW,IAAA,CAAK,UAAU,CAAA,CAAE,GAAA;AAC1C,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,MAAA,EAAW,IAAA,CAAK,UAAU,CAAA,CAAE,GAAA;AAC1C,IAAA;AAAA,EACF;AACA,EAAA,IAAI,CAAA,CAAE,SAAA,KAAc,MAAA,EAAW,IAAA,CAAK,YAAY,CAAA,CAAE,SAAA;AAClD,EAAA,IAAI,CAAA,CAAE,SAAA,KAAc,MAAA,EAAW,IAAA,CAAK,YAAY,CAAA,CAAE,SAAA;AAClD,EAAA,IAAI,CAAA,CAAE,OAAA,KAAY,MAAA,EAAW,IAAA,CAAK,UAAU,CAAA,CAAE,OAAA;AAChD;AAEA,SAAS,iBAAA,CAAkB,MAAc,KAAA,EAAgC;AACvE,EAAA,MAAM,IAAA,GAAmB;AAAA,IACvB,KAAA,EAAO,MAAM,KAAA,IAAS,IAAA;AAAA;AAAA;AAAA;AAAA,IAItB,kBAAkB,KAAA,CAAM;AAAA,GAC1B;AACA,EAAA,IAAI,KAAA,CAAM,IAAA,EAAM,IAAA,CAAK,WAAA,GAAc,KAAA,CAAM,IAAA;AACzC,EAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,IAAA,CAAK,UAAU,KAAA,CAAM,OAAA;AACtD,EAAA,MAAM,MAAA,GAAS,YAAA,CAAa,KAAA,CAAM,IAAI,CAAA;AACtC,EAAA,IAAI,MAAA,OAAa,MAAA,GAAS,MAAA;AAE1B,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,QAAA;AACH,MAAA,IAAA,CAAK,IAAA,GAAO,QAAA;AACZ,MAAA,eAAA,CAAgB,MAAM,KAAK,CAAA;AAC3B,MAAA,OAAO,IAAA;AAAA,IACT,KAAK,SAAA;AACH,MAAA,IAAA,CAAK,IAAA,GAAO,SAAA;AACZ,MAAA,OAAO,IAAA;AAAA,IACT,KAAK,MAAA;AAGH,MAAA,OAAO,IAAA;AAAA,IACT,KAAK,OAAA;AACH,MAAA,IAAA,CAAK,IAAA,GAAO,QAAA;AACZ,MAAA,IAAA,CAAK,UAAA,GAAa,EAAE,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAS,EAAG,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAS,EAAE;AACrE,MAAA,IAAA,CAAK,QAAA,GAAW,CAAC,KAAA,EAAO,KAAK,CAAA;AAC7B,MAAA,IAAA,CAAK,oBAAA,GAAuB,KAAA;AAC5B,MAAA,OAAO,IAAA;AAAA,IACT,KAAK,KAAA;AACH,MAAA,IAAA,CAAK,IAAA,GAAO,QAAA;AACZ,MAAA,IAAA,CAAK,mBAAmB,IAAI,KAAA,CAAM,MAAA;AAClC,MAAA,OAAO,IAAA;AAAA,IACT,KAAK,QAAA;AACH,MAAA,IAAA,CAAK,IAAA,GAAO,QAAA;AACZ,MAAA,IAAA,CAAK,IAAA,GAAA,CAAQ,MAAM,OAAA,IAAW,IAAI,GAAA,CAAI,CAAC,MAAA,KAAW,MAAA,CAAO,KAAK,CAAA;AAC9D,MAAA,OAAO,IAAA;AAAA,IACT;AAEE,MAAA,IAAA,CAAK,IAAA,GAAO,QAAA;AACZ,MAAA,eAAA,CAAgB,MAAM,KAAK,CAAA;AAC3B,MAAA,OAAO,IAAA;AAAA;AAEb;AAQO,SAAS,mBAAmB,WAAA,EAAsF;AACvH,EAAA,MAAM,aAAyC,EAAC;AAChD,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,CAAC,MAAM,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,WAAA,CAAY,MAAM,CAAA,EAAG;AAC9D,IAAA,UAAA,CAAW,IAAI,CAAA,GAAI,iBAAA,CAAkB,IAAA,EAAM,KAAK,CAAA;AAChD,IAAA,IAAI,KAAA,CAAM,QAAA,EAAU,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAAA,EACxC;AACA,EAAA,MAAM,MAAA,GAAqB;AAAA,IACzB,IAAA,EAAM,QAAA;AAAA,IACN,OAAO,WAAA,CAAY,KAAA;AAAA,IACnB,UAAA;AAAA,IACA,oBAAA,EAAsB;AAAA,GACxB;AACA,EAAA,IAAI,WAAA,CAAY,WAAA,EAAa,MAAA,CAAO,WAAA,GAAc,WAAA,CAAY,WAAA;AAC9D,EAAA,IAAI,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,MAAA,CAAO,QAAA,GAAW,QAAA;AAC3C,EAAA,OAAO,MAAA;AACT;AAaA,SAAS,OAAO,KAAA,EAAwB;AACtC,EAAA,OAAO,KAAA,CAAM,QAAQ,KAAK,CAAA,GAAI,UAAU,KAAA,KAAU,IAAA,GAAO,SAAS,OAAO,KAAA;AAC3E;AAKA,SAAS,WAAA,CACP,MAAA,EACA,IAAA,EACA,KAAA,EACA,KAAA,EACM;AACN,EAAA,MAAM,IAAI,KAAA,CAAM,UAAA;AAChB,EAAA,IAAI,CAAC,CAAA,EAAG;AACR,EAAA,MAAM,OAAA,GAAU,CAAC,OAAA,KAAoB,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,CAAA;AAE/F,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,MAAA,IAAa,KAAA,GAAQ,CAAA,CAAE,GAAA,EAAK,OAAA,CAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,0BAAA,EAA6B,CAAA,CAAE,GAAG,CAAA,CAAE,CAAA;AAC9F,IAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,MAAA,IAAa,KAAA,GAAQ,CAAA,CAAE,GAAA,EAAK,OAAA,CAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,0BAAA,EAA6B,CAAA,CAAE,GAAG,CAAA,CAAE,CAAA;AAC9F,IAAA;AAAA,EACF;AACA,EAAA,IAAI,EAAE,SAAA,KAAc,MAAA,IAAa,KAAA,CAAM,MAAA,GAAS,EAAE,SAAA,EAAW;AAC3D,IAAA,OAAA,CAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,kBAAA,EAAqB,CAAA,CAAE,SAAS,CAAA,aAAA,CAAe,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,EAAE,SAAA,KAAc,MAAA,IAAa,KAAA,CAAM,MAAA,GAAS,EAAE,SAAA,EAAW;AAC3D,IAAA,OAAA,CAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,iBAAA,EAAoB,CAAA,CAAE,SAAS,CAAA,aAAA,CAAe,CAAA;AAAA,EAChE;AACA,EAAA,IAAI,CAAA,CAAE,YAAY,MAAA,EAAW;AAC3B,IAAA,IAAI,EAAA,GAAoB,IAAA;AACxB,IAAA,IAAI;AACF,MAAA,EAAA,GAAK,IAAI,MAAA,CAAO,CAAA,CAAE,OAAO,CAAA;AAAA,IAC3B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,CAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,6CAAA,CAA+C,CAAA;AAAA,IACjE;AACA,IAAA,IAAI,EAAA,IAAM,CAAC,EAAA,CAAG,IAAA,CAAK,KAAK,CAAA,EAAG,OAAA,CAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,oCAAA,CAAsC,CAAA;AAAA,EACnF;AACF;AAMO,SAAS,wBAAA,CACd,aACA,IAAA,EACqB;AACrB,EAAA,MAAM,SAA8B,EAAC;AACrC,EAAA,IAAI,OAAO,SAAS,QAAA,IAAY,IAAA,KAAS,QAAQ,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACpE,IAAA,OAAO,CAAC,EAAE,IAAA,EAAM,EAAA,EAAI,IAAA,EAAM,eAAA,EAAiB,OAAA,EAAS,CAAA,8BAAA,EAAiC,MAAA,CAAO,IAAI,CAAC,CAAA,CAAA,EAAI,CAAA;AAAA,EACvG;AACA,EAAA,MAAM,MAAA,GAAS,IAAA;AACf,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AAEjD,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,MAAA,CAAO,IAAI,CAAA;AACrC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,IAAA;AAAA,QACN,IAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAS,UAAU,IAAI,CAAA,gCAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AAC3C,IAAA,QAAQ,MAAM,IAAA;AAAM,MAClB,KAAK,QAAA;AACH,QAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AACxD,UAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,MAAM,eAAA,EAAiB,OAAA,EAAS,CAAA,CAAA,EAAI,IAAI,CAAA,wBAAA,EAA2B,MAAA,CAAO,KAAK,CAAC,IAAI,CAAA;AAAA,QAChH,CAAA,MAAO;AACL,UAAA,WAAA,CAAY,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA;AAAA,QACxC;AACA,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,UAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,MAAM,eAAA,EAAiB,OAAA,EAAS,CAAA,CAAA,EAAI,IAAI,CAAA,yBAAA,EAA4B,MAAA,CAAO,KAAK,CAAC,IAAI,CAAA;AAAA,QACjH;AACA,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA;AAAA;AAAA,MACF,KAAK,OAAA,EAAS;AACZ,QAAA,MAAM,KAAA,GAAQ,KAAA;AACd,QAAA,IACE,OAAO,KAAK,CAAA,KAAM,QAAA,IAClB,OAAO,MAAM,GAAA,KAAQ,QAAA,IACrB,OAAO,KAAA,CAAM,QAAQ,QAAA,IACrB,MAAA,CAAO,KAAK,KAAK,CAAA,CAAE,WAAW,CAAA,EAC9B;AACA,UAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,iBAAiB,OAAA,EAAS,CAAA,CAAA,EAAI,IAAI,CAAA,oCAAA,CAAA,EAAwC,CAAA;AAAA,QAC5G;AACA,QAAA;AAAA,MACF;AAAA,MACA,KAAK,QAAA,EAAU;AACb,QAAA,MAAM,OAAA,GAAA,CAAW,MAAM,OAAA,IAAW,IAAI,GAAA,CAAI,CAAC,MAAA,KAAW,MAAA,CAAO,KAAK,CAAA;AAClE,QAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,UAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,MAAM,eAAA,EAAiB,OAAA,EAAS,CAAA,CAAA,EAAI,IAAI,CAAA,wBAAA,EAA2B,MAAA,CAAO,KAAK,CAAC,IAAI,CAAA;AAAA,QAChH,CAAA,MAAA,IAAW,CAAC,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AACnC,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,IAAA,EAAM,IAAA;AAAA,YACN,IAAA,EAAM,eAAA;AAAA,YACN,OAAA,EAAS,CAAA,CAAA,EAAI,IAAI,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAA,CAAA;AAAA,YAC5C,KAAA,EAAO;AAAA,WACR,CAAA;AAAA,QACH;AACA,QAAA;AAAA,MACF;AAAA,MACA;AAEE,QAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,UAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,MAAM,eAAA,EAAiB,OAAA,EAAS,CAAA,CAAA,EAAI,IAAI,CAAA,wBAAA,EAA2B,MAAA,CAAO,KAAK,CAAC,IAAI,CAAA;AAAA,QAChH,CAAA,MAAO;AACL,UAAA,WAAA,CAAY,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA;AAAA,QACxC;AAAA;AACJ,EACF;AAEA,EAAA,KAAA,MAAW,CAAC,MAAM,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,WAAA,CAAY,MAAM,CAAA,EAAG;AAC9D,IAAA,IAAI,KAAA,CAAM,QAAA,KAAa,MAAA,CAAO,IAAI,CAAA,KAAM,MAAA,IAAa,MAAA,CAAO,IAAI,CAAA,KAAM,IAAA,IAAQ,MAAA,CAAO,IAAI,MAAM,EAAA,CAAA,EAAK;AAClG,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,iBAAiB,OAAA,EAAS,CAAA,gBAAA,EAAmB,IAAI,CAAA,YAAA,CAAA,EAAgB,CAAA;AAAA,IACnG;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAkBO,SAAS,gBAAA,GAAuC;AACrD,EAAA,OAAO,yBAAA,CAA0B,QAAA,EAAS,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS;AACxD,IAAA,MAAM,WAAA,GAAc,yBAAA,CAA0B,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AACzD,IAAA,OAAO;AAAA,MACL,GAAG,IAAA;AAAA,MACH,cAAc,IAAA,CAAK,MAAA;AAAA,MACnB,QAAQ,WAAA,CAAY,MAAA;AAAA,MACpB,OAAO,WAAA,CAAY,KAAA;AAAA,MACnB,SAAS,WAAA,CAAY,OAAA;AAAA,MACrB,SAAS,WAAA,CAAY,OAAA;AAAA,MACrB,YAAY,WAAA,CAAY,UAAA;AAAA,MACxB,eAAe,WAAA,CAAY;AAAA,KAC7B;AAAA,EACF,CAAC,CAAA;AACH;AAOA,IAAM,mBAAA,GAA0D;AAAA,EAC9D,IAAA,EAAM,MAAA;AAAA,EACN,QAAA,EAAU,UAAA;AAAA,EACV,MAAA,EAAQ,QAAA;AAAA,EACR,OAAA,EAAS,SAAA;AAAA;AAAA;AAAA;AAAA,EAIT,IAAA,EAAM,UAAA;AAAA,EACN,KAAA,EAAO,MAAA;AAAA,EACP,KAAA,EAAO,OAAA;AAAA,EACP,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,UAAA;AAAA,EACL,IAAA,EAAM,MAAA;AAAA,EACN,QAAA,EAAU,UAAA;AAAA,EACV,MAAA,EAAQ;AACV,CAAA;AAcO,SAAS,gBAAgB,WAAA,EAAiD;AAC/E,EAAA,MAAM,MAAA,GAAqB,MAAA,CAAO,OAAA,CAAQ,WAAA,CAAY,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,KAAK,CAAA,KAAM;AACnF,IAAA,MAAM,GAAA,GAAgB;AAAA,MACpB,GAAA,EAAK,IAAA;AAAA,MACL,KAAA,EAAO,MAAM,KAAA,IAAS,IAAA;AAAA,MACtB,IAAA,EAAM,mBAAA,CAAoB,KAAA,CAAM,IAAI,CAAA;AAAA,MACpC,UAAA,EAAY,IAAA;AAAA,MACZ,WAAA,EAAa,WAAA,CAAY,aAAA,CAAc,QAAA,CAAS,IAAI;AAAA,KACtD;AACA,IAAA,IAAI,KAAA,CAAM,QAAA,EAAU,GAAA,CAAI,QAAA,GAAW,IAAA;AACnC,IAAA,IAAI,KAAA,CAAM,IAAA,EAAM,GAAA,CAAI,IAAA,GAAO,KAAA,CAAM,IAAA;AACjC,IAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,GAAA,CAAI,eAAe,KAAA,CAAM,OAAA;AAC1D,IAAA,IAAI,MAAM,IAAA,KAAS,MAAA,EAAQ,GAAA,CAAI,IAAA,GAAO,MAAM,IAAA,IAAQ,YAAA;AACpD,IAAA,IAAI,MAAM,IAAA,KAAS,OAAA,EAAS,GAAA,CAAI,IAAA,GAAO,MAAM,IAAA,IAAQ,SAAA;AACrD,IAAA,IAAI,KAAA,CAAM,SAAS,QAAA,EAAU;AAC3B,MAAA,GAAA,CAAI,WAAW,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,IAAI,CAAC,MAAA,MAAY,EAAE,KAAA,EAAO,OAAO,KAAA,IAAS,MAAA,CAAO,OAAO,KAAA,EAAO,MAAA,CAAO,OAAM,CAAE,CAAA;AAAA,IACpH;AACA,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,KAAA,IAAS,KAAA,CAAM,MAAA,EAAQ;AACxC,MAAA,GAAA,CAAI,QAAA,GAAW;AAAA,QACb,KAAA,EAAO,YAAY,OAAA,CAAQ,KAAA;AAAA,QAC3B,UAAA,EAAY,IAAA;AAAA,QACZ,UAAA,EAAY,MAAA;AAAA,QACZ,MAAA,EAAQ,EAAE,MAAA,EAAQ,KAAA,CAAM,MAAA;AAAO,OACjC;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,MAAA,EAAQ,WAAA,CAAY,KAAK,KAAA,EAAO,WAAA,CAAY,OAAO,MAAA,EAAO;AACrE;AAmBA,IAAM,YAAA,GAAe,mBAAA;AAOd,IAAM,oBAAA,GAAuB,IAAI,QAAA,CAAkC,cAAc;AAMjF,SAAS,kBAAA,CACd,SAAA,EACA,MAAA,EACA,IAAA,GAAuD,EAAC,EAC/B;AACzB,EAAA,IAAI,CAAC,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA,EAAG;AACjC,IAAA,IAAA,CAAK,CAAA,qBAAA,EAAwB,SAAS,CAAA,8BAAA,EAAiC,YAAY,CAAA,EAAA,CAAI,CAAA;AAAA,EACzF;AACA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG;AAC7B,MAAA,IAAA,CAAK,uBAAuB,SAAS,CAAA,KAAA,EAAQ,IAAI,CAAA,6BAAA,EAAgC,aAAa,CAAA,EAAA,CAAI,CAAA;AAAA,IACpG;AACA,IAAA,IAAI,CAAE,kBAAA,CAAyC,QAAA,CAAS,KAAA,EAAO,IAAc,CAAA,EAAG;AAC9E,MAAA,IAAA,CAAK,CAAA,oBAAA,EAAuB,SAAS,CAAA,WAAA,EAAc,IAAI,CAAA,oBAAA,EAAuB,OAAO,KAAA,EAAO,IAAI,CAAC,CAAA,EAAA,CAAA,EAAM,kBAAkB,CAAA;AAAA,IAC3H;AACA,IAAA,IAAI,KAAA,CAAM,SAAS,QAAA,IAAY,CAAA,CAAE,MAAM,OAAA,IAAW,IAAI,MAAA,EAAQ;AAC5D,MAAA,IAAA,CAAK,CAAA,oBAAA,EAAuB,SAAS,CAAA,kBAAA,EAAqB,IAAI,CAAA,sBAAA,CAAwB,CAAA;AAAA,IACxF;AAAA,EACF;AACA,EAAA,MAAM,WAAA,GAAuC,EAAE,SAAA,EAAW,MAAA,EAAO;AACjE,EAAA,oBAAA,CAAqB,QAAA,CAAS,WAAW,WAAA,EAAa;AAAA,IACpD,KAAA,EAAO,kBAAkB,SAAS,CAAA,CAAA;AAAA,IAClC,WAAA,EAAa,mBAAmB,EAAE,KAAA,EAAO,GAAG,SAAS,CAAA,cAAA,CAAA,EAAkB,QAAQ,CAAA;AAAA,IAC/E,MAAA,EAAQ,KAAK,MAAA,IAAU,KAAA;AAAA,IACvB,UAAU,IAAA,CAAK;AAAA,GAChB,CAAA;AACD,EAAA,OAAO,WAAA;AACT;AAOO,SAAS,qBAAqB,SAAA,EAAgD;AACnF,EAAA,OAAO,oBAAA,CAAqB,GAAA,CAAI,SAAS,CAAA,EAAG,UAAU,EAAC;AACzD;AAEO,SAAS,2BAA2B,SAAA,EAA4B;AACrE,EAAA,OAAO,oBAAA,CAAqB,IAAI,SAAS,CAAA;AAC3C;AAGO,SAAS,6BAAA,GAAsC;AACpD,EAAA,oBAAA,CAAqB,KAAA,EAAM;AAC7B","file":"chunk-EWKX4VUM.js","sourcesContent":["import type { BlockPreset, BlockSetting, BlockStability } from './block-schema'\n\n// ---------------------------------------------------------------------------\n// The Registry class and its meta envelope, in a leaf module.\n//\n// Split from ./index so sibling modules that instantiate a registry at module\n// scope (./handles) can import the class without evaluating the whole registry\n// barrel — ESM hoists `export … from` like any import, so a barrel that both\n// defines the class and re-exports an instantiating sibling dead-locks on\n// itself. Public API is unchanged: ./index re-exports everything here.\n// ---------------------------------------------------------------------------\n\n/** A JSON Schema object (loosely typed; validated by tooling, not at runtime). */\nexport type JsonSchema = Record<string, unknown>\n\nexport type RegistrySource = 'sdk' | 'plugin' | 'app'\n\n/**\n * A child a block cannot function without — re-inserted at its template index\n * when a generated or edited tree drops it (WooCommerce's `use-forced-layout`).\n * `props` seeds the re-inserted instance; the child's own setting defaults fill\n * whatever `props` leaves unsaid.\n */\nexport interface RequiredBlockChild {\n type: string\n /** Stable id for the re-inserted node. Defaults to `type`. */\n id?: string\n props?: Record<string, unknown>\n}\n\n// --- Data needs (spine M3) ----------------------------------------------------\n// Part of the meta envelope because it is a DECLARATION, not code: a block says\n// which loader feeds it and how the loader's params are filled. The page-level\n// resolver reads it; validateStore checks it; the document can carry it.\n\n/** A param value bound to a route param of the page being rendered\n * (`{ category: { $param: 'slug' } }`). */\nexport interface LoaderParamRef {\n $param: string\n}\n\n/** A param value bound to one of the declaring block instance's own props\n * (`{ limit: { $prop: 'limit' } }`). Setting defaults fill unset props, so the\n * declared need and the rendered block always agree on the value. */\nexport interface LoaderPropRef {\n $prop: string\n}\n\n/**\n * One named data need: which loader, with which params. A param value is a\n * JSON literal (a document-level constant), a {@link LoaderParamRef} or a\n * {@link LoaderPropRef}.\n */\nexport interface BlockDataNeed {\n /** Registered loader id — unknown ids are an I2 hard error. */\n loader: string\n params?: Record<string, unknown>\n}\n\n/** A block's named data needs (`{ products: { loader: 'products.list' } }`). */\nexport type BlockDataNeeds = Record<string, BlockDataNeed>\n\nexport interface RegistryMeta {\n /** Human title — the canonical name of the uniform meta envelope. `label` is\n * the legacy alias; `register()` folds the two so either spelling reads back\n * through both fields. */\n title?: string\n /** Human label for the platform editor. @see title */\n label?: string\n description?: string\n /** Where this artifact came from (for introspection / conflict reporting). */\n source?: RegistrySource\n /** Owning plugin id, when source is 'plugin'. */\n pluginId?: string\n /** JSON Schema for this artifact's props/config — drives the visual editor\n * and constrains AI generation. Optional but strongly encouraged.\n *\n * Prefer declaring `settings` and letting `defineBlock` compile this: the two\n * must not be hand-maintained side by side or they drift. */\n propsSchema?: JsonSchema\n /** Authoring-level prop declaration. Compiles to {@link propsSchema}. */\n settings?: readonly BlockSetting[]\n /** Named starting points offered when the artifact is inserted. */\n presets?: readonly BlockPreset[]\n /**\n * Surfaces this artifact may be placed on. Absent means \"anywhere\".\n *\n * The vocabulary belongs to the surface, not to core — the storefront uses\n * page kinds (`home`, `catalog`, `product`, …), an admin scaffold uses its\n * own. Core only carries the constraint so tooling can enforce it uniformly.\n */\n enabledOn?: readonly string[]\n /** Contract stability. Absent means `stable`. */\n stability?: BlockStability\n /** SDK/plugin version this entry first appeared in (semver string). Part of\n * the uniform meta envelope so tooling can say \"since 0.9\" about any\n * registry entry — blocks today, entities/rules/actions later. */\n since?: string\n /** One-line description of the value this entry resolves to. Loaders declare\n * it so the agent knows what a data need yields without running it. */\n output?: string\n /**\n * Named data needs this entry resolves through the page-level resolver\n * (spine M3): `{ products: { loader: 'products.list', params: {...} } }`.\n * Declared on blocks; a document block instance may add or override needs\n * with the same shape. Loaders are the ONLY read path (I11) — a block with a\n * `data` declaration must not fetch for itself.\n */\n data?: BlockDataNeeds\n\n // --- Composition constraints (WooCommerce block.json vocabulary) ------------\n // Declared as data so the validator, the renderer and the editor enforce the\n // same rules from one declaration (spine I7). All optional; absent means\n // unconstrained. Enforced by `checkBlockConstraints` and at render time.\n\n /** Block ids this artifact may ONLY be a DIRECT child of (block.json `parent`).\n * A block declaring this cannot sit at a tree root. */\n parent?: readonly string[]\n /** Block ids that must appear somewhere ABOVE this artifact, at any depth\n * (block.json `ancestor`). Weaker than `parent`; both may be declared. */\n ancestor?: readonly string[]\n /** Context keys this artifact reads at runtime (block.json `usesContext`).\n * A placement where no ancestor provides them is reported as advisory —\n * the surface (page, slot) may supply them instead. */\n usesContext?: readonly string[]\n /** Context keys this artifact provides to its descendants\n * (block.json `providesContext`). */\n providesContext?: readonly string[]\n /** May this artifact appear more than once in one tree\n * (block.json `supports.multiple`)? Absent means true. */\n allowMultiple?: boolean\n /** Children this artifact cannot function without — re-inserted by\n * `repairBlockTree` when missing (use-forced-layout). Order is the template\n * order, which decides the index a missing child is re-inserted at. */\n requiredChildren?: readonly RequiredBlockChild[]\n}\n\nexport interface RegistryEntry<T> {\n id: string\n value: T\n meta: RegistryMeta\n}\n\n/**\n * The uniform meta envelope, as data. Every registry — blocks today, entities,\n * rules and actions later — describes its entries through this one shape, so a\n * catalog consumer (the editor, the AI, `fayz catalog`) reads N registries with\n * one parser. Richer per-kind descriptors (e.g. `BlockDescriptor` with settings\n * and presets) extend this rather than replacing it.\n */\nexport interface RegistryEntryDescriptor {\n id: string\n /** The owning registry's kind ('block', 'handle', …). */\n kind: string\n title?: string\n description?: string\n /** JSON Schema for the entry's props/config, when declared. */\n schema?: JsonSchema\n stability: BlockStability\n since?: string\n source?: RegistrySource\n pluginId?: string\n}\n\n/** A typed, introspectable id→value map. Last registration wins (so an app's\n * registry.tsx can override an SDK artifact by re-registering its id). */\nexport class Registry<T> {\n private readonly entries = new Map<string, RegistryEntry<T>>()\n\n constructor(readonly kind: string) {}\n\n register(id: string, value: T, meta: RegistryMeta = {}): void {\n // Fold the title/label alias both ways at the door, so consumers written\n // against either generation of the meta shape read the same string.\n const title = meta.title ?? meta.label\n this.entries.set(id, { id, value, meta: title === undefined ? meta : { ...meta, title, label: title } })\n }\n\n get(id: string): T | undefined {\n return this.entries.get(id)?.value\n }\n\n getEntry(id: string): RegistryEntry<T> | undefined {\n return this.entries.get(id)\n }\n\n has(id: string): boolean {\n return this.entries.has(id)\n }\n\n list(): RegistryEntry<T>[] {\n return Array.from(this.entries.values())\n }\n\n ids(): string[] {\n return Array.from(this.entries.keys())\n }\n\n /**\n * Every entry reduced to the uniform meta envelope, sorted by id.\n *\n * Sorted for the same reason as `describeBlocks`: this feeds prompts,\n * documents and generated catalogs, and registration order is an\n * implementation detail that would make every diff noisy.\n */\n describe(): RegistryEntryDescriptor[] {\n return this.list()\n .map(({ id, meta }) => ({\n id,\n kind: this.kind,\n title: meta.title ?? meta.label,\n description: meta.description,\n schema: meta.propsSchema,\n stability: meta.stability ?? 'stable',\n since: meta.since,\n source: meta.source,\n pluginId: meta.pluginId,\n }))\n .sort((a, b) => a.id.localeCompare(b.id))\n }\n\n clear(): void {\n this.entries.clear()\n }\n}\n\n/** True for app-local custom artifacts (`custom:*`). */\nexport function isCustomId(id: string): boolean {\n return id.startsWith('custom:')\n}\n","import { Registry } from './registry-class'\nimport type { JsonSchema, RegistryEntryDescriptor, RegistrySource } from './registry-class'\nimport type { FieldDef, FieldType } from '../types/crud'\n\n// ---------------------------------------------------------------------------\n// Entities — a new KIND of data as one declaration (spine §3 L1, milestone M4).\n//\n// defineEntity('store_location', { fields, scope, access, indexes }) is the\n// whole authoring surface. From that single declaration the system emits:\n//\n// 1. the JSON Schema a record is validated against on WRITE (I1 — same\n// one-declaration→schema emission as block settings → propsSchema),\n// 2. the storage descriptor (which table holds the records, so a hot entity\n// can be promoted to typed columns behind the I5 indirection),\n// 3. the tenant-scoping RLS policy SQL (generated in @fayz-ai/shop from this\n// declaration — nobody hand-writes a policy, I6),\n// 4. the query surface (the storefront's entity.* loaders),\n// 5. the admin CRUD form descriptor (entityAdminForm, targeting the existing\n// FieldDef vocabulary the SaaS CRUD renders).\n//\n// This module is the DECLARATION layer only, deliberately compile-target-\n// agnostic (I11): nothing here knows SQL, Supabase, or Shopify metaobjects.\n// The physical compilation lives with the backend that owns it.\n//\n// I2 everywhere: an unknown entity, field type, or field reference is a hard\n// error naming the valid set — never a silent drop.\n//\n// Leaf-module discipline (see registry-class.ts): instantiates registries at\n// module scope, so it imports only sibling leaves, never ./index.\n// ---------------------------------------------------------------------------\n\n/** The field-type vocabulary an entity may declare. */\nexport type EntityFieldType =\n | 'text'\n | 'richtext'\n | 'number'\n | 'boolean'\n | 'json'\n | 'image'\n | 'url'\n | 'ref'\n | 'point'\n | 'date'\n | 'datetime'\n | 'select'\n\n/** The vocabulary as a runtime value, for catalogs and I2 error messages.\n * `satisfies` + exhaustiveness keep the union and the list from drifting.\n * It also mirrors the CHECK on plg_entity_fields.type (migration 035) — a type\n * is a MODEL change, in both places at once, never an insert. */\nexport const ENTITY_FIELD_TYPES = [\n 'text',\n 'richtext',\n 'number',\n 'boolean',\n 'json',\n 'image',\n 'url',\n 'ref',\n 'point',\n 'date',\n 'datetime',\n 'select',\n] as const satisfies readonly EntityFieldType[]\ntype MissingEntityFieldType = Exclude<EntityFieldType, (typeof ENTITY_FIELD_TYPES)[number]>\nconst _entityFieldTypesExhaustive: [MissingEntityFieldType] extends [never] ? true : never = true\nvoid _entityFieldTypesExhaustive\n\n/**\n * Bounds a value must respect beyond its type. Kept as data, not code, because\n * a merchant defines these in the admin and they have to survive the round trip\n * through plg_entity_fields.validation without anything being compiled.\n */\nexport interface EntityFieldValidation {\n /** Numbers: inclusive bounds. */\n min?: number\n max?: number\n /** Strings: inclusive length bounds. */\n minLength?: number\n maxLength?: number\n /** Strings: an anchored-as-written regular expression. */\n pattern?: string\n}\n\n/** One choice of a `select` field. The value is what lands in custom_fields. */\nexport interface EntityFieldOption {\n value: string\n label?: string\n}\n\nexport interface EntityField {\n type: EntityFieldType\n /** Human label — drives the admin form and the agent's understanding. */\n label?: string\n help?: string\n required?: boolean\n default?: unknown\n /** `ref` only: the entity key this field points to (stores that entity's record id). */\n entity?: string\n /** `select` only: the closed set of values. */\n options?: readonly EntityFieldOption[]\n validation?: EntityFieldValidation\n}\n\nexport type EntityReadAccess = 'public' | 'staff'\n\n/**\n * Who reads and who writes. `write` is 'staff' only on purpose: shopper-writable\n * entities (reviews) need the action/rate-limit layer (M7), not an RLS grant.\n */\nexport interface EntityAccess {\n read: EntityReadAccess\n write: 'staff'\n}\n\n/** Where records live. Generic jsonb storage first (I5); promoting a hot entity\n * to typed columns changes THIS value, and nothing else callers see. */\nexport interface EntityStorageDescriptor {\n mode: 'generic' | 'dedicated'\n /** Physical table. 'generic' mode shares it across entities. */\n table: string\n}\n\nexport interface EntityDeclarationInput {\n /** Human title (singular). Defaults to the key. */\n title?: string\n description?: string\n fields: Record<string, EntityField>\n /** Only 'tenant' exists today: every record belongs to one store. */\n scope?: 'tenant'\n /** Default: staff-only both ways — public exposure is opt-in, never implied. */\n access?: Partial<EntityAccess>\n /** Field-name tuples to index for querying/filtering. */\n indexes?: readonly (readonly string[])[]\n /** Field whose value titles a record in lists. Default: first text field. */\n titleField?: string\n /** Fields blocks display by default (entityList). Default: every non-json field. */\n displayFields?: readonly string[]\n}\n\nexport interface EntityDeclaration {\n key: string\n title: string\n description?: string\n fields: Record<string, EntityField>\n scope: 'tenant'\n access: EntityAccess\n indexes: readonly (readonly string[])[]\n titleField?: string\n displayFields: readonly string[]\n storage: EntityStorageDescriptor\n}\n\n/** The shared jsonb records table (see @fayz-ai/shop migrations 0030). */\nexport const GENERIC_ENTITY_TABLE = 'plg_entity_records'\n\n/** Entity keys become table/policy-name fragments and document keys: snake_case. */\nconst ENTITY_KEY_RE = /^[a-z][a-z0-9_]*$/\nconst FIELD_NAME_RE = /^[a-z][a-z0-9_]*$/\n\n/** Structural record columns a declared field must not shadow. */\nexport const RESERVED_ENTITY_FIELDS = ['id', 'slug', 'entity', 'tenant_id', 'created_at', 'updated_at'] as const\n\nexport const entityDeclarationRegistry = new Registry<EntityDeclaration>('entity')\n\nfunction fail(message: string, valid?: readonly string[]): never {\n throw new Error(valid?.length ? `${message} Valid: ${valid.join(', ')}.` : message)\n}\n\nfunction normalizeDeclaration(key: string, input: EntityDeclarationInput): EntityDeclaration {\n if (!ENTITY_KEY_RE.test(key)) {\n fail(`defineEntity: \"${key}\" is not a valid entity key — keys are snake_case (${ENTITY_KEY_RE}).`)\n }\n const fieldNames = Object.keys(input.fields ?? {})\n if (fieldNames.length === 0) {\n fail(`defineEntity(\"${key}\"): an entity declares at least one field.`)\n }\n for (const [name, field] of Object.entries(input.fields)) {\n if (!FIELD_NAME_RE.test(name)) {\n fail(`defineEntity(\"${key}\"): \"${name}\" is not a valid field name — fields are snake_case (${FIELD_NAME_RE}).`)\n }\n if ((RESERVED_ENTITY_FIELDS as readonly string[]).includes(name)) {\n fail(`defineEntity(\"${key}\"): \"${name}\" is a structural record column and cannot be a declared field.`, RESERVED_ENTITY_FIELDS)\n }\n if (!(ENTITY_FIELD_TYPES as readonly string[]).includes(field?.type as string)) {\n fail(`defineEntity(\"${key}\"): field \"${name}\" has unknown type \"${String(field?.type)}\".`, ENTITY_FIELD_TYPES)\n }\n if (field.type === 'ref' && !field.entity) {\n fail(`defineEntity(\"${key}\"): ref field \"${name}\" must name the entity it points to ({ type: 'ref', entity: '<key>' }).`)\n }\n }\n const knows = (name: string, where: string): void => {\n if (!fieldNames.includes(name)) {\n fail(`defineEntity(\"${key}\"): ${where} references undeclared field \"${name}\".`, fieldNames)\n }\n }\n for (const index of input.indexes ?? []) {\n for (const name of index) knows(name, 'an index')\n }\n if (input.titleField) knows(input.titleField, 'titleField')\n for (const name of input.displayFields ?? []) knows(name, 'displayFields')\n\n const titleField =\n input.titleField ?? fieldNames.find((name) => input.fields[name]!.type === 'text')\n const displayFields =\n input.displayFields ?? fieldNames.filter((name) => input.fields[name]!.type !== 'json')\n\n return {\n key,\n title: input.title ?? key,\n description: input.description,\n fields: input.fields,\n scope: input.scope ?? 'tenant',\n access: { read: input.access?.read ?? 'staff', write: 'staff' },\n indexes: input.indexes ?? [],\n titleField,\n displayFields,\n storage: { mode: 'generic', table: GENERIC_ENTITY_TABLE },\n }\n}\n\n/**\n * Declare an entity. One call → registry entry on the uniform meta envelope,\n * with the record JSON Schema as `propsSchema` — the same emission discipline\n * as `defineBlock` (I1), so every catalog consumer reads entities and blocks\n * with one parser.\n */\nexport function defineEntity(\n key: string,\n input: EntityDeclarationInput,\n meta: { source?: RegistrySource; pluginId?: string; since?: string } = {},\n): EntityDeclaration {\n const declaration = normalizeDeclaration(key, input)\n entityDeclarationRegistry.register(key, declaration, {\n title: declaration.title,\n description: declaration.description,\n propsSchema: entityRecordSchema(declaration),\n source: meta.source ?? 'app',\n pluginId: meta.pluginId,\n since: meta.since,\n })\n return declaration\n}\n\nfunction formatValidEntities(): string {\n const ids = entityDeclarationRegistry.ids().sort()\n return ids.length\n ? `Declared entities: ${ids.join(', ')}`\n : 'No entities are declared — call defineEntity(key, declaration) first.'\n}\n\n/** Resolve a declaration or throw naming the valid set — the I2 contract. */\nexport function resolveEntityDeclaration(key: string): EntityDeclaration {\n const declaration = entityDeclarationRegistry.get(key)\n if (!declaration) throw new Error(`Unknown entity \"${key}\". ${formatValidEntities()}`)\n return declaration\n}\n\nexport function hasEntityDeclaration(key: string): boolean {\n return entityDeclarationRegistry.has(key)\n}\n\n/** All declared entity keys, sorted. */\nexport function listEntityDeclarations(): string[] {\n return entityDeclarationRegistry.ids().sort()\n}\n\n/** Test seam — a suite that declares entities must not leak into the next. */\nexport function clearEntityDeclarations(): void {\n entityDeclarationRegistry.clear()\n}\n\n// --- JSON Schema emission (I1) ------------------------------------------------\n\nconst FIELD_FORMAT: Partial<Record<EntityFieldType, string>> = {\n image: 'uri',\n url: 'uri',\n date: 'date',\n datetime: 'date-time',\n}\n\n/** Declared bounds, projected onto the JSON Schema node the agent generates\n * against — so the contract states them instead of only the validator. */\nfunction applyValidation(node: JsonSchema, field: EntityField): void {\n const v = field.validation\n if (!v) return\n if (field.type === 'number') {\n if (v.min !== undefined) node.minimum = v.min\n if (v.max !== undefined) node.maximum = v.max\n return\n }\n if (v.minLength !== undefined) node.minLength = v.minLength\n if (v.maxLength !== undefined) node.maxLength = v.maxLength\n if (v.pattern !== undefined) node.pattern = v.pattern\n}\n\nfunction fieldToJsonSchema(name: string, field: EntityField): JsonSchema {\n const node: JsonSchema = {\n title: field.label ?? name,\n // The control survives the compile, exactly as in block settings: a `ref`\n // is a string in JSON Schema terms, but an editor rendering it as a text\n // input (instead of a record picker) is a bug.\n 'x-fayz-control': field.type,\n }\n if (field.help) node.description = field.help\n if (field.default !== undefined) node.default = field.default\n const format = FIELD_FORMAT[field.type]\n if (format) node.format = format\n\n switch (field.type) {\n case 'number':\n node.type = 'number'\n applyValidation(node, field)\n return node\n case 'boolean':\n node.type = 'boolean'\n return node\n case 'json':\n // Any JSON value. The one field type with no shape on purpose — it is\n // the declared escape hatch, not an accident like Medusa's `metadata`.\n return node\n case 'point':\n node.type = 'object'\n node.properties = { lat: { type: 'number' }, lng: { type: 'number' } }\n node.required = ['lat', 'lng']\n node.additionalProperties = false\n return node\n case 'ref':\n node.type = 'string'\n node['x-fayz-ref-entity'] = field.entity\n return node\n case 'select':\n node.type = 'string'\n node.enum = (field.options ?? []).map((option) => option.value)\n return node\n default:\n // text, richtext, image, url, date, datetime\n node.type = 'string'\n applyValidation(node, field)\n return node\n }\n}\n\n/**\n * The JSON Schema one record's `data` is validated against — on write, in the\n * admin form, and as the agent's generation contract. `additionalProperties:\n * false` is the schema-level I2: a field the declaration does not know is an\n * error, not silently-unfilterable baggage (the Medusa `metadata` disease).\n */\nexport function entityRecordSchema(declaration: Pick<EntityDeclaration, 'fields' | 'title' | 'description'>): JsonSchema {\n const properties: Record<string, JsonSchema> = {}\n const required: string[] = []\n for (const [name, field] of Object.entries(declaration.fields)) {\n properties[name] = fieldToJsonSchema(name, field)\n if (field.required) required.push(name)\n }\n const schema: JsonSchema = {\n type: 'object',\n title: declaration.title,\n properties,\n additionalProperties: false,\n }\n if (declaration.description) schema.description = declaration.description\n if (required.length > 0) schema.required = required\n return schema\n}\n\n// --- Write-time validation ----------------------------------------------------\n\nexport interface EntityRecordIssue {\n /** Dotted path into the record data ('hours', 'geo.lat'). */\n path: string\n code: 'unknown-field' | 'missing-field' | 'invalid-value'\n message: string\n /** The valid set, on unknown-id errors — what the agent corrects on. */\n valid?: string[]\n}\n\nfunction typeOf(value: unknown): string {\n return Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value\n}\n\n/** Declared bounds, checked after the type already matched. A malformed\n * `pattern` is the merchant's typo, not a crash: it fails the value it was\n * meant to guard rather than taking the whole write down. */\nfunction checkBounds(\n issues: EntityRecordIssue[],\n name: string,\n field: EntityField,\n value: string | number,\n): void {\n const v = field.validation\n if (!v) return\n const invalid = (message: string) => issues.push({ path: name, code: 'invalid-value', message })\n\n if (typeof value === 'number') {\n if (v.min !== undefined && value < v.min) invalid(`\"${name}\" is below the minimum of ${v.min}`)\n if (v.max !== undefined && value > v.max) invalid(`\"${name}\" is above the maximum of ${v.max}`)\n return\n }\n if (v.minLength !== undefined && value.length < v.minLength) {\n invalid(`\"${name}\" is shorter than ${v.minLength} character(s)`)\n }\n if (v.maxLength !== undefined && value.length > v.maxLength) {\n invalid(`\"${name}\" is longer than ${v.maxLength} character(s)`)\n }\n if (v.pattern !== undefined) {\n let re: RegExp | null = null\n try {\n re = new RegExp(v.pattern)\n } catch {\n invalid(`\"${name}\" has an unreadable pattern in its definition`)\n }\n if (re && !re.test(value)) invalid(`\"${name}\" does not match the expected format`)\n }\n}\n\n/**\n * Validate one record's `data` against a declaration — the write gate every\n * EntityStore implementation runs. Pure and total: returns issues, never throws.\n */\nexport function validateEntityRecordData(\n declaration: Pick<EntityDeclaration, 'fields'>,\n data: unknown,\n): EntityRecordIssue[] {\n const issues: EntityRecordIssue[] = []\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n return [{ path: '', code: 'invalid-value', message: `record data is an object, got ${typeOf(data)}` }]\n }\n const record = data as Record<string, unknown>\n const fieldNames = Object.keys(declaration.fields)\n\n for (const [name, value] of Object.entries(record)) {\n const field = declaration.fields[name]\n if (!field) {\n issues.push({\n path: name,\n code: 'unknown-field',\n message: `field \"${name}\" is not declared by this entity`,\n valid: fieldNames,\n })\n continue\n }\n if (value === null || value === undefined) continue // absence checked below\n switch (field.type) {\n case 'number':\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n issues.push({ path: name, code: 'invalid-value', message: `\"${name}\" expects a number, got ${typeOf(value)}` })\n } else {\n checkBounds(issues, name, field, value)\n }\n break\n case 'boolean':\n if (typeof value !== 'boolean') {\n issues.push({ path: name, code: 'invalid-value', message: `\"${name}\" expects a boolean, got ${typeOf(value)}` })\n }\n break\n case 'json':\n break // any JSON value\n case 'point': {\n const point = value as Record<string, unknown>\n if (\n typeOf(value) !== 'object' ||\n typeof point.lat !== 'number' ||\n typeof point.lng !== 'number' ||\n Object.keys(point).length !== 2\n ) {\n issues.push({ path: name, code: 'invalid-value', message: `\"${name}\" expects {lat: number, lng: number}` })\n }\n break\n }\n case 'select': {\n const allowed = (field.options ?? []).map((option) => option.value)\n if (typeof value !== 'string') {\n issues.push({ path: name, code: 'invalid-value', message: `\"${name}\" expects a string, got ${typeOf(value)}` })\n } else if (!allowed.includes(value)) {\n issues.push({\n path: name,\n code: 'invalid-value',\n message: `\"${name}\" does not accept \"${value}\"`,\n valid: allowed,\n })\n }\n break\n }\n default:\n // text, richtext, image, url, date, datetime, ref — strings on the wire.\n if (typeof value !== 'string') {\n issues.push({ path: name, code: 'invalid-value', message: `\"${name}\" expects a string, got ${typeOf(value)}` })\n } else {\n checkBounds(issues, name, field, value)\n }\n }\n }\n\n for (const [name, field] of Object.entries(declaration.fields)) {\n if (field.required && (record[name] === undefined || record[name] === null || record[name] === '')) {\n issues.push({ path: name, code: 'missing-field', message: `required field \"${name}\" is missing` })\n }\n }\n return issues\n}\n\n// --- Catalog ------------------------------------------------------------------\n\n/** The uniform envelope plus the entity-specific fields the agent reads. */\nexport interface EntityDescriptor extends RegistryEntryDescriptor {\n /** JSON Schema for a record's data (alias of `schema`, named for intent). */\n recordSchema?: JsonSchema\n access: EntityAccess\n scope: 'tenant'\n storage: EntityStorageDescriptor\n indexes: readonly (readonly string[])[]\n titleField?: string\n displayFields: readonly string[]\n}\n\n/** Every declared entity reduced to its descriptor, sorted by key — what\n * describeStore publishes and the agent generates against. */\nexport function describeEntities(): EntityDescriptor[] {\n return entityDeclarationRegistry.describe().map((base) => {\n const declaration = entityDeclarationRegistry.get(base.id)!\n return {\n ...base,\n recordSchema: base.schema,\n access: declaration.access,\n scope: declaration.scope,\n storage: declaration.storage,\n indexes: declaration.indexes,\n titleField: declaration.titleField,\n displayFields: declaration.displayFields,\n }\n })\n}\n\n// --- Generated admin CRUD descriptor -------------------------------------------\n\n/** How each entity field type is edited. Targets the existing FieldDef\n * vocabulary (packages/core/src/types/crud.ts) that the SaaS CRUD renders —\n * the descriptor is data, so a form is derivable without new machinery. */\nconst FIELD_TYPE_TO_INPUT: Record<EntityFieldType, FieldType> = {\n text: 'text',\n richtext: 'markdown',\n number: 'number',\n boolean: 'boolean',\n // JSON and point have no dedicated control yet; they degrade to text inputs\n // with a hint, which is honest — the descriptor still names the real type in\n // the record schema, so a richer control can adopt them without a migration.\n json: 'textarea',\n point: 'text',\n image: 'image',\n url: 'url',\n ref: 'relation',\n date: 'date',\n datetime: 'datetime',\n select: 'select',\n}\n\nexport interface EntityAdminForm {\n entity: string\n title: string\n fields: FieldDef[]\n}\n\n/**\n * The admin CRUD form for an entity, emitted from the declaration as data.\n * Field order is declaration order; labels default to the field name; `ref`\n * fields become relation pickers over the generic records table filtered to\n * the target entity.\n */\nexport function entityAdminForm(declaration: EntityDeclaration): EntityAdminForm {\n const fields: FieldDef[] = Object.entries(declaration.fields).map(([name, field]) => {\n const def: FieldDef = {\n key: name,\n label: field.label ?? name,\n type: FIELD_TYPE_TO_INPUT[field.type],\n showInForm: true,\n showInTable: declaration.displayFields.includes(name),\n }\n if (field.required) def.required = true\n if (field.help) def.hint = field.help\n if (field.default !== undefined) def.defaultValue = field.default\n if (field.type === 'json') def.hint = field.help ?? 'JSON value'\n if (field.type === 'point') def.hint = field.help ?? 'lat,lng'\n if (field.type === 'select') {\n def.options = (field.options ?? []).map((option) => ({ label: option.label ?? option.value, value: option.value }))\n }\n if (field.type === 'ref' && field.entity) {\n def.relation = {\n table: declaration.storage.table,\n valueField: 'id',\n labelField: 'slug',\n filter: { entity: field.entity },\n }\n }\n return def\n })\n return { entity: declaration.key, title: declaration.title, fields }\n}\n\n// --- Custom fields on core records ---------------------------------------------\n// Extra fields on a record the SDK already owns are not a new entity, and not a\n// new column: they are keys inside `custom_fields` (migration 034), governed by\n// plg_entity_fields (035). A key the registry does not know is a write error —\n// unlike Medusa's `metadata` (76 of 148 models, validated as z.unknown, and\n// silently unfilterable), and unlike CRM's people.metadata->'fields' today.\n//\n// Two halves make the registry, and they merge:\n// declared — this module. Comes from plugin/app code, re-asserted on deploy.\n// merchant — plg_entity_fields rows, defined in the admin with no deploy.\n// This file owns the declared half only; @fayz-ai/core/fields loads the other\n// and merges them. Declared wins on a collision, so a deploy can adopt a key a\n// merchant invented without either side losing work.\n\n/** The record kind a field hangs off: an archetype name, snake_case. Open on\n * purpose — the next archetype is a value, not a release. Mirrors the CHECK on\n * plg_entity_fields.reference. */\nconst REFERENCE_RE = /^[a-z][a-z0-9_]*$/\n\nexport interface CustomFieldsDeclaration {\n reference: string\n fields: Record<string, EntityField>\n}\n\nexport const customFieldsRegistry = new Registry<CustomFieldsDeclaration>('customFields')\n\n/**\n * Declare custom fields on a core record kind. One declaration per reference\n * (re-declaring replaces — registry semantics, so an app's registry.tsx wins).\n */\nexport function defineCustomFields(\n reference: string,\n fields: Record<string, EntityField>,\n meta: { source?: RegistrySource; pluginId?: string } = {},\n): CustomFieldsDeclaration {\n if (!REFERENCE_RE.test(reference)) {\n fail(`defineCustomFields: \"${reference}\" is not a valid record kind (${REFERENCE_RE}).`)\n }\n for (const [name, field] of Object.entries(fields)) {\n if (!FIELD_NAME_RE.test(name)) {\n fail(`defineCustomFields(\"${reference}\"): \"${name}\" is not a valid field name (${FIELD_NAME_RE}).`)\n }\n if (!(ENTITY_FIELD_TYPES as readonly string[]).includes(field?.type as string)) {\n fail(`defineCustomFields(\"${reference}\"): field \"${name}\" has unknown type \"${String(field?.type)}\".`, ENTITY_FIELD_TYPES)\n }\n if (field.type === 'select' && !(field.options ?? []).length) {\n fail(`defineCustomFields(\"${reference}\"): select field \"${name}\" declares no options.`)\n }\n }\n const declaration: CustomFieldsDeclaration = { reference, fields }\n customFieldsRegistry.register(reference, declaration, {\n title: `Custom fields: ${reference}`,\n propsSchema: entityRecordSchema({ title: `${reference} custom fields`, fields }),\n source: meta.source ?? 'app',\n pluginId: meta.pluginId,\n })\n return declaration\n}\n\n/**\n * The declared half for a record kind. Returns an empty set rather than\n * throwing: a tenant whose only fields came from the admin is the normal case,\n * and the merge in @fayz-ai/core/fields is what completes the picture.\n */\nexport function declaredCustomFields(reference: string): Record<string, EntityField> {\n return customFieldsRegistry.get(reference)?.fields ?? {}\n}\n\nexport function hasCustomFieldsDeclaration(reference: string): boolean {\n return customFieldsRegistry.has(reference)\n}\n\n/** Test seam. */\nexport function clearCustomFieldsDeclarations(): void {\n customFieldsRegistry.clear()\n}\n"]}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
// src/data/filters.ts
|
|
4
|
+
var LOWER_INCLUSIVE = ["from", "gte", "start", "after", "since", "min"];
|
|
5
|
+
var LOWER_EXCLUSIVE = ["gt"];
|
|
6
|
+
var UPPER_INCLUSIVE = ["to", "lte", "end", "until", "before", "max"];
|
|
7
|
+
var UPPER_EXCLUSIVE = ["lt"];
|
|
8
|
+
function pick(source, names) {
|
|
9
|
+
for (const name of names) {
|
|
10
|
+
if (source[name] !== void 0 && source[name] !== null) return source[name];
|
|
11
|
+
const dollar = `$${name}`;
|
|
12
|
+
if (source[dollar] !== void 0 && source[dollar] !== null) return source[dollar];
|
|
13
|
+
}
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
function parseRangeFilter(value) {
|
|
17
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
18
|
+
const source = value;
|
|
19
|
+
const range = {};
|
|
20
|
+
const gte = pick(source, LOWER_INCLUSIVE);
|
|
21
|
+
const gt = pick(source, LOWER_EXCLUSIVE);
|
|
22
|
+
const lte = pick(source, UPPER_INCLUSIVE);
|
|
23
|
+
const lt = pick(source, UPPER_EXCLUSIVE);
|
|
24
|
+
if (gte !== void 0) range.gte = gte;
|
|
25
|
+
if (gt !== void 0) range.gt = gt;
|
|
26
|
+
if (lte !== void 0) range.lte = lte;
|
|
27
|
+
if (lt !== void 0) range.lt = lt;
|
|
28
|
+
return Object.keys(range).length ? range : null;
|
|
29
|
+
}
|
|
30
|
+
function isFilterObject(value) {
|
|
31
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32
|
+
}
|
|
33
|
+
function comparable(value) {
|
|
34
|
+
if (typeof value === "number") return value;
|
|
35
|
+
if (value instanceof Date) return value.getTime();
|
|
36
|
+
const ts = Date.parse(String(value));
|
|
37
|
+
if (!Number.isNaN(ts)) return ts;
|
|
38
|
+
return Number(value);
|
|
39
|
+
}
|
|
40
|
+
function matchesRange(raw, range) {
|
|
41
|
+
const value = comparable(raw);
|
|
42
|
+
if (Number.isNaN(value)) return false;
|
|
43
|
+
if (range.gte !== void 0 && value < comparable(range.gte)) return false;
|
|
44
|
+
if (range.gt !== void 0 && value <= comparable(range.gt)) return false;
|
|
45
|
+
if (range.lte !== void 0 && value > comparable(range.lte)) return false;
|
|
46
|
+
if (range.lt !== void 0 && value >= comparable(range.lt)) return false;
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
function applyRangeToQuery(query, column, range) {
|
|
50
|
+
let q = query;
|
|
51
|
+
for (const op of ["gte", "gt", "lte", "lt"]) {
|
|
52
|
+
const bound = range[op];
|
|
53
|
+
if (bound === void 0) continue;
|
|
54
|
+
q = q[op](column, bound);
|
|
55
|
+
}
|
|
56
|
+
return q;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/data/supabase.ts
|
|
60
|
+
function camelToSnake(str) {
|
|
61
|
+
return str.replace(/[A-Z]/g, (c) => "_" + c.toLowerCase());
|
|
62
|
+
}
|
|
63
|
+
function snakeToCamel(str) {
|
|
64
|
+
return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
65
|
+
}
|
|
66
|
+
function mapRow(row, columnMap) {
|
|
67
|
+
const result = {};
|
|
68
|
+
for (const [key, value] of Object.entries(row)) {
|
|
69
|
+
const camelKey = columnMap?.[key] ?? snakeToCamel(key);
|
|
70
|
+
result[camelKey] = value;
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
function mapEntity(entity, columnMap) {
|
|
75
|
+
const reverseMap = {};
|
|
76
|
+
if (columnMap) {
|
|
77
|
+
for (const [snake, camel] of Object.entries(columnMap)) {
|
|
78
|
+
reverseMap[camel] = snake;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const result = {};
|
|
82
|
+
for (const [key, value] of Object.entries(entity)) {
|
|
83
|
+
if (key === "id" || key === "createdAt" || key === "updatedAt" || key === "tenantId" || key === "createdBy") continue;
|
|
84
|
+
const snakeKey = reverseMap[key] ?? camelToSnake(key);
|
|
85
|
+
result[snakeKey] = value;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
var _globalSupabaseClient = null;
|
|
90
|
+
function setGlobalSupabaseClient(client) {
|
|
91
|
+
_globalSupabaseClient = client;
|
|
92
|
+
}
|
|
93
|
+
function getSupabaseClientOptional() {
|
|
94
|
+
return _globalSupabaseClient;
|
|
95
|
+
}
|
|
96
|
+
function createSupabaseProvider(table, config) {
|
|
97
|
+
const schema = config?.schema ?? "public";
|
|
98
|
+
const tenantIdCol = config?.tenantIdColumn ?? "tenant_id";
|
|
99
|
+
const searchCols = config?.searchColumns ?? [];
|
|
100
|
+
const selectCols = config?.selectColumns ?? "*";
|
|
101
|
+
const columnMap = config?.columnMap;
|
|
102
|
+
function resolveTenantId() {
|
|
103
|
+
if (!config?.tenantId) return void 0;
|
|
104
|
+
return typeof config.tenantId === "function" ? config.tenantId() : config.tenantId;
|
|
105
|
+
}
|
|
106
|
+
function getClient() {
|
|
107
|
+
const supabase = config?.supabaseClient ?? _globalSupabaseClient;
|
|
108
|
+
if (!supabase) throw new Error(`[@fayz-ai/core] Supabase client not available. Call createFayzApp with a provider first.`);
|
|
109
|
+
return schema === "public" ? supabase : supabase.schema(schema);
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
async list(query) {
|
|
113
|
+
const wantCount = query.countMode !== "none";
|
|
114
|
+
let q = getClient().from(table).select(selectCols, wantCount ? { count: "exact" } : void 0);
|
|
115
|
+
const tenantId = resolveTenantId();
|
|
116
|
+
if (tenantId) q = q.eq(tenantIdCol, tenantId);
|
|
117
|
+
if (config?.filters) {
|
|
118
|
+
for (const [col, val] of Object.entries(config.filters)) {
|
|
119
|
+
q = q.eq(col, val);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (query.filters) {
|
|
123
|
+
for (const [key, val] of Object.entries(query.filters)) {
|
|
124
|
+
if (val == null || val === "") continue;
|
|
125
|
+
const col = columnMap?.[key] ?? camelToSnake(key);
|
|
126
|
+
const range = parseRangeFilter(val);
|
|
127
|
+
if (range) {
|
|
128
|
+
q = applyRangeToQuery(q, col, range);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (isFilterObject(val)) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
`[@fayz-ai/core] Filter "${key}" is an object with no recognised bound. Use {from,to} / {gte,lte,gt,lt} for ranges, or a plain value for equality.`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
q = q.eq(col, val);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (query.search && searchCols.length > 0) {
|
|
140
|
+
const term = `%${query.search}%`;
|
|
141
|
+
const orClause = searchCols.map((col) => `${camelToSnake(col)}.ilike.${term}`).join(",");
|
|
142
|
+
q = q.or(orClause);
|
|
143
|
+
}
|
|
144
|
+
if (query.sortBy) {
|
|
145
|
+
q = q.order(camelToSnake(query.sortBy), { ascending: query.sortDir !== "desc" });
|
|
146
|
+
} else {
|
|
147
|
+
q = q.order("created_at", { ascending: false });
|
|
148
|
+
}
|
|
149
|
+
const page = query.page ?? 1;
|
|
150
|
+
const pageSize = query.pageSize ?? 50;
|
|
151
|
+
const from = (page - 1) * pageSize;
|
|
152
|
+
q = q.range(from, from + pageSize - 1);
|
|
153
|
+
const { data, error, count } = await q;
|
|
154
|
+
if (error) throw error;
|
|
155
|
+
return {
|
|
156
|
+
data: (data ?? []).map((row) => mapRow(row, columnMap)),
|
|
157
|
+
total: count ?? 0
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
async create(data) {
|
|
161
|
+
const row = mapEntity(data, columnMap);
|
|
162
|
+
const tenantId = resolveTenantId();
|
|
163
|
+
if (tenantId) row[tenantIdCol] = tenantId;
|
|
164
|
+
if (config?.defaults) {
|
|
165
|
+
for (const [col, val] of Object.entries(config.defaults)) {
|
|
166
|
+
if (row[col] === void 0) row[col] = val;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const { data: created, error } = await getClient().from(table).insert(row).select().single();
|
|
170
|
+
if (error) throw error;
|
|
171
|
+
return mapRow(created, columnMap);
|
|
172
|
+
},
|
|
173
|
+
async createMany(rows, options) {
|
|
174
|
+
const tenantId = resolveTenantId();
|
|
175
|
+
const size = Math.max(1, options?.chunkSize ?? 200);
|
|
176
|
+
const prepared = rows.map((r) => {
|
|
177
|
+
const row = mapEntity(r, columnMap);
|
|
178
|
+
if (tenantId) row[tenantIdCol] = tenantId;
|
|
179
|
+
if (config?.defaults) {
|
|
180
|
+
for (const [col, val] of Object.entries(config.defaults)) {
|
|
181
|
+
if (row[col] === void 0) row[col] = val;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return row;
|
|
185
|
+
});
|
|
186
|
+
let created = 0;
|
|
187
|
+
const failed = [];
|
|
188
|
+
for (let start = 0; start < prepared.length; start += size) {
|
|
189
|
+
const chunk = prepared.slice(start, start + size);
|
|
190
|
+
const { error } = await getClient().from(table).insert(chunk);
|
|
191
|
+
if (!error) {
|
|
192
|
+
created += chunk.length;
|
|
193
|
+
} else {
|
|
194
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
195
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
196
|
+
const { error: rowError } = await getClient().from(table).insert(chunk[i]);
|
|
197
|
+
if (rowError) {
|
|
198
|
+
failed.push({
|
|
199
|
+
index: start + i,
|
|
200
|
+
message: rowError instanceof Error ? rowError.message : String(rowError ?? message)
|
|
201
|
+
});
|
|
202
|
+
} else created += 1;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
options?.onProgress?.(Math.min(start + chunk.length, prepared.length), prepared.length);
|
|
206
|
+
}
|
|
207
|
+
return { created, failed };
|
|
208
|
+
},
|
|
209
|
+
async update(id, data) {
|
|
210
|
+
const row = mapEntity(data, columnMap);
|
|
211
|
+
const { data: updated, error } = await getClient().from(table).update(row).eq("id", id).select().single();
|
|
212
|
+
if (error) throw error;
|
|
213
|
+
return mapRow(updated, columnMap);
|
|
214
|
+
},
|
|
215
|
+
async remove(id) {
|
|
216
|
+
const { error } = await getClient().from(table).delete().eq("id", id);
|
|
217
|
+
if (error) throw error;
|
|
218
|
+
},
|
|
219
|
+
async removeMany(ids) {
|
|
220
|
+
if (!ids.length) return;
|
|
221
|
+
const { error } = await getClient().from(table).delete().in("id", ids);
|
|
222
|
+
if (error) throw error;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/lib/cache.ts
|
|
228
|
+
function sortDeep(value) {
|
|
229
|
+
if (value === null || value === void 0 || typeof value !== "object") return value;
|
|
230
|
+
if (Array.isArray(value)) return value.map(sortDeep);
|
|
231
|
+
const sorted = {};
|
|
232
|
+
for (const k of Object.keys(value).sort()) {
|
|
233
|
+
sorted[k] = sortDeep(value[k]);
|
|
234
|
+
}
|
|
235
|
+
return sorted;
|
|
236
|
+
}
|
|
237
|
+
function stableKey(...parts) {
|
|
238
|
+
return parts.map((p) => typeof p === "string" ? p : JSON.stringify(sortDeep(p))).join(":");
|
|
239
|
+
}
|
|
240
|
+
function createCacheStore(config) {
|
|
241
|
+
const defaultTTL = config?.defaultTTL ?? 6e4;
|
|
242
|
+
const maxEntries = config?.maxEntries ?? 500;
|
|
243
|
+
const entries = /* @__PURE__ */ new Map();
|
|
244
|
+
function evictLRU() {
|
|
245
|
+
if (entries.size <= maxEntries) return;
|
|
246
|
+
let oldestKey = null;
|
|
247
|
+
let oldestAccess = Infinity;
|
|
248
|
+
for (const [key, entry] of entries) {
|
|
249
|
+
if (entry.lastAccess < oldestAccess) {
|
|
250
|
+
oldestAccess = entry.lastAccess;
|
|
251
|
+
oldestKey = key;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (oldestKey) entries.delete(oldestKey);
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
get(key) {
|
|
258
|
+
const entry = entries.get(key);
|
|
259
|
+
if (!entry) return void 0;
|
|
260
|
+
if (Date.now() > entry.expiresAt) {
|
|
261
|
+
entries.delete(key);
|
|
262
|
+
return void 0;
|
|
263
|
+
}
|
|
264
|
+
entry.lastAccess = Date.now();
|
|
265
|
+
return entry.data;
|
|
266
|
+
},
|
|
267
|
+
set(key, data, ttl) {
|
|
268
|
+
const now = Date.now();
|
|
269
|
+
entries.set(key, {
|
|
270
|
+
data,
|
|
271
|
+
expiresAt: now + (ttl ?? defaultTTL),
|
|
272
|
+
lastAccess: now
|
|
273
|
+
});
|
|
274
|
+
evictLRU();
|
|
275
|
+
},
|
|
276
|
+
invalidate(prefix) {
|
|
277
|
+
for (const key of entries.keys()) {
|
|
278
|
+
if (key.startsWith(prefix)) {
|
|
279
|
+
entries.delete(key);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
clear() {
|
|
284
|
+
entries.clear();
|
|
285
|
+
},
|
|
286
|
+
size() {
|
|
287
|
+
return entries.size;
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
var globalCache = createCacheStore();
|
|
292
|
+
function clearGlobalCache() {
|
|
293
|
+
globalCache.clear();
|
|
294
|
+
}
|
|
295
|
+
var _activeTenantId;
|
|
296
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
297
|
+
function setActiveTenantId(id) {
|
|
298
|
+
if (id !== _activeTenantId) {
|
|
299
|
+
_activeTenantId = id;
|
|
300
|
+
clearGlobalCache();
|
|
301
|
+
for (const l of listeners) l();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function getActiveTenantId() {
|
|
305
|
+
return _activeTenantId;
|
|
306
|
+
}
|
|
307
|
+
function subscribeActiveTenant(listener) {
|
|
308
|
+
listeners.add(listener);
|
|
309
|
+
return () => {
|
|
310
|
+
listeners.delete(listener);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function useActiveTenantId() {
|
|
314
|
+
return React.useSyncExternalStore(subscribeActiveTenant, getActiveTenantId, getActiveTenantId);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export { applyRangeToQuery, clearGlobalCache, createCacheStore, createSupabaseProvider, getActiveTenantId, getSupabaseClientOptional, globalCache, isFilterObject, matchesRange, parseRangeFilter, setActiveTenantId, setGlobalSupabaseClient, stableKey, subscribeActiveTenant, useActiveTenantId };
|
|
318
|
+
//# sourceMappingURL=chunk-LARZWDHA.js.map
|
|
319
|
+
//# sourceMappingURL=chunk-LARZWDHA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/data/filters.ts","../src/data/supabase.ts","../src/lib/cache.ts","../src/lib/tenant.ts"],"names":[],"mappings":";;;AAiBA,IAAM,kBAAkB,CAAC,MAAA,EAAQ,OAAO,OAAA,EAAS,OAAA,EAAS,SAAS,KAAK,CAAA;AACxE,IAAM,eAAA,GAAkB,CAAC,IAAI,CAAA;AAC7B,IAAM,kBAAkB,CAAC,IAAA,EAAM,OAAO,KAAA,EAAO,OAAA,EAAS,UAAU,KAAK,CAAA;AACrE,IAAM,eAAA,GAAkB,CAAC,IAAI,CAAA;AAE7B,SAAS,IAAA,CAAK,QAAiC,KAAA,EAA0B;AACvE,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,MAAA,CAAO,IAAI,CAAA,KAAM,MAAA,IAAa,MAAA,CAAO,IAAI,CAAA,KAAM,IAAA,EAAM,OAAO,MAAA,CAAO,IAAI,CAAA;AAC3E,IAAA,MAAM,MAAA,GAAS,IAAI,IAAI,CAAA,CAAA;AACvB,IAAA,IAAI,MAAA,CAAO,MAAM,CAAA,KAAM,MAAA,IAAa,MAAA,CAAO,MAAM,CAAA,KAAM,IAAA,EAAM,OAAO,MAAA,CAAO,MAAM,CAAA;AAAA,EACnF;AACA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,iBAAiB,KAAA,EAAoC;AACnE,EAAA,IAAI,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,IAAA;AAChF,EAAA,MAAM,MAAA,GAAS,KAAA;AACf,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,EAAQ,eAAe,CAAA;AACxC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,MAAA,EAAQ,eAAe,CAAA;AACvC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,EAAQ,eAAe,CAAA;AACxC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,MAAA,EAAQ,eAAe,CAAA;AACvC,EAAA,IAAI,GAAA,KAAQ,MAAA,EAAW,KAAA,CAAM,GAAA,GAAM,GAAA;AACnC,EAAA,IAAI,EAAA,KAAO,MAAA,EAAW,KAAA,CAAM,EAAA,GAAK,EAAA;AACjC,EAAA,IAAI,GAAA,KAAQ,MAAA,EAAW,KAAA,CAAM,GAAA,GAAM,GAAA;AACnC,EAAA,IAAI,EAAA,KAAO,MAAA,EAAW,KAAA,CAAM,EAAA,GAAK,EAAA;AACjC,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,KAAA,GAAQ,IAAA;AAC7C;AAGO,SAAS,eAAe,KAAA,EAAyB;AACtD,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAEA,SAAS,WAAW,KAAA,EAAwB;AAC1C,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,KAAA,YAAiB,IAAA,EAAM,OAAO,KAAA,CAAM,OAAA,EAAQ;AAChD,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACnC,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,EAAE,GAAG,OAAO,EAAA;AAC9B,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AAGO,SAAS,YAAA,CAAa,KAAc,KAAA,EAA6B;AACtE,EAAA,MAAM,KAAA,GAAQ,WAAW,GAAG,CAAA;AAC5B,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,EAAG,OAAO,KAAA;AAChC,EAAA,IAAI,KAAA,CAAM,QAAQ,MAAA,IAAa,KAAA,GAAQ,WAAW,KAAA,CAAM,GAAG,GAAG,OAAO,KAAA;AACrE,EAAA,IAAI,KAAA,CAAM,OAAO,MAAA,IAAa,KAAA,IAAS,WAAW,KAAA,CAAM,EAAE,GAAG,OAAO,KAAA;AACpE,EAAA,IAAI,KAAA,CAAM,QAAQ,MAAA,IAAa,KAAA,GAAQ,WAAW,KAAA,CAAM,GAAG,GAAG,OAAO,KAAA;AACrE,EAAA,IAAI,KAAA,CAAM,OAAO,MAAA,IAAa,KAAA,IAAS,WAAW,KAAA,CAAM,EAAE,GAAG,OAAO,KAAA;AACpE,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,iBAAA,CACd,KAAA,EACA,MAAA,EACA,KAAA,EACG;AACH,EAAA,IAAI,CAAA,GAAI,KAAA;AACR,EAAA,KAAA,MAAW,MAAM,CAAC,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,IAAI,CAAA,EAAY;AACpD,IAAA,MAAM,KAAA,GAAQ,MAAM,EAAE,CAAA;AACtB,IAAA,IAAI,UAAU,MAAA,EAAW;AACzB,IAAA,CAAA,GAAI,CAAA,CAAE,EAAE,CAAA,CAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,CAAA;AACT;;;AC1EA,SAAS,aAAa,GAAA,EAAqB;AACzC,EAAA,OAAO,GAAA,CAAI,QAAQ,QAAA,EAAU,CAAC,MAAM,GAAA,GAAM,CAAA,CAAE,aAAa,CAAA;AAC3D;AAEA,SAAS,aAAa,GAAA,EAAqB;AACzC,EAAA,OAAO,GAAA,CAAI,QAAQ,WAAA,EAAa,CAAC,GAAG,CAAA,KAAc,CAAA,CAAE,aAAa,CAAA;AACnE;AAEA,SAAS,MAAA,CAAU,KAA8B,SAAA,EAAuC;AACtF,EAAA,MAAM,SAAkC,EAAC;AACzC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9C,IAAA,MAAM,QAAA,GAAW,SAAA,GAAY,GAAG,CAAA,IAAK,aAAa,GAAG,CAAA;AACrD,IAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,KAAA;AAAA,EACrB;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,SAAA,CAAU,QAAiC,SAAA,EAA6D;AAC/G,EAAA,MAAM,aAAqC,EAAC;AAC5C,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtD,MAAA,UAAA,CAAW,KAAK,CAAA,GAAI,KAAA;AAAA,IACtB;AAAA,EACF;AACA,EAAA,MAAM,SAAkC,EAAC;AACzC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAKjD,IAAA,IAAI,GAAA,KAAQ,QAAQ,GAAA,KAAQ,WAAA,IAAe,QAAQ,WAAA,IAAe,GAAA,KAAQ,UAAA,IAAc,GAAA,KAAQ,WAAA,EAAa;AAC7G,IAAA,MAAM,QAAA,GAAW,UAAA,CAAW,GAAG,CAAA,IAAK,aAAa,GAAG,CAAA;AACpD,IAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,KAAA;AAAA,EACrB;AACA,EAAA,OAAO,MAAA;AACT;AAGA,IAAI,qBAAA,GAAwC,IAAA;AAErC,SAAS,wBAAwB,MAAA,EAAuB;AAC7D,EAAA,qBAAA,GAAwB,MAAA;AAC1B;AAEO,SAAS,yBAAA,GAA4C;AAC1D,EAAA,OAAO,qBAAA;AACT;AAEO,SAAS,sBAAA,CACd,OACA,MAAA,EACiB;AACjB,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,QAAA;AACjC,EAAA,MAAM,WAAA,GAAc,QAAQ,cAAA,IAAkB,WAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,MAAA,EAAQ,aAAA,IAAiB,EAAC;AAC7C,EAAA,MAAM,UAAA,GAAa,QAAQ,aAAA,IAAiB,GAAA;AAC5C,EAAA,MAAM,YAAY,MAAA,EAAQ,SAAA;AAE1B,EAAA,SAAS,eAAA,GAAsC;AAC7C,IAAA,IAAI,CAAC,MAAA,EAAQ,QAAA,EAAU,OAAO,MAAA;AAC9B,IAAA,OAAO,OAAO,MAAA,CAAO,QAAA,KAAa,aAAa,MAAA,CAAO,QAAA,KAAa,MAAA,CAAO,QAAA;AAAA,EAC5E;AAEA,EAAA,SAAS,SAAA,GAAY;AACnB,IAAA,MAAM,QAAA,GAAY,QAAQ,cAAA,IAAkB,qBAAA;AAI5C,IAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,MAAM,CAAA,wFAAA,CAA0F,CAAA;AACzH,IAAA,OAAO,MAAA,KAAW,QAAA,GAAY,QAAA,GAAiD,QAAA,CAAS,OAAO,MAAM,CAAA;AAAA,EACvG;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,KAAA,EAA0C;AAEnD,MAAA,MAAM,SAAA,GAAY,MAAM,SAAA,KAAc,MAAA;AACtC,MAAA,IAAI,CAAA,GAAK,SAAA,EAAU,CAAE,IAAA,CAAK,KAAK,CAAA,CAC5B,MAAA,CAAO,UAAA,EAAY,SAAA,GAAY,EAAE,KAAA,EAAO,OAAA,KAAY,MAAS,CAAA;AAEhE,MAAA,MAAM,WAAW,eAAA,EAAgB;AACjC,MAAA,IAAI,QAAA,EAAU,CAAA,GAAK,CAAA,CAAoD,EAAA,CAAG,aAAa,QAAQ,CAAA;AAE/F,MAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,QAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,EAAG;AACvD,UAAA,CAAA,GAAK,CAAA,CAAgD,EAAA,CAAG,GAAA,EAAK,GAAG,CAAA;AAAA,QAClE;AAAA,MACF;AAKA,MAAA,IAAI,MAAM,OAAA,EAAS;AACjB,QAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA,EAAG;AACtD,UAAA,IAAI,GAAA,IAAO,IAAA,IAAQ,GAAA,KAAQ,EAAA,EAAI;AAC/B,UAAA,MAAM,GAAA,GAAM,SAAA,GAAY,GAAG,CAAA,IAAK,aAAa,GAAG,CAAA;AAChD,UAAA,MAAM,KAAA,GAAQ,iBAAiB,GAAG,CAAA;AAClC,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,CAAA,GAAI,iBAAA,CAAkB,CAAA,EAAG,GAAA,EAAK,KAAK,CAAA;AACnC,YAAA;AAAA,UACF;AACA,UAAA,IAAI,cAAA,CAAe,GAAG,CAAA,EAAG;AACvB,YAAA,MAAM,IAAI,KAAA;AAAA,cACR,2BAA2B,GAAG,CAAA,mHAAA;AAAA,aAEhC;AAAA,UACF;AACA,UAAA,CAAA,GAAK,CAAA,CAAiD,EAAA,CAAG,GAAA,EAAK,GAAG,CAAA;AAAA,QACnE;AAAA,MACF;AAEA,MAAA,IAAI,KAAA,CAAM,MAAA,IAAU,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG;AACzC,QAAA,MAAM,IAAA,GAAO,CAAA,CAAA,EAAI,KAAA,CAAM,MAAM,CAAA,CAAA,CAAA;AAC7B,QAAA,MAAM,QAAA,GAAW,UAAA,CAAW,GAAA,CAAI,CAAC,QAAQ,CAAA,EAAG,YAAA,CAAa,GAAG,CAAC,CAAA,OAAA,EAAU,IAAI,CAAA,CAAE,CAAA,CAAE,KAAK,GAAG,CAAA;AACvF,QAAA,CAAA,GAAK,CAAA,CAAqC,GAAG,QAAQ,CAAA;AAAA,MACvD;AAEA,MAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,QAAA,CAAA,GAAK,CAAA,CACF,KAAA,CAAM,YAAA,CAAa,KAAA,CAAM,MAAM,CAAA,EAAG,EAAE,SAAA,EAAW,KAAA,CAAM,OAAA,KAAY,MAAA,EAAQ,CAAA;AAAA,MAC9E,CAAA,MAAO;AACL,QAAA,CAAA,GAAK,EACF,KAAA,CAAM,YAAA,EAAc,EAAE,SAAA,EAAW,OAAO,CAAA;AAAA,MAC7C;AAEA,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,IAAQ,CAAA;AAC3B,MAAA,MAAM,QAAA,GAAW,MAAM,QAAA,IAAY,EAAA;AACnC,MAAA,MAAM,IAAA,GAAA,CAAQ,OAAO,CAAA,IAAK,QAAA;AAC1B,MAAA,CAAA,GAAK,CAAA,CAAmD,KAAA,CAAM,IAAA,EAAM,IAAA,GAAO,WAAW,CAAC,CAAA;AAEvF,MAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,KAAU,MAAM,CAAA;AACrC,MAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,MAAA,OAAO;AAAA,QACL,IAAA,EAAA,CAAO,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,GAAA,KAAQ,MAAA,CAAU,GAAA,EAAK,SAAS,CAAC,CAAA;AAAA,QACzD,OAAO,KAAA,IAAS;AAAA,OAClB;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,OAAO,IAAA,EAAM;AACjB,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,EAAiC,SAAS,CAAA;AAChE,MAAA,MAAM,WAAW,eAAA,EAAgB;AACjC,MAAA,IAAI,QAAA,EAAU,GAAA,CAAI,WAAW,CAAA,GAAI,QAAA;AACjC,MAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,QAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA,EAAG;AACxD,UAAA,IAAI,IAAI,GAAG,CAAA,KAAM,MAAA,EAAW,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA;AAAA,QACzC;AAAA,MACF;AAEA,MAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAM,GAAK,MAAO,SAAA,EAAU,CAAE,IAAA,CAAK,KAAK,EAE5D,MAAA,CAAO,GAAG,CAAA,CAAE,MAAA,GAAS,MAAA,EAAO;AAE/B,MAAA,IAAI,OAAO,MAAM,KAAA;AACjB,MAAA,OAAO,MAAA,CAAU,SAAU,SAAS,CAAA;AAAA,IACtC,CAAA;AAAA,IAEA,MAAM,UAAA,CAAW,IAAA,EAAM,OAAA,EAAS;AAC9B,MAAA,MAAM,WAAW,eAAA,EAAgB;AACjC,MAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,EAAS,aAAa,GAAG,CAAA;AAClD,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM;AAC/B,QAAA,MAAM,GAAA,GAAM,SAAA,CAAU,CAAA,EAA8B,SAAS,CAAA;AAC7D,QAAA,IAAI,QAAA,EAAU,GAAA,CAAI,WAAW,CAAA,GAAI,QAAA;AACjC,QAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,UAAA,KAAA,MAAW,CAAC,KAAK,GAAG,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA,EAAG;AACxD,YAAA,IAAI,IAAI,GAAG,CAAA,KAAM,MAAA,EAAW,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA;AAAA,UACzC;AAAA,QACF;AACA,QAAA,OAAO,GAAA;AAAA,MACT,CAAC,CAAA;AAED,MAAA,IAAI,OAAA,GAAU,CAAA;AACd,MAAA,MAAM,SAAoD,EAAC;AAC3D,MAAA,KAAA,IAAS,QAAQ,CAAA,EAAG,KAAA,GAAQ,QAAA,CAAS,MAAA,EAAQ,SAAS,IAAA,EAAM;AAC1D,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,KAAA,EAAO,QAAQ,IAAI,CAAA;AAChD,QAAA,MAAM,EAAE,KAAA,EAAM,GAAK,MAAO,SAAA,GAAY,IAAA,CAAK,KAAK,CAAA,CAE7C,MAAA,CAAO,KAAK,CAAA;AACf,QAAA,IAAI,CAAC,KAAA,EAAO;AACV,UAAA,OAAA,IAAW,KAAA,CAAM,MAAA;AAAA,QACnB,CAAA,MAAO;AAIL,UAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,UAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,YAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAS,GAAK,MAAO,SAAA,EAAU,CAAE,IAAA,CAAK,KAAK,CAAA,CAEvD,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA;AAClB,YAAA,IAAI,QAAA,EAAU;AACZ,cAAA,MAAA,CAAO,IAAA,CAAK;AAAA,gBACV,OAAO,KAAA,GAAQ,CAAA;AAAA,gBACf,SAAS,QAAA,YAAoB,KAAA,GAAQ,SAAS,OAAA,GAAU,MAAA,CAAO,YAAY,OAAO;AAAA,eACnF,CAAA;AAAA,YACH,OAAO,OAAA,IAAW,CAAA;AAAA,UACpB;AAAA,QACF;AACA,QAAA,OAAA,EAAS,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,KAAA,GAAQ,KAAA,CAAM,QAAQ,QAAA,CAAS,MAAM,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA;AAAA,MACxF;AACA,MAAA,OAAO,EAAE,SAAS,MAAA,EAAO;AAAA,IAC3B,CAAA;AAAA,IAEA,MAAM,MAAA,CAAO,EAAA,EAAI,IAAA,EAAM;AACrB,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,EAAiC,SAAS,CAAA;AAChE,MAAA,MAAM,EAAE,MAAM,OAAA,EAAS,KAAA,KAAW,MAAO,SAAA,GAAY,IAAA,CAAK,KAAK,EAE5D,MAAA,CAAO,GAAG,EAAE,EAAA,CAAG,IAAA,EAAM,EAAE,CAAA,CAAE,MAAA,GAAS,MAAA,EAAO;AAE5C,MAAA,IAAI,OAAO,MAAM,KAAA;AACjB,MAAA,OAAO,MAAA,CAAU,SAAU,SAAS,CAAA;AAAA,IACtC,CAAA;AAAA,IAEA,MAAM,OAAO,EAAA,EAAI;AACf,MAAA,MAAM,EAAE,KAAA,EAAM,GAAK,MAAO,SAAA,EAAU,CAAE,IAAA,CAAK,KAAK,CAAA,CAE7C,MAAA,EAAO,CAAE,EAAA,CAAG,MAAM,EAAE,CAAA;AACvB,MAAA,IAAI,OAAO,MAAM,KAAA;AAAA,IACnB,CAAA;AAAA,IAEA,MAAM,WAAW,GAAA,EAAK;AACpB,MAAA,IAAI,CAAC,IAAI,MAAA,EAAQ;AACjB,MAAA,MAAM,EAAE,KAAA,EAAM,GAAK,MAAO,SAAA,EAAU,CAAE,IAAA,CAAK,KAAK,CAAA,CAE7C,MAAA,EAAO,CAAE,EAAA,CAAG,MAAM,GAAG,CAAA;AACxB,MAAA,IAAI,OAAO,MAAM,KAAA;AAAA,IACnB;AAAA,GACF;AACF;;;ACnNA,SAAS,SAAS,KAAA,EAAyB;AACzC,EAAA,IAAI,UAAU,IAAA,IAAQ,KAAA,KAAU,UAAa,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAC/E,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,QAAQ,CAAA;AACnD,EAAA,MAAM,SAAkC,EAAC;AACzC,EAAA,KAAA,MAAW,KAAK,MAAA,CAAO,IAAA,CAAK,KAAgC,CAAA,CAAE,MAAK,EAAG;AACpE,IAAA,MAAA,CAAO,CAAC,CAAA,GAAI,QAAA,CAAU,KAAA,CAAkC,CAAC,CAAC,CAAA;AAAA,EAC5D;AACA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,aAAa,KAAA,EAA0B;AACrD,EAAA,OAAO,MAAM,GAAA,CAAI,CAAC,CAAA,KAAO,OAAO,MAAM,QAAA,GAAW,CAAA,GAAI,IAAA,CAAK,SAAA,CAAU,SAAS,CAAC,CAAC,CAAE,CAAA,CAAE,KAAK,GAAG,CAAA;AAC7F;AAMO,SAAS,iBAAiB,MAAA,EAAkC;AACjE,EAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,GAAA;AACzC,EAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,GAAA;AACzC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAwB;AAE5C,EAAA,SAAS,QAAA,GAAW;AAClB,IAAA,IAAI,OAAA,CAAQ,QAAQ,UAAA,EAAY;AAEhC,IAAA,IAAI,SAAA,GAA2B,IAAA;AAC/B,IAAA,IAAI,YAAA,GAAe,QAAA;AACnB,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,OAAA,EAAS;AAClC,MAAA,IAAI,KAAA,CAAM,aAAa,YAAA,EAAc;AACnC,QAAA,YAAA,GAAe,KAAA,CAAM,UAAA;AACrB,QAAA,SAAA,GAAY,GAAA;AAAA,MACd;AAAA,IACF;AACA,IAAA,IAAI,SAAA,EAAW,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA;AAAA,EACzC;AAEA,EAAA,OAAO;AAAA,IACL,IAAO,GAAA,EAA4B;AACjC,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAC7B,MAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,MAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA,CAAM,SAAA,EAAW;AAChC,QAAA,OAAA,CAAQ,OAAO,GAAG,CAAA;AAClB,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,KAAA,CAAM,UAAA,GAAa,KAAK,GAAA,EAAI;AAC5B,MAAA,OAAO,KAAA,CAAM,IAAA;AAAA,IACf,CAAA;AAAA,IAEA,GAAA,CAAO,GAAA,EAAa,IAAA,EAAS,GAAA,EAAoB;AAC/C,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,OAAA,CAAQ,IAAI,GAAA,EAAK;AAAA,QACf,IAAA;AAAA,QACA,SAAA,EAAW,OAAO,GAAA,IAAO,UAAA,CAAA;AAAA,QACzB,UAAA,EAAY;AAAA,OACb,CAAA;AACD,MAAA,QAAA,EAAS;AAAA,IACX,CAAA;AAAA,IAEA,WAAW,MAAA,EAAsB;AAC/B,MAAA,KAAA,MAAW,GAAA,IAAO,OAAA,CAAQ,IAAA,EAAK,EAAG;AAChC,QAAA,IAAI,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,UAAA,OAAA,CAAQ,OAAO,GAAG,CAAA;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IAEA,KAAA,GAAc;AACZ,MAAA,OAAA,CAAQ,KAAA,EAAM;AAAA,IAChB,CAAA;AAAA,IAEA,IAAA,GAAe;AACb,MAAA,OAAO,OAAA,CAAQ,IAAA;AAAA,IACjB;AAAA,GACF;AACF;AAMO,IAAM,cAAc,gBAAA;AAIpB,SAAS,gBAAA,GAAyB;AACvC,EAAA,WAAA,CAAY,KAAA,EAAM;AACpB;AC9GA,IAAI,eAAA;AACJ,IAAM,SAAA,uBAAgB,GAAA,EAAgB;AAE/B,SAAS,kBAAkB,EAAA,EAA8B;AAC9D,EAAA,IAAI,OAAO,eAAA,EAAiB;AAC1B,IAAA,eAAA,GAAkB,EAAA;AAClB,IAAA,gBAAA,EAAiB;AACjB,IAAA,KAAA,MAAW,CAAA,IAAK,WAAW,CAAA,EAAE;AAAA,EAC/B;AACF;AAEO,SAAS,iBAAA,GAAwC;AACtD,EAAA,OAAO,eAAA;AACT;AAQO,SAAS,sBAAsB,QAAA,EAAkC;AACtE,EAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,EAAA,OAAO,MAAM;AAAE,IAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,EAAE,CAAA;AAC5C;AAIO,SAAS,iBAAA,GAAwC;AACtD,EAAA,OAAa,KAAA,CAAA,oBAAA,CAAqB,qBAAA,EAAuB,iBAAA,EAAmB,iBAAiB,CAAA;AAC/F","file":"chunk-LARZWDHA.js","sourcesContent":["/**\n * ONE filter grammar, shared by the providers and by the agent's data tools.\n *\n * Models express ranges in whatever dialect they were trained on — `{from,to}`,\n * `{gte,lte}`, Mongo's `{$gte,$lt}`. When only some of those are recognised the\n * unrecognised one falls through to an equality compare against\n * \"[object Object]\", which matches nothing and reads as \"there are no\n * appointments today\" instead of \"I did not understand that filter\".\n */\n\nexport interface RangeFilter {\n gte?: unknown\n gt?: unknown\n lte?: unknown\n lt?: unknown\n}\n\nconst LOWER_INCLUSIVE = ['from', 'gte', 'start', 'after', 'since', 'min']\nconst LOWER_EXCLUSIVE = ['gt']\nconst UPPER_INCLUSIVE = ['to', 'lte', 'end', 'until', 'before', 'max']\nconst UPPER_EXCLUSIVE = ['lt']\n\nfunction pick(source: Record<string, unknown>, names: string[]): unknown {\n for (const name of names) {\n if (source[name] !== undefined && source[name] !== null) return source[name]\n const dollar = `$${name}`\n if (source[dollar] !== undefined && source[dollar] !== null) return source[dollar]\n }\n return undefined\n}\n\n/**\n * Parse a filter value into a range, or return null when it is a plain\n * (equality) value. An object that looks like a filter but carries no\n * recognised bound returns `null` too — callers treat that as \"invalid\",\n * never as \"matches nothing\".\n */\nexport function parseRangeFilter(value: unknown): RangeFilter | null {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return null\n const source = value as Record<string, unknown>\n const range: RangeFilter = {}\n const gte = pick(source, LOWER_INCLUSIVE)\n const gt = pick(source, LOWER_EXCLUSIVE)\n const lte = pick(source, UPPER_INCLUSIVE)\n const lt = pick(source, UPPER_EXCLUSIVE)\n if (gte !== undefined) range.gte = gte\n if (gt !== undefined) range.gt = gt\n if (lte !== undefined) range.lte = lte\n if (lt !== undefined) range.lt = lt\n return Object.keys(range).length ? range : null\n}\n\n/** True for any object value — including ones no bound could be read from. */\nexport function isFilterObject(value: unknown): boolean {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction comparable(value: unknown): number {\n if (typeof value === 'number') return value\n if (value instanceof Date) return value.getTime()\n const ts = Date.parse(String(value))\n if (!Number.isNaN(ts)) return ts\n return Number(value)\n}\n\n/** Client-side counterpart of the range a provider would push to SQL. */\nexport function matchesRange(raw: unknown, range: RangeFilter): boolean {\n const value = comparable(raw)\n if (Number.isNaN(value)) return false\n if (range.gte !== undefined && value < comparable(range.gte)) return false\n if (range.gt !== undefined && value <= comparable(range.gt)) return false\n if (range.lte !== undefined && value > comparable(range.lte)) return false\n if (range.lt !== undefined && value >= comparable(range.lt)) return false\n return true\n}\n\n/** Apply a range to a PostgREST query builder. */\nexport function applyRangeToQuery<Q>(\n query: Q,\n column: string,\n range: RangeFilter,\n): Q {\n let q = query as Record<string, (c: string, v: unknown) => unknown>\n for (const op of ['gte', 'gt', 'lte', 'lt'] as const) {\n const bound = range[op]\n if (bound === undefined) continue\n q = q[op](column, bound) as Record<string, (c: string, v: unknown) => unknown>\n }\n return q as Q\n}\n","import type { DataProvider, CrudQuery, CrudResult } from './types'\nimport { applyRangeToQuery, isFilterObject, parseRangeFilter } from './filters'\n\nexport interface SupabaseProviderConfig {\n schema?: string\n tenantId?: string | (() => string | undefined)\n tenantIdColumn?: string\n searchColumns?: string[]\n selectColumns?: string\n columnMap?: Record<string, string>\n filters?: Record<string, string>\n defaults?: Record<string, unknown>\n supabaseClient?: unknown\n}\n\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase())\n}\n\nfunction snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n}\n\nfunction mapRow<T>(row: Record<string, unknown>, columnMap?: Record<string, string>): T {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const camelKey = columnMap?.[key] ?? snakeToCamel(key)\n result[camelKey] = value\n }\n return result as T\n}\n\nfunction mapEntity(entity: Record<string, unknown>, columnMap?: Record<string, string>): Record<string, unknown> {\n const reverseMap: Record<string, string> = {}\n if (columnMap) {\n for (const [snake, camel] of Object.entries(columnMap)) {\n reverseMap[camel] = snake\n }\n }\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(entity)) {\n // `createdBy` entra na lista: quem o escreve é o gatilho do banco, com\n // `auth.uid()`. Deixá-lo passar daria à interface a chance de dizer quem\n // cadastrou — e um autor que o próprio formulário pode escolher não vale\n // como procedência. Ver packages/db/migrations/025_created_by.sql.\n if (key === 'id' || key === 'createdAt' || key === 'updatedAt' || key === 'tenantId' || key === 'createdBy') continue\n const snakeKey = reverseMap[key] ?? camelToSnake(key)\n result[snakeKey] = value\n }\n return result\n}\n\n// Global Supabase client registry — set once via createFayzApp\nlet _globalSupabaseClient: unknown | null = null\n\nexport function setGlobalSupabaseClient(client: unknown): void {\n _globalSupabaseClient = client\n}\n\nexport function getSupabaseClientOptional(): unknown | null {\n return _globalSupabaseClient\n}\n\nexport function createSupabaseProvider<T extends { id: string }>(\n table: string,\n config?: SupabaseProviderConfig,\n): DataProvider<T> {\n const schema = config?.schema ?? 'public'\n const tenantIdCol = config?.tenantIdColumn ?? 'tenant_id'\n const searchCols = config?.searchColumns ?? []\n const selectCols = config?.selectColumns ?? '*'\n const columnMap = config?.columnMap\n\n function resolveTenantId(): string | undefined {\n if (!config?.tenantId) return undefined\n return typeof config.tenantId === 'function' ? config.tenantId() : config.tenantId\n }\n\n function getClient() {\n const supabase = (config?.supabaseClient ?? _globalSupabaseClient) as {\n schema: (s: string) => unknown\n from: (t: string) => unknown\n } | null\n if (!supabase) throw new Error(`[@fayz-ai/core] Supabase client not available. Call createFayzApp with a provider first.`)\n return schema === 'public' ? (supabase as { from: (t: string) => unknown }) : (supabase.schema(schema) as { from: (t: string) => unknown })\n }\n\n return {\n async list(query: CrudQuery): Promise<CrudResult<T>> {\n // 'none' skips PostgREST's count aggregate entirely — see CrudQuery.countMode.\n const wantCount = query.countMode !== 'none'\n let q = (getClient().from(table) as { select: (...args: unknown[]) => unknown })\n .select(selectCols, wantCount ? { count: 'exact' } : undefined) as Record<string, unknown>\n\n const tenantId = resolveTenantId()\n if (tenantId) q = (q as { eq: (col: string, val: string) => unknown }).eq(tenantIdCol, tenantId) as Record<string, unknown>\n\n if (config?.filters) {\n for (const [col, val] of Object.entries(config.filters)) {\n q = (q as { eq: (c: string, v: string) => unknown }).eq(col, val) as Record<string, unknown>\n }\n }\n\n // Faceted / dynamic filters from the query, mapped to columns. Equality\n // by default; a range object ({from,to} / {gte,lt} / {$gte,$lt}) becomes\n // real SQL bounds instead of an equality compare against \"[object Object]\".\n if (query.filters) {\n for (const [key, val] of Object.entries(query.filters)) {\n if (val == null || val === '') continue\n const col = columnMap?.[key] ?? camelToSnake(key)\n const range = parseRangeFilter(val)\n if (range) {\n q = applyRangeToQuery(q, col, range)\n continue\n }\n if (isFilterObject(val)) {\n throw new Error(\n `[@fayz-ai/core] Filter \"${key}\" is an object with no recognised bound. ` +\n 'Use {from,to} / {gte,lte,gt,lt} for ranges, or a plain value for equality.',\n )\n }\n q = (q as { eq: (c: string, v: unknown) => unknown }).eq(col, val) as Record<string, unknown>\n }\n }\n\n if (query.search && searchCols.length > 0) {\n const term = `%${query.search}%`\n const orClause = searchCols.map((col) => `${camelToSnake(col)}.ilike.${term}`).join(',')\n q = (q as { or: (c: string) => unknown }).or(orClause) as Record<string, unknown>\n }\n\n if (query.sortBy) {\n q = (q as { order: (col: string, opts: unknown) => unknown })\n .order(camelToSnake(query.sortBy), { ascending: query.sortDir !== 'desc' }) as Record<string, unknown>\n } else {\n q = (q as { order: (col: string, opts: unknown) => unknown })\n .order('created_at', { ascending: false }) as Record<string, unknown>\n }\n\n const page = query.page ?? 1\n const pageSize = query.pageSize ?? 50\n const from = (page - 1) * pageSize\n q = (q as { range: (f: number, t: number) => unknown }).range(from, from + pageSize - 1) as Record<string, unknown>\n\n const { data, error, count } = await q as { data: Record<string, unknown>[] | null; error: unknown; count: number | null }\n if (error) throw error\n\n return {\n data: (data ?? []).map((row) => mapRow<T>(row, columnMap)),\n total: count ?? 0,\n }\n },\n\n async create(data) {\n const row = mapEntity(data as Record<string, unknown>, columnMap)\n const tenantId = resolveTenantId()\n if (tenantId) row[tenantIdCol] = tenantId\n if (config?.defaults) {\n for (const [col, val] of Object.entries(config.defaults)) {\n if (row[col] === undefined) row[col] = val\n }\n }\n\n const { data: created, error } = (await (getClient().from(table) as {\n insert: (r: unknown) => { select: () => { single: () => Promise<{ data: unknown; error: unknown }> } }\n }).insert(row).select().single()) as { data: Record<string, unknown> | null; error: unknown }\n\n if (error) throw error\n return mapRow<T>(created!, columnMap)\n },\n\n async createMany(rows, options) {\n const tenantId = resolveTenantId()\n const size = Math.max(1, options?.chunkSize ?? 200)\n const prepared = rows.map((r) => {\n const row = mapEntity(r as Record<string, unknown>, columnMap)\n if (tenantId) row[tenantIdCol] = tenantId\n if (config?.defaults) {\n for (const [col, val] of Object.entries(config.defaults)) {\n if (row[col] === undefined) row[col] = val\n }\n }\n return row\n })\n\n let created = 0\n const failed: Array<{ index: number; message: string }> = []\n for (let start = 0; start < prepared.length; start += size) {\n const chunk = prepared.slice(start, start + size)\n const { error } = (await (getClient().from(table) as {\n insert: (r: unknown) => Promise<{ error: unknown }>\n }).insert(chunk)) as { error: unknown }\n if (!error) {\n created += chunk.length\n } else {\n // One bad row rejects its whole chunk. Retrying it row by row keeps\n // the other 199 — an import that loses 200 records over one malformed\n // phone number is worse than no import.\n const message = error instanceof Error ? error.message : String(error)\n for (let i = 0; i < chunk.length; i++) {\n const { error: rowError } = (await (getClient().from(table) as {\n insert: (r: unknown) => Promise<{ error: unknown }>\n }).insert(chunk[i])) as { error: unknown }\n if (rowError) {\n failed.push({\n index: start + i,\n message: rowError instanceof Error ? rowError.message : String(rowError ?? message),\n })\n } else created += 1\n }\n }\n options?.onProgress?.(Math.min(start + chunk.length, prepared.length), prepared.length)\n }\n return { created, failed }\n },\n\n async update(id, data) {\n const row = mapEntity(data as Record<string, unknown>, columnMap)\n const { data: updated, error } = (await (getClient().from(table) as {\n update: (r: unknown) => { eq: (c: string, v: string) => { select: () => { single: () => Promise<{ data: unknown; error: unknown }> } } }\n }).update(row).eq('id', id).select().single()) as { data: Record<string, unknown> | null; error: unknown }\n\n if (error) throw error\n return mapRow<T>(updated!, columnMap)\n },\n\n async remove(id) {\n const { error } = (await (getClient().from(table) as {\n delete: () => { eq: (c: string, v: string) => Promise<{ error: unknown }> }\n }).delete().eq('id', id)) as { error: unknown }\n if (error) throw error\n },\n\n async removeMany(ids) {\n if (!ids.length) return\n const { error } = (await (getClient().from(table) as {\n delete: () => { in: (c: string, v: string[]) => Promise<{ error: unknown }> }\n }).delete().in('id', ids)) as { error: unknown }\n if (error) throw error\n },\n }\n}\n","// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface CacheEntry<T = unknown> {\n data: T\n expiresAt: number\n lastAccess: number\n}\n\nexport interface CacheStore {\n get<T>(key: string): T | undefined\n set<T>(key: string, data: T, ttl?: number): void\n /** Clear all entries whose key starts with `prefix` */\n invalidate(prefix: string): void\n clear(): void\n size(): number\n}\n\nexport interface CacheConfig {\n /** Default time-to-live in ms (default: 60 000 — 1 minute) */\n defaultTTL?: number\n /** Maximum cached entries before LRU eviction (default: 500) */\n maxEntries?: number\n}\n\n// ---------------------------------------------------------------------------\n// Stable key helper — deterministic JSON for cache keys\n// ---------------------------------------------------------------------------\n\nfunction sortDeep(value: unknown): unknown {\n if (value === null || value === undefined || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(sortDeep)\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = sortDeep((value as Record<string, unknown>)[k])\n }\n return sorted\n}\n\nexport function stableKey(...parts: unknown[]): string {\n return parts.map((p) => (typeof p === 'string' ? p : JSON.stringify(sortDeep(p)))).join(':')\n}\n\n// ---------------------------------------------------------------------------\n// CacheStore implementation\n// ---------------------------------------------------------------------------\n\nexport function createCacheStore(config?: CacheConfig): CacheStore {\n const defaultTTL = config?.defaultTTL ?? 60_000\n const maxEntries = config?.maxEntries ?? 500\n const entries = new Map<string, CacheEntry>()\n\n function evictLRU() {\n if (entries.size <= maxEntries) return\n // Find the entry with the oldest lastAccess\n let oldestKey: string | null = null\n let oldestAccess = Infinity\n for (const [key, entry] of entries) {\n if (entry.lastAccess < oldestAccess) {\n oldestAccess = entry.lastAccess\n oldestKey = key\n }\n }\n if (oldestKey) entries.delete(oldestKey)\n }\n\n return {\n get<T>(key: string): T | undefined {\n const entry = entries.get(key)\n if (!entry) return undefined\n if (Date.now() > entry.expiresAt) {\n entries.delete(key)\n return undefined\n }\n entry.lastAccess = Date.now()\n return entry.data as T\n },\n\n set<T>(key: string, data: T, ttl?: number): void {\n const now = Date.now()\n entries.set(key, {\n data,\n expiresAt: now + (ttl ?? defaultTTL),\n lastAccess: now,\n })\n evictLRU()\n },\n\n invalidate(prefix: string): void {\n for (const key of entries.keys()) {\n if (key.startsWith(prefix)) {\n entries.delete(key)\n }\n }\n },\n\n clear(): void {\n entries.clear()\n },\n\n size(): number {\n return entries.size\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Global singleton — auto-flushes on tenant/org switch\n// ---------------------------------------------------------------------------\n\nexport const globalCache = createCacheStore()\n\n/** Flush the global cache — called by the tenant accessor when the active\n * tenant changes (replaces the old org-store subscription). */\nexport function clearGlobalCache(): void {\n globalCache.clear()\n}\n","// Active tenant context — a global accessor the data layer reads for tenant\n// scoping and cache keying. The host (saas shell / app) sets it from its org\n// store via setActiveTenantId; the data providers stay decoupled from any\n// specific org-store implementation (runtime DI).\nimport * as React from 'react'\nimport { clearGlobalCache } from './cache'\n\nlet _activeTenantId: string | undefined\nconst listeners = new Set<() => void>()\n\nexport function setActiveTenantId(id: string | undefined): void {\n if (id !== _activeTenantId) {\n _activeTenantId = id\n clearGlobalCache()\n for (const l of listeners) l()\n }\n}\n\nexport function getActiveTenantId(): string | undefined {\n return _activeTenantId\n}\n\n/**\n * Subscribes to tenant changes. A getter alone makes every read a race with the\n * shell: a view that mounts before the org store resolves reads `undefined`,\n * and a tenant-scoped fetch that answers \"no tenant\" looks exactly like \"no\n * rows\" — it never retries and the screen stays empty until a remount.\n */\nexport function subscribeActiveTenant(listener: () => void): () => void {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n}\n\n/** The active tenant, re-rendering when it resolves or changes. Use this to key\n * effects that fetch tenant-scoped data. */\nexport function useActiveTenantId(): string | undefined {\n return React.useSyncExternalStore(subscribeActiveTenant, getActiveTenantId, getActiveTenantId)\n}\n"]}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// src/router/index.ts
|
|
2
|
+
function normalize(path) {
|
|
3
|
+
if (!path) return "/";
|
|
4
|
+
return path.startsWith("/") ? path : `/${path}`;
|
|
5
|
+
}
|
|
6
|
+
function hashRouterAdapter() {
|
|
7
|
+
return {
|
|
8
|
+
navigate(to) {
|
|
9
|
+
window.location.hash = to;
|
|
10
|
+
},
|
|
11
|
+
replace(to) {
|
|
12
|
+
window.history.replaceState(null, "", `#${normalize(to)}`);
|
|
13
|
+
},
|
|
14
|
+
getCurrentPath() {
|
|
15
|
+
return window.location.hash.slice(1) || "/";
|
|
16
|
+
},
|
|
17
|
+
onPathChange(cb) {
|
|
18
|
+
const handler = () => cb(window.location.hash.slice(1) || "/");
|
|
19
|
+
window.addEventListener("hashchange", handler);
|
|
20
|
+
return () => window.removeEventListener("hashchange", handler);
|
|
21
|
+
},
|
|
22
|
+
href(to) {
|
|
23
|
+
return `#${normalize(to)}`;
|
|
24
|
+
},
|
|
25
|
+
interceptsLinkClicks: false
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function historyRouterAdapter() {
|
|
29
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
30
|
+
let popstateBound = false;
|
|
31
|
+
const currentPath = () => window.location.pathname + window.location.search;
|
|
32
|
+
const emit = () => {
|
|
33
|
+
for (const cb of subscribers) cb(currentPath());
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
navigate(to) {
|
|
37
|
+
const next = normalize(to);
|
|
38
|
+
if (next === currentPath()) return;
|
|
39
|
+
window.history.pushState(null, "", next);
|
|
40
|
+
emit();
|
|
41
|
+
},
|
|
42
|
+
replace(to) {
|
|
43
|
+
const next = normalize(to);
|
|
44
|
+
if (next === currentPath()) return;
|
|
45
|
+
window.history.replaceState(null, "", next);
|
|
46
|
+
emit();
|
|
47
|
+
},
|
|
48
|
+
getCurrentPath() {
|
|
49
|
+
return currentPath();
|
|
50
|
+
},
|
|
51
|
+
onPathChange(cb) {
|
|
52
|
+
subscribers.add(cb);
|
|
53
|
+
if (!popstateBound) {
|
|
54
|
+
window.addEventListener("popstate", emit);
|
|
55
|
+
popstateBound = true;
|
|
56
|
+
}
|
|
57
|
+
return () => {
|
|
58
|
+
subscribers.delete(cb);
|
|
59
|
+
if (subscribers.size === 0 && popstateBound) {
|
|
60
|
+
window.removeEventListener("popstate", emit);
|
|
61
|
+
popstateBound = false;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
href(to) {
|
|
66
|
+
return normalize(to);
|
|
67
|
+
},
|
|
68
|
+
interceptsLinkClicks: true
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function staticRouterAdapter(path, options = {}) {
|
|
72
|
+
const fixed = normalize(path);
|
|
73
|
+
const writeHref = options.href ?? ((to) => normalize(to));
|
|
74
|
+
return {
|
|
75
|
+
navigate() {
|
|
76
|
+
},
|
|
77
|
+
replace() {
|
|
78
|
+
},
|
|
79
|
+
getCurrentPath() {
|
|
80
|
+
return fixed;
|
|
81
|
+
},
|
|
82
|
+
onPathChange() {
|
|
83
|
+
return () => {
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
href(to) {
|
|
87
|
+
return writeHref(to);
|
|
88
|
+
},
|
|
89
|
+
interceptsLinkClicks: true
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function hostRouterAdapter(host) {
|
|
93
|
+
return {
|
|
94
|
+
navigate(to) {
|
|
95
|
+
host.navigate(normalize(to));
|
|
96
|
+
},
|
|
97
|
+
replace(to) {
|
|
98
|
+
(host.replace ?? host.navigate)(normalize(to));
|
|
99
|
+
},
|
|
100
|
+
getCurrentPath() {
|
|
101
|
+
return normalize(host.currentPath());
|
|
102
|
+
},
|
|
103
|
+
onPathChange(cb) {
|
|
104
|
+
return host.subscribe?.(cb) ?? (() => {
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
href(to) {
|
|
108
|
+
return normalize(to);
|
|
109
|
+
},
|
|
110
|
+
interceptsLinkClicks: true
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function defaultRouterAdapter(scheme = "hash", ssrPath = "/") {
|
|
114
|
+
if (typeof window !== "undefined") {
|
|
115
|
+
return scheme === "history" ? historyRouterAdapter() : hashRouterAdapter();
|
|
116
|
+
}
|
|
117
|
+
return staticRouterAdapter(ssrPath, {
|
|
118
|
+
href: scheme === "hash" ? (to) => `#${normalize(to)}` : void 0
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
var windowRouterAdapter = historyRouterAdapter;
|
|
122
|
+
|
|
123
|
+
export { defaultRouterAdapter, hashRouterAdapter, historyRouterAdapter, hostRouterAdapter, staticRouterAdapter, windowRouterAdapter };
|
|
124
|
+
//# sourceMappingURL=chunk-OXQGRJZT.js.map
|
|
125
|
+
//# sourceMappingURL=chunk-OXQGRJZT.js.map
|