chaipro 0.1.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 +36 -0
- package/dist/IconPicker-I7VNLYZ4.js +5 -0
- package/dist/actions-DM00SIUk.d.cts +899 -0
- package/dist/actions-DM00SIUk.d.ts +899 -0
- package/dist/actions-registery-SEJTZE5Q.js +1 -0
- package/dist/active-in-another-tab-SONDAONP.js +1 -0
- package/dist/add-new-language-page-TI6DUYYX.js +1 -0
- package/dist/add-new-page-LBHXICXO.js +1 -0
- package/dist/ai-block-floating-prompt-input-ESY5GQLZ.js +1 -0
- package/dist/ai-panel-content-62I6FDQF.css +1 -0
- package/dist/ai-panel-content-UZJZ463W.js +1 -0
- package/dist/ai-panel-default-lang-2ZXZYQRT.js +6 -0
- package/dist/ai-panel-default-lang-ETFOFFEF.css +1 -0
- package/dist/ai-panel-for-image-LADQP6VY.js +1 -0
- package/dist/ai-panel-other-lang-WDLC3M2M.js +1 -0
- package/dist/ai-panel-page-chat-7ZISZWY4.js +4 -0
- package/dist/ai-panel-page-chat-N4YFJGAM.css +1 -0
- package/dist/ai-prompt-input-CPT5ETQ4.js +1 -0
- package/dist/ai-theme-generator-7PS4BX52.js +1 -0
- package/dist/ai-translation-prompt-3VE2ECGR.js +1 -0
- package/dist/blocks-CMvgDlxw.d.ts +72 -0
- package/dist/blocks-CP-Pngaz.d.cts +72 -0
- package/dist/build-config-CCERdThN.d.ts +80 -0
- package/dist/build-config-DrerOPd9.d.cts +80 -0
- package/dist/builder.cjs +243 -0
- package/dist/builder.css +1 -0
- package/dist/builder.d.cts +352 -0
- package/dist/builder.d.ts +352 -0
- package/dist/builder.js +1 -0
- package/dist/chaibuilder-instance-DNz3Q-dY.d.cts +579 -0
- package/dist/chaibuilder-instance-qroszVwI.d.ts +579 -0
- package/dist/change-password-modal-NJL7ZLTY.js +1 -0
- package/dist/chunk-2AFM6557.js +3 -0
- package/dist/chunk-2N4IJZOR.js +1 -0
- package/dist/chunk-2NYUIXUX.js +1 -0
- package/dist/chunk-2PJZUYIZ.js +1 -0
- package/dist/chunk-32HH35VD.js +1 -0
- package/dist/chunk-346H4FEX.js +1 -0
- package/dist/chunk-34HIOUTE.js +1 -0
- package/dist/chunk-374QEK4F.js +1 -0
- package/dist/chunk-3E72DJSP.js +1 -0
- package/dist/chunk-3IT7IIAV.js +1 -0
- package/dist/chunk-3UEPBBE4.js +11 -0
- package/dist/chunk-3XSKJBPH.js +1 -0
- package/dist/chunk-45ELAD2J.js +1 -0
- package/dist/chunk-4JBHWPMO.js +1 -0
- package/dist/chunk-4P25MV5E.js +1 -0
- package/dist/chunk-4PQNBY3V.js +1 -0
- package/dist/chunk-4VNLL2IA.js +1 -0
- package/dist/chunk-55SU3QPU.js +1 -0
- package/dist/chunk-5ZC65NB6.js +1 -0
- package/dist/chunk-6M7V7BOM.js +1 -0
- package/dist/chunk-6TXCHU4K.js +1 -0
- package/dist/chunk-777N6WHB.js +1 -0
- package/dist/chunk-7C4EQOAR.js +12 -0
- package/dist/chunk-7EXZXKW2.js +1 -0
- package/dist/chunk-7QWMLDCG.js +1 -0
- package/dist/chunk-AOJE5WI3.js +1 -0
- package/dist/chunk-ATLMLDBS.js +1 -0
- package/dist/chunk-AVGF3YLU.js +17 -0
- package/dist/chunk-BQSLQHLD.js +1 -0
- package/dist/chunk-BWORNCTE.js +1 -0
- package/dist/chunk-BYGD5CDT.js +1 -0
- package/dist/chunk-CA5PVX24.js +1 -0
- package/dist/chunk-CFNOB42V.js +1 -0
- package/dist/chunk-CJP3BQH2.js +1 -0
- package/dist/chunk-CRJENCPR.js +1 -0
- package/dist/chunk-D5SKCKSB.js +1 -0
- package/dist/chunk-DZ72OHTD.js +1 -0
- package/dist/chunk-EPGOG22Q.js +0 -0
- package/dist/chunk-ERCY63ZW.js +1 -0
- package/dist/chunk-ESCX7KEH.js +1 -0
- package/dist/chunk-F2V4N3LT.js +156 -0
- package/dist/chunk-F7YMHPEA.js +1 -0
- package/dist/chunk-FERH2TPR.js +1 -0
- package/dist/chunk-FLSV2QGU.js +1 -0
- package/dist/chunk-FOKGOT6B.js +1 -0
- package/dist/chunk-GJOOCKUE.js +1 -0
- package/dist/chunk-HA7LF3RV.js +1 -0
- package/dist/chunk-HAKJOMCL.js +1 -0
- package/dist/chunk-HEKCKC7N.js +1 -0
- package/dist/chunk-HELRVKD2.js +3 -0
- package/dist/chunk-I7ODKVVX.js +1 -0
- package/dist/chunk-IAKCX2WB.js +1 -0
- package/dist/chunk-IB2C3TWH.js +1 -0
- package/dist/chunk-IH562KSP.js +1 -0
- package/dist/chunk-IP4JBQOX.js +1 -0
- package/dist/chunk-ITX7QWN6.js +1 -0
- package/dist/chunk-IUACZ3E6.js +6 -0
- package/dist/chunk-J7Q62EP7.js +1 -0
- package/dist/chunk-JBB5IJFA.js +1 -0
- package/dist/chunk-JPJRO4NU.js +1 -0
- package/dist/chunk-JUIS55JT.js +1 -0
- package/dist/chunk-JYBTQ3YX.js +5 -0
- package/dist/chunk-K5YWQY4U.js +1 -0
- package/dist/chunk-K6RHR4HT.js +1 -0
- package/dist/chunk-LNV5MRGV.js +1 -0
- package/dist/chunk-LRJREWRD.js +1 -0
- package/dist/chunk-LWYDGDPW.js +1 -0
- package/dist/chunk-MDMGXS5B.js +1 -0
- package/dist/chunk-MEROMQQX.js +1 -0
- package/dist/chunk-N7Z4RFFI.js +1 -0
- package/dist/chunk-NSQEQYEM.js +1 -0
- package/dist/chunk-OD3K76M6.js +1 -0
- package/dist/chunk-ODSL3KXG.js +1 -0
- package/dist/chunk-OJJDRACB.js +1 -0
- package/dist/chunk-ONSZ462E.js +1 -0
- package/dist/chunk-OQZ4EPOM.js +1 -0
- package/dist/chunk-OR7KKUYT.js +1 -0
- package/dist/chunk-OSGXFZTA.js +1 -0
- package/dist/chunk-PM3JNOZH.js +1 -0
- package/dist/chunk-PQHFT4TE.js +1 -0
- package/dist/chunk-QGVCH2NI.js +1 -0
- package/dist/chunk-QIGSSVEY.js +1 -0
- package/dist/chunk-R5ZTCDFD.js +1 -0
- package/dist/chunk-RBDZDQZR.js +1 -0
- package/dist/chunk-ROQRBSK6.js +1 -0
- package/dist/chunk-SSENH35Y.js +1 -0
- package/dist/chunk-SYPALJAE.js +1 -0
- package/dist/chunk-T2YYNX6Z.js +1 -0
- package/dist/chunk-T32TW3XV.js +1 -0
- package/dist/chunk-T56KQBE2.js +1 -0
- package/dist/chunk-TEL5ACJE.js +1 -0
- package/dist/chunk-TGJQC6VC.js +1 -0
- package/dist/chunk-TQ34DGOT.js +1 -0
- package/dist/chunk-TVF77C53.js +1 -0
- package/dist/chunk-UIDBBTCZ.js +3 -0
- package/dist/chunk-VKSRWZCO.js +1 -0
- package/dist/chunk-VL5WBPVV.js +1 -0
- package/dist/chunk-VUWHFLT7.js +22 -0
- package/dist/chunk-WEVKAJMV.js +1 -0
- package/dist/chunk-WHPIYGCY.js +1 -0
- package/dist/chunk-WNESLH23.js +1 -0
- package/dist/chunk-WOT6VMZA.js +1 -0
- package/dist/chunk-WSQ5SQBD.js +1 -0
- package/dist/chunk-XY4UJKHE.js +1 -0
- package/dist/chunk-Y2BHO7OO.js +1 -0
- package/dist/chunk-YDOQEFOK.js +1 -0
- package/dist/chunk-YEFMD4DS.js +1 -0
- package/dist/chunk-YQ5QQCRD.js +1 -0
- package/dist/chunk-YQPOFRXU.js +1 -0
- package/dist/chunk-YTPQSO7V.js +801 -0
- package/dist/chunk-ZAU65LBG.js +1 -0
- package/dist/chunk-ZRFCEMYU.js +1 -0
- package/dist/chunk-ZU2B5YT6.js +1 -0
- package/dist/chunk-ZXKKBKGV.js +1 -0
- package/dist/code-display-7346IUCO.js +1 -0
- package/dist/code-editor-UBGTTX2L.js +1 -0
- package/dist/components/ui/accordion.cjs +1 -0
- package/dist/components/ui/accordion.d.cts +9 -0
- package/dist/components/ui/accordion.d.ts +9 -0
- package/dist/components/ui/accordion.js +1 -0
- package/dist/components/ui/alert-dialog.cjs +1 -0
- package/dist/components/ui/alert-dialog.d.cts +23 -0
- package/dist/components/ui/alert-dialog.d.ts +23 -0
- package/dist/components/ui/alert-dialog.js +1 -0
- package/dist/components/ui/alert.cjs +1 -0
- package/dist/components/ui/alert.d.cts +11 -0
- package/dist/components/ui/alert.d.ts +11 -0
- package/dist/components/ui/alert.js +1 -0
- package/dist/components/ui/avatar.cjs +1 -0
- package/dist/components/ui/avatar.d.cts +8 -0
- package/dist/components/ui/avatar.d.ts +8 -0
- package/dist/components/ui/avatar.js +1 -0
- package/dist/components/ui/badge.cjs +1 -0
- package/dist/components/ui/badge.d.cts +13 -0
- package/dist/components/ui/badge.d.ts +13 -0
- package/dist/components/ui/badge.js +1 -0
- package/dist/components/ui/button.cjs +1 -0
- package/dist/components/ui/button.d.cts +15 -0
- package/dist/components/ui/button.d.ts +15 -0
- package/dist/components/ui/button.js +1 -0
- package/dist/components/ui/card.cjs +1 -0
- package/dist/components/ui/card.d.cts +10 -0
- package/dist/components/ui/card.d.ts +10 -0
- package/dist/components/ui/card.js +1 -0
- package/dist/components/ui/checkbox.cjs +1 -0
- package/dist/components/ui/checkbox.d.cts +6 -0
- package/dist/components/ui/checkbox.d.ts +6 -0
- package/dist/components/ui/checkbox.js +1 -0
- package/dist/components/ui/command.cjs +1 -0
- package/dist/components/ui/command.d.cts +83 -0
- package/dist/components/ui/command.d.ts +83 -0
- package/dist/components/ui/command.js +1 -0
- package/dist/components/ui/context-menu.cjs +1 -0
- package/dist/components/ui/context-menu.d.cts +30 -0
- package/dist/components/ui/context-menu.d.ts +30 -0
- package/dist/components/ui/context-menu.js +1 -0
- package/dist/components/ui/dialog.cjs +1 -0
- package/dist/components/ui/dialog.d.cts +22 -0
- package/dist/components/ui/dialog.d.ts +22 -0
- package/dist/components/ui/dialog.js +1 -0
- package/dist/components/ui/dropdown-menu.cjs +1 -0
- package/dist/components/ui/dropdown-menu.d.cts +30 -0
- package/dist/components/ui/dropdown-menu.d.ts +30 -0
- package/dist/components/ui/dropdown-menu.js +1 -0
- package/dist/components/ui/hover-card.cjs +1 -0
- package/dist/components/ui/hover-card.d.cts +8 -0
- package/dist/components/ui/hover-card.d.ts +8 -0
- package/dist/components/ui/hover-card.js +1 -0
- package/dist/components/ui/input.cjs +1 -0
- package/dist/components/ui/input.d.cts +5 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.js +1 -0
- package/dist/components/ui/label.cjs +1 -0
- package/dist/components/ui/label.d.cts +8 -0
- package/dist/components/ui/label.d.ts +8 -0
- package/dist/components/ui/label.js +1 -0
- package/dist/components/ui/loader.cjs +1 -0
- package/dist/components/ui/loader.d.cts +12 -0
- package/dist/components/ui/loader.d.ts +12 -0
- package/dist/components/ui/loader.js +1 -0
- package/dist/components/ui/navigation-menu.cjs +1 -0
- package/dist/components/ui/navigation-menu.d.cts +15 -0
- package/dist/components/ui/navigation-menu.d.ts +15 -0
- package/dist/components/ui/navigation-menu.js +1 -0
- package/dist/components/ui/popover.cjs +1 -0
- package/dist/components/ui/popover.d.cts +9 -0
- package/dist/components/ui/popover.d.ts +9 -0
- package/dist/components/ui/popover.js +1 -0
- package/dist/components/ui/progress.cjs +1 -0
- package/dist/components/ui/progress.d.cts +8 -0
- package/dist/components/ui/progress.d.ts +8 -0
- package/dist/components/ui/progress.js +1 -0
- package/dist/components/ui/scroll-area.cjs +1 -0
- package/dist/components/ui/scroll-area.d.cts +7 -0
- package/dist/components/ui/scroll-area.d.ts +7 -0
- package/dist/components/ui/scroll-area.js +1 -0
- package/dist/components/ui/select.cjs +1 -0
- package/dist/components/ui/select.d.cts +15 -0
- package/dist/components/ui/select.d.ts +15 -0
- package/dist/components/ui/select.js +1 -0
- package/dist/components/ui/separator.cjs +1 -0
- package/dist/components/ui/separator.d.cts +6 -0
- package/dist/components/ui/separator.d.ts +6 -0
- package/dist/components/ui/separator.js +1 -0
- package/dist/components/ui/sheet.cjs +1 -0
- package/dist/components/ui/sheet.d.cts +29 -0
- package/dist/components/ui/sheet.d.ts +29 -0
- package/dist/components/ui/sheet.js +1 -0
- package/dist/components/ui/skeleton.cjs +1 -0
- package/dist/components/ui/skeleton.d.cts +5 -0
- package/dist/components/ui/skeleton.d.ts +5 -0
- package/dist/components/ui/skeleton.js +1 -0
- package/dist/components/ui/slider.cjs +1 -0
- package/dist/components/ui/slider.d.cts +6 -0
- package/dist/components/ui/slider.d.ts +6 -0
- package/dist/components/ui/slider.js +1 -0
- package/dist/components/ui/switch.cjs +1 -0
- package/dist/components/ui/switch.d.cts +9 -0
- package/dist/components/ui/switch.d.ts +9 -0
- package/dist/components/ui/switch.js +1 -0
- package/dist/components/ui/tabs.cjs +1 -0
- package/dist/components/ui/tabs.d.cts +9 -0
- package/dist/components/ui/tabs.d.ts +9 -0
- package/dist/components/ui/tabs.js +1 -0
- package/dist/components/ui/textarea.cjs +1 -0
- package/dist/components/ui/textarea.d.cts +5 -0
- package/dist/components/ui/textarea.d.ts +5 -0
- package/dist/components/ui/textarea.js +1 -0
- package/dist/components/ui/toggle.cjs +1 -0
- package/dist/components/ui/toggle.d.cts +15 -0
- package/dist/components/ui/toggle.d.ts +15 -0
- package/dist/components/ui/toggle.js +1 -0
- package/dist/components/ui/tooltip.cjs +1 -0
- package/dist/components/ui/tooltip.d.cts +9 -0
- package/dist/components/ui/tooltip.d.ts +9 -0
- package/dist/components/ui/tooltip.js +1 -0
- package/dist/config-registry-RSJCAKY5.js +1 -0
- package/dist/continue-editing-in-this-client-QBMOFRLL.js +1 -0
- package/dist/core-BNe4bA6z.d.cts +5455 -0
- package/dist/core-BNe4bA6z.d.ts +5455 -0
- package/dist/css-import-modal-NMFRQGCY.js +13 -0
- package/dist/db/better-sqlite3.cjs +1 -0
- package/dist/db/better-sqlite3.d.cts +16 -0
- package/dist/db/better-sqlite3.d.ts +16 -0
- package/dist/db/better-sqlite3.js +1 -0
- package/dist/db/d1.cjs +1 -0
- package/dist/db/d1.d.cts +17 -0
- package/dist/db/d1.d.ts +17 -0
- package/dist/db/d1.js +1 -0
- package/dist/db/libsql.cjs +1 -0
- package/dist/db/libsql.d.cts +23 -0
- package/dist/db/libsql.d.ts +23 -0
- package/dist/db/libsql.js +1 -0
- package/dist/db/node-pg.cjs +1 -0
- package/dist/db/node-pg.d.cts +21 -0
- package/dist/db/node-pg.d.ts +21 -0
- package/dist/db/node-pg.js +1 -0
- package/dist/db/postgres.cjs +1 -0
- package/dist/db/postgres.d.cts +28 -0
- package/dist/db/postgres.d.ts +28 -0
- package/dist/db/postgres.js +1 -0
- package/dist/delete-page-CGR6VXZC.css +1 -0
- package/dist/delete-page-FQYTEMBN.js +1 -0
- package/dist/digital-asset-manager-PIZMJEMX.js +1 -0
- package/dist/digital-asset-manager-PSTDGMY2.css +1 -0
- package/dist/dispatch-action-3IV56BNY.js +1 -0
- package/dist/duplicate-page-HPPMQRL3.js +1 -0
- package/dist/dynamic-page-selector-LFHJQLYY.js +1 -0
- package/dist/dynamic-page-selector-SXJQAIGL.css +1 -0
- package/dist/edit-url-panel-Q3NJCV55.js +1 -0
- package/dist/get-blocks-styles-SLZ5NDUF.js +1 -0
- package/dist/get-page-styles-Q4FWW5LX.js +1 -0
- package/dist/image-editor-PLXDYVKE.css +1 -0
- package/dist/image-editor-RSEHWRGV.js +1 -0
- package/dist/json-diff-viewer-FQYK2FUX.js +8 -0
- package/dist/lang-panel-57UGEL6B.css +1 -0
- package/dist/lang-panel-HH5LEOF4.js +1 -0
- package/dist/license-overlay-4Q525E53.js +1 -0
- package/dist/log-ai-request-LHPKU2C5.js +1 -0
- package/dist/manage-design-tokens-264H25A2.js +1 -0
- package/dist/manage-design-tokens-modal-OIWIZ53K.js +1 -0
- package/dist/mark-as-template-7TCCEMGC.js +1 -0
- package/dist/nested-path-selector-content-N4XN7QUS.js +1 -0
- package/dist/nextjs/render-client.cjs +1 -0
- package/dist/nextjs/render-client.css +1 -0
- package/dist/nextjs/render-client.d.cts +14 -0
- package/dist/nextjs/render-client.d.ts +14 -0
- package/dist/nextjs/render-client.js +1 -0
- package/dist/nextjs/render.cjs +829 -0
- package/dist/nextjs/render.d.cts +78 -0
- package/dist/nextjs/render.d.ts +78 -0
- package/dist/nextjs/render.js +1 -0
- package/dist/nextjs/server.cjs +807 -0
- package/dist/nextjs/server.d.cts +329 -0
- package/dist/nextjs/server.d.ts +329 -0
- package/dist/nextjs/server.js +1 -0
- package/dist/nextjs.cjs +1 -0
- package/dist/nextjs.d.cts +17 -0
- package/dist/nextjs.d.ts +17 -0
- package/dist/nextjs.js +1 -0
- package/dist/no-language-page-content-NQIROTIL.js +1 -0
- package/dist/no-language-page-dialog-CWG5PI7N.js +1 -0
- package/dist/page-creator-2L6L6EFV.js +1 -0
- package/dist/page-lock-7HMG34UJ.js +1 -0
- package/dist/page-locked-dialog-ACMWVAZX.js +1 -0
- package/dist/page-manager-new-SCZFNGKO.js +1 -0
- package/dist/page-manager-new-VWRASZTI.css +1 -0
- package/dist/page-manager-search-and-filter-7CHPYAPV.js +1 -0
- package/dist/page-manager-sheet-KZZBKQ6M.js +1 -0
- package/dist/page-manager-sheet-U5YEB5CS.css +1 -0
- package/dist/page-revisions-content-DHPEQ4CA.js +1 -0
- package/dist/page-revisions-trigger-XGC4HOTL.js +1 -0
- package/dist/pages-DlMX1Lj2.d.cts +21 -0
- package/dist/pages-Dol4CXrN.d.ts +21 -0
- package/dist/payload/builder.cjs +243 -0
- package/dist/payload/builder.css +1 -0
- package/dist/payload/builder.d.cts +13 -0
- package/dist/payload/builder.d.ts +13 -0
- package/dist/payload/builder.js +1 -0
- package/dist/payload.cjs +807 -0
- package/dist/payload.d.cts +603 -0
- package/dist/payload.d.ts +603 -0
- package/dist/payload.js +1 -0
- package/dist/preview-banner-SDDZGGRW.js +1 -0
- package/dist/publish-pages-content-3AZ45DYH.js +1 -0
- package/dist/registry.cjs +11 -0
- package/dist/registry.d.cts +74 -0
- package/dist/registry.d.ts +74 -0
- package/dist/registry.js +1 -0
- package/dist/relations-DDBTFCMR.js +1 -0
- package/dist/revalidate-G2DEOH4Z.js +1 -0
- package/dist/rte-widget-modal-7RXFEYHK.js +1 -0
- package/dist/save-to-lib-65EGTZE5.js +1 -0
- package/dist/schema-IVNMPI4V.js +1 -0
- package/dist/schema.sqlite-CYBLikNv.d.cts +5852 -0
- package/dist/schema.sqlite-CYBLikNv.d.ts +5852 -0
- package/dist/seo-panel-WQ47FNP4.css +1 -0
- package/dist/seo-panel-Z6OBXHQ4.js +2 -0
- package/dist/server-config-b29G6_aQ.d.cts +116 -0
- package/dist/server-config-oPlt3V1X.d.ts +116 -0
- package/dist/state-RAP56WXS.js +1 -0
- package/dist/take-over-request-EB464ZGU.js +1 -0
- package/dist/translation-warning-modal-EES6I2QV.js +1 -0
- package/dist/types.cjs +1 -0
- package/dist/types.d.cts +38 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +1 -0
- package/dist/unmark-as-template-6STMTBP5.js +1 -0
- package/dist/unpublish-page-CE3CJK5C.js +1 -0
- package/dist/unpublished-partials-modal-OZBWBCLN.js +1 -0
- package/dist/utils.cjs +1 -0
- package/dist/utils.d.cts +168 -0
- package/dist/utils.d.ts +168 -0
- package/dist/utils.js +1 -0
- package/dist/web-blocks.cjs +1 -0
- package/dist/web-blocks.d.cts +3 -0
- package/dist/web-blocks.d.ts +3 -0
- package/dist/web-blocks.js +1 -0
- package/dist/web-preview-EIWOXGPY.js +1 -0
- package/package.json +322 -0
|
@@ -0,0 +1,801 @@
|
|
|
1
|
+
import{a as tn}from"./chunk-346H4FEX.js";import{b as Qr,c as Xr,f as g,g as m,h as n}from"./chunk-CFNOB42V.js";import{i as Jr,o as Te,p as We,q as Ae,r as nn,s as Ye}from"./chunk-DZ72OHTD.js";import{z as rn}from"./chunk-OSGXFZTA.js";import{c as G,j as an}from"./chunk-OQZ4EPOM.js";import{a as b}from"./chunk-CRJENCPR.js";import{a as Za,b as en}from"./chunk-6M7V7BOM.js";import{f as ot}from"./chunk-OR7KKUYT.js";import{a as st}from"./chunk-YDOQEFOK.js";import{d as nt,f as ze,l as Ja}from"./chunk-3UEPBBE4.js";import"server-only";import"server-only";import{z as B}from"zod";var p=class extends Error{constructor(t,r="ACTION_ERROR",a=400,i,o){super(t);this.code=r;this.status=a;this.error=i;this.metadata=o;this.name="ActionError",i&&console.error(i)}};function Q(s){throw new p(s.message,s.code,s.statusCode)}var z=class extends Error{constructor(t,r="UNKNOWN_ERROR",a=500,i){super(t);this.code=r;this.statusCode=a;this.originalError=i;this.name="AIChatError"}toJSON(){return{error:!0,code:this.code,message:this.message,statusCode:this.statusCode}}};var Ki=`
|
|
2
|
+
# ANIMATION RULES
|
|
3
|
+
- Add \`data-animation\` attribute to elements when appropriate to add entry animations on scroll.
|
|
4
|
+
- **Do not overuse animations.** Only animate important elements like hero images, feature cards & section heading etc.
|
|
5
|
+
- The format MUST exactly be: \`data-animation="ANIMATION|EASING|DURATION|DELAY|TIME"\`
|
|
6
|
+
- **ANIMATION**: fade-in, slide-up, slide-down, slide-left, slide-right, zoom-in, zoom-out, flip-x, flip-y, rotate-in
|
|
7
|
+
- **EASING**: linear, ease-in, ease-out, ease-in-out
|
|
8
|
+
- **DURATION**: in milliseconds (e.g., 500, 700, 1000)
|
|
9
|
+
- **DELAY**: in milliseconds (e.g., 0, 200, 300) so that the animation starts after a delay and not immediately
|
|
10
|
+
- **TIME**: once (plays once) or infinite (repeats every time it enters the viewport)
|
|
11
|
+
- Example: \`<div data-animation="slide-up|ease-in-out|500|300|once" class="...">\`
|
|
12
|
+
`,on='\n\n# IMAGE RULES\n- Use **placeholder images only** \u2014 never use external image services like Picsum.\n- Format: `https://placehold.co/{width}x{height}/e2e8f0/e2e8f0`\n (light gray background, no text)\n\n- Suggested sizes:\n * Hero: 1200x600\n * Cards: 400x300\n * Team: 300x300\n\n- **Alt text is mandatory and must be descriptive and meaningful** \u2014 describe what the image *would* show in context, not just "image" or "placeholder".\n - \u2705 Good: `alt="A modern open-plan office with large windows and natural light"`\n - \u274C Bad: `alt="Image"`, `alt="Placeholder"`, `alt="Photo"`, `alt=""`\n- Always include explicit `width` and `height` HTML attributes on every `<img>` tag matching the image dimensions.\n Example: `<img src="https://placehold.co/1200x600/e2e8f0/e2e8f0" alt="A sweeping aerial view of a modern city skyline at sunset" width="1200" height="600">`\n',Qi=`\u{1F6A8} CRITICAL FORMAT REQUIREMENT: Your response MUST start with '--START--' immediately. NEVER include any text, thinking, or reasoning before '--START--'. \u{1F6A8}
|
|
13
|
+
|
|
14
|
+
# 1. RESPONSE FORMAT RULES (ALWAYS OBEY FIRST)
|
|
15
|
+
|
|
16
|
+
Every response MUST follow this structure:
|
|
17
|
+
|
|
18
|
+
--START--
|
|
19
|
+
--THINKING={short plain-language reasoning}
|
|
20
|
+
(one or more ACTION blocks: ADD / EDIT / REMOVE)
|
|
21
|
+
--END--
|
|
22
|
+
|
|
23
|
+
Rules:
|
|
24
|
+
- The VERY FIRST characters must be '--START--'.
|
|
25
|
+
- '--THINKING=' must appear immediately after '--START--'.
|
|
26
|
+
- No commentary, markdown, or text outside '--START--' and '--END--'.
|
|
27
|
+
- Use simple natural language in THINKING. Do NOT mention ids, attributes, DOM, HTML tags, or technical terms.
|
|
28
|
+
- If no action is required, still output:
|
|
29
|
+
--START--
|
|
30
|
+
--THINKING={why no changes needed}
|
|
31
|
+
--END--
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# 2. ACTION FORMAT DEFINITIONS (MANDATORY)
|
|
35
|
+
|
|
36
|
+
### ADD Action
|
|
37
|
+
Used to insert new HTML.
|
|
38
|
+
Do not add bid attribute to any element.
|
|
39
|
+
|
|
40
|
+
Format:
|
|
41
|
+
--ACTION=ADD|PARENT={parent_id or 'undefined'}|POS={position or -1}--
|
|
42
|
+
--TASK={plain-language description of what you are adding}
|
|
43
|
+
--HTML--
|
|
44
|
+
{HTML here}
|
|
45
|
+
--ENDHTML--
|
|
46
|
+
--MSG={plain-language explanation}
|
|
47
|
+
--ENDACTION--
|
|
48
|
+
|
|
49
|
+
Rules:
|
|
50
|
+
- PARENT = bid of parent, or 'undefined' for root.
|
|
51
|
+
- POS = -1 to append at the end.
|
|
52
|
+
- HTML must include full and valid tags.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### EDIT Action
|
|
56
|
+
Used to replace an existing element completely.
|
|
57
|
+
Combine multiple edits into one action with one edit id where possible.
|
|
58
|
+
|
|
59
|
+
Format:
|
|
60
|
+
--ACTION=EDIT|ID={target_id}--
|
|
61
|
+
--TASK={plain-language description of what you are changing}
|
|
62
|
+
--HTML--
|
|
63
|
+
{full replacement HTML here}
|
|
64
|
+
--ENDHTML--
|
|
65
|
+
--MSG={plain-language explanation}
|
|
66
|
+
--ENDACTION--
|
|
67
|
+
|
|
68
|
+
Rules:
|
|
69
|
+
- Must include full tag being replaced.
|
|
70
|
+
- Never partially edit; always replace full HTML for the target element.
|
|
71
|
+
|
|
72
|
+
### REMOVE Action
|
|
73
|
+
Used to delete elements.
|
|
74
|
+
|
|
75
|
+
Format:
|
|
76
|
+
--ACTION=REMOVE|IDS={id1, id2, ...}--
|
|
77
|
+
--TASK={plain-language description of what you are removing}
|
|
78
|
+
--MSG={plain-language explanation}
|
|
79
|
+
--ENDACTION--
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
### THINKING Block (STRICT)
|
|
83
|
+
Placed immediately after '--START--'.
|
|
84
|
+
|
|
85
|
+
Format:
|
|
86
|
+
--THINKING={short plain-language reasoning}
|
|
87
|
+
|
|
88
|
+
Rules:
|
|
89
|
+
- Only one concise line.
|
|
90
|
+
- No mentions of tags, ids, attributes, DOM, or code.
|
|
91
|
+
- Focus on visual/content intentions.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# 3. HTML GENERATION RULES (MANDATORY)
|
|
95
|
+
|
|
96
|
+
You are an expert HTML/CSS developer specializing in Tailwind CSS and shadcn/ui patterns.
|
|
97
|
+
You produce clean, semantic, accessible, production-ready HTML.
|
|
98
|
+
Generate **pure HTML**, with no markdown, no comments, no extra text.
|
|
99
|
+
|
|
100
|
+
### General Guidelines
|
|
101
|
+
1. Use **only Tailwind CSS v3 utility classes**, no custom CSS.
|
|
102
|
+
2. Use **shadcn/ui design system** semantic tokens for all colors.
|
|
103
|
+
3. Use **semantic HTML** with proper accessibility.
|
|
104
|
+
4. Always produce **responsive, mobile-first** layout.
|
|
105
|
+
5. **Do NOT include** <!DOCTYPE>, <html>, <head>, or <body>.
|
|
106
|
+
6. Keep UI varied \u2014 don't repeat the same layout patterns.
|
|
107
|
+
7. Use \`<details><summary>\` for accordion, FAQ, and mobile menu interactions.
|
|
108
|
+
8. Do NOT use Tailwind container queries.
|
|
109
|
+
9. If UI is generated from a user-provided image, ensure full responsiveness.
|
|
110
|
+
10. **If the user has attached an image, the HTML MUST be generated based strictly on the layout, spacing, hierarchy, and visual appearance of that image.**
|
|
111
|
+
- Match structure as closely as possible
|
|
112
|
+
- Maintain the Tailwind + shadcn theme rules
|
|
113
|
+
- The HTML output should reflect the exact design of the provided image
|
|
114
|
+
|
|
115
|
+
### \u{1F6A8} CRITICAL: Avoid HTML "Div Soup" for Decorative UI Elements
|
|
116
|
+
**NEVER generate complex HTML markup for decorative UI elements that should be images:**
|
|
117
|
+
- \u274C DO NOT create HTML mockups of: code snippets, terminal windows, browser frames, device mockups, window chrome, syntax-highlighted code blocks
|
|
118
|
+
- \u2705 INSTEAD: Use placeholder images for these decorative elements
|
|
119
|
+
- **Reasoning**: Complex nested div structures for visual decoration create "div soup" that bloats markup unnecessarily
|
|
120
|
+
- **When to use images**: If the element is purely decorative/visual and not interactive content (e.g., showing a code example as part of a design, not actual executable code)
|
|
121
|
+
- **Examples**:
|
|
122
|
+
* For a "code snippet showcase" \u2192 Use an image: \`<img src="https://placehold.co/800x400/e2e8f0/e2e8f0" alt="Code editor showing React component example" width="800" height="400">\`
|
|
123
|
+
* For a "browser window mockup" \u2192 Use an image: \`<img src="https://placehold.co/1000x600/e2e8f0/e2e8f0" alt="Browser window displaying dashboard interface" width="1000" height="600">\`
|
|
124
|
+
* For actual interactive content \u2192 Use semantic HTML
|
|
125
|
+
|
|
126
|
+
### \u{1F6A8} Design Tokens (MANDATORY)
|
|
127
|
+
You MUST use design tokens whenever appropriate. Design tokens are predefined groupings of Tailwind classes identified by the \`dt#\` prefix.
|
|
128
|
+
1. **Placement**: Always place design tokens at the START of the \`class\` attribute.
|
|
129
|
+
2. **Overrides**: Any Tailwind classes following a design token act as overrides, similar to how \`tailwind-merge\` works.
|
|
130
|
+
3. **Example**: \`<button class="dt#btn p-2">\` where \`p-2\` overrides the default padding in \`dt#btn\`.
|
|
131
|
+
|
|
132
|
+
**Available Design Tokens**:
|
|
133
|
+
{{DESIGN_TOKENS_LIST}}
|
|
134
|
+
|
|
135
|
+
# 3.1 DESIGN EXCELLENCE & CREATIVITY (CRITICAL)
|
|
136
|
+
|
|
137
|
+
Create distinctive, production-grade interfaces that avoid generic "AI slop" aesthetics. Every UI you generate should be visually striking, memorable, and intentionally designed.
|
|
138
|
+
|
|
139
|
+
### Design Thinking Process
|
|
140
|
+
Before generating HTML, commit to a BOLD aesthetic direction:
|
|
141
|
+
- **Purpose**: Consider what problem this interface solves and who uses it
|
|
142
|
+
- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
|
|
143
|
+
|
|
144
|
+
**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
|
|
145
|
+
|
|
146
|
+
### Design Excellence Guidelines
|
|
147
|
+
|
|
148
|
+
**Typography & Font Selection**:
|
|
149
|
+
- Choose fonts that are beautiful, unique, and interesting
|
|
150
|
+
- AVOID generic fonts: Arial, Inter, Roboto, system fonts
|
|
151
|
+
- Use distinctive font combinations that elevate the design
|
|
152
|
+
- Pair a distinctive display font with a refined body font
|
|
153
|
+
- Consider: font-serif, font-mono for variety, or use weight variations (font-light, font-bold) creatively
|
|
154
|
+
|
|
155
|
+
**Color & Visual Hierarchy**:
|
|
156
|
+
- Commit to a cohesive aesthetic with dominant colors and sharp accents
|
|
157
|
+
- Avoid timid, evenly-distributed palettes
|
|
158
|
+
- Use shadcn tokens creatively (not just bg-background everywhere)
|
|
159
|
+
- Consider bold color blocking, dramatic contrasts, or refined monochrome
|
|
160
|
+
- AVOID: purple gradients on white backgrounds, predictable color schemes
|
|
161
|
+
|
|
162
|
+
**Spatial Composition**:
|
|
163
|
+
- Create unexpected layouts with asymmetry, overlap, diagonal flow
|
|
164
|
+
- Use grid-breaking elements and generous negative space OR controlled density
|
|
165
|
+
- Avoid predictable grid patterns - be creative with positioning
|
|
166
|
+
- Consider: absolute positioning, creative flexbox/grid layouts, overlapping elements
|
|
167
|
+
|
|
168
|
+
**Backgrounds & Visual Details**:
|
|
169
|
+
- Create atmosphere and depth rather than defaulting to solid colors
|
|
170
|
+
- Consider: gradient meshes, subtle textures, geometric patterns
|
|
171
|
+
- Use layered transparencies, dramatic shadows, decorative borders
|
|
172
|
+
- Add visual interest with background patterns or accent elements
|
|
173
|
+
|
|
174
|
+
**NEVER Use Generic AI Aesthetics**:
|
|
175
|
+
- Overused font families (Inter, Roboto, Arial, system fonts)
|
|
176
|
+
- Cliched color schemes (purple gradients on white)
|
|
177
|
+
- Predictable layouts and component patterns
|
|
178
|
+
- Cookie-cutter designs lacking context-specific character
|
|
179
|
+
- NEVER converge on common choices (Space Grotesk, etc.) across generations
|
|
180
|
+
|
|
181
|
+
**Implementation Complexity**:
|
|
182
|
+
- Match complexity to the aesthetic vision
|
|
183
|
+
- Maximalist designs: elaborate code with extensive effects
|
|
184
|
+
- Minimalist designs: restraint, precision, careful spacing and typography
|
|
185
|
+
- Elegance comes from executing the vision well
|
|
186
|
+
|
|
187
|
+
**Variation Mandate**:
|
|
188
|
+
- Every design should be different
|
|
189
|
+
- Vary between light and dark themes
|
|
190
|
+
- Change fonts, layouts, color schemes between generations
|
|
191
|
+
- Interpret user requests creatively with unexpected choices
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
# 4. ATTRIBUTE & CUSTOM COMPONENT RULES
|
|
195
|
+
|
|
196
|
+
### chai-name
|
|
197
|
+
- Add \`chai-name\` attribute to tags
|
|
198
|
+
- Use descriptive section names (e.g., "Hero Section", "Navigation").
|
|
199
|
+
|
|
200
|
+
## Custom Web components(CRITICAL)
|
|
201
|
+
- Html can have custom web components. All web components starts with <chai- prefix.
|
|
202
|
+
- Use "about-this-component" attribute to understand what the component does.
|
|
203
|
+
- Check for can-move and can-delete attribute to check if the component can be moved or deleted.
|
|
204
|
+
- If an attribute value starts with #styles: treat it like class attribute with tailwind classes.
|
|
205
|
+
Use the attribute key to understand what the attribute does and apply classes. Maintain the #styles: at start followed by tailwind classes.
|
|
206
|
+
- Do not change the chai-type attribute. Do not remove any attributes.
|
|
207
|
+
|
|
208
|
+
## Tool Usage Rules
|
|
209
|
+
- To ADD a registered custom block (listed in "Available Custom Blocks"), USE THE add_custom_block TOOL \u2014 do NOT generate HTML for it.
|
|
210
|
+
- To REMOVE blocks, USE THE remove_blocks TOOL \u2014 do NOT use --ACTION=REMOVE-- text protocol.
|
|
211
|
+
- To SET a data binding on an existing block prop, USE THE bind_prop TOOL.
|
|
212
|
+
- When building a full page layout or when the user asks to include a header, footer, or any global section,
|
|
213
|
+
CALL get_partial_blocks FIRST to discover available partial block IDs, then place them with <chai-partial-block partial-id="ID">.
|
|
214
|
+
- Continue using --ACTION=ADD-- with --HTML-- for new standard HTML sections (hero, cards, grids, etc.) \u2014 these benefit from streaming preview.
|
|
215
|
+
- Continue using --ACTION=EDIT-- with --HTML-- for editing existing HTML blocks.
|
|
216
|
+
|
|
217
|
+
## Data Binding (CRITICAL)
|
|
218
|
+
- Block prop values may contain binding expressions using double-curly syntax: {{path.to.data}}
|
|
219
|
+
- When you see {{...}} in an existing element's attribute value, it is a live data binding \u2014 NEVER remove or replace it with a static value. Preserve it exactly.
|
|
220
|
+
- You MAY use binding expressions when setting props on custom blocks, but ONLY using paths listed in the "Available Data Binding Paths" section below.
|
|
221
|
+
- Repeater blocks use a special prop: repeater-items="{{collectionName}}" where collectionName is the array to iterate.
|
|
222
|
+
- Inside a Repeater, child block props can reference each item's fields via {{$index.fieldName}}.
|
|
223
|
+
- Binding syntax must use exactly two curly braces: {{path}} \u2014 not {path} or \${{path}}.
|
|
224
|
+
- (global) paths are site-wide and available on every page. (page) paths are only available on this specific page type.
|
|
225
|
+
|
|
226
|
+
**Available Data Binding Paths**:
|
|
227
|
+
{{DATA_BINDING_PATHS}}
|
|
228
|
+
|
|
229
|
+
## Current Page Type
|
|
230
|
+
{{PAGE_TYPE_CONTEXT}}
|
|
231
|
+
|
|
232
|
+
## Available Custom Blocks
|
|
233
|
+
The following custom block types are registered and available for use. Use them with the ADD action using <chai-{kebab-type}> tags. Provide the props listed for each block as kebab-case HTML attributes. Complex values (objects, arrays) must be JSON-encoded.
|
|
234
|
+
|
|
235
|
+
{{CUSTOM_BLOCK_CATALOG}}
|
|
236
|
+
|
|
237
|
+
## Special Blocks
|
|
238
|
+
|
|
239
|
+
### Repeater \u2014 <chai-repeater>
|
|
240
|
+
Used to render a list by iterating over an array data binding.
|
|
241
|
+
- Required prop: \`repeater-items="{{arrayPath}}"\` where \`arrayPath\` is an array-type binding path.
|
|
242
|
+
- Only bind to paths marked as arrays in "Available Data Binding Paths".
|
|
243
|
+
- Child blocks inside a Repeater reference the current item's fields using \`{{$index.fieldName}}\`.
|
|
244
|
+
- Example: \`<chai-repeater repeater-items="{{page.products}}"><h3>{{$index.name}}</h3></chai-repeater>\`
|
|
245
|
+
- Do NOT use a Repeater for static lists \u2014 only when iterating over bound data.
|
|
246
|
+
|
|
247
|
+
### PartialBlock \u2014 <chai-partial-block>
|
|
248
|
+
Partial blocks are global reusable blocks (e.g. header, footer, navigation) shared across pages.
|
|
249
|
+
- Reference them by their ID: \`<chai-partial-block partial-id="THE_PARTIAL_ID"></chai-partial-block>\`
|
|
250
|
+
- Never modify a partial block's content inline \u2014 only reference it.
|
|
251
|
+
- When asked to build a full page layout, use the \`get_partial_blocks\` tool (available in Plan 007)
|
|
252
|
+
to discover available partial IDs before placing them.
|
|
253
|
+
- If the tool is not available, ask the user for the partial IDs to use.
|
|
254
|
+
|
|
255
|
+
## Icons
|
|
256
|
+
- Icons use the **Lucide** icon set (https://lucide.dev/icons).
|
|
257
|
+
- Always include \`chai-type="Icon"\` on icon elements and preserve any existing attributes (e.g. \`bid\`).
|
|
258
|
+
- Express each icon as \`<chai-icon chai-type="Icon" icon-name="kebab-case-name" width="16" height="16">\`
|
|
259
|
+
e.g. \`<chai-icon chai-type="Icon" icon-name="search" width="16" height="16">\`, \`<chai-icon chai-type="Icon" icon-name="arrow-right" width="24" height="24">\`.
|
|
260
|
+
- Pick semantically appropriate icon names from Lucide; do not embed raw \`<svg>\` markup inside \`<chai-icon>\`.
|
|
261
|
+
|
|
262
|
+
### SVG
|
|
263
|
+
- Always include width/height attributes.
|
|
264
|
+
- Ensure correct \`viewBox\`.
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
# 5. SHADCN/THEME COLOR RULES (STRICT)
|
|
268
|
+
|
|
269
|
+
Use ONLY these semantic tokens:
|
|
270
|
+
- bg-background + text-foreground
|
|
271
|
+
- bg-card + text-card-foreground
|
|
272
|
+
- bg-primary + text-primary-foreground
|
|
273
|
+
- bg-secondary + text-secondary-foreground
|
|
274
|
+
- bg-muted + text-muted-foreground
|
|
275
|
+
- bg-accent + text-accent-foreground
|
|
276
|
+
- bg-destructive + text-destructive-foreground
|
|
277
|
+
- border-border, border-input
|
|
278
|
+
- ring-ring
|
|
279
|
+
|
|
280
|
+
### Contrast Rules
|
|
281
|
+
- Always maintain clear readable contrast.
|
|
282
|
+
- Never pair same-family bg/text tokens (e.g., bg-primary + text-primary).
|
|
283
|
+
|
|
284
|
+
### Hover Rules
|
|
285
|
+
- Primary buttons: hover:bg-primary/90
|
|
286
|
+
- Cards: hover:bg-accent hover:text-accent-foreground
|
|
287
|
+
- Links: text-muted-foreground hover:text-foreground
|
|
288
|
+
- Nav links: text-foreground/80 hover:text-foreground
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# 6. RESPONSIVENESS RULES
|
|
292
|
+
|
|
293
|
+
- Mobile-first approach.
|
|
294
|
+
- Breakpoints: sm, md, lg, xl.
|
|
295
|
+
- Smooth scaling between sizes.
|
|
296
|
+
- At md breakpoint:
|
|
297
|
+
* Reduce grid columns (lg:4 \u2192 md:2 \u2192 sm:1)
|
|
298
|
+
* Adjust padding, spacing, and layouts
|
|
299
|
+
* Ensure nav/mobilmenus behave correctly
|
|
300
|
+
* Ensure cards remain aligned
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# 7. SPECIFIC UI PATTERNS
|
|
304
|
+
|
|
305
|
+
### Forms & Fields
|
|
306
|
+
- Always include proper \`type\` and \`autocomplete\` attributes for form fields (e.g., \`type="email" autocomplete="email"\`, \`type="text" autocomplete="given-name"\`, \`type="tel" autocomplete="tel"\`).
|
|
307
|
+
|
|
308
|
+
### Mobile Menu (<details><summary>)
|
|
309
|
+
- Use 'summary' containing an SVG hamburger icon.
|
|
310
|
+
- Mobile menu container sample:
|
|
311
|
+
absolute right-1 mt-2 min-w-64 bg-card border border-border rounded-lg shadow-lg z-50 p-4
|
|
312
|
+
- Menu item sample:
|
|
313
|
+
block py-2 px-4 hover:bg-accent rounded-md transition-colors
|
|
314
|
+
- Touch targets must be at least 44px tall.
|
|
315
|
+
|
|
316
|
+
### Accordions / Nested Menus
|
|
317
|
+
- Always use <details> and <summary>.
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
# 8. COMMON RULES
|
|
321
|
+
|
|
322
|
+
{{ANIMATION_RULES}}
|
|
323
|
+
{{IMAGE_RULES}}
|
|
324
|
+
|
|
325
|
+
# 9. OUTPUT RESTRICTIONS
|
|
326
|
+
- Output ONLY the exact allowed action blocks inside the mandatory format.
|
|
327
|
+
- NEVER include stray text.
|
|
328
|
+
- NEVER include markdown.
|
|
329
|
+
- NEVER break the format.
|
|
330
|
+
- NEVER place ANYTHING before '--START--' and after '--END--'.
|
|
331
|
+
- The output must always begin with '--START--' and end with '--END--'.
|
|
332
|
+
`.trim(),Zr=s=>{let e=Qi;return s!=null&&s.animation?e=e.replace("{{ANIMATION_RULES}}",Ki):e=e.replace("{{ANIMATION_RULES}}",""),s!=null&&s.image,e=e.replace("{{IMAGE_RULES}}",on),e};var sn=`Generate image based on the user request.
|
|
333
|
+
The image should be suitable for use as a website asset such as hero backgrounds, product images, team photos, icons, or decorative elements.
|
|
334
|
+
Ensure the image is medium quality, professional, and appropriate for web use. Do not add text or button on image if not explicitly requested.`;var ln=`You are an expert language translator specializing in preserving data structure integrity while translating content.
|
|
335
|
+
|
|
336
|
+
TASK: Translate all text content within the provided JSON structure to the target language.
|
|
337
|
+
|
|
338
|
+
TRANSLATION PATTERN:
|
|
339
|
+
1. Content Translation Strategy:
|
|
340
|
+
- Identify text content properties (e.g., 'content', 'label', 'text', 'title', 'description')
|
|
341
|
+
- Preserve the original property as the default language content
|
|
342
|
+
- Add language-specific variants using the pattern: '{propertyName}-{languageCode}'
|
|
343
|
+
|
|
344
|
+
2. Property Naming Convention:
|
|
345
|
+
- Original: 'content' (default language)
|
|
346
|
+
- Translated: 'content-fr', 'content-es', 'content-de', etc.
|
|
347
|
+
- Examples: 'label' \u2192 'label-fr', 'title' \u2192 'title-es', 'description' \u2192 'description-de'
|
|
348
|
+
|
|
349
|
+
3. Implementation Rules:
|
|
350
|
+
- NEVER override or remove the original property
|
|
351
|
+
- Language code is provided in the user request
|
|
352
|
+
- If there is already a property with the same name as the translated property, replace it with the translated property.
|
|
353
|
+
|
|
354
|
+
REQUIREMENTS (Common):
|
|
355
|
+
1. Return ONLY the translated JSON structure - no markdown formatting, code blocks, or explanations
|
|
356
|
+
2. Preserve the exact JSON structure, keys, and data types
|
|
357
|
+
3. Maintain proper grammar, tone, and cultural context in the target language
|
|
358
|
+
4. Maintain the original structure and data types
|
|
359
|
+
5. Translate ONLY human-readable text content - do NOT translate:
|
|
360
|
+
- JSON keys/property names
|
|
361
|
+
- Data binding placeholders (format: {{dataBindingId}})
|
|
362
|
+
- HTML attributes (class, id, data-*, etc.)
|
|
363
|
+
- URLs, file paths, or technical identifiers
|
|
364
|
+
- Code snippets or technical values
|
|
365
|
+
6. Ensure translated text fits naturally within the original context
|
|
366
|
+
7. Keep numbers, dates, and technical terms unchanged unless culturally appropriate to translate
|
|
367
|
+
|
|
368
|
+
OUTPUT FORMAT: Valid JSON only, ready to be parsed directly.`;var cn=`You are an expert language translator and content editor specializing in preserving data structure integrity while modifying content.
|
|
369
|
+
|
|
370
|
+
TASK: Modify content within the provided JSON structure according to user request for the target language.
|
|
371
|
+
|
|
372
|
+
CONTENT MODIFICATION STRATEGY:
|
|
373
|
+
1. Language Property Selection:
|
|
374
|
+
- First, check if '{propertyName}-{languageCode}' exists (e.g., 'content-fr', 'label-es', 'title-de')
|
|
375
|
+
- If language-specific property exists: Use and modify that property's content
|
|
376
|
+
- If language-specific property does NOT exist: Use the default language property content, translate it to the target language, and create the '{propertyName}-{languageCode}' property with the translated content
|
|
377
|
+
|
|
378
|
+
2. Property Naming Convention:
|
|
379
|
+
- Default language: 'content', 'label', 'text', 'title', 'description'
|
|
380
|
+
- Language-specific: 'content-{languageCode}', 'label-{languageCode}', etc.
|
|
381
|
+
- Examples: 'content-fr', 'label-es', 'title-de', 'description-ja'
|
|
382
|
+
|
|
383
|
+
3. Implementation Rules:
|
|
384
|
+
- NEVER modify the original default language property
|
|
385
|
+
- Only modify or create the language-specific property ('{propertyName}-{languageCode}')
|
|
386
|
+
- Language code is provided in the user request
|
|
387
|
+
- Preserve all other language variants unchanged
|
|
388
|
+
|
|
389
|
+
REQUIREMENTS (Common):
|
|
390
|
+
1. Return ONLY the modified JSON structure - no markdown formatting, code blocks, or explanations
|
|
391
|
+
2. Preserve the exact JSON structure, keys, and data types
|
|
392
|
+
3. Maintain proper grammar, tone, and cultural context in the target language
|
|
393
|
+
4. Maintain the original structure and data types
|
|
394
|
+
|
|
395
|
+
CRITICAL REQUIREMENTS (Content Modification):
|
|
396
|
+
1. Apply user-requested modifications (improve, lengthen, shorten, fix grammar, change tone, rephrase, etc.) to the language-specific property
|
|
397
|
+
2. If language-specific property exists: Modify its content according to user request
|
|
398
|
+
3. If language-specific property does NOT exist: Translate default content to target language first, then apply modifications
|
|
399
|
+
4. Do NOT translate or modify:
|
|
400
|
+
- JSON keys/property names
|
|
401
|
+
- Data binding placeholders (format: {{dataBindingId}})
|
|
402
|
+
- HTML attributes (class, id, data-*, etc.)
|
|
403
|
+
- URLs, file paths, or technical identifiers
|
|
404
|
+
- Code snippets or technical values
|
|
405
|
+
5. Preserve all other language variants and properties unchanged
|
|
406
|
+
6. Apply changes consistently across related properties when applicable
|
|
407
|
+
|
|
408
|
+
OUTPUT FORMAT: Valid JSON only, ready to be parsed directly.`;function Se(s=null,e={}){if(s)switch(s){case"GENERATE_IMAGE":return sn;case"TRANSLATE_CONTENT":return ln;case"UPDATE_CONTENT":return cn;default:return Zr(e)}return Zr(e)}import{generateImage as no,generateText as io,streamText as oo,stepCountIs as so}from"ai";import"server-only";var Xi=/data:[^;]+;base64,[A-Za-z0-9+/=]+/g;function Ke(s,e=120){let t=s.replace(Xi,"[data-uri]");return t.length<=e?t:`${t.slice(0,e)}\u2026`}function ea(s){return`messages=${s.length}`}import{z as pn}from"zod";var y=class{constructor(){this.context=null}getValidationSchema(){return{}}validate(e){if(!e)return!0;try{let t=this.getValidationSchema();return t!=null&&t.parse&&t.parse(e),!0}catch(t){return!1}}getValidationErrors(e){if(!e)return null;try{let t=this.getValidationSchema();return t!=null&&t.parse&&t.parse(e),null}catch(t){return t instanceof pn.ZodError?t.issues.map(a=>`${a.path.join(".")}: ${a.message}`).join(", "):null}}setContext(e){this.context=e}async run(e){if(!this.validate(e)){let t=this.getValidationErrors(e),r=t?`Validation failed: ${t}`:"Validation failed";throw new p(r,"VALIDATION_ERROR")}return this.execute(e)}handleError(e){if(e instanceof p)throw e;if(e instanceof pn.ZodError){let t=e.issues.map(r=>`${r.path.join(".")}: ${r.message}`).join(", ");throw new p(`Validation failed: ${t}`,"VALIDATION_ERROR")}else{let t=e instanceof Error?e.message:"Unknown error";throw new p(t,"ACTION_ERROR")}}};var w=(s,e)=>(console.error(e),new Error(s));function _e(){return Qe().credits.enabled}function lt(){return Qe().logging.logger}function dn(s,e="UNKNOWN"){let t=Qe();if(!s)return{model:s};if(typeof s=="object"&&"modelId"in s)return{model:s};if(t.resolveModel){let r=t.resolveModel(s,e);if(r)return r}if(t.models&&typeof s=="string"){let r=t.models.find(a=>a.id===s);if(r)return{model:r}}return{model:s}}function ta(s,e="UNKNOWN"){let t=dn(s,e);return{model:t.model,providerOptions:t.providerOptions}}function ra(s,e="UNKNOWN"){let t=dn(s,e);return{model:t.model,providerOptions:t.providerOptions}}import{and as gn,asc as Ji,eq as X,gte as Zi,lt as eo,sql as na}from"drizzle-orm";var ct=1e3,aa=new Map;async function to(s){if(aa.has(s))return aa.get(s)||null;let{data:e,error:t}=await m(()=>g.select({user:n.apps.user,client:n.apps.client}).from(n.apps).where(X(n.apps.id,s)).limit(1)),r=!t&&e&&e.length>0&&e[0].user?{user:e[0].user,client:e[0].client}:null;return aa.set(s,r),r}async function mn(s){let{data:e,error:t}=await m(()=>g.select({planId:n.appUserPlans.planId,nextBilledAt:n.appUserPlans.nextBilledAt,clientId:n.appUserPlans.client,plansAndAddOns:n.clients.plansAndAddOns}).from(n.appUserPlans).innerJoin(n.clients,X(n.appUserPlans.client,n.clients.id)).where(X(n.appUserPlans.user,s)).limit(1));return t||!e||e.length===0?null:{planId:e[0].planId||"FREE",nextBilledAt:new Date(e[0].nextBilledAt),clientId:e[0].clientId,plansConfig:e[0].plansAndAddOns}}async function ro(s,e,t){let r=[X(n.apps.user,s),X(n.aiLogs.creditSource,"monthly")];e&&r.push(Zi(n.aiLogs.createdAt,e.toISOString())),t&&r.push(eo(n.aiLogs.createdAt,t.toISOString()));let{data:a,error:i}=await m(()=>g.select({total:na`COALESCE(SUM(CAST(${n.aiLogs.totalTokens} AS NUMERIC)), 0)`}).from(n.aiLogs).innerJoin(n.apps,X(n.aiLogs.app,n.apps.id)).where(gn(...r)));return i||!a||a.length===0?0:parseFloat(a[0].total)||0}async function ao(s){let{data:e,error:t}=await m(()=>g.select({id:n.aiCreditAddons.id,creditsTotal:n.aiCreditAddons.creditsTotal,creditsUsed:n.aiCreditAddons.creditsUsed}).from(n.aiCreditAddons).where(gn(X(n.aiCreditAddons.user,s),X(n.aiCreditAddons.status,"active"))).orderBy(Ji(n.aiCreditAddons.createdAt)));if(t||!e||e.length===0)return{total:0,used:0,remaining:0,addons:[]};let r=0,a=0,i=[];for(let o of e){let l=parseFloat(o.creditsTotal)||0,c=parseFloat(o.creditsUsed)||0,d=l-c;r+=l,a+=c,d>0&&i.push({id:o.id,remaining:parseFloat(d.toFixed(2))})}return{total:r,used:a,remaining:parseFloat((r-a).toFixed(2)),addons:i}}async function ia(s){var E,x,C;let e=await to(s);if(!e)return null;let t=await mn(e.user),r=(t==null?void 0:t.plansConfig)||(e.client?await oa(e.client):null);if(!r)return null;let a=(t==null?void 0:t.planId)||"FREE",i=(E=r.plans)==null?void 0:E.find(R=>{var S;return a==="FREE"&&R.isFree||((S=R.items)==null?void 0:S.some(D=>D.id===a||D.sandboxId===a))}),o=(C=(x=i==null?void 0:i.limits)==null?void 0:x.no_of_ai_credits)!=null?C:0,l=(i==null?void 0:i.isFree)||a==="FREE",c,d;l||(d=new Date(t.nextBilledAt),c=new Date(d),c.setMonth(c.getMonth()-1));let[u,h]=await Promise.all([ro(e.user,c,d),ao(e.user)]),f=parseFloat((u/ct).toFixed(2)),T=Math.min(f,o),A=Math.max(0,o-f),I={total:h.total,used:Math.min(h.used,h.total),remaining:Math.max(0,h.remaining),addons:h.addons.map(R=>({id:R.id,remaining:R.remaining}))};return{monthly:{used:T,limit:o,remaining:parseFloat(A.toFixed(2))},addon:I,totalAvailable:parseFloat((A+I.remaining).toFixed(2)),canBuyCredits:(r.addOns||[]).length>0,billingPeriod:c&&d?{start:c,end:d}:void 0}}async function un(s){if(!_e())return{available:!0,status:null};let e=await ia(s);return e?{available:e.totalAvailable>0,status:e}:{available:!1,status:null}}function pc(s,e){let t=e/ct;return s.monthly.remaining>=t?{success:!0,creditSource:"monthly",addonId:null}:s.addon.remaining>0&&s.addon.addons.length>0?{success:!0,creditSource:"addon",addonId:s.addon.addons[0].id}:s.totalAvailable<t?{success:!1,creditSource:"monthly",addonId:null,error:"Insufficient credits"}:s.monthly.remaining>0?{success:!0,creditSource:"monthly",addonId:null}:s.addon.addons.length>0?{success:!0,creditSource:"addon",addonId:s.addon.addons[0].id}:{success:!1,creditSource:"monthly",addonId:null,error:"No credits available"}}async function dc(s,e){let{error:t}=await m(()=>g.update(n.aiCreditAddons).set({creditsUsed:na`CAST(${n.aiCreditAddons.creditsUsed} AS NUMERIC) + ${(e/ct).toFixed(2)}`,status:na`CASE WHEN CAST(${n.aiCreditAddons.creditsUsed} AS NUMERIC) + ${(e/ct).toFixed(2)} >= CAST(${n.aiCreditAddons.creditsTotal} AS NUMERIC) THEN 'exhausted' ELSE 'active' END`}).where(X(n.aiCreditAddons.id,s)));return t?{success:!1,error:"Failed to update addon credits"}:{success:!0}}async function hn(s){let e=await mn(s);return e?{planId:e.planId,nextBilledAt:e.nextBilledAt,clientId:e.clientId}:null}async function oa(s){let{data:e,error:t}=await m(()=>g.select({plansAndAddOns:n.clients.plansAndAddOns}).from(n.clients).where(X(n.clients.id,s)).limit(1));return t||!e||e.length===0?null:e[0].plansAndAddOns}var pt=class pt extends y{getActionLabel(){var e,t;return(t=(e=this.context)==null?void 0:e.action)!=null?t:"UNKNOWN_AI_ACTION"}logTokenUsage(e,t){var a;if(!G(2))return;let r=(a=t==null?void 0:t.totalTokens)!=null?a:e==null?void 0:e.totalTokens;r!==void 0&&Ae(`tokens=${r}`)}getLoggablePrompt(e){if(typeof e.prompt=="string")return e.prompt;if(Array.isArray(e.messages)){let t=e.messages.find(r=>r.role==="user");if(t)return typeof t.content=="string"?t.content:JSON.stringify(t.content)}return""}selectPromptVariant(){if(!this.prompts||this.prompts.length===0)return null;if(this.prompts.length===1)return{variant:this.prompts[0],index:0};let e=this.prompts.reduce((r,a)=>r+(a.weight||1),0),t=Math.random()*e;for(let r=0;r<this.prompts.length;r++){let a=this.prompts[r].weight||1;if(t<a)return{variant:this.prompts[r],index:r};t-=a}return{variant:this.prompts[0],index:0}}async checkCredits(){var r;if(!_e())return{available:!0,status:null};let{available:e,status:t}=await un(this.context.appId);if(!e){let a=t?"You have run out of AI credits. Please purchase additional credits or wait for your monthly credits to reset.":"Unable to verify credit status. Please try again.";throw new p(a,"RATE_LIMIT",429,void 0,{canBuyCredits:(r=t==null?void 0:t.canBuyCredits)!=null?r:!1})}return{available:e,status:t}}async generateText(e){var d,u,h,f;let t=await this.checkCredits();if(!t.available)throw new p("AI credits are required to generate text","RATE_LIMIT",429);let r=typeof e.model=="string"?e.model:this.model;if(r){let T=ta(r,(u=(d=this.context)==null?void 0:d.action)!=null?u:"UNKNOWN");e={...e,...T}}else!e.model&&this.model&&(e={...e,model:this.model});let a=lt(),i=Date.now(),o=this.getLoggablePrompt(e),l=(f=(h=e.model)==null?void 0:h.toString())!=null?f:"unknown",c=this.getActionLabel();G(1)&&We(c,"generateText"),G(2)&&(Array.isArray(e.messages)&&Ae(ea(e.messages)),o&&Ae(`prompt \xB7 ${Ke(o)}`));try{let T=await io(e);return G(1)&&Te(l,Date.now()-i,"generateText",c),this.logTokenUsage(T.usage,T.totalUsage),a==null||a({response:T,userId:this.context.userId,appId:this.context.appId,creditStatus:t.status,startTime:i,prompt:o,model:e.model.toString()}),T}catch(T){throw G(1)&&Te(l,Date.now()-i,"generateText (error)",c),a==null||a({error:T instanceof Error?T.message:String(T),response:{},userId:this.context.userId,appId:this.context.appId,creditStatus:t.status,startTime:i,prompt:o,model:e.model.toString()}),T}}async generateImage(e){var d,u,h,f,T,A,I;let t=await this.checkCredits();if(!t.available)throw new p("AI credits are required to generate images","RATE_LIMIT",429);let r=e;if(e.model!==void 0)r=typeof e.model=="string"?{...r,model:ra(e.model,(u=(d=this.context)==null?void 0:d.action)!=null?u:"UNKNOWN").model}:{...r,model:e.model};else if(this.model){let E=ra(this.model,(f=(h=this.context)==null?void 0:h.action)!=null?f:"UNKNOWN");r={...r,model:E.model}}let a=lt(),i=Date.now(),o=typeof r.prompt=="string"?r.prompt:typeof r.prompt=="object"&&((T=r.prompt)!=null&&T.text)?r.prompt.text:"",l=(I=(A=r.model)==null?void 0:A.toString())!=null?I:"unknown",c=this.getActionLabel();G(1)&&We(c,"generateImage"),G(2)&&o&&Ae(`prompt \xB7 ${Ke(o)}`);try{let E=await no(r);return G(1)&&Te(l,Date.now()-i,"generateImage",c),a==null||a({response:E,userId:this.context.userId,appId:this.context.appId,creditStatus:t.status,startTime:i,prompt:o,model:r.model.toString()}),E}catch(E){throw G(1)&&Te(l,Date.now()-i,"generateImage (error)",c),a==null||a({error:E instanceof Error?E.message:String(E),response:{},userId:this.context.userId,appId:this.context.appId,creditStatus:t.status,startTime:i,prompt:o,model:r.model.toString()}),E}}async streamText(e){var d,u,h,f;let t=await this.checkCredits();if(!t.available)throw new p("AI credits are required to stream text","RATE_LIMIT",429);let r=typeof e.model=="string"?e.model:this.model;if(r){let T=ta(r,(u=(d=this.context)==null?void 0:d.action)!=null?u:"UNKNOWN");e={...e,model:T.model}}let a=lt(),i=Date.now(),o=this.getLoggablePrompt(e),l=(f=(h=e.model)==null?void 0:h.toString())!=null?f:"unknown",c=this.getActionLabel();return G(1)&&We(c,"streamText"),G(2)&&(Array.isArray(e.messages)&&Ae(ea(e.messages)),o&&Ae(`prompt \xB7 ${Ke(o)}`)),oo({...e,onFinish:T=>{G(1)&&Te(l,Date.now()-i,"streamText",c),this.logTokenUsage(T.usage,T.totalUsage),a==null||a({response:T,userId:this.context.userId,appId:this.context.appId,creditStatus:t.status,startTime:i,prompt:o,model:l})},onError:T=>{G(1)&&Te(l,Date.now()-i,"streamText (error)",c),a==null||a({error:T instanceof Error?T.message:String(T),response:{},userId:this.context.userId,appId:this.context.appId,creditStatus:t.status,startTime:i,prompt:o,model:l})}})}createChaiStreamTransformer(){let e=new TextEncoder,t=!1;return new TransformStream({start(){},transform(r,a){!t&&!r.includes("--START--")?(a.enqueue(e.encode(`--START--
|
|
409
|
+
`)),t=!0):!t&&r.includes("--START--")&&(t=!0),a.enqueue(e.encode(r))},flush(r){t||r.enqueue(e.encode(`--START--
|
|
410
|
+
`)),r.enqueue(e.encode(`
|
|
411
|
+
--END--`))}})}createErrorStream(e){let t=new TextEncoder,r=this.sanitizeErrorMessageForStream(e.message||String(e));return new ReadableStream({start(a){a.enqueue(t.encode(`--START--
|
|
412
|
+
--MSG=${tn(r)}--
|
|
413
|
+
--END--`)),a.close()}})}sanitizeErrorMessageForStream(e){return e.replace(/[\r\n]+/g," ").replace(/--/g,"- -").replace(/[\x00-\x1F\x7F]/g,"").trim()}async streamChaiBuilderText(e){try{return{_streamingResponse:!0,_streamResult:{textStream:(await this.streamText(e)).textStream.pipeThrough(this.createChaiStreamTransformer())}}}catch(t){return{_streamingResponse:!0,_streamResult:{textStream:this.createErrorStream(t)}}}}createFullStreamMixedEncoder(e){let t=new TextEncoder,r=this.getActionLabel(),a=!1,i=!1,o="";return new ReadableStream({async start(l){var c,d;Ye("open",r);try{for await(let u of e.fullStream)if(u.type==="text-delta"){let h=o+u.text;o=h.slice(-32);let f=h.includes("--START--"),T=h.includes("--END--");!a&&!f?(l.enqueue(t.encode(`--START--
|
|
414
|
+
`)),a=!0):!a&&f&&(a=!0),T&&(i=!0),l.enqueue(t.encode(u.text))}else u.type==="tool-call"&&pt.CLIENT_ONLY_AI_TOOLS.has(u.toolName)?(nn(u.toolName,Ke(JSON.stringify(u.input))),l.enqueue(t.encode(`9:${JSON.stringify({toolCallId:u.toolCallId,toolName:u.toolName,args:u.input})}
|
|
415
|
+
`))):u.type==="finish"?(Ye("finish",(c=u.finishReason)!=null?c:"stop"),l.enqueue(t.encode(`d:${JSON.stringify({finishReason:(d=u.finishReason)!=null?d:"stop"})}
|
|
416
|
+
`))):u.type==="error"&&(Ye("error",String(u.error),1),l.enqueue(t.encode(`3:${JSON.stringify(String(u.error))}
|
|
417
|
+
`)));a||l.enqueue(t.encode(`--START--
|
|
418
|
+
`)),i||l.enqueue(t.encode(`
|
|
419
|
+
--END--`)),Ye("close"),l.close()}catch(u){l.error(u)}}})}async streamChaiBuilderWithTools(e){try{let{tools:t,...r}=e,a=await this.streamText({...r,tools:t,toolChoice:"auto",stopWhen:so(8)});return{_streamingResponse:!0,_streamResult:{textStream:this.createFullStreamMixedEncoder(a)}}}catch(t){return{_streamingResponse:!0,_streamResult:{textStream:this.createErrorStream(t)}}}}async streamChaiBuilderUIMessageResponse(e){return{_streamingResponse:!0,_streamResult:{isDataStream:!0,dataStream:(await this.streamText({toolChoice:"auto",...e})).toUIMessageStreamResponse({sendReasoning:!0,onError:r=>this.sanitizeErrorMessageForStream(r instanceof Error?r.message:String(r))})}}}formatBase64(e){return e.includes(",")?e.split(",")[1]:e}};pt.CLIENT_ONLY_AI_TOOLS=new Set(["remove_blocks","add_custom_block","bind_prop"]);var U=pt;var lo=B.record(B.string(),B.object({name:B.string(),value:B.string(),description:B.string().optional(),archived:B.boolean().optional()})).optional(),dt=class extends U{getValidationSchema(){return B.object({messages:B.array(B.any()),model:B.string().optional(),context:B.any().optional(),designTokens:lo,images:B.array(B.string()).optional(),attachments:B.array(B.any()).optional(),options:B.any().optional()})}async execute(e){var S,D,k,le,qa,ja;this.context||Q(new z("Context not set. Please try again.","INVALID_REQUEST",500)),(!e.messages||e.messages.length===0)&&Q(new z("No messages provided. Please enter a prompt.","INVALID_REQUEST",400));let t=e.messages.filter(_=>_.role!=="system"),r=t[t.length-1];r||Q(new z("No user message found in the request.","INVALID_REQUEST",400));let a=Se(null,e==null?void 0:e.options),i={...st,...e.designTokens||{}},o=Object.entries(i).filter(([,_])=>_!=null&&!_.archived).map(([_,te])=>`- ${_}: ${te.value} (${te.name})`).join(`
|
|
420
|
+
`);a=a.replace("{{DESIGN_TOKENS_LIST}}",o);let l=new Set(["Box","Button","Checkbox","Divider","EmptyBox","Form","FormButton","Heading","Input","Label","LineBreak","Link","List","ListItem","Paragraph","Radio","RichText","Select","Span","Text","TextArea","Video","Icon","GlobalBlock"]),c=(S=e==null?void 0:e.options)==null?void 0:S.pageType,d=nt(),u=Object.values(d).filter(_=>!l.has(_.type)&&ot(_,c||"page")),h;u.length===0?h="No custom blocks registered.":h=u.map(_=>{var za,Wa,Ya;let te=(Wa=(za=_.props)==null?void 0:za.schema)!=null&&Wa.properties?Object.entries(_.props.schema.properties).filter(([,M])=>!(M!=null&&M.styles)&&!(M!=null&&M.runtime)&&!(M!=null&&M.hidden)).map(([M,V])=>{var Ka,Qa,Xa;let zi=Array.isArray(V==null?void 0:V.type)?V.type.join("|"):(Ka=V==null?void 0:V.type)!=null?Ka:"any",Wi=(V==null?void 0:V.default)!==void 0?` (default: ${JSON.stringify(V.default)})`:"",Yi=(Qa=_.aiProps)!=null&&Qa.includes(M)?" [AI-settable]":"";return` - ${M} (${zi})${Wi}${Yi}: ${(Xa=V==null?void 0:V.title)!=null?Xa:M}`}).join(`
|
|
421
|
+
`):" (no declared props)",qi=_.wrapper?" [wrapper \u2014 can contain child blocks]":"",ji=_.type.replace(/([A-Z])/g,M=>`-${M.toLowerCase()}`).replace(/^-/,"");return`### ${_.type} \u2192 <chai-${ji}>${qi}
|
|
422
|
+
Description: ${(Ya=_.description)!=null?Ya:_.label}
|
|
423
|
+
Props:
|
|
424
|
+
${te}`}).join(`
|
|
425
|
+
|
|
426
|
+
`),a=a.replace("{{CUSTOM_BLOCK_CATALOG}}",h);let f=(k=(D=e==null?void 0:e.options)==null?void 0:D.dataBindingPaths)!=null?k:{global:[],page:[]},T=f.global.map(_=>`- (global) {{${_}}}`),A=f.page.map(_=>`- (page) {{${_}}}`),I=[...T,...A],E=I.length>0?I.join(`
|
|
427
|
+
`):"No data binding paths available for this page.";a=a.replace("{{DATA_BINDING_PATHS}}",E);let x;if(!c)x="Standard page (no specific page type).";else{let _=Xe(c),te=(le=_==null?void 0:_.description)!=null?le:_==null?void 0:_.helpText;x=te?`Page type: ${c}
|
|
428
|
+
${te}`:`Page type: ${c}`}a=a.replace("{{PAGE_TYPE_CONTEXT}}",x),e.context&&(a+=`
|
|
429
|
+
|
|
430
|
+
## Additional Information`,(qa=e.context)!=null&&qa.site&&(a+=`
|
|
431
|
+
|
|
432
|
+
## Website Information
|
|
433
|
+
${JSON.stringify(e.context.site)}`),(ja=e.context)!=null&&ja.page&&(a+=`
|
|
434
|
+
|
|
435
|
+
## Page Information
|
|
436
|
+
${JSON.stringify(e.context.page)}`));let C=[{type:"text",text:typeof r.content=="string"?r.content:JSON.stringify(r.content)}];e.images&&e.images.length>0&&e.images.forEach(_=>{C.push({type:"image",image:_})}),e.attachments&&e.attachments.length>0&&e.attachments.forEach(_=>{if(_.url&&_.mediaType){let te=this.formatBase64(_.url);C.push({type:"file",data:te,mediaType:_.mediaType,..._.filename&&{filename:_.filename}})}});let R=C.length>1?[...t.slice(0,-1),{role:"user",content:C}]:e.messages;return this.streamChaiBuilderText({model:e.model,system:a,messages:R,temperature:.7})}};import{z as De}from"zod";var gt=class extends U{getValidationSchema(){return De.object({messages:De.array(De.any()),model:De.string().optional(),context:De.any().optional(),initiator:De.enum(["TRANSLATE_CONTENT","UPDATE_CONTENT"])})}async execute(e){this.context||Q(new z("Context not set. Please try again.","INVALID_REQUEST",500));let t=e.messages.filter(i=>i.role!=="system");t[t.length-1]||Q(new z("No user message found in the request.","INVALID_REQUEST",400));let a=Se(e.initiator);return this.streamChaiBuilderText({model:e.model,system:a,messages:e.messages,temperature:.7})}};import{convertToModelMessages as wo,stepCountIs as Io}from"ai";import{z as $}from"zod";var co=`
|
|
437
|
+
# ANIMATION RULES
|
|
438
|
+
- Add \`data-animation\` attribute to elements when appropriate to add entry animations on scroll.
|
|
439
|
+
- **Do not overuse animations.** Only animate important elements like hero images, feature cards & section heading etc.
|
|
440
|
+
- The format MUST exactly be: \`data-animation="ANIMATION|EASING|DURATION|DELAY|TIME"\`
|
|
441
|
+
- **ANIMATION**: fade-in, slide-up, slide-down, slide-left, slide-right, zoom-in, zoom-out, flip-x, flip-y, rotate-in
|
|
442
|
+
- **EASING**: linear, ease-in, ease-out, ease-in-out
|
|
443
|
+
- **DURATION**: in milliseconds (e.g., 500, 700, 1000)
|
|
444
|
+
- **DELAY**: in milliseconds (e.g., 0, 200, 300) so that the animation starts after a delay and not immediately
|
|
445
|
+
- **TIME**: once (plays once) or infinite (repeats every time it enters the viewport)
|
|
446
|
+
- Example: \`<div data-animation="slide-up|ease-in-out|500|300|once" class="...">\`
|
|
447
|
+
`,po='\n\n# IMAGE RULES\n- Use **placeholder images only** \u2014 never use external image services like Picsum.\n- Format: `https://placehold.co/{width}x{height}/e2e8f0/e2e8f0`\n (light gray background, no text)\n\n- Suggested sizes:\n * Hero: 1200x600\n * Cards: 400x300\n * Team: 300x300\n\n- **Alt text is mandatory and must be descriptive and meaningful** \u2014 describe what the image *would* show in context, not just "image" or "placeholder".\n - \u2705 Good: `alt="A modern open-plan office with large windows and natural light"`\n - \u274C Bad: `alt="Image"`, `alt="Placeholder"`, `alt="Photo"`, `alt=""`\n- Always include explicit `width` and `height` HTML attributes on every `<img>` tag matching the image dimensions.\n Example: `<img src="https://placehold.co/1200x600/e2e8f0/e2e8f0" alt="A sweeping aerial view of a modern city skyline at sunset" width="1200" height="600">`\n',go=`You are the AI page editor for Chai Builder. You edit the user's page exclusively through the tools provided. You never output raw HTML in your chat text \u2014 HTML only ever appears inside tool call arguments.
|
|
448
|
+
|
|
449
|
+
# 1. HOW YOU WORK (TOOL WORKFLOW \u2014 ALWAYS OBEY)
|
|
450
|
+
|
|
451
|
+
You see a compact PAGE OUTLINE of the current page (below). Each line is one block:
|
|
452
|
+
\`{bid} | {type} | {name} | {short text}\`. Indentation shows nesting.
|
|
453
|
+
|
|
454
|
+
Available tools:
|
|
455
|
+
- **read_block_html** \u2014 fetch the full current HTML of one or more existing blocks by bid. YOU MUST call this before editing a block with edit_block. Never guess a block's markup from the outline.
|
|
456
|
+
- **edit_block** \u2014 replace ONE existing block (by bid) with new HTML. The html must be the full replacement for that element (its entire tag), not a partial diff.
|
|
457
|
+
- **add_blocks** \u2014 insert new HTML into the page. parentId is the bid of the container (omit for page root); position is the child index (-1 or omit to append).
|
|
458
|
+
- **remove_blocks** \u2014 delete blocks by bid.
|
|
459
|
+
- **add_custom_block** \u2014 add a registered custom block (anything listed in "Available Custom Blocks") with typed props. Use this \u2014 NOT HTML \u2014 for those block types.
|
|
460
|
+
- **bind_prop** \u2014 set a data binding on a prop of an existing block.
|
|
461
|
+
- **get_partial_blocks** \u2014 list available partial blocks (global reusable sections like header/footer). Call before placing <chai-partial-block> elements.
|
|
462
|
+
|
|
463
|
+
Workflow rules:
|
|
464
|
+
1. Before each tool call, write ONE short plain-language sentence telling the user what you are about to do (e.g. "I'll brighten up the hero section with a bolder headline."). Friendly, non-technical \u2014 never mention bids, tags, HTML, tools, or code.
|
|
465
|
+
2. To modify an existing section: read_block_html first (batch multiple bids into one call), then edit_block.
|
|
466
|
+
3. Work one section at a time \u2014 one edit_block or add_blocks call per section. Never rewrite the whole page in a single call when the user asked for a targeted change.
|
|
467
|
+
4. Prefer editing the smallest block that fully contains the change. If the user asks to change a headline, edit the heading's nearest sensible parent, not the entire page section \u2014 but always replace a complete element.
|
|
468
|
+
5. In every edit_block/add_blocks call, fill the arguments in this exact order: task first, then blockId/parentId/position, then html LAST.
|
|
469
|
+
6. \`task\` is a short user-facing progress label (e.g. "Redesigning hero section"). Plain language, no technical terms.
|
|
470
|
+
7. When the user's request is ambiguous, unrelated to the page, or a question \u2014 just answer in plain text without calling tools.
|
|
471
|
+
8. Partial blocks (<chai-partial-block>) cannot be edited from this page. If asked to change one, explain the user should open that partial page to edit it. You may still add/remove/move partial block references on this page.
|
|
472
|
+
9. After a tool result returns ok: false with an error, correct your approach based on the error message and retry once. Do not repeat the identical failing call.
|
|
473
|
+
10. When done, finish with ONE short sentence of what changed. Skip the summary entirely for a single trivial edit \u2014 the task labels already show what happened.
|
|
474
|
+
|
|
475
|
+
# 1.1 CHAT OUTPUT \u2014 KEEP IT MINIMAL (MANDATORY)
|
|
476
|
+
|
|
477
|
+
The chat is read by non-technical users. Keep your visible text as short as possible \u2014 every extra word costs tokens for no benefit.
|
|
478
|
+
- Write like a friendly human, never like a developer. NEVER show or describe code, HTML, tags, class names, tokens, bids, tool names, or file structure.
|
|
479
|
+
- Total visible text per turn: at most one short lead-in sentence and one short closing sentence. No paragraphs, no bullet lists, no headings, no markdown formatting, no code blocks or backticks.
|
|
480
|
+
- Do NOT restate, quote, or narrate the HTML/markup you generate \u2014 it appears live on the canvas, not in chat.
|
|
481
|
+
- Do NOT explain your reasoning, list the steps you took, or enumerate the design choices unless the user explicitly asks.
|
|
482
|
+
- If the user asks a question, answer in one or two plain sentences.
|
|
483
|
+
|
|
484
|
+
# 2. EDIT SEMANTICS
|
|
485
|
+
- edit_block html MUST be a full valid replacement of the target element, keeping its role in the layout.
|
|
486
|
+
- Preserve existing \`bid\` attributes on elements you keep within an edited block; do NOT invent bids for new elements \u2014 new elements simply have no bid.
|
|
487
|
+
- Never add a bid attribute in add_blocks html.
|
|
488
|
+
- Preserve all attributes you don't intentionally change (especially chai-type, data bindings, #styles: values).
|
|
489
|
+
|
|
490
|
+
# 3. HTML GENERATION RULES (MANDATORY)
|
|
491
|
+
|
|
492
|
+
You are an expert HTML/CSS developer specializing in Tailwind CSS and shadcn/ui patterns.
|
|
493
|
+
You produce clean, semantic, accessible, production-ready HTML.
|
|
494
|
+
Generate **pure HTML**, with no markdown, no comments, no extra text.
|
|
495
|
+
|
|
496
|
+
### General Guidelines
|
|
497
|
+
1. Use **only Tailwind CSS v3 utility classes**, no custom CSS.
|
|
498
|
+
2. Use **shadcn/ui design system** semantic tokens for all colors.
|
|
499
|
+
3. Use **semantic HTML** with proper accessibility.
|
|
500
|
+
4. Always produce **responsive, mobile-first** layout.
|
|
501
|
+
5. **Do NOT include** <!DOCTYPE>, <html>, <head>, or <body>.
|
|
502
|
+
6. Keep UI varied \u2014 don't repeat the same layout patterns.
|
|
503
|
+
7. Use \`<details><summary>\` for accordion, FAQ, and mobile menu interactions.
|
|
504
|
+
8. Do NOT use Tailwind container queries.
|
|
505
|
+
9. If UI is generated from a user-provided image, ensure full responsiveness.
|
|
506
|
+
10. **If the user has attached an image, the HTML MUST be generated based strictly on the layout, spacing, hierarchy, and visual appearance of that image.**
|
|
507
|
+
- Match structure as closely as possible
|
|
508
|
+
- Maintain the Tailwind + shadcn theme rules
|
|
509
|
+
- The HTML output should reflect the exact design of the provided image
|
|
510
|
+
|
|
511
|
+
### \u{1F6A8} CRITICAL: Avoid HTML "Div Soup" for Decorative UI Elements
|
|
512
|
+
**NEVER generate complex HTML markup for decorative UI elements that should be images:**
|
|
513
|
+
- \u274C DO NOT create HTML mockups of: code snippets, terminal windows, browser frames, device mockups, window chrome, syntax-highlighted code blocks
|
|
514
|
+
- \u2705 INSTEAD: Use placeholder images for these decorative elements
|
|
515
|
+
- **Reasoning**: Complex nested div structures for visual decoration create "div soup" that bloats markup unnecessarily
|
|
516
|
+
- **When to use images**: If the element is purely decorative/visual and not interactive content (e.g., showing a code example as part of a design, not actual executable code)
|
|
517
|
+
- **Examples**:
|
|
518
|
+
* For a "code snippet showcase" \u2192 Use an image: \`<img src="https://placehold.co/800x400/e2e8f0/e2e8f0" alt="Code editor showing React component example" width="800" height="400">\`
|
|
519
|
+
* For a "browser window mockup" \u2192 Use an image: \`<img src="https://placehold.co/1000x600/e2e8f0/e2e8f0" alt="Browser window displaying dashboard interface" width="1000" height="600">\`
|
|
520
|
+
* For actual interactive content \u2192 Use semantic HTML
|
|
521
|
+
|
|
522
|
+
### \u{1F6A8} Design Tokens (MANDATORY)
|
|
523
|
+
You MUST use design tokens whenever appropriate. Design tokens are predefined groupings of Tailwind classes identified by the \`dt#\` prefix.
|
|
524
|
+
1. **Placement**: Always place design tokens at the START of the \`class\` attribute.
|
|
525
|
+
2. **Overrides**: Any Tailwind classes following a design token act as overrides, similar to how \`tailwind-merge\` works.
|
|
526
|
+
3. **Example**: \`<button class="dt#btn p-2">\` where \`p-2\` overrides the default padding in \`dt#btn\`.
|
|
527
|
+
|
|
528
|
+
**Available Design Tokens**:
|
|
529
|
+
{{DESIGN_TOKENS_LIST}}
|
|
530
|
+
|
|
531
|
+
# 3.1 DESIGN EXCELLENCE & CREATIVITY (CRITICAL)
|
|
532
|
+
|
|
533
|
+
Create distinctive, production-grade interfaces that avoid generic "AI slop" aesthetics. Every UI you generate should be visually striking, memorable, and intentionally designed.
|
|
534
|
+
|
|
535
|
+
### Design Thinking Process
|
|
536
|
+
Before generating HTML, commit to a BOLD aesthetic direction:
|
|
537
|
+
- **Purpose**: Consider what problem this interface solves and who uses it
|
|
538
|
+
- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
|
|
539
|
+
|
|
540
|
+
**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
|
|
541
|
+
|
|
542
|
+
### Design Excellence Guidelines
|
|
543
|
+
|
|
544
|
+
**Typography & Font Selection**:
|
|
545
|
+
- Choose fonts that are beautiful, unique, and interesting
|
|
546
|
+
- AVOID generic fonts: Arial, Inter, Roboto, system fonts
|
|
547
|
+
- Use distinctive font combinations that elevate the design
|
|
548
|
+
- Pair a distinctive display font with a refined body font
|
|
549
|
+
- Consider: font-serif, font-mono for variety, or use weight variations (font-light, font-bold) creatively
|
|
550
|
+
|
|
551
|
+
**Color & Visual Hierarchy**:
|
|
552
|
+
- Commit to a cohesive aesthetic with dominant colors and sharp accents
|
|
553
|
+
- Avoid timid, evenly-distributed palettes
|
|
554
|
+
- Use shadcn tokens creatively (not just bg-background everywhere)
|
|
555
|
+
- Consider bold color blocking, dramatic contrasts, or refined monochrome
|
|
556
|
+
- AVOID: purple gradients on white backgrounds, predictable color schemes
|
|
557
|
+
|
|
558
|
+
**Spatial Composition**:
|
|
559
|
+
- Create unexpected layouts with asymmetry, overlap, diagonal flow
|
|
560
|
+
- Use grid-breaking elements and generous negative space OR controlled density
|
|
561
|
+
- Avoid predictable grid patterns - be creative with positioning
|
|
562
|
+
- Consider: absolute positioning, creative flexbox/grid layouts, overlapping elements
|
|
563
|
+
|
|
564
|
+
**Backgrounds & Visual Details**:
|
|
565
|
+
- Create atmosphere and depth rather than defaulting to solid colors
|
|
566
|
+
- Consider: gradient meshes, subtle textures, geometric patterns
|
|
567
|
+
- Use layered transparencies, dramatic shadows, decorative borders
|
|
568
|
+
- Add visual interest with background patterns or accent elements
|
|
569
|
+
|
|
570
|
+
**NEVER Use Generic AI Aesthetics**:
|
|
571
|
+
- Overused font families (Inter, Roboto, Arial, system fonts)
|
|
572
|
+
- Cliched color schemes (purple gradients on white)
|
|
573
|
+
- Predictable layouts and component patterns
|
|
574
|
+
- Cookie-cutter designs lacking context-specific character
|
|
575
|
+
- NEVER converge on common choices (Space Grotesk, etc.) across generations
|
|
576
|
+
|
|
577
|
+
**Implementation Complexity**:
|
|
578
|
+
- Match complexity to the aesthetic vision
|
|
579
|
+
- Maximalist designs: elaborate code with extensive effects
|
|
580
|
+
- Minimalist designs: restraint, precision, careful spacing and typography
|
|
581
|
+
- Elegance comes from executing the vision well
|
|
582
|
+
|
|
583
|
+
**Variation Mandate**:
|
|
584
|
+
- Every design should be different
|
|
585
|
+
- Vary between light and dark themes
|
|
586
|
+
- Change fonts, layouts, color schemes between generations
|
|
587
|
+
- Interpret user requests creatively with unexpected choices
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
# 4. ATTRIBUTE & CUSTOM COMPONENT RULES
|
|
591
|
+
|
|
592
|
+
### chai-name
|
|
593
|
+
- Add \`chai-name\` attribute to tags
|
|
594
|
+
- Use descriptive section names (e.g., "Hero Section", "Navigation").
|
|
595
|
+
|
|
596
|
+
## Custom Web components(CRITICAL)
|
|
597
|
+
- Html can have custom web components. All web components starts with <chai- prefix.
|
|
598
|
+
- Use "about-this-component" attribute to understand what the component does.
|
|
599
|
+
- Check for can-move and can-delete attribute to check if the component can be moved or deleted.
|
|
600
|
+
- If an attribute value starts with #styles: treat it like class attribute with tailwind classes.
|
|
601
|
+
Use the attribute key to understand what the attribute does and apply classes. Maintain the #styles: at start followed by tailwind classes.
|
|
602
|
+
- Do not change the chai-type attribute. Do not remove any attributes.
|
|
603
|
+
|
|
604
|
+
## Data Binding (CRITICAL)
|
|
605
|
+
- Block prop values may contain binding expressions using double-curly syntax: {{path.to.data}}
|
|
606
|
+
- When you see {{...}} in an existing element's attribute value, it is a live data binding \u2014 NEVER remove or replace it with a static value. Preserve it exactly.
|
|
607
|
+
- You MAY use binding expressions when setting props on custom blocks, but ONLY using paths listed in the "Available Data Binding Paths" section below.
|
|
608
|
+
- Repeater blocks use a special prop: repeater-items="{{collectionName}}" where collectionName is the array to iterate.
|
|
609
|
+
- Inside a Repeater, child block props can reference each item's fields via {{$index.fieldName}}.
|
|
610
|
+
- Binding syntax must use exactly two curly braces: {{path}} \u2014 not {path} or \${{path}}.
|
|
611
|
+
- (global) paths are site-wide and available on every page. (page) paths are only available on this specific page type.
|
|
612
|
+
|
|
613
|
+
**Available Data Binding Paths**:
|
|
614
|
+
{{DATA_BINDING_PATHS}}
|
|
615
|
+
|
|
616
|
+
## Current Page Type
|
|
617
|
+
{{PAGE_TYPE_CONTEXT}}
|
|
618
|
+
|
|
619
|
+
## Available Custom Blocks
|
|
620
|
+
The following custom block types are registered and available. To ADD one of these, USE THE add_custom_block TOOL with camelCase props \u2014 do NOT generate <chai-*> HTML for them. When one already exists in the page you may edit its props via edit_block (keeping every attribute intact) or bind_prop.
|
|
621
|
+
|
|
622
|
+
{{CUSTOM_BLOCK_CATALOG}}
|
|
623
|
+
|
|
624
|
+
## Special Blocks
|
|
625
|
+
These may appear as web components INSIDE the html argument of add_blocks/edit_block:
|
|
626
|
+
|
|
627
|
+
### Repeater \u2014 <chai-repeater>
|
|
628
|
+
Used to render a list by iterating over an array data binding.
|
|
629
|
+
- Required prop: \`repeater-items="{{arrayPath}}"\` where \`arrayPath\` is an array-type binding path.
|
|
630
|
+
- Only bind to paths marked as arrays in "Available Data Binding Paths".
|
|
631
|
+
- Child blocks inside a Repeater reference the current item's fields using \`{{$index.fieldName}}\`.
|
|
632
|
+
- Example: \`<chai-repeater repeater-items="{{page.products}}"><h3>{{$index.name}}</h3></chai-repeater>\`
|
|
633
|
+
- Do NOT use a Repeater for static lists \u2014 only when iterating over bound data.
|
|
634
|
+
|
|
635
|
+
### PartialBlock \u2014 <chai-partial-block>
|
|
636
|
+
Partial blocks are global reusable blocks (e.g. header, footer, navigation) shared across pages.
|
|
637
|
+
- Reference them by their ID: \`<chai-partial-block partial-id="THE_PARTIAL_ID"></chai-partial-block>\`
|
|
638
|
+
- Never modify a partial block's content inline \u2014 only reference it. Their content is edited on the partial's own page.
|
|
639
|
+
- When asked to build a full page layout, call the \`get_partial_blocks\` tool to discover available partial IDs before placing them.
|
|
640
|
+
|
|
641
|
+
## Icons
|
|
642
|
+
- Icons use the **Lucide** icon set (https://lucide.dev/icons).
|
|
643
|
+
- Always include \`chai-type="Icon"\` on icon elements and preserve any existing attributes (e.g. \`bid\`).
|
|
644
|
+
- Express each icon as \`<chai-icon chai-type="Icon" icon-name="kebab-case-name" width="16" height="16">\`
|
|
645
|
+
e.g. \`<chai-icon chai-type="Icon" icon-name="search" width="16" height="16">\`, \`<chai-icon chai-type="Icon" icon-name="arrow-right" width="24" height="24">\`.
|
|
646
|
+
- Pick semantically appropriate icon names from Lucide; do not embed raw \`<svg>\` markup inside \`<chai-icon>\`.
|
|
647
|
+
|
|
648
|
+
### SVG
|
|
649
|
+
- Always include width/height attributes.
|
|
650
|
+
- Ensure correct \`viewBox\`.
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
# 5. SHADCN/THEME COLOR RULES (STRICT)
|
|
654
|
+
|
|
655
|
+
Use ONLY these semantic tokens:
|
|
656
|
+
- bg-background + text-foreground
|
|
657
|
+
- bg-card + text-card-foreground
|
|
658
|
+
- bg-primary + text-primary-foreground
|
|
659
|
+
- bg-secondary + text-secondary-foreground
|
|
660
|
+
- bg-muted + text-muted-foreground
|
|
661
|
+
- bg-accent + text-accent-foreground
|
|
662
|
+
- bg-destructive + text-destructive-foreground
|
|
663
|
+
- border-border, border-input
|
|
664
|
+
- ring-ring
|
|
665
|
+
|
|
666
|
+
### Contrast Rules
|
|
667
|
+
- Always maintain clear readable contrast.
|
|
668
|
+
- Never pair same-family bg/text tokens (e.g., bg-primary + text-primary).
|
|
669
|
+
|
|
670
|
+
### Hover Rules
|
|
671
|
+
- Primary buttons: hover:bg-primary/90
|
|
672
|
+
- Cards: hover:bg-accent hover:text-accent-foreground
|
|
673
|
+
- Links: text-muted-foreground hover:text-foreground
|
|
674
|
+
- Nav links: text-foreground/80 hover:text-foreground
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
# 6. RESPONSIVENESS RULES
|
|
678
|
+
|
|
679
|
+
- Mobile-first approach.
|
|
680
|
+
- Breakpoints: sm, md, lg, xl.
|
|
681
|
+
- Smooth scaling between sizes.
|
|
682
|
+
- At md breakpoint:
|
|
683
|
+
* Reduce grid columns (lg:4 \u2192 md:2 \u2192 sm:1)
|
|
684
|
+
* Adjust padding, spacing, and layouts
|
|
685
|
+
* Ensure nav/mobile menus behave correctly
|
|
686
|
+
* Ensure cards remain aligned
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
# 7. SPECIFIC UI PATTERNS
|
|
690
|
+
|
|
691
|
+
### Forms & Fields
|
|
692
|
+
- Always include proper \`type\` and \`autocomplete\` attributes for form fields (e.g., \`type="email" autocomplete="email"\`, \`type="text" autocomplete="given-name"\`, \`type="tel" autocomplete="tel"\`).
|
|
693
|
+
|
|
694
|
+
### Mobile Menu (<details><summary>)
|
|
695
|
+
- Use 'summary' containing an SVG hamburger icon.
|
|
696
|
+
- Mobile menu container sample:
|
|
697
|
+
absolute right-1 mt-2 min-w-64 bg-card border border-border rounded-lg shadow-lg z-50 p-4
|
|
698
|
+
- Menu item sample:
|
|
699
|
+
block py-2 px-4 hover:bg-accent rounded-md transition-colors
|
|
700
|
+
- Touch targets must be at least 44px tall.
|
|
701
|
+
|
|
702
|
+
### Accordions / Nested Menus
|
|
703
|
+
- Always use <details> and <summary>.
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
# 8. COMMON RULES
|
|
707
|
+
|
|
708
|
+
{{ANIMATION_RULES}}
|
|
709
|
+
{{IMAGE_RULES}}
|
|
710
|
+
|
|
711
|
+
# 9. CURRENT PAGE OUTLINE
|
|
712
|
+
|
|
713
|
+
Each line: bid | type | name | short text. Indentation = nesting. This reflects the page state at the start of this request; your applied tool calls update the real page immediately.
|
|
714
|
+
|
|
715
|
+
{{PAGE_OUTLINE}}
|
|
716
|
+
`.trim(),yn=(s={})=>{let e=go;return e=e.replace("{{ANIMATION_RULES}}",s!=null&&s.animation?co:""),e=e.replace("{{IMAGE_RULES}}",po),e};var mo=new Set(["Box","Button","Checkbox","Divider","EmptyBox","Form","FormButton","Heading","Input","Label","LineBreak","Link","List","ListItem","Paragraph","Radio","RichText","Select","Span","Text","TextArea","Video","Icon","GlobalBlock"]),uo=s=>{let e={...st,...s||{}};return Object.entries(e).filter(([,t])=>t!=null&&!t.archived).map(([t,r])=>`- ${t}: ${r.value} (${r.name})`).join(`
|
|
717
|
+
`)},ho=s=>{let e=nt(),t=Object.entries(e).filter(([r,a])=>{var o,l;let i=(o=a.type)!=null?o:r;return!i||mo.has(i)||!ot(a,s||"page")?!1:!!((l=a.label)!=null?l:a.props)});return t.length===0?"No custom blocks registered.":t.map(([r,a])=>{var d,u,h,f;let i=(d=a.type)!=null?d:r,o=(h=(u=a.props)==null?void 0:u.schema)!=null&&h.properties?Object.entries(a.props.schema.properties).filter(([,T])=>!(T!=null&&T.styles)&&!(T!=null&&T.runtime)&&!(T!=null&&T.hidden)).map(([T,A])=>{var C,R,S;let I=Array.isArray(A==null?void 0:A.type)?A.type.join("|"):(C=A==null?void 0:A.type)!=null?C:"any",E=(A==null?void 0:A.default)!==void 0?` (default: ${JSON.stringify(A.default)})`:"",x=(R=a.aiProps)!=null&&R.includes(T)?" [AI-settable]":"";return` - ${T} (${I})${E}${x}: ${(S=A==null?void 0:A.title)!=null?S:T}`}).join(`
|
|
718
|
+
`):" (no declared props)",l=a.wrapper?" [wrapper \u2014 can contain child blocks]":"",c=i.replace(/([A-Z])/g,T=>`-${T.toLowerCase()}`).replace(/^-/,"");return`### ${i} \u2192 <chai-${c}>${l}
|
|
719
|
+
Description: ${(f=a.description)!=null?f:a.label}
|
|
720
|
+
Props:
|
|
721
|
+
${o}`}).join(`
|
|
722
|
+
|
|
723
|
+
`)},fo=s=>{let e=s!=null?s:{global:[],page:[]},t=e.global.map(i=>`- (global) {{${i}}}`),r=e.page.map(i=>`- (page) {{${i}}}`),a=[...t,...r];return a.length>0?a.join(`
|
|
724
|
+
`):"No data binding paths available for this page."},yo=s=>{var r;if(!s)return"Standard page (no specific page type).";let e=Xe(s),t=(r=e==null?void 0:e.description)!=null?r:e==null?void 0:e.helpText;return t?`Page type: ${s}
|
|
725
|
+
${t}`:`Page type: ${s}`},Tn=(s,e)=>{var r,a,i,o,l;let t=s;return t=t.replace("{{DESIGN_TOKENS_LIST}}",uo(e.designTokens)),t=t.replace("{{CUSTOM_BLOCK_CATALOG}}",ho((r=e==null?void 0:e.options)==null?void 0:r.pageType)),t=t.replace("{{DATA_BINDING_PATHS}}",fo((a=e==null?void 0:e.options)==null?void 0:a.dataBindingPaths)),t=t.replace("{{PAGE_TYPE_CONTEXT}}",yo((i=e==null?void 0:e.options)==null?void 0:i.pageType)),e.context&&(t+=`
|
|
726
|
+
|
|
727
|
+
## Additional Information`,(o=e.context)!=null&&o.site&&(t+=`
|
|
728
|
+
|
|
729
|
+
## Website Information
|
|
730
|
+
${JSON.stringify(e.context.site)}`),(l=e.context)!=null&&l.page&&(t+=`
|
|
731
|
+
|
|
732
|
+
## Page Information
|
|
733
|
+
${JSON.stringify(e.context.page)}`)),t};import{tool as Ee,zodSchema as be}from"ai";import{and as To,eq as sa,isNull as Ao}from"drizzle-orm";import{parse as Eo,stringify as bo}from"himalaya";import{z as N}from"zod";var Po=(s,e)=>{let t=new Set(e),r={},a=(o,l)=>{var d,u,h,f;let c=[...(d=l.children)!=null?d:[]];for(;c.length;){let T=c.pop();if(!T||T.type!=="element")continue;let A=(h=(u=T.attributes)==null?void 0:u.find(I=>I.key==="bid"))==null?void 0:h.value;A&&t.has(A)&&(r[A]=`NOTE: bid "${A}" is inside block "${o}" which was already returned. Use the "${o}" HTML slice to edit it, or request only "${A}".`,t.delete(A)),(f=T.children)!=null&&f.length&&c.push(...T.children)}},i=o=>{var c,d,u;if(t.size===0||o.type!=="element")return;let l=(d=(c=o.attributes)==null?void 0:c.find(h=>h.key==="bid"))==null?void 0:d.value;if(l&&t.has(l)){r[l]=bo([o]),t.delete(l),a(l,o);return}(u=o.children)==null||u.forEach(i)};Eo(s).forEach(i);for(let o of t)r[o]=`ERROR: no block found with bid "${o}". Check the page outline for valid bids.`;return r},An=({pageHtml:s})=>({read_block_html:Ee({description:"Read the full current HTML of one or more existing blocks by their bid (from the page outline). ALWAYS call this before edit_block \u2014 never guess a block's markup. Batch all bids you need into one call.",inputSchema:be(N.object({blockIds:N.array(N.string()).min(1).describe("bids of the blocks to read")})),execute:async({blockIds:e})=>Po(s,e)}),edit_block:Ee({description:"Replace one existing block (identified by bid) with new HTML. The html must be the complete replacement for the target element. Call read_block_html for the target first.",inputSchema:be(N.object({task:N.string().describe("Short user-facing progress label, e.g. 'Redesigning hero section'"),blockId:N.string().describe("bid of the block to replace"),html:N.string().describe("Full replacement HTML for the target element")}))}),add_blocks:Ee({description:"Insert new HTML into the page. Use for new sections/elements built from standard HTML and special blocks (repeater, partial-block, icon). Do NOT use for registered custom blocks \u2014 use add_custom_block.",inputSchema:be(N.object({task:N.string().describe("Short user-facing progress label, e.g. 'Adding pricing section'"),parentId:N.string().nullish().describe("bid of the parent container; omit to add at page root"),position:N.number().nullish().describe("Child index position; -1 or omit to append at end"),html:N.string().describe("HTML to insert")}))}),remove_blocks:Ee({description:"Remove one or more existing blocks from the page by their block IDs (bid attribute). Use when the user asks to delete, clear, or replace content.",inputSchema:be(N.object({ids:N.array(N.string()).min(1).describe("Array of block IDs (bid attribute values) to remove"),task:N.string().nullish().describe("Short user-facing progress label, e.g. 'Removing testimonial section'")}))}),add_custom_block:Ee({description:"Add a registered custom block to the page using its schema-validated props. Use this (not HTML) for any block type listed in the 'Available Custom Blocks' catalog.",inputSchema:be(N.object({task:N.string().nullish().describe("Short user-facing progress label"),type:N.string().describe("Block type exactly as listed in the catalog, e.g. 'ProductCard'"),parentId:N.string().nullish().describe("bid of the parent block, or omit to add at page root"),position:N.number().nullish().describe("Child index position; -1 or omit to append at end"),props:N.record(N.string(),N.any()).describe("Block props as a JSON object using camelCase keys matching the catalog schema. Use {{path.to.data}} values for bound props.")}))}),bind_prop:Ee({description:"Set a data binding on a specific prop of an existing block. The binding path must come from the 'Available Data Binding Paths' list in the system prompt.",inputSchema:be(N.object({task:N.string().nullish().describe("Short user-facing progress label"),blockId:N.string().describe("bid of the block to update"),propName:N.string().describe("camelCase prop name on the block"),bindingPath:N.string().describe("Full binding expression including double braces, e.g. '{{product.name}}' or '{{$index.title}}'")}))}),get_partial_blocks:Ee({description:"Retrieve all available partial blocks (global reusable sections such as header, footer, navigation). Call this before building a full page layout or when the user asks to include a global section. Returns each partial's ID, name, and description. Use the ID in <chai-partial-block partial-id='ID'>.",inputSchema:be(N.object({})),execute:async()=>{let{appId:e}=an(),{data:t,error:r}=await m(()=>g.select({id:n.appPages.id,name:n.appPages.name,metadata:n.appPages.metadata,pageType:n.appPages.pageType}).from(n.appPages).where(To(sa(n.appPages.app,e),sa(n.appPages.slug,""),sa(n.appPages.lang,""),Ao(n.appPages.deletedAt))));if(r)throw new Error(`Failed to fetch partial blocks: ${r.message}`);let a={};return t&&t.forEach(i=>{var l,c,d;let o=(l=i.metadata)!=null?l:{};a[i.id]={name:i.name,description:(c=o.description)!=null?c:"",type:(d=i.pageType)!=null?d:"partial"}}),a}})});var xo=$.record($.string(),$.object({name:$.string(),value:$.string(),description:$.string().optional(),archived:$.boolean().optional()})).optional(),Co=12,Ro=s=>{let e=s.findLastIndex(t=>t.role==="assistant");return s.map((t,r)=>t.role!=="assistant"||r===e||!Array.isArray(t.parts)?t:{...t,parts:t.parts.map(a=>{var i;return typeof(a==null?void 0:a.type)=="string"&&(a.type==="tool-edit_block"||a.type==="tool-add_blocks")&&((i=a.input)!=null&&i.html)?{...a,input:{...a.input,html:"[html omitted \u2014 read the block again if needed]"}}:a})})},mt=class extends U{getValidationSchema(){return $.object({messages:$.array($.any()).min(1),model:$.string().optional(),context:$.any().optional(),designTokens:xo,pageHtml:$.string().optional(),pageOutline:$.string().optional(),options:$.any().optional()})}async execute(e){var l,c,d,u;this.context||Q(new z("Context not set. Please try again.","INVALID_REQUEST",500)),(!e.messages||e.messages.length===0)&&Q(new z("No messages provided. Please enter a prompt.","INVALID_REQUEST",400));let t=yn({animation:(l=e==null?void 0:e.options)==null?void 0:l.animation});t=t.replace("{{PAGE_OUTLINE}}",((c=e.pageOutline)==null?void 0:c.trim())||"The page is currently empty."),t=Tn(t,e);let r=[...e.messages].reverse().find(h=>h.role==="user"),a=(d=r==null?void 0:r.metadata)==null?void 0:d.selectedBlockId;a&&(t+=`
|
|
734
|
+
|
|
735
|
+
## Currently Selected Block
|
|
736
|
+
The user currently has the block with bid "${a}" selected. Prioritize changes to this block unless the request explicitly requires broader changes.`);let i=Ro(e.messages.slice(-Co)),o=await wo(i,{ignoreIncompleteToolCalls:!0});return this.streamChaiBuilderUIMessageResponse({model:e.model,system:t,messages:o,temperature:.7,tools:An({pageHtml:(u=e.pageHtml)!=null?u:""}),stopWhen:Io(8)})}};import{z as H}from"zod";var ut=class extends U{getValidationSchema(){return H.object({messages:H.array(H.any()),model:H.string().optional(),context:H.any().optional(),designTokens:H.any().optional(),images:H.array(H.string()).optional(),attachments:H.array(H.any()).optional(),initiator:H.literal("GENERATE_IMAGE"),image:H.object({lastImage:H.string().optional(),aspectRatio:H.string().optional(),quality:H.number().optional()}).optional()})}async execute(e){var T,A,I;if(!this.context)return{_streamingResponse:!0,_streamResult:{textStream:this.createErrorStream(new Error("Context not set. Please try again."))}};let t=e.messages.filter(E=>E.role!=="system"),r=t[t.length-1];if(!r)return{_streamingResponse:!0,_streamResult:{textStream:this.createErrorStream(new Error("No user message found in the request."))}};let a=Se(e.initiator),i=typeof r.content=="string"?r.content:"Generate a random image",o=a?`${a}
|
|
737
|
+
|
|
738
|
+
${i}`:i,l=((T=e.image)==null?void 0:T.aspectRatio)||"16:9",c=((A=e.image)==null?void 0:A.quality)||80,u=(I={"1:1":"1024x1024","16:9":"1536x1024","9:16":"1024x1536","4:3":"1536x1024","3:4":"1024x1536"}[l])!=null?I:"1536x1024",h=new TextEncoder;return{_streamingResponse:!0,_streamResult:{textStream:new ReadableStream({start:async E=>{var x;try{let R=(await this.generateImage({model:e.model,prompt:(x=e.image)!=null&&x.lastImage?{text:o,images:[e.image.lastImage]}:o,size:u,providerOptions:{openai:{quality:c>=90?"high":c>=50?"medium":"low"}}})).image;if(!(R!=null&&R.base64))throw new Error("Failed to generate image. No valid image data received from the AI.");let S=R.base64.startsWith("data:")?R.base64:`data:${R.mediaType};base64,${R.base64}`;E.enqueue(h.encode(S)),E.close()}catch(C){let R=C instanceof Error?C.message:String(C);E.enqueue(h.encode(`--START--
|
|
739
|
+
--MSG=${R}--
|
|
740
|
+
--END--`)),E.close()}}})}}}};import{z as Je}from"zod";var ht=class extends U{getValidationSchema(){return Je.object({type:Je.enum(["site","page","prompt"]),content:Je.string().min(1),siteContext:Je.string().optional(),model:Je.string().optional()})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");if(!e.content||e.content.trim()==="")throw new p("Content is required for AI enhancement","INVALID_DATA");let t="";e.type==="site"?t=`You are an expert SEO copywriter. The user will provide a rough draft of their website's business context. Enhance it to be professional, clear, and comprehensive. Synthesize the text into a well-structured summary. Output ONLY the enhanced text. Format the output with bold keys as follows:
|
|
741
|
+
|
|
742
|
+
**Business Name & Industry**: [Content]
|
|
743
|
+
**Target Audience**: [Content]
|
|
744
|
+
**Unique Value Proposition**: [Content]
|
|
745
|
+
**Key Products/Services**: [Content]
|
|
746
|
+
|
|
747
|
+
Keep it to a maximum of 150 words.`:e.type==="page"?t=`You are an expert SEO copywriter. The user will provide a rough draft of a page's context. Enhance it to be professional, clear, and concise. Do not use placeholder text; instead, use details from the site context if available. Synthesize the text into a well-structured summary. Output ONLY the enhanced text. Format the output with bold keys as follows:
|
|
748
|
+
|
|
749
|
+
**Page Purpose**: [Content]
|
|
750
|
+
**Target Keywords**: [Content]
|
|
751
|
+
**Primary H1 Goal**: [Content]
|
|
752
|
+
|
|
753
|
+
Keep it to a maximum of 150 words.`:t="You are an expert AI prompt engineer. The user will provide a rough draft of a prompt. Enhance it to be clear, detailed, and optimized for high-quality AI generation. Add necessary context, constraints, and structural guidance to make the prompt more effective. Output ONLY the enhanced prompt text.";let r=` ${e.siteContext?`
|
|
754
|
+
|
|
755
|
+
Site Context: ${e.siteContext}
|
|
756
|
+
|
|
757
|
+
`:""} Please enhance the following rough draft:
|
|
758
|
+
|
|
759
|
+
${e.content}`;return{success:!0,enhancedContent:(await this.generateText({model:e.model||"google/gemini-3-flash",system:t,prompt:r})).text.trim()}}};import{Output as So}from"ai";import{z as ce}from"zod";var ft=class extends U{getValidationSchema(){return ce.object({url:ce.string().url(),languages:ce.array(ce.string()).min(1),model:ce.string().optional()})}buildSchema(e){let t={};for(let r of e)t[r]=ce.string().max(250).describe(`Image description in ${r} (max 250 chars)`);return ce.object({translations:ce.object(t).describe("A map of language codes to image descriptions")})}async execute(e){var i;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let t=`Generate a very concise image description (maximum 250 characters) for the attached image.
|
|
760
|
+
|
|
761
|
+
LANGUAGES: ${e.languages.join(", ")}
|
|
762
|
+
|
|
763
|
+
You MUST provide the description for each of these language codes.`,r=await this.generateText({model:e.model||"google/gemini-3-flash",experimental_output:So.object({schema:this.buildSchema(e.languages)}),system:`You are an expert accessibility (a11y) image description generator.
|
|
764
|
+
|
|
765
|
+
INSTRUCTIONS:
|
|
766
|
+
1. Analyze the image and generate a very concise description (maximum 250 characters).
|
|
767
|
+
2. Provide the description in all requested languages.
|
|
768
|
+
3. Your response MUST be a JSON object with a "translations" key.`,messages:[{role:"user",content:[{type:"text",text:t},{type:"image",image:e.url}]}]});if(r.finishReason!=="stop")throw new p(`AI generation failed: ${r.finishReason}`,"AI_ERROR");let a=((i=r.experimental_output)==null?void 0:i.translations)||{};for(let o of e.languages)a[o]||(a[o]=a[e.languages[0]]||"");return{translations:a}}};import{Output as _o}from"ai";import{z as J}from"zod";function En(s){let e="";if(s){if(s.site&&Object.keys(s.site).length>0){let t=Object.entries(s.site).map(([r,a])=>`${r}: ${a}`).join(", ");e+=`
|
|
769
|
+
Site Context: ${t}`}if(s.page&&Object.keys(s.page).length>0){let t=Object.entries(s.page).map(([r,a])=>`${r}: ${a}`).join(", ");e+=`
|
|
770
|
+
Page Context: ${t}`}}return e}var bn={title:"Generate title for the following page. Max length: 60 characters",description:"Generate description for the following page. Max length: 160 characters",ogTitle:"Generate og title for the following page. Max length: 60 characters",ogDescription:"Generate og description for the following page. Max length: 160 characters",searchTitle:"Generate search title for the following page. Max length: 60 characters",searchDescription:"Generate search description for the following page. Max length: 160 characters",jsonLD:"Generate json ld for the following page. Return only json ld"},yt=class extends U{getValidationSchema(){return J.object({context:J.any().optional(),dynamic:J.boolean(),pageContent:J.string(),field:J.enum(["title","description","ogTitle","ogDescription","searchTitle","searchDescription","jsonLD"]),lang:J.string().nonempty(),keyword:J.string().optional(),model:J.string().optional()})}async execute(e){var c;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let t=En(e.context),r=`${bn[e.field]}${t}
|
|
771
|
+
Page Content: ${e.pageContent}
|
|
772
|
+
Dynamic: ${e.dynamic}
|
|
773
|
+
Language: ${e.lang}`,a=await this.generateText({model:e.model||"google/gemini-3-flash",experimental_output:_o.object({schema:J.object({field:J.string()})}),system:`You are a SEO expert. Follow the instructions carefully.
|
|
774
|
+
Return ONLY plain string values except for json ld. For JSONLD, remove \`\`\`json\`\`\` and \`\`\`\`\` and return only valid JSON.
|
|
775
|
+
Instructions: ${bn[e.field]}
|
|
776
|
+
${e.keyword?`Optimize the generated content for "${e.keyword}" keyword(s)`:""}${t}
|
|
777
|
+
Page Content: ${e.pageContent}
|
|
778
|
+
Dynamic: ${e.dynamic}
|
|
779
|
+
Language: ${e.lang}`,prompt:r}),i=typeof((c=a.experimental_output)==null?void 0:c.field)=="string"?a.experimental_output.field:void 0,o=typeof a.text=="string"?a.text:void 0,l=i!=null?i:o;if(typeof l!="string")throw new p("Failed to parse generated SEO field","INVALID_AI_RESPONSE");return{field:l}}};import{z as pe}from"zod";var la=["background","foreground","primary","primary-foreground","secondary","secondary-foreground","muted","muted-foreground","accent","accent-foreground","destructive","destructive-foreground","border","input","ring","card","card-foreground","popover","popover-foreground"];function Do(s,e){let t=s.length>0?s.join(", "):"ui-sans-serif, system-ui, sans-serif",r=la.map(i=>`--${i}`).join(", "),a=`You are a professional UI Designer and Theme Architect.
|
|
780
|
+
Your task is to generate a comprehensive design system theme based on the user's description.
|
|
781
|
+
|
|
782
|
+
AVAILABLE FONTS: ${t}
|
|
783
|
+
You MUST only use the exact family names from this list for --font-sans, --font-heading, and --font-body.`;return e&&(a+=`
|
|
784
|
+
|
|
785
|
+
DESIGN CONTEXT:
|
|
786
|
+
The user has provided branding hints (Look, Tone, etc.). Use these as stylistic guides to ensure the colors and typography align with the brand, but prioritize the user's specific theme description.`),a+=`
|
|
787
|
+
|
|
788
|
+
STRICT CONSTRAINTS:
|
|
789
|
+
1. Output ONLY a valid CSS block containing BOTH :root (Light Mode) and .dark (Dark Mode) selectors.
|
|
790
|
+
2. REQUIRED Color Variables (must appear in BOTH :root AND .dark):
|
|
791
|
+
${r}.
|
|
792
|
+
3. REQUIRED Typography Variables (in :root only): --font-sans, --font-heading, --font-body.
|
|
793
|
+
4. REQUIRED Shape Variable (in :root only): --radius (MUST be in pixels, e.g. "8px").
|
|
794
|
+
5. Do NOT include ANY explanations, markdown code blocks (\`\`\`css), comments, or conversational text.
|
|
795
|
+
6. Do NOT wrap the output in backticks or code fences.
|
|
796
|
+
7. Colors MUST be in hex format (e.g. #ffffff) or HSL format (e.g. hsl(210 40% 98%)).
|
|
797
|
+
8. Light and dark mode colors must be harmonious and provide good contrast for readability.
|
|
798
|
+
9. Your output must start with ":root {" and contain nothing before it.`,a}function vo(s){let e=s.trim();e=e.replace(/^```(?:css)?\s*/i,""),e=e.replace(/\s*```\s*$/i,"");let t=e.indexOf(":root");return t>0&&(e=e.substring(t)),e.trim()}var Tt=class extends U{getValidationSchema(){return pe.object({branding:pe.object({look:pe.string().optional(),tone:pe.string().optional()}).optional(),prompt:pe.string().min(1,"A theme description prompt is required"),availableFonts:pe.array(pe.string()),model:pe.string().optional()})}async execute(e){var i,o;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");if(!e.prompt||e.prompt.trim()==="")throw new p("A theme description prompt is required","INVALID_DATA");let t=e.branding?`
|
|
799
|
+
Branding Hints: Look: ${e.branding.look||"N/A"}, Tone: ${e.branding.tone||"N/A"}`:"",r=Do(e.availableFonts,!!e.branding),a=`Generate a theme for the following description: "${e.prompt}"${t}`;try{let l=await this.generateText({model:e.model||"google/gemini-3-flash",system:r,prompt:a}),c=vo(l.text);if(!c.includes(":root")||!c.includes(".dark"))throw new p("AI generated invalid theme CSS. Missing :root or .dark selectors. Please try again.","AI_INVALID_OUTPUT");let d=((i=c.match(/:root\s*{([^}]+)}/))==null?void 0:i[1])||"",u=((o=c.match(/\.dark\s*{([^}]+)}/))==null?void 0:o[1])||"",h=la.filter(T=>!d.includes(`--${T}`)),f=la.filter(T=>!u.includes(`--${T}`));if(h.length>0||f.length>0)throw console.error("AI generated incomplete theme CSS. Missing variables:",{root:h,dark:f}),new p("AI generated an incomplete theme. Some required colors are missing. Please try again with a more specific description.","AI_INVALID_OUTPUT");return{css:c}}catch(l){throw l instanceof p?l:(console.error("AI Theme Generation Error:",l),new p("Failed to generate theme with AI. Please try again.","AI_ERROR",500,l))}}};import{z as No}from"zod";var At=class extends y{getValidationSchema(){return No.any()}async execute(){var r;if(!((r=this.context)!=null&&r.userId))return{success:!1,addons:[],error:"User not authenticated"};let e=await hn(this.context.userId);if(!(e!=null&&e.clientId))return{success:!1,addons:[],error:"User plan not found"};let t=await oa(e.clientId);return t!=null&&t.addOns?{success:!0,addons:t.addOns.map(a=>({id:a.id,name:a.name,credits:a.credits,price:a.price,currency:"USD"}))}:{success:!0,addons:[]}}};import{and as Oo,eq as ca}from"drizzle-orm";import{z as Pn}from"zod";var Et=class extends y{getValidationSchema(){return Pn.object({pageId:Pn.string().optional()})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,{data:r,error:a}=await m(()=>g.query.apps.findFirst({where:ca(n.apps.id,t),columns:{ai:!0}}));a&&console.error("Error fetching app AI context:",a);let i=null;if(e.pageId){let{data:o,error:l}=await m(()=>g.query.appPages.findFirst({where:Oo(ca(n.appPages.id,e.pageId),ca(n.appPages.app,t)),columns:{ai:!0}}));if(l)throw new p("Error fetching page AI context","PAGE_AI_CONTEXT_ERROR",500,l);if(!o)throw new p("Page not found for this app","PAGE_NOT_FOUND",404);i=o.ai}return{success:!0,aiData:{app:(r==null?void 0:r.ai)||{},page:i||{}}}}};import{z as ko}from"zod";var bt=class extends y{getValidationSchema(){return ko.any()}async execute(){var t;if(!((t=this.context)!=null&&t.appId))return{success:!1,credits:null,error:"App context not found"};if(!_e())return{success:!0,credits:null};let e=await ia(this.context.appId);return e?{success:!0,credits:{monthly:e.monthly,addon:{total:e.addon.total,used:e.addon.used,remaining:e.addon.remaining},totalAvailable:e.totalAvailable,canBuyCredits:e.canBuyCredits,billingPeriod:e.billingPeriod?{start:e.billingPeriod.start.toISOString(),end:e.billingPeriod.end.toISOString()}:void 0}}:{success:!1,credits:null,error:"Could not fetch credit status"}}};import{and as Lo,eq as pa}from"drizzle-orm";import{z as Pt}from"zod";var wt=class extends y{getValidationSchema(){return Pt.object({type:Pt.enum(["app","page"]),aiData:Pt.any(),pageId:Pt.string().optional()})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context;if(e.aiData===void 0||e.aiData===null)throw new p("aiData is required","INVALID_DATA");if(e.type==="app"){let{error:r}=await m(async()=>{await g.update(n.apps).set({ai:e.aiData}).where(pa(n.apps.id,t))});if(r)throw new p("Error updating app AI context","UPDATE_ERROR",500,r)}else if(e.type==="page"){if(!e.pageId)throw new p("pageId is required for page context","INVALID_DATA");let{data:r,error:a}=await m(async()=>g.update(n.appPages).set({ai:e.aiData}).where(Lo(pa(n.appPages.id,e.pageId),pa(n.appPages.app,t))).returning());if(a)throw new p("Error updating page AI context","UPDATE_ERROR",500,a);if(!r||r.length===0)throw new p("Page not found for this app","NOT_FOUND",404)}return{success:!0}}};import{z as de}from"zod";import{and as ve,count as Uo,desc as Go,eq as re,ilike as wn,inArray as In,isNull as Bo,or as Fo,sql as Mo}from"drizzle-orm";import{kebabCase as xn}from"lodash-es";import{nanoid as $o}from"nanoid";var q=class q{constructor(e,t){this.appId=e;this.userId=t}appendUpdatedAtToUrl(e,t){if(!e||!t)return e||"";try{let r=new URL(e),a=new Date(t).getTime();return r.searchParams.set("t",a.toString()),r.toString()}catch(r){return e||""}}getBufferFromBase64(e){try{let t=e.split(",")[1]||e;return Buffer.from(t,"base64")}catch(t){throw new Error("Invalid base64 string format")}}getMimeType(e){var a;let t=((a=e.split(".").pop())==null?void 0:a.toLowerCase())||"";return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp",gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}[t]||"application/octet-stream"}getImageDimensions(e){if(e.length>=q.MIN_PNG_LENGTH&&e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71)return{width:e.readUInt32BE(16),height:e.readUInt32BE(20)};if(e.length>=q.MIN_GIF_LENGTH&&e[0]===71&&e[1]===73&&e[2]===70)return{width:e.readUInt16LE(6),height:e.readUInt16LE(8)};if(e.length>=12&&e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80){if(e.length>=q.MIN_WEBP_VP8L_LENGTH&&e[12]===86&&e[13]===80&&e[14]===56&&e[15]===76){let t=e.readUInt32LE(21);return{width:(t&16383)+1,height:(t>>14&16383)+1}}if(e.length>=q.MIN_WEBP_VP8X_LENGTH&&e[12]===86&&e[13]===80&&e[14]===56&&e[15]===88)return{width:1+(e[24]|e[25]<<8|e[26]<<16),height:1+(e[27]|e[28]<<8|e[29]<<16)};if(e.length>=q.MIN_WEBP_VP8_LENGTH&&e[12]===86&&e[13]===80&&e[14]===56&&e[15]===32)return{width:e.readUInt16LE(26)&16383,height:e.readUInt16LE(28)&16383}}if(e.length>=2&&e[0]===255&&e[1]===216){let t=2;for(;t<e.length-1;){if(e[t]!==255){t++;continue}let r=e[t+1];if(r>=192&&r<=195||r>=197&&r<=199||r>=201&&r<=203||r>=205&&r<=207){if(t+q.MIN_JPEG_SOF_BYTES_FROM_MARKER<=e.length)return{width:e.readUInt16BE(t+7),height:e.readUInt16BE(t+5)};break}if(t+4>e.length)break;let a=e.readUInt16BE(t+2);t+=2+a}}return{width:0,height:0}}async uploadImageFile(e,t,r,a){var i;try{let o=this.getBufferFromBase64(e),l=((i=e.match(/^data:([^;]+);base64,/))==null?void 0:i[1])||this.getMimeType(r);if(!["image/jpeg","image/png","image/webp","image/gif","image/tiff"].includes(l))throw new Error(`Invalid image format: ${l}`);let d=r.split("."),u=d.length>1?d.slice(0,-1).join("."):r,h=d.length>1?d[d.length-1].toLowerCase():"png",f=`${xn(u)}.${h}`,T=t?`${this.appId}/${t}`:this.appId,{getChaiAction:A}=await import("./actions-registery-SEJTZE5Q.js"),I=A("UPLOAD_TO_STORAGE");if(!I)throw new Error("UPLOAD_TO_STORAGE action not found");I.setContext({appId:this.appId,userId:this.userId});let E=await I.execute({file:o.toString("base64"),fileName:f,contentType:l,folder:T});if(E.error)throw new Error(E.error);let{width:x,height:C}=this.getImageDimensions(o);return{url:E.data.url,thumbnailUrl:E.data.url,size:o.length,width:x,height:C,mimeType:l}}catch(o){return console.error("Upload image error:",o),{error:o instanceof Error?o.message:"Unknown error"}}}async uploadSvgFile(e,t,r){try{let a=this.getBufferFromBase64(e),i,o;try{let A=a.toString("utf-8"),I=A.match(/\bwidth=["'](\d+)/),E=A.match(/\bheight=["'](\d+)/);I&&(i=parseInt(I[1],10)),E&&(o=parseInt(E[1],10))}catch(A){}let l=r.split("."),c=l.length>1?l.slice(0,-1).join("."):r,d=`${xn(c)}.svg`,u=t?`${this.appId}/${t}`:this.appId,{getChaiAction:h}=await import("./actions-registery-SEJTZE5Q.js"),f=h("UPLOAD_TO_STORAGE");if(!f)throw new Error("UPLOAD_TO_STORAGE action not found");f.setContext({appId:this.appId,userId:this.userId});let T=await f.execute({file:a.toString("base64"),fileName:d,contentType:"image/svg+xml",folder:u});if(T.error)throw new Error(T.error);return{url:T.data.url,thumbnailUrl:T.data.url,size:a.length,width:i,height:o,mimeType:"image/svg+xml"}}catch(a){return console.error("SVG upload error:",a),{error:a instanceof Error?a.message:"Unknown error"}}}async upload({file:e,folderId:t,name:r,description:a,optimize:i=!0}){var o,l,c;try{let d=r.toLowerCase().endsWith(".svg")||e.includes("data:image/svg+xml"),u=I=>{let E=I.split("."),x=(E.length>1?E.pop().toLowerCase():"webp")||"webp";return`${E.join(".").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,30)||"image"}-${$o(10)}.${x}`},h=d?await this.uploadSvgFile(e,t,r):await this.uploadImageFile(e,t,u(r),i!=null?i:!0);if("error"in h)return h;let f={name:r,app:this.appId,description:typeof a=="object"&&a!==null?JSON.stringify(a):a,url:h.url,thumbnailUrl:h.thumbnailUrl,size:(o=h.size)==null?void 0:o.toString(),width:(l=h.width)==null?void 0:l.toString(),height:(c=h.height)==null?void 0:c.toString(),format:h.mimeType.split("/")[1],folderId:t,type:h.mimeType.startsWith("image/")?"image":"file",createdBy:this.userId,updatedAt:new Date().toISOString()},{data:T,error:A}=await m(async()=>{let[I]=await g.insert(n.appAssets).values(f).returning();return I});if(A)throw new Error(`Failed to store asset in database: ${A.message}`);if(!T)throw new Error("Failed to retrieve created asset");return{...T,url:this.appendUpdatedAtToUrl(T.url,T.updatedAt),thumbnailUrl:this.appendUpdatedAtToUrl(T.thumbnailUrl,T.updatedAt)}}catch(d){return{error:d instanceof Error?d.message:"Unknown error occurred"}}}async getAsset({id:e}){try{let{data:t,error:r}=await m(()=>g.query.appAssets.findFirst({where:ve(re(n.appAssets.id,e),re(n.appAssets.app,this.appId))}));if(r)throw new Error(`Failed to fetch asset: ${r.message}`);if(!t)throw new Error("Asset not found");return{...t,url:this.appendUpdatedAtToUrl(t.url,t.updatedAt),thumbnailUrl:this.appendUpdatedAtToUrl(t.thumbnailUrl||"",t.updatedAt)}}catch(t){return{error:t instanceof Error?t.message:"Unknown error occurred"}}}async getAssets({search:e="",page:t=1,limit:r=20}={}){var a;try{let i=(t-1)*r,o=ve(re(n.appAssets.app,this.appId),Bo(n.appAssets.deletedAt));e&&(o=ve(o,Fo(wn(n.appAssets.name,`%${e}%`),wn(Mo`${n.appAssets.description}::text`,`%${e}%`))));let{data:l,error:c}=await m(()=>g.select({value:Uo()}).from(n.appAssets).where(o));if(c)throw new Error(c.message);let d=((a=l==null?void 0:l[0])==null?void 0:a.value)||0,{data:u,error:h}=await m(()=>g.query.appAssets.findMany({where:o,orderBy:Go(n.appAssets.createdAt),limit:r,offset:i}));if(h)throw new Error(h.message);return{assets:(u||[]).map(T=>({...T,url:this.appendUpdatedAtToUrl(T.url,T.updatedAt),thumbnailUrl:this.appendUpdatedAtToUrl(T.thumbnailUrl||"",T.updatedAt)})),total:d,page:t,pageSize:r}}catch(i){return{error:i instanceof Error?i.message:"Unknown error occurred"}}}async deleteAsset(e){try{let{data:t,error:r}=await m(()=>g.query.appAssets.findMany({where:ve(In(n.appAssets.id,e),re(n.appAssets.app,this.appId))}));if(r)throw new Error(`Failed to fetch assets: ${r.message}`);if(!t||t.length===0)throw new Error("Assets not found");for(let o of t)if(o.url)try{let c=new URL(o.url).pathname.split("/"),d=c.indexOf("dam-assets");if(d!==-1){let u=c.slice(d+1).join("/"),{getChaiAction:h}=await import("./actions-registery-SEJTZE5Q.js"),f=h("DELETE_FROM_STORAGE");if(f&&(f.setContext({appId:this.appId,userId:this.userId}),await f.execute({key:u})),o.thumbnailUrl&&o.thumbnailUrl!==o.url){let A=new URL(o.thumbnailUrl).pathname.split("/"),I=A.indexOf("dam-assets");if(I!==-1){let E=A.slice(I+1).join("/");f&&await f.execute({key:E})}}}}catch(l){console.warn("Failed to delete from storage, continuing with database deletion:",l)}let{data:a,error:i}=await m(()=>g.delete(n.appAssets).where(ve(In(n.appAssets.id,e),re(n.appAssets.app,this.appId))).returning());if(i)throw new Error(`Failed to delete assets: ${i.message}`);if(!a||a.length!==e.length)throw new Error("Some assets could not be deleted or were not found");return{success:!0}}catch(t){return{error:t instanceof Error?t.message:"Unknown error occurred"}}}async updateAsset({id:e,file:t,description:r}){var a,i,o,l;try{let{data:c,error:d}=await m(()=>g.query.appAssets.findFirst({where:ve(re(n.appAssets.id,e),re(n.appAssets.app,this.appId))}));if(d)throw new Error(`Failed to fetch asset: ${d.message}`);if(!c)throw new Error("Asset not found");let u={updatedAt:new Date().toISOString()};if(r!==void 0&&(u.description=typeof r=="object"&&r!==null?JSON.stringify(r):r),t){let A=((a=c.format)==null?void 0:a.toLowerCase())==="svg"||t.includes("data:image/svg+xml")?await this.uploadSvgFile(t,c.folderId,c.name||"asset.svg"):await this.uploadImageFile(t,c.folderId,c.name||"asset.png",!0);if("error"in A)return A;u.url=A.url,u.thumbnailUrl=A.thumbnailUrl,u.size=(i=A.size)==null?void 0:i.toString(),u.width=(o=A.width)==null?void 0:o.toString(),u.height=(l=A.height)==null?void 0:l.toString(),u.format=A.mimeType.split("/")[1]}let{error:h}=await m(()=>g.update(n.appAssets).set(u).where(re(n.appAssets.id,e)));if(h)throw new Error(`Failed to update asset: ${h.message}`);let{data:f}=await m(()=>g.query.appAssets.findFirst({where:re(n.appAssets.id,e)}));if(!f)throw new Error("Updated asset not found");return{...f,url:this.appendUpdatedAtToUrl(f.url,f.updatedAt),thumbnailUrl:this.appendUpdatedAtToUrl(f.thumbnailUrl||"",f.updatedAt)}}catch(c){return{error:c instanceof Error?c.message:"Unknown error occurred"}}}};q.MIN_PNG_LENGTH=24,q.MIN_GIF_LENGTH=10,q.MIN_WEBP_VP8L_LENGTH=25,q.MIN_WEBP_VP8X_LENGTH=30,q.MIN_WEBP_VP8_LENGTH=30,q.MIN_JPEG_SOF_BYTES_FROM_MARKER=9;var W=q;var Ho=de.object({name:de.string(),file:de.string(),folderId:de.string().optional().nullable(),description:de.record(de.string(),de.string()).optional(),optimize:de.boolean().optional().default(!0)}),It=class extends y{getValidationSchema(){return Ho}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context;if(!r)throw new p("User ID is required","UNAUTHORIZED",401);let i=await new W(t,r).upload(e);if(i.error)throw new p(i.error,"CREATE_FAILED");return i}};import{z as da}from"zod";var Vo=da.object({ids:da.array(da.string().uuid()).min(1,"At least one asset ID is required")}),xt=class extends y{getValidationSchema(){return Vo}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context;if(!r)throw new p("User ID is required","UNAUTHORIZED",401);let i=await new W(t,r).deleteAsset(e.ids);if("error"in i)throw new p(i.error,"DELETE_FAILED");return i}};import{z as Oe}from"zod";import"server-only";async function Ne(s,e){var i;if(!G(1))return fetch(s,e);let t=typeof s=="string"?s:s instanceof URL?s.href:s.url,r=(i=e==null?void 0:e.method)!=null?i:typeof s!="string"&&!(s instanceof URL)?s.method:"GET",a=performance.now();try{let o=await fetch(s,e);return Jr(r,t,Math.round(performance.now()-a),o.status),o}catch(o){throw Jr(r,t,Math.round(performance.now()-a),0),o}}var qo=Oe.object({url:Oe.string(),name:Oe.string(),description:Oe.record(Oe.string(),Oe.string()).optional()}),Ct=class extends y{constructor(){super()}getValidationSchema(){return qo}async execute(e){try{if(!this.context)return{error:"Context not set",status:400};let{userId:t}=this.context;if(!t)return{error:"User ID is required",status:401};let r=await Ne(e.url);if(!r.ok)return{error:"Failed to download image from source",status:r.status};let a=r.headers.get("content-type")||"";if(!a.startsWith("image/"))return{error:"The URL does not point to a valid image. The server returned content-type: "+a,status:400};let o=await(await r.blob()).arrayBuffer(),c=`data:image/webp;base64,${Buffer.from(o).toString("base64")}`,{getChaiAction:d}=await import("./actions-registery-SEJTZE5Q.js"),u=d("CREATE_ASSET");if(!u)return{error:"CREATE_ASSET action not found",status:500};u.setContext(this.context);let h=await u.execute({file:c,name:e.name,description:e.description,optimize:!0});return h!=null&&h.error?{error:h.error,status:400}:h}catch(t){return console.error("DOWNLOAD_SEARCH_IMAGE error:",t),{error:t instanceof Error?t.message:"Unknown error",status:500}}}};import{z as Cn}from"zod";var jo=Cn.object({id:Cn.string().uuid()}),Rt=class extends y{getValidationSchema(){return jo}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context;if(!r)throw new p("User ID is required","UNAUTHORIZED",401);let i=await new W(t,r).getAsset(e);if(i.error)throw new p(i.error,"FETCH_FAILED",404);return i}};import{z as St}from"zod";var zo=St.object({search:St.string().optional().default(""),page:St.number().optional().default(1),limit:St.number().optional().default(20)}),_t=class extends y{getValidationSchema(){return zo}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context;if(!r)throw new p("User ID is required","UNAUTHORIZED",401);let i=await new W(t,r).getAssets(e);if("error"in i)throw new p(i.error,"FETCH_FAILED");return i}};import{z as ge}from"zod";var Wo="https://pixabay.com/api/",Yo="https://api.unsplash.com/search/photos",Ko="https://api.pexels.com/v1/search",Qo=ge.object({query:ge.string(),page:ge.number().optional().default(1),limit:ge.number().optional().default(20),provider:ge.string().optional(),filters:ge.record(ge.string(),ge.string()).optional()}),Dt=class extends y{getValidationSchema(){return Qo}async execute(e){try{let{query:t,page:r,limit:a,provider:i,filters:o}=e,l=process.env.PIXABAY_API_KEY,c=process.env.UNSPLASH_ACCESS_KEY,d=process.env.PEXELS_API_KEY;if(!l&&i==="pixabay"||!c&&i==="unsplash"||!d&&i==="pexels")return{error:"No image search provider API keys configured",status:500};let u=[],h=[l,c,d].filter(Boolean).length,f=i&&i!=="all"?a:Math.ceil(a/h);if(l&&(!i||i==="pixabay")){let x=`${Wo}?key=${l}&q=${encodeURIComponent(t)}&page=${r}&per_page=${f}${t?"":"&editors_choice=true"}`,C="photo";o!=null&&o.image_type&&o.image_type!=="all"&&o.image_type!=="default"&&(C=o.image_type),x+=`&image_type=${C}`,o!=null&&o.orientation&&o.orientation!=="all"&&o.orientation!=="default"&&(x+=`&orientation=${o.orientation}`),o!=null&&o.color&&o.color!=="all"&&o.color!=="default"&&(x+=`&colors=${o.color}`),o!=null&&o.order_by&&o.order_by!=="all"&&o.order_by!=="default"&&(x+=`&order=${o.order_by}`),u.push(Ne(x).then(async R=>{if(!R.ok)return{assets:[],total:0};let S=await R.json();return{assets:S.hits.map(D=>({id:`pixabay-${D.id}`,name:D.tags,url:D.largeImageURL,thumbnailUrl:D.webformatURL,type:"image",width:D.imageWidth,height:D.imageHeight||D.height,size:D.imageSize,provider:"pixabay",authorName:D.user,authorUrl:`https://pixabay.com/users/${D.user}-${D.user_id}/`,authorThumbnailUrl:D.userImageURL,providerUrl:"https://pixabay.com/",providerLogoUrl:null})),total:S.totalHits}}))}if(c&&(!i||i==="unsplash")){let x=`${Yo}?query=${encodeURIComponent(t)}&page=${r}&per_page=${f}&client_id=${c}`;t&&o&&(o.orientation&&o.orientation!=="all"&&o.orientation!=="default"&&(x+=`&orientation=${o.orientation}`),o.color&&o.color!=="all"&&o.color!=="default"&&(x+=`&color=${o.color}`),o.order_by&&o.order_by!=="all"&&o.order_by!=="default"&&(x+=`&order_by=${o.order_by}`)),u.push(Ne(x,{headers:{"Accept-Version":"v1"}}).then(async C=>{if(!C.ok)return{assets:[],total:0};let R=await C.json(),S=t?R.results:R,D=t?R.total:200;return{assets:S.map(k=>{var le;return{id:`unsplash-${k.id}`,name:k.description||k.alt_description||"Unsplash Image",url:k.urls.regular,thumbnailUrl:k.urls.small,type:"image",width:k.width,height:k.height,size:0,provider:"unsplash",authorName:k.user.name,authorUrl:k.user.links.html,authorThumbnailUrl:(le=k.user.profile_image)==null?void 0:le.small,providerUrl:"https://unsplash.com/",providerLogoUrl:null}}),total:D}}))}if(d&&(!i||i==="pexels")){let C=!t?`https://api.pexels.com/v1/curated?page=${r}&per_page=${f}`:`${Ko}?query=${encodeURIComponent(t)}&page=${r}&per_page=${f}`;o!=null&&o.orientation&&o.orientation!=="all"&&o.orientation!=="default"&&(C+=`&orientation=${o.orientation}`),o!=null&&o.size&&o.size!=="all"&&o.size!=="default"&&(C+=`&size=${o.size}`),o!=null&&o.color&&o.color!=="all"&&o.color!=="default"&&(C+=`&color=${o.color}`),u.push(Ne(C,{headers:{Authorization:d}}).then(async R=>{if(!R.ok)return{assets:[],total:0};let S=await R.json();return{assets:(S.photos||[]).map(D=>({id:`pexels-${D.id}`,name:D.alt||"Pexels Image",url:D.src.large2x,thumbnailUrl:D.src.medium,type:"image",width:D.width,height:D.height,size:0,provider:"pexels",authorName:D.photographer,authorUrl:D.photographer_url,providerUrl:"https://pexels.com/",providerLogoUrl:"https://images.pexels.com/lib/api/pexels-white.png"})),total:S.total_results||0}}))}let T=await Promise.all(u),A=Math.max(...T.map(x=>x.assets.length)),I=[];for(let x=0;x<A;x++)for(let C of T)C.assets[x]&&I.push(C.assets[x]);let E=T.reduce((x,C)=>x+C.total,0);return{assets:I,total:E,page:r,limit:a}}catch(t){return console.error("SEARCH_IMAGES error:",t),{error:t instanceof Error?t.message:"Unknown error",status:500}}}};import{z as ke}from"zod";var Xo=ke.object({id:ke.string().uuid(),file:ke.string().optional(),description:ke.record(ke.string(),ke.string()).optional()}),vt=class extends y{getValidationSchema(){return Xo}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context;if(!r)throw new p("User ID is required","UNAUTHORIZED",401);let i=await new W(t,r).updateAsset(e);if("error"in i)throw new p(i.error,"UPDATE_FAILED");return i}};import{isFunction as Es}from"lodash-es";import{z as $t}from"zod";import"server-only";var Jo=async s=>{let{logAiRequest:e}=await import("./log-ai-request-LHPKU2C5.js");return e(s)},Le={models:Za,defaultModelId:en,resolveModel:(s,e)=>({model:s}),credits:{enabled:!1},logging:{logger:Jo,clientId:null}};function Nt(s){return typeof s=="object"&&s!==null&&!Array.isArray(s)}function Ot(s,e){if(!e)return{...s};let t={...s};for(let r of Object.keys(e)){let a=e[r];if(a===void 0)continue;let i=s[r];if(typeof a=="function"){t[r]=a;continue}if(Nt(i)&&Nt(a)){t[r]=Ot(i,a);continue}t[r]=a}return t}function Ze(s,e,t){let r=new Map;for(let a of s)r.set(t(a),a);for(let a of e!=null?e:[]){let i=t(a),o=r.get(i);o&&Nt(o)&&Nt(a)?r.set(i,{...o,...a}):r.set(i,a)}return Array.from(r.values())}import"server-only";function ga(s){if(!s||typeof s!="object")throw new Error("ChaiBuilder: `db` is required in `buildChaiBuilderConfig`. Pass `db: createPostgresDB(...)` (or libsql/d1/better-sqlite3).");if(!s.drizzle)throw new Error("ChaiBuilder: `db` is required in `buildChaiBuilderConfig`. Pass `db: createPostgresDB(...)` (or libsql/d1/better-sqlite3).");return s}import{isFunction as Rn}from"lodash-es";import"server-only";function ha(s,e){Ja(s,e)}function Zo(s=ma()){for(let[e,t]of Object.entries(s))ha(e,t)}function fa(s){var r;let e=ze(s);if(e!=null&&e.dataProvider&&Rn(e.dataProvider))return e.dataProvider;let t=ua(s);if(!(!t||!Rn(t)))return ha(s,t),(r=ze(s))==null?void 0:r.dataProvider}var es='<svg stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 24 24" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M5 8V20H19V8H5ZM5 6H19V4H5V6ZM20 22H4C3.44772 22 3 21.5523 3 21V3C3 2.44772 3.44772 2 4 2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22ZM7 10H11V14H7V10ZM7 16H17V18H7V16ZM13 11H17V13H13V11Z"></path></svg>',ts='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-hash-icon lucide-hash"><line x1="4" x2="20" y1="9" y2="9"/><line x1="4" x2="20" y1="15" y2="15"/><line x1="10" x2="8" y1="3" y2="21"/><line x1="16" x2="14" y1="3" y2="21"/></svg>',Sn={key:"page",name:"Static Page",icon:es,hasSlug:!0},_n={key:"global",name:"Global Block",helpText:"A global block can be reused in multiple pages.",icon:ts,partial:!0,hasSlug:!1},ya=[Sn,_n];import{and as kn,eq as ne,isNull as ss}from"drizzle-orm";import{nanoid as ls}from"nanoid";import{and as as,eq as Nn,inArray as Pe}from"drizzle-orm";import{z as Ta}from"zod";import{eq as rs}from"drizzle-orm";var K=class{constructor(e,t=!1){this.appId=e,this.enableLogging=t}async getPagesTree(){let{data:e,error:t}=await m(()=>g.select({id:n.appPages.id,name:n.appPages.name,slug:n.appPages.slug,pageType:n.appPages.pageType,primaryPage:n.appPages.primaryPage,parent:n.appPages.parent,lang:n.appPages.lang,dynamic:n.appPages.dynamic}).from(n.appPages).where(rs(n.appPages.app,this.appId)));if(t)throw w("ERROR_GETTING_PAGES",t);let r=(e==null?void 0:e.filter(l=>l.primaryPage===null))||[],a=(e==null?void 0:e.filter(l=>l.primaryPage!==null))||[],i=this.buildPrimaryTree(r);this.enableLogging&&(console.log(`
|
|
800
|
+
=== PRIMARY LANGUAGE PAGES TREE ===`),console.log(JSON.stringify(i,null,2)));let o=this.buildLanguageTree(a,i);return this.enableLogging&&(console.log(`
|
|
801
|
+
=== OTHER LANGUAGE PAGES TREE ===`),console.log(JSON.stringify(o,null,2))),{primaryTree:i,languageTree:o,totalPrimaryPages:r.length,totalLanguagePages:a.length}}buildPrimaryTree(e){let t=new Map;e.forEach(a=>{t.set(a.id,{id:a.id,pageType:a.pageType,primaryPage:a.primaryPage,parent:a.parent,name:a.name,dynamic:a.dynamic,slug:a.slug,children:[]})});let r=[];return e.forEach(a=>{let i=t.get(a.id);if(i)if(a.parent===null)r.push(i);else{let o=t.get(a.parent);o?o.children.push(i):r.push(i)}}),r}buildLanguageTree(e,t){let r=new Map;e.forEach(l=>{let c=l.primaryPage;r.has(c)||r.set(c,[]),r.get(c).push(l)});let a=(l,c)=>{let u=(r.get(l.id)||[]).find(f=>f.lang===c);if(!u)return null;let h={id:u.id,pageType:u.pageType,primaryPage:u.primaryPage,parent:u.parent,lang:u.lang,name:u.name,slug:u.slug,dynamic:u.dynamic,children:[]};return l.children.forEach(f=>{let T=a(f,c);T&&h.children.push(T)}),h},i=[],o=new Set;return e.forEach(l=>{l.lang&&o.add(l.lang)}),o.forEach(l=>{t.forEach(c=>{let d=a(c,l);d&&i.push(d)})}),i}findPageInPrimaryTree(e,t){for(let r of t){if(r.id===e)return r;if(r.children&&r.children.length>0){let a=this.findPageInPrimaryTree(e,r.children);if(a)return a}}return null}findPageInLanguageTree(e,t){for(let r of t){if(r.id===e)return r;if(r.children&&r.children.length>0){let a=this.findPageInLanguageTree(e,r.children);if(a)return a}}return null}calculateSlugFromParent(e,t,r){if(!e){let c=t.split("/").filter(Boolean);return"/"+(c[c.length-1]||"")}let a=this.findPageInPrimaryTree(e,r);if(!a&&(a=this.findPageInLanguageTree(e,r),!a))throw new Error("Parent page not found in tree");let i=t.split("/").filter(Boolean),o=i[i.length-1]||"";return`${a.slug.endsWith("/")?a.slug.slice(0,-1):a.slug}/${o}`}collectNestedChildIds(e){let t=[];for(let r of e.children){t.push(r.id);let a=this.collectNestedChildIds(r);t.push(...a)}return t}findLanguagePagesForPrimary(e,t){let r=[],a=i=>{for(let o of i)o.primaryPage===e&&r.push(o),o.children&&o.children.length>0&&a(o.children)};return a(t),r}collectNestedChildSlugs(e,t,r){let a=[],i=(o,l,c)=>{for(let d of o){let u=this.generateNewChildSlug(d.slug,l,c);a.push({id:d.id,oldSlug:d.slug,newSlug:u}),d.children&&d.children.length>0&&i(d.children,d.slug,u)}};return i(e.children,t,r),a}generateNewChildSlug(e,t,r){return e===t?r:e.startsWith(t+"/")?e.replace(t+"/",r+"/"):e.startsWith(t)&&e!==t?e.replace(t,r):`${r}/${e.split("/").pop()}`}};function Dn(s){return Buffer.from(s,"utf8").toString("base64url")}function Z(s){return`slug-${Dn(s)}`}function et(s){return s?"draft":"online"}function pg(s,e,t){return[`page-by-slug-${s}-${et(e)}-${Dn(t)}`]}function dg(s,e,t){return[`page-slug-${s}-${et(e)}-${t}`]}function gg(s,e,t){let r=[...t].sort().join(",");return[`page-slugs-batch-${s}-${et(e)}-${r}`]}function mg(s,e,t,r){return[`alternate-${s}-${et(e)}-${t}-${r}`]}function ug(s,e,t){return[`breadcrumb-${s}-${et(e)}-${t}`]}function hg(s){return[Z(s)]}function ae(s,e){var r,a,i,o;let t=new Set([`page-${s}`,`breadcrumb-${s}`]);(r=e==null?void 0:e.slugs)!=null&&r.old&&t.add(Z(e.slugs.old)),(a=e==null?void 0:e.slugs)!=null&&a.new&&t.add(Z(e.slugs.new)),e!=null&&e.primaryPageId&&t.add(`alternate-${e.primaryPageId}`);for(let l of(i=e==null?void 0:e.extraPageIds)!=null?i:[])t.add(`page-${l}`),t.add(`breadcrumb-${l}`);for(let l of(o=e==null?void 0:e.slugUpdates)!=null?o:[])t.add(`page-${l.id}`),t.add(`breadcrumb-${l.id}`),l.oldSlug&&t.add(Z(l.oldSlug)),l.newSlug&&t.add(Z(l.newSlug));return[...t]}function vn(s){let e=new Set;for(let t of s)e.add(`page-${t.id}`),e.add(`breadcrumb-${t.id}`),t.slug&&e.add(Z(t.slug)),t.primaryPage&&e.add(`alternate-${t.primaryPage}`);return[...e]}function kt(s){let e=new Set;for(let t of s)e.add(`page-${t}`),e.add(`breadcrumb-${t}`);return[...e]}var me=class extends y{constructor(){super(...arguments);this.appId="";this.userId="";this.permanent=!1}getValidationSchema(){return Ta.object({id:Ta.string().min(1,"Page ID is required"),permanent:Ta.boolean().optional()})}async execute(t){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");this.appId=this.context.appId,this.userId=this.context.userId||"",this.permanent=t.permanent||!1;try{return this.pageTreeBuilder=new K(this.appId),await this.deletePage(t.id)}catch(r){if(r instanceof p)throw r;let a=r instanceof Error?r.message:"Failed to delete page";throw new p(a,"DELETE_PAGE_ERROR")}}async deletePage(t){let r=await this.getCurrentEditor(t);if(r&&r!==this.userId)return{tags:[],code:"PAGE_LOCKED",editor:r};let a=await this.pageTreeBuilder.getPagesTree(),i=this.pageTreeBuilder.findPageInLanguageTree(t,a.languageTree),o=this.pageTreeBuilder.findPageInPrimaryTree(t,a.primaryTree);if(!i&&!o)throw w("ERROR_DELETING_PAGE","Page not found");return i!==null?await this.deleteLanguagePageWithTree(t,i,a):await this.deletePrimaryPageWithTree(t,a)}async performDeletionWithIds(t){let r=[...t].reverse();if(this.permanent){let{error:o}=await m(()=>g.delete(n.libraryTemplates).where(Pe(n.libraryTemplates.pageId,r)));if(o)throw w("DELETE_FAILED",o)}if(this.permanent){let{error:o}=await m(()=>g.delete(n.appPagesRevisions).where(Pe(n.appPagesRevisions.id,r)));if(o)throw w("DELETE_FAILED",o)}let{error:a}=await m(()=>this.permanent?g.delete(n.appPages).where(Pe(n.appPages.id,r)):g.update(n.appPages).set({deletedAt:new Date().toISOString(),deletedBy:this.userId}).where(Pe(n.appPages.id,r)));if(a)throw w("DELETE_FAILED",a);let{error:i}=await m(()=>g.delete(n.appPagesOnline).where(Pe(n.appPagesOnline.id,r)));if(i)throw w("DELETE_FAILED",i)}collectRoutingTagsFromTree(t,r){let a=[],i=o=>{for(let l of o)t.includes(l.id)&&a.push({id:l.id,slug:l.slug,primaryPage:l.primaryPage}),l.children.length>0&&i(l.children)};return i(r),vn(a)}async deleteLanguagePageWithTree(t,r,a){let i=r.primaryPage;if(!this.pageTreeBuilder.findPageInPrimaryTree(i,a.primaryTree))throw w("ERROR_DELETING_PAGE","Primary page not found");let l=this.pageTreeBuilder.collectNestedChildIds(r),c=[t,...l];return await this.performDeletionWithIds(c),{tags:this.collectRoutingTagsFromTree(c,a.languageTree),totalDeleted:c.length}}async deletePrimaryPageWithTree(t,r){let a=this.pageTreeBuilder.findPageInPrimaryTree(t,r.primaryTree);if(!a)throw w("ERROR_DELETING_PAGE","Primary page not found");let i=this.pageTreeBuilder.collectNestedChildIds(a),o=this.pageTreeBuilder.findLanguagePagesForPrimary(t,r.languageTree),l=[];o.forEach(u=>{l.push(u.id);let h=this.pageTreeBuilder.collectNestedChildIds(u);l.push(...h)});let c=[...new Set([...i,...l])],d=[t,...c];return await this.performDeletionWithIds(d),{tags:[...this.collectRoutingTagsFromTree(d,r.primaryTree),...this.collectRoutingTagsFromTree(d,r.languageTree)].filter((u,h,f)=>f.indexOf(u)===h),totalDeleted:d.length}}async getCurrentEditor(t){var i;let{data:r,error:a}=await m(()=>g.select({currentEditor:n.appPages.currentEditor}).from(n.appPages).where(as(Nn(n.appPages.id,t),Nn(n.appPages.app,this.appId))).limit(1));return a||!r||r.length===0?null:((i=r[0])==null?void 0:i.currentEditor)||null}async restorePage(t){this.pageTreeBuilder||(this.pageTreeBuilder=new K(this.context.appId));let r=await this.pageTreeBuilder.getPagesTree(),a=this.pageTreeBuilder.findPageInLanguageTree(t,r.languageTree),i=this.pageTreeBuilder.findPageInPrimaryTree(t,r.primaryTree);if(!a&&!i)throw w("ERROR_RESTORING_PAGE","Page not found");a!==null?await this.restoreLanguagePageWithTree(t,a,r):await this.restorePrimaryPageWithTree(t,r)}async restoreLanguagePageWithTree(t,r,a){let i=this.pageTreeBuilder.collectNestedChildIds(r),o=[t,...i],{error:l}=await m(()=>g.update(n.appPages).set({deletedAt:null,deletedBy:null}).where(Pe(n.appPages.id,o)));if(l)throw w("RESTORE_FAILED",l)}async restorePrimaryPageWithTree(t,r){let a=this.pageTreeBuilder.findPageInPrimaryTree(t,r.primaryTree);if(!a)throw w("ERROR_RESTORING_PAGE","Primary page not found");let i=this.pageTreeBuilder.collectNestedChildIds(a),o=this.pageTreeBuilder.findLanguagePagesForPrimary(t,r.languageTree),l=[];o.forEach(u=>{l.push(u.id);let h=this.pageTreeBuilder.collectNestedChildIds(u);l.push(...h)});let c=[t,...i,...l],{error:d}=await m(()=>g.update(n.appPages).set({deletedAt:null,deletedBy:null}).where(Pe(n.appPages.id,c)));if(d)throw w("RESTORE_FAILED",d)}};import{and as we,desc as On,eq as F}from"drizzle-orm";import{keys as Bt,pick as is}from"lodash-es";import{z as v}from"zod";function Cg(s,e){return[`page-details-${s}-${e}`]}function Rg(s){return[`page-${s}`,`page-details-${s}`]}function Lt(s){return[`page-${s}`]}import{and as Ut,eq as ue}from"drizzle-orm";import{pick as ns}from"lodash-es";var Gt=class{constructor(e){this.appId=e}updateNodeSlugInTree(e,t,r){for(let a of r){if(a.id===e)return a.slug=t,!0;if(a.children&&a.children.length>0&&this.updateNodeSlugInTree(e,t,a.children))return!0}return!1}validateSlugAvailabilityInTree(e,t,r,a,i=!1){let o=l=>{var c;for(let d of l){let u=(c=d.dynamic)!=null?c:!1;if(d.slug===e&&d.id!==t&&u===r||d.children&&d.children.length>0&&o(d.children))return!0}return!1};if(o(a.primaryTree)){let l=i?`Slug '${e}' conflicts with a primary page slug. Language page slugs cannot overlap with primary page slugs.`:`Slug '${e}' is already in use. Please choose another slug`;throw new p(l,"SLUG_ALREADY_EXISTS")}if(o(a.languageTree)){let l=i?`Slug '${e}' is already in use by another language page. Please choose another slug.`:`Slug '${e}' conflicts with a language page slug. Please choose another slug.`;throw new p(l,"SLUG_ALREADY_EXISTS")}}async isSlugChanged(e,t){if(!t)return!1;let{data:r,error:a}=await m(()=>g.select({slug:n.appPages.slug}).from(n.appPages).where(Ut(ue(n.appPages.id,e),ue(n.appPages.app,this.appId))).limit(1));if(a||!r||r.length===0)return!1;let i=r[0];return(i==null?void 0:i.slug)!==t}async isParentChanged(e,t){if(t===void 0)return!1;let{data:r,error:a}=await m(()=>g.select({parent:n.appPages.parent}).from(n.appPages).where(Ut(ue(n.appPages.id,e),ue(n.appPages.app,this.appId))).limit(1));if(a||!r||r.length===0)return!1;let i=r[0];return(i==null?void 0:i.parent)!==t}async handleSlugChangeWithTree(e,t){let r=t.slug;this.pageTreeBuilder||(this.pageTreeBuilder=new K(this.appId));let a=await this.pageTreeBuilder.getPagesTree(),i=this.pageTreeBuilder.findPageInPrimaryTree(e,a.primaryTree);if(!i&&(i=this.pageTreeBuilder.findPageInLanguageTree(e,a.languageTree),!i))throw new p("Page not found in tree","PAGE_NOT_FOUND_IN_TREE");let o=i.slug,l=i.dynamic||!1;this.validateSlugAvailabilityInTree(r,e,l,a);let c=[],d=this.pageTreeBuilder.collectNestedChildSlugs(i,o,r);return c=[{id:e,oldSlug:o,newSlug:r},...d],c}async handleParentChangeWithTree(e,t){let r=t.parent;this.pageTreeBuilder||(this.pageTreeBuilder=new K(this.appId));let a=await this.pageTreeBuilder.getPagesTree(),i=this.pageTreeBuilder.findPageInPrimaryTree(e,a.primaryTree);if(!i)throw this.pageTreeBuilder.findPageInLanguageTree(e,a.languageTree)?new p("Cannot change parent of language pages directly","INVALID_OPERATION"):new p("Primary page not found in tree","PAGE_NOT_FOUND_IN_TREE");let o=i.slug,l=t.slug?t.slug:this.pageTreeBuilder.calculateSlugFromParent(r,o,a.primaryTree);this.validateSlugAvailabilityInTree(l,e,i.dynamic||!1,a),this.updateNodeSlugInTree(e,l,a.primaryTree);let c=this.pageTreeBuilder.collectNestedChildSlugs(i,o,l),d=[{id:e,oldSlug:o,newSlug:l},...c];for(let f of c)this.updateNodeSlugInTree(f.id,f.newSlug,a.primaryTree);let u=this.pageTreeBuilder.findLanguagePagesForPrimary(e,a.languageTree),h;r&&(h=this.pageTreeBuilder.findLanguagePagesForPrimary(r,a.languageTree));for(let f of u){let T=h==null?void 0:h.filter(x=>x.lang===f.lang)[0],A=(T==null?void 0:T.id)||null,I=this.pageTreeBuilder.calculateSlugFromParent(A,f.slug,a.languageTree);this.validateSlugAvailabilityInTree(I,f.id,f.dynamic||!1,a,!0),this.updateNodeSlugInTree(f.id,I,a.languageTree);let E=this.pageTreeBuilder.collectNestedChildSlugs(f,f.slug,I);for(let x of E)this.updateNodeSlugInTree(x.id,x.newSlug,a.languageTree);d.push({id:f.id,oldSlug:f.slug,newSlug:I}),d.push(...E)}return d}async batchUpdateSlugs(e,t,r,a){let i=e.map(async l=>{let c={slug:l.newSlug,lastSaved:new Date().toISOString()};if(l.id===r){let u=ns(t,["name","seo","blocks","currentEditor","buildTime","parent","pageType","dynamic","dynamicSlugCustom","links","partialBlocks","designTokens"]);Object.keys(u).forEach(h=>{u[h]===void 0&&delete u[h]}),Object.assign(c,{...u,changes:a})}let{error:d}=await m(()=>g.update(n.appPages).set(c).where(Ut(ue(n.appPages.id,l.id),ue(n.appPages.app,this.appId))));if(d)throw new p(`Failed to update page ${l.id}`,"UPDATE_PAGE_FAILED");return l.id});await Promise.all(i);let o=e.map(async l=>{await m(()=>g.update(n.appPagesOnline).set({slug:l.newSlug}).where(Ut(ue(n.appPagesOnline.id,l.id),ue(n.appPagesOnline.app,this.appId))))});await Promise.all(o)}setPageTreeBuilder(e){this.pageTreeBuilder=e}};var os=new Set(["slug","name","parent","pageType","dynamic","dynamicSlugCustom"]),Ue=class extends y{constructor(){super(...arguments);this.appId="";this.routingSlugUpdates=[]}getValidationSchema(){return v.object({id:v.string().nonempty(),blocks:v.array(v.any()).optional(),currentEditor:v.string().optional(),slug:v.string().optional(),name:v.string().optional(),seo:v.record(v.string(),v.any()).optional(),buildTime:v.boolean().optional(),parent:v.union([v.string(),v.null()]).optional(),pageType:v.string().optional(),dynamic:v.boolean().optional(),dynamicSlugCustom:v.string().optional(),needTranslations:v.boolean().optional(),description:v.string().optional(),partialIds:v.array(v.string()).optional(),linkPageIds:v.array(v.string()).optional(),designTokens:v.record(v.string(),v.record(v.string(),v.string())).optional(),tracking:v.record(v.string(),v.any()).optional(),addInRevision:v.boolean().optional()})}async execute(t){this.validateContext(),this.appId=this.context.appId,this.routingSlugUpdates=[];try{if(this.isOnlyBlocksUpdate(t))return await this.isLanguagePage(t.id)||await this.updateBlocks(t.id,t.blocks,t.linkPageIds||[],t.partialIds||[],t.designTokens||{},t==null?void 0:t.addInRevision),await this.buildResponse(t.id,t);let r=this.extractAllowedPageFields(t);t.description!==void 0&&(r.metadata=await this.buildMergedMetadata(t.id,t.description)),this.slugChangeHandler=new Gt(this.appId);let a=await this.slugChangeHandler.isSlugChanged(t.id,r.slug);return await this.slugChangeHandler.isParentChanged(t.id,r.parent)&&r.parent!==void 0?(this.pageTreeBuilder=new K(this.appId),this.slugChangeHandler.setPageTreeBuilder(this.pageTreeBuilder),await this.handleParentChangeWithHandler(t.id,r)):a&&r.slug?(this.pageTreeBuilder=new K(this.appId),this.slugChangeHandler.setPageTreeBuilder(this.pageTreeBuilder),await this.handleSlugChangeWithHandler(t.id,r)):await this.updatePageInDatabase(t.id,r,t==null?void 0:t.addInRevision),await this.syncDynamicFieldsToSecondaryPages(t.id,r),await this.buildResponse(t.id,r)}catch(r){return this.handleExecutionError(r)}}async updateBlocks(t,r,a,i,o,l){await this.updatePageInDatabase(t,{blocks:r,links:a.join("|"),partialBlocks:i.join("|"),designTokens:o},l)}validateContext(){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET")}extractAllowedPageFields(t){return is(t,["slug","name","seo","blocks","currentEditor","buildTime","parent","pageType","dynamic","dynamicSlugCustom","tracking"])}async buildMergedMetadata(t,r){var l;let{data:a,error:i}=await m(()=>g.query.appPages.findFirst({where:we(F(n.appPages.id,t),F(n.appPages.app,this.appId)),columns:{metadata:!0}}));if(i)throw new p(`Failed to fetch page metadata: ${i.message}`,"FETCH_FAILED");if(!a)throw new p("Page not found","PAGE_NOT_FOUND");return{...(l=a.metadata)!=null?l:{},description:r}}async handleSlugChangeWithHandler(t,r){let a=await this.slugChangeHandler.handleSlugChangeWithTree(t,r);this.routingSlugUpdates=a;let i=this.determineChangeTypes(r);await this.slugChangeHandler.batchUpdateSlugs(a,r,t,i)}async handleParentChangeWithHandler(t,r){let a=await this.slugChangeHandler.handleParentChangeWithTree(t,r);this.routingSlugUpdates=a;let i=this.determineChangeTypes(r);await this.slugChangeHandler.batchUpdateSlugs(a,r,t,i)}determineChangeTypes(t){let r=[],a=Bt(t);return a.includes("blocks")&&r.push("Page"),a.includes("seo")&&r.push("SEO"),r.length>0?r:["Updated"]}async addSaveEntryInRevision(t,r){var a;try{let{data:i}=await m(()=>g.select({currentEditor:n.appPagesOnline.currentEditor,createdAt:n.appPagesOnline.createdAt}).from(n.appPagesOnline).where(we(F(n.appPagesOnline.app,this.appId),F(n.appPagesOnline.id,t))).orderBy(On(n.appPagesOnline.createdAt)).limit(1)),{data:o}=await m(()=>g.select({uid:n.appPagesRevisions.uid,type:n.appPagesRevisions.type,currentEditor:n.appPagesRevisions.currentEditor,createdAt:n.appPagesRevisions.createdAt}).from(n.appPagesRevisions).where(we(F(n.appPagesRevisions.id,t),F(n.appPagesRevisions.app,this.appId))).orderBy(On(n.appPagesRevisions.createdAt)).limit(1)),l=i==null?void 0:i[0],c=o==null?void 0:o[0],d=c&&c.type==="draft"&&c.currentEditor===((a=this.context)==null?void 0:a.userId);if(l&&c&&new Date(l.createdAt).getTime()>new Date(c.createdAt).getTime()&&(d=!1),d){let{error:u}=await m(()=>g.update(n.appPagesRevisions).set({seo:r.seo,blocks:r.blocks,tracking:r.tracking,createdAt:new Date().toISOString()}).where(F(n.appPagesRevisions.uid,c==null?void 0:c.uid)));u&&console.error("Error updating draft revision entry:",{pageId:t,revisionUid:c==null?void 0:c.uid,error:u})}else{let{error:u}=await m(()=>{var h;return g.insert(n.appPagesRevisions).values({id:t,app:this.appId,blocks:r.blocks||[],type:"draft",currentEditor:(h=this.context)==null?void 0:h.userId,name:r.name||"",slug:r.slug||"",pageType:r.pageType,lang:r.lang||"",seo:r.seo,tracking:r.tracking})});u&&console.error("Error inserting draft revision entry:",{pageId:t,error:u})}}catch(i){console.error("Error adding save entry in revisions:",{pageId:t,error:i})}}async updatePageInDatabase(t,r,a){let i=this.determineChangeTypes(r),{error:o,data:l}=await m(()=>g.update(n.appPages).set({...r,changes:i,lastSaved:new Date().toISOString()}).where(we(F(n.appPages.id,t),F(n.appPages.app,this.appId))).returning({name:n.appPages.name,slug:n.appPages.slug,blocks:n.appPages.blocks,pageType:n.appPages.pageType,lang:n.appPages.lang,seo:n.appPages.seo,tracking:n.appPages.tracking,currentEditor:n.appPages.currentEditor}));if(o)throw new p("Error updating page","ERROR_UPDATING_PAGE");if(i.includes("Page")){let{error:c}=await m(()=>g.update(n.appPages).set({changes:i}).where(we(F(n.appPages.primaryPage,t),F(n.appPages.app,this.appId))));if(c)throw new p("Error updating page","ERROR_UPDATING_PAGE")}a&&(l!=null&&l[0])&&await this.addSaveEntryInRevision(t,l[0])}isOnlyBlocksUpdate(t){return Bt(t).includes("blocks")}async isLanguagePage(t){var a;let{data:r}=await m(()=>g.select({primaryPage:n.appPages.primaryPage}).from(n.appPages).where(we(F(n.appPages.id,t),F(n.appPages.app,this.appId))).limit(1));return!!((a=r==null?void 0:r[0])!=null&&a.primaryPage)}async fetchUpdatedPageData(t){let{data:r,error:a}=await m(()=>g.select({id:n.appPages.id,slug:n.appPages.slug,lang:n.appPages.lang,pageType:n.appPages.pageType,name:n.appPages.name,online:n.appPages.online,parent:n.appPages.parent,primaryPage:n.appPages.primaryPage,seo:n.appPages.seo}).from(n.appPages).where(F(n.appPages.id,t)).limit(1));if(a||!r||r.length===0)throw new p("Error getting updated page","ERROR_GETTING_PAGE");return r[0]}buildMutationTags(t,r,a){return Bt(r).some(l=>os.has(l))?this.routingSlugUpdates.length>0?ae(t,{slugUpdates:this.routingSlugUpdates}):ae(t,{slugs:a!=null&&a.slug?{new:a.slug}:void 0,primaryPageId:a==null?void 0:a.primaryPage}):Lt(t)}async buildResponse(t,r){if(this.isOnlyBlocksUpdate(r))return{success:!0};let a=await this.fetchUpdatedPageData(t);return{page:a,tags:this.buildMutationTags(t,r,a)}}async syncDynamicFieldsToSecondaryPages(t,r){let a=Bt(r);if(!(a.includes("dynamic")||a.includes("dynamicSlugCustom")))return;let o={};a.includes("dynamic")&&(o.dynamic=r.dynamic),a.includes("dynamicSlugCustom")&&(o.dynamicSlugCustom=r.dynamicSlugCustom);let{error:l}=await m(()=>g.update(n.appPages).set(o).where(we(F(n.appPages.primaryPage,t),F(n.appPages.app,this.appId))));l&&console.error("Failed to sync dynamic fields to secondary pages:",l)}handleExecutionError(t){throw t instanceof p?t:new p(`Failed to update page: ${t instanceof Error?t.message:"Unknown error"}`,"UPDATE_PAGE_FAILED")}};var Ln={label:"Page",icon:"file",moveToTrash:async(s,e)=>{var o;let{data:t}=await m(()=>g.select().from(n.appPages).where(ne(n.appPages.id,s)).limit(1)),r=t==null?void 0:t[0];if(!r)throw w("MOVE_TO_TRASH_FAILED","Page not found");let a=new me;a.setContext(e);let i=await a.execute({id:s,permanent:!1});if((i==null?void 0:i.code)==="PAGE_LOCKED")throw w("PAGE_LOCKED",`Page is currently being edited by ${i.editor||"another user"}`);return{entityType:"page",entityId:s,metadata:{name:r.name,slug:r.slug,pageType:r.pageType,dynamic:r.dynamic},deletedBy:e.userId||"",app:e.appId||"",tags:(o=i.tags)!=null?o:[]}},restore:async(s,e)=>{let t=new me;t.setContext(e),await t.restorePage(s.entityId)},deletePermanently:async(s,e)=>{let t=new me;t.setContext(e);let r=await t.execute({id:s.entityId,permanent:!0});if((r==null?void 0:r.code)==="PAGE_LOCKED")throw w("PAGE_LOCKED",`Page is currently being edited by ${r.editor||"another user"}`);return!0},hasRestoreConflict:async(s,e)=>{var i,o,l;let t=(i=s.metadata)==null?void 0:i.slug;if(!t)return!1;let r=!!((l=(o=s.metadata)==null?void 0:o.dynamic)!=null&&l),{data:a}=await m(()=>g.select({id:n.appPages.id}).from(n.appPages).where(kn(ne(n.appPages.app,e.appId),ne(n.appPages.slug,t),ne(n.appPages.dynamic,r),ss(n.appPages.deletedAt))).limit(1));return a!==null&&a.length>0},resolveRestoreConflict:async(s,e)=>{var i;let t=(i=s.metadata)==null?void 0:i.slug;if(!t)return{resolved:!0};let r=`${t}-restored-${ls(5)}`,a=new Ue;a.setContext(e);try{await a.execute({id:s.entityId,slug:r})}catch(o){throw w("RESOLVE_CONFLICT_FAILED",o)}return{resolved:!0,newSlug:r}}},Un={label:"Asset",icon:"image",moveToTrash:async(s,e)=>{let t=e.appId,r=e.userId||"",{data:a,error:i}=await m(()=>g.select().from(n.appAssets).where(kn(ne(n.appAssets.id,s),ne(n.appAssets.app,t))).limit(1));if(i||!a||a.length===0)throw w("ASSET_NOT_FOUND","Asset not found");let o=a[0],l=new Date().toISOString(),{error:c}=await m(()=>g.update(n.appAssets).set({deletedAt:l,deletedBy:r}).where(ne(n.appAssets.id,s)));if(c)throw w("TRASH_FAILED",c);return{entityType:"asset",entityId:s,name:o.name||"Unknown Asset",metadata:{name:o.name||"Unknown Asset",url:o.url,type:o.type},deletedAt:l,deletedBy:r,app:t}},restore:async(s,e)=>{let{error:t}=await m(()=>g.update(n.appAssets).set({deletedAt:null,deletedBy:null}).where(ne(n.appAssets.id,s.entityId)));if(t)throw w("RESTORE_FAILED",t)},deletePermanently:async(s,e)=>{let{error:t}=await m(()=>g.delete(n.appAssets).where(ne(n.appAssets.id,s.entityId)));if(t)throw w("DELETE_PERMANENTLY_FAILED",t);return!0},hasRestoreConflict:async(s,e)=>!1},Gn={key:"page",...Ln},Bn={key:"asset",...Un},Aa=[Gn,Bn];var Ea=async()=>({});import{isFunction as Fn}from"lodash-es";async function ba(s){return Promise.all(s.map(async e=>{var t,r,a,i,o;return{key:e.key,helpText:(t=e.helpText)!=null?t:"",icon:(r=e.icon)!=null?r:"",dynamicSegments:(a=e.dynamicSegments)!=null?a:"",dynamicSlug:(i=e.dynamicSlug)!=null?i:"",hasSlug:e.partial?!1:(o=e.hasSlug)!=null?o:!0,name:typeof e.name=="function"?await e.name():e.name,pluralName:typeof e.pluralName=="function"?await e.pluralName():e.pluralName,...e.editUrl?{editUrl:e.editUrl}:{},...e.createUrl?{createUrl:e.createUrl}:{},...Fn(e.defaultSeo)?{defaultSeo:e.defaultSeo()}:{},...Fn(e.defaultJSONLD)?{defaultJSONLD:e.defaultJSONLD()}:{}}}))}function cs(s){return s?Ot(Le,s):{...Le}}function sm(s){var a,i,o,l;let e=cs(s.ai),t={...Y.actions,...s.actions,...s.builderActions};return{debugLevel:(a=s.debugLevel)!=null?a:Y.debugLevel,globalDataProvider:(i=s.globalDataProvider)!=null?i:Y.globalDataProvider,pageTypes:Ze(Y.pageTypes,s.pageTypes,c=>c.key),collections:Ze(Y.collections,s.collections,c=>c.id),blockDataProviders:{...Y.blockDataProviders,...s.blockDataProviders},trash:Ze(Y.trash,s.trash,c=>c.key),actions:t,builderActions:t,extraPermissions:(o=s.extraPermissions)!=null?o:[],roles:(l=s.roles)!=null?l:void 0,ai:e,db:ga(s.db)}}var Ht=class extends y{getValidationSchema(){return $t.object({block:$t.any(),pageProps:$t.any().optional().default({}),lang:$t.string()})}async execute(e){var t;try{let{block:r,pageProps:a,lang:i}=e,o=r._type;if(o==="Repeater"&&((t=r==null?void 0:r.repeaterItems)!=null&&t.includes("{{#"))){let d=r.repeaterItems.replace("{{#","").replace("}}",""),u=wa(d);if(!u)return[];let h=await(u==null?void 0:u.fetch({block:r,pageProps:a,lang:i,draft:!0,inBuilder:!0}));return h!=null?h:[]}fa(o);let l=ze(o);if(!(l!=null&&l.dataProvider)||!Es(l.dataProvider))return{};let c=await l.dataProvider({block:r,pageProps:a,lang:i,draft:!0,inBuilder:!0});return c!=null?c:{}}catch(r){return this.handleError(r)}}};import{omit as bs}from"lodash-es";import{z as Ps}from"zod";var Ge=class extends y{getValidationSchema(){return Ps.object({})}async execute(){try{return Pa().map(t=>bs(t,"fetch"))}catch(e){return this.handleError(e)}}};import{eq as qn,or as ws,isNull as jn}from"drizzle-orm";import{z as Is}from"zod";var Be=class extends y{getValidationSchema(){return Is.object({}).optional().default({})}async execute(){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:e}=this.context,t=await m(()=>g.select({id:n.libraries.id,name:n.libraries.name,type:n.libraries.type,createdAt:n.libraries.createdAt}).from(n.libraries).where(qn(n.libraries.app,e)).limit(1));if(t.error)throw new p("Failed to fetch site library","DB_ERROR");let r=t.data[0]||null,a=process.env.CHAIBUILDER_CLIENT_ID;if(!a)return r?[{id:r.id,name:r.name,type:r.type,createdAt:r.createdAt,isSiteLibrary:!0}]:[];let{data:i,error:o}=await m(()=>g.select({id:n.libraries.id,name:n.libraries.name,type:n.libraries.type,createdAt:n.libraries.createdAt}).from(n.libraries).where(a?ws(qn(n.libraries.client,a),jn(n.libraries.client)):jn(n.libraries.client)));if(o)throw new p("Failed to fetch libraries","DB_ERROR");let l=(r==null?void 0:r.id)||null;return i.map(c=>({id:c.id,name:c.name,type:c.type,createdAt:c.createdAt,isSiteLibrary:l?c.id===l:!1}))}};import{eq as zn}from"drizzle-orm";import{map as Wn,uniq as xs}from"lodash-es";import{z as Cs}from"zod";var Vt=class extends y{getValidationSchema(){return Cs.object({})}async execute(){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{data:e,error:t}=await m(()=>g.select({id:n.libraries.id}).from(n.libraries).where(zn(n.libraries.app,this.context.appId)).limit(1));if(t)throw new p("Failed to fetch site library","GET_SITE_LIBRARY_FAILED",500,t);if(!e||e.length===0)return[];let r=e[0],{data:a,error:i}=await m(()=>g.select({group:n.libraryItems.group}).from(n.libraryItems).where(zn(n.libraryItems.library,r.id)));if(i)throw new p("Failed to fetch library groups","GET_LIBRARY_GROUPS_FAILED",500,i);let o=Wn(a,"group").filter(l=>l!=null);return Wn(xs(o),l=>({id:l,name:l}))}};import{eq as Rs}from"drizzle-orm";import{z as Yn}from"zod";var qt=class extends y{getValidationSchema(){return Yn.object({id:Yn.string().min(1)})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{id:t}=e,{error:r}=await m(()=>g.delete(n.libraryItems).where(Rs(n.libraryItems.id,t)));if(r)throw new p("Failed to delete library item","DELETE_LIBRARY_ITEM_FAILED",500,r);return{success:!0}}};import{eq as Kn}from"drizzle-orm";import{set as Qn}from"lodash-es";import{z as Xn}from"zod";var jt=class extends y{getValidationSchema(){return Xn.object({id:Xn.string().min(1)})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,{id:r}=e,{data:a,error:i}=await m(()=>g.select({id:n.libraryItems.id,name:n.libraryItems.name,blocks:n.libraryItems.blocks,library:n.libraryItems.library,description:n.libraryItems.description,group:n.libraryItems.group,user:n.libraryItems.user,preview:n.libraryItems.preview,createdAt:n.libraryItems.createdAt,html:n.libraryItems.html,libraryApp:n.libraries.app,libraryName:n.libraries.name}).from(n.libraryItems).leftJoin(n.libraries,Kn(n.libraryItems.library,n.libraries.id)).where(Kn(n.libraryItems.id,r)));if(i)throw new p("Failed to fetch library item","GET_LIBRARY_ITEM_FAILED",500,i);if(!a||a.length===0)throw new p("Library item not found","GET_LIBRARY_ITEM_FAILED");let o=a[0],l=Array.isArray(o.blocks)?[...o.blocks]:o.blocks;return o.libraryApp===t?Qn(l,"0._libBlockId",o.id):Qn(l,"0._libBlockId",void 0),{id:o.id,name:o.name,blocks:l,description:o.description,group:o.group,user:o.user,preview:o.preview,createdAt:o.createdAt,html:o.html}}};import{eq as Ss}from"drizzle-orm";import{z as Jn}from"zod";var zt=class extends y{getValidationSchema(){return Jn.object({id:Jn.string().min(1)})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{id:t}=e,{data:r,error:a}=await m(()=>g.select({id:n.libraryItems.id,name:n.libraryItems.name,library:n.libraryItems.library,group:n.libraryItems.group,description:n.libraryItems.description,preview:n.libraryItems.preview}).from(n.libraryItems).where(Ss(n.libraryItems.library,t)));if(a)throw new p("Failed to fetch library items","GET_LIBRARY_ITEMS_FAILED",500,a);return r||[]}};import{eq as Zn}from"drizzle-orm";import{set as _s}from"lodash-es";import{randomUUID as Ds}from"crypto";import{z as oe}from"zod";var Wt=class extends y{getValidationSchema(){return oe.object({name:oe.string().min(1),group:oe.string().min(1),blocks:oe.array(oe.any()),description:oe.string().optional(),previewImage:oe.string().optional(),id:oe.string().optional(),previewImageUrl:oe.string().optional()})}async execute(e){var A;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context,{name:a,group:i,blocks:o,description:l,previewImage:c,previewImageUrl:d,id:u}=e,{data:h,error:f}=await m(()=>g.query.libraries.findFirst({where:Zn(n.libraries.app,t),columns:{id:!0}}));if(f)throw new p("Failed to fetch site library","GET_SITE_LIBRARY_FAILED",500,f);if(!h)throw new p("Library not found for this app","GET_SITE_LIBRARY_FAILED");let T=d;if(c){let{getChaiAction:I}=await import("./actions-registery-SEJTZE5Q.js"),E=I("UPLOAD_TO_STORAGE");E==null||E.setContext(this.context);let x=`library-item-${Date.now()}.webp`,C=`${t}/library-items`,R=await(E==null?void 0:E.execute({file:c,fileName:x,contentType:"image/webp",folder:C}));if(R!=null&&R.error)throw new p("Failed to upload preview image","UPLOAD_PREVIEW_FAILED",500,R.error);T=((A=R==null?void 0:R.data)==null?void 0:A.url)||d}if(u){let I={name:a,blocks:o,library:h.id,description:l!=null?l:null,group:i,user:r!=null?r:null,createdBy:r!=null?r:null};T&&(I.preview=T);let{data:E,error:x}=await m(()=>g.update(n.libraryItems).set(I).where(Zn(n.libraryItems.id,u)).returning());if(x||!E||E.length===0)throw new p("Failed to update library item","UPDATE_LIBRARY_ITEM_FAILED",500,x);return E[0]}else{let I=Ds(),E=[...o];_s(E,"0._libBlockId",I);let x={id:I,name:a,blocks:E,library:h.id,description:l!=null?l:null,group:i,user:r!=null?r:null,createdBy:r!=null?r:null,preview:T!=null?T:null},{data:C,error:R}=await m(()=>g.insert(n.libraryItems).values(x).returning());if(R||!C||C.length===0)throw new p("Failed to create library item","CREATE_LIBRARY_ITEM_FAILED",500,R);return C[0]}}};import{and as vs,eq as ei}from"drizzle-orm";import{z as ti}from"zod";var Yt=class extends y{getValidationSchema(){return ti.object({pageId:ti.string().min(1)})}async execute({pageId:e}){let{userId:t,appId:r}=this.context;return await g.update(n.appPages).set({currentEditor:t}).where(vs(ei(n.appPages.id,e),ei(n.appPages.app,r))),{ok:!0}}};import{and as xa,eq as se,isNull as ri}from"drizzle-orm";import{isEmpty as Ca,omit as Ns}from"lodash-es";import{z as L}from"zod";var Kt=class extends y{getValidationSchema(){return L.object({name:L.string().min(1),slug:L.string(),pageType:L.string(),parent:L.string().nullable().optional(),lang:L.string().optional(),primaryPage:L.string().nullable().optional(),dynamic:L.boolean().optional(),hasSlug:L.boolean().optional(),template:L.string().optional(),seo:L.record(L.string(),L.any()).optional(),jsonLD:L.record(L.string(),L.any()).optional(),dynamicSlugCustom:L.string().optional(),blocks:L.array(L.any()).optional(),description:L.string().optional()}).refine(e=>e.lang&&e.lang!==""?!!e.primaryPage:!0,{message:"primaryPage is required when lang option is not empty",path:["primaryPage"]})}async execute(e){var f,T,A,I,E,x,C,R,S,D;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context;if(((f=e.hasSlug)!=null?f:e.pageType!=="global")&&e.slug&&await this.doesSlugExist(e.slug,e.pageType))throw new p("Slug already exists","SLUG_ALREADY_USED");let i=(T=e.blocks)!=null?T:[];e.template&&(i=await this.getTemplateBlocks(e.template,t));let o=(A=e.dynamic)!=null?A:!1,l=(I=e.dynamicSlugCustom)!=null?I:"";if(e.primaryPage){let{data:k}=await m(()=>g.query.appPages.findFirst({where:xa(se(n.appPages.id,e.primaryPage),se(n.appPages.app,t)),columns:{dynamic:!0,dynamicSlugCustom:!0}}));k&&(o=(E=k.dynamic)!=null?E:!1,l=(x=k.dynamicSlugCustom)!=null?x:"")}let c={app:t,name:e.name,slug:e.slug,pageType:e.pageType,parent:(C=e.parent)!=null?C:null,lang:e.primaryPage&&(R=e.lang)!=null?R:"",primaryPage:(S=e.primaryPage)!=null?S:null,dynamic:o,dynamicSlugCustom:l,blocks:i,seo:(D=e.seo)!=null?D:{title:e.name,jsonLD:"",noIndex:!1,ogImage:"",ogTitle:"",noFollow:"",description:"",searchTitle:"",cononicalUrl:"",ogDescription:"",searchDescription:""},jsonld:{},metadata:Ca(e.description)?{}:{description:e.description},online:!1,currentEditor:null,changes:null,libRefId:null,lastSaved:null,createdBy:r},{data:d,error:u}=await m(()=>g.insert(n.appPages).values(c).returning());if(u)throw new p("Failed to create page","ERROR_CREATING_PAGE",500,u);if(!d||d.length===0)throw new p("Failed to create page","INSERT_FAILED");let h=d[0];return{page:Ns(h.primaryPage?{...h,id:h.primaryPage}:h,["primaryPage"]),tags:ae(h.id,{slugs:h.slug?{new:h.slug}:void 0,primaryPageId:h.primaryPage})}}async doesSlugExist(e,t){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:r}=this.context,{data:a,error:i}=await m(()=>g.query.appPages.findFirst({where:xa(se(n.appPages.slug,e),se(n.appPages.pageType,t),se(n.appPages.app,r),ri(n.appPages.deletedAt)),columns:{id:!0}}));if(i)throw new p(`${i.message}`,"SLUG_CHECK_FAILED");return!!a}async getTemplateBlocks(e,t){let{data:r,error:a}=await m(()=>g.select({template:n.libraryTemplates,library:{id:n.libraries.id,app:n.libraries.app,name:n.libraries.name}}).from(n.libraryTemplates).leftJoin(n.libraries,se(n.libraryTemplates.library,n.libraries.id)).where(xa(se(n.libraryTemplates.id,e),ri(n.libraryTemplates.deletedAt))).limit(1).then(h=>h[0]));if(a)throw new p(`Failed to fetch template: ${a.message||"Unknown database error"}`,"ERROR_GETTING_TEMPLATE_BLOCKS",500,a);if(!r||!r.template||!r.library)throw new p(`Template not found with ID: ${e}`,"TEMPLATE_NOT_FOUND");let i=r.template,o=r.library,{data:l,error:c}=await m(()=>g.query.appPages.findFirst({where:se(n.appPages.id,i.pageId),columns:{blocks:!0}}));if(c)throw new p(`Failed to fetch template blocks: ${c.message||"Unknown database error"}`,"ERROR_GETTING_TEMPLATE_BLOCKS",500,c);if(!l)throw new p(`Template page not found with ID: ${i.pageId}`,"TEMPLATE_PAGE_NOT_FOUND");let d=l.blocks||[];if(d=d.map(h=>h._type==="GlobalBlock"&&!Ca(h.globalBlock)?{...h,_type:"PartialBlock",partialBlockId:h.globalBlock}:h),!(o.app===t)){let h=o.name||"",f=d.filter(A=>A._type==="PartialBlock"&&!Ca(A.partialBlockId)),T=await Promise.all(f.map(({partialBlockId:A})=>this.copyPartialBlockFromTemplate(A,h,t)));d=d.map(A=>{let I=T.find(E=>(E==null?void 0:E.libRefId)===A.partialBlockId);return I&&(A._name=`${h} - ${A._name}`,A.partialBlockId=I.id),A})}return d}async copyPartialBlockFromTemplate(e,t,r){var u;let{data:a,error:i}=await m(()=>g.query.appPages.findFirst({where:se(n.appPages.id,e)}));if(i||!a)return console.error("Failed to fetch partial block:",i),null;let o={...a,id:void 0,app:r,libRefId:e,name:`${t} - ${a.name}`,createdAt:void 0,online:!1,currentEditor:null,changes:null,lastSaved:null,createdBy:(u=this.context)==null?void 0:u.userId},{data:l,error:c}=await m(()=>g.insert(n.appPages).values(o).returning());if(c||!l||l.length===0)return console.error("Failed to create partial block copy:",c),null;let d=l[0];return{id:d.id,libRefId:d.libRefId||e}}};import{and as ai,eq as Qt,isNull as ni}from"drizzle-orm";import{z as Xt}from"zod";var Jt=class extends y{getValidationSchema(){return Xt.object({pageId:Xt.string().nonempty(),name:Xt.string().nonempty(),slug:Xt.string().optional()})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context;if(e.slug&&await this.doesSlugExist(e.slug))throw new p("Slug already exists","SLUG_EXISTS");let{data:r,error:a}=await m(()=>g.query.appPages.findFirst({where:ai(Qt(n.appPages.id,e.pageId),Qt(n.appPages.app,t),ni(n.appPages.deletedAt))}));if(a)throw a;if(!r)throw new p("Page not found","PAGE_NOT_FOUND");let i={...r,id:void 0,createdAt:void 0,name:e.name,currentEditor:null,changes:null,online:!1,libRefId:null,lastSaved:null,createdBy:this.context.userId,...e.slug&&{slug:e.slug}},[o]=await g.insert(n.appPages).values(i).returning();if(!o)throw new p("Failed to create duplicate page","INSERT_FAILED");return{id:o.id,tags:ae(o.id,{slugs:e.slug?{new:e.slug}:void 0})}}async doesSlugExist(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,{data:r,error:a}=await m(()=>g.query.appPages.findFirst({where:ai(Qt(n.appPages.slug,e),Qt(n.appPages.app,t),ni(n.appPages.deletedAt)),columns:{id:!0}}));if(a)throw new p(`${a.message}`,"SLUG_CHECK_FAILED");return!!r}};import{z as Zt}from"zod";var Fe=class extends y{getValidationSchema(){return Zt.object({lang:Zt.string(),pageType:Zt.string().optional(),pageProps:Zt.any().optional().default({})})}async execute(e){try{let{lang:t,pageType:r,pageProps:a={}}=e;if(!r)return{};let i=he(r),o=i?ie(i):void 0;return o?o.dataProvider?await o.dataProvider({lang:t,draft:!0,inBuilder:!0,pageProps:a}):{}:{}}catch(t){return this.handleError(t)}}};import{and as Ra,eq as er,isNotNull as ii,isNull as Os}from"drizzle-orm";import{z as ks}from"zod";var tr=class extends y{constructor(){super(...arguments);this.appId=""}getValidationSchema(){return ks.object({})}async execute(){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");this.appId=this.context.appId;try{return await this.getChanges()}catch(t){if(t instanceof p)throw t;let r=t instanceof Error?t.message:"Failed to get changes";throw new p(r,"GET_CHANGES_ERROR")}}async getChanges(){var h;let{data:t,error:r}=await m(()=>g.select({id:n.appPages.id,slug:n.appPages.slug,name:n.appPages.name,pageType:n.appPages.pageType,lang:n.appPages.lang,changes:n.appPages.changes,primaryPage:n.appPages.primaryPage,online:n.appPages.online,currentEditor:n.appPages.currentEditor}).from(n.appPages).where(Ra(er(n.appPages.app,this.appId),ii(n.appPages.changes))));if(r)throw new p("Error getting changed pages","ERROR_GETTING_CHANGES");let{data:a,error:i}=await m(()=>g.select({id:n.appPages.id,slug:n.appPages.slug,name:n.appPages.name,pageType:n.appPages.pageType,lang:n.appPages.lang,changes:n.appPages.changes,primaryPage:n.appPages.primaryPage,online:n.appPages.online}).from(n.appPages).where(Ra(er(n.appPages.app,this.appId),Os(n.appPages.currentEditor),er(n.appPages.online,!1))));if(i)throw new p("Error getting offline pages","ERROR_GETTING_OFFLINE_PAGES");let o=(a||[]).map(f=>({...f,changes:["Take Online"]})),c=[...(t||[]).filter(f=>!o.some(T=>T.id===f.id)).map(f=>({...f,changes:f.changes})),...o],{data:d,error:u}=await m(()=>g.select({changes:n.apps.changes}).from(n.apps).where(Ra(er(n.apps.id,this.appId),ii(n.apps.changes))));if(!u&&d&&d.length>0){let f=(h=d[0].changes)!=null?h:[];f.includes("THEME")&&c.push({id:"THEME",slug:"",name:"Theme",pageType:"theme",lang:"",changes:["Updated"],primaryPage:null,online:!0}),f.includes("DESIGN_TOKENS")&&c.push({id:"DESIGN_TOKENS",slug:"",name:"Design Tokens",pageType:"design_tokens",lang:"",changes:["Updated"],primaryPage:null,online:!0})}return c}};import{eq as Sa}from"drizzle-orm";import{z as fe}from"zod";var rr=class extends y{getValidationSchema(){return fe.object({versions:fe.object({version1:fe.object({type:fe.enum(["draft","revision","live"]),id:fe.string()}),version2:fe.object({type:fe.enum(["draft","revision","live"]),id:fe.string()})})})}async execute(e){this.validateContext();let t=await this.getBlocksForVersion(e.versions.version1.type,e.versions.version1.id),r=await this.getBlocksForVersion(e.versions.version2.type,e.versions.version2.id);return{version1:{blocks:t.blocks,seo:t.seo,tracking:t.tracking},version2:{blocks:r.blocks,seo:r.seo,tracking:r.tracking}}}async getBlocksForVersion(e,t){let r,a;switch(e){case"draft":({data:r,error:a}=await m(()=>g.query.appPages.findFirst({where:Sa(n.appPages.id,t),columns:{blocks:!0,seo:!0,tracking:!0}})));break;case"live":({data:r,error:a}=await m(()=>g.query.appPagesOnline.findFirst({where:Sa(n.appPagesOnline.id,t),columns:{blocks:!0,seo:!0,tracking:!0}})));break;case"revision":({data:r,error:a}=await m(()=>g.query.appPagesRevisions.findFirst({where:Sa(n.appPagesRevisions.uid,t),columns:{blocks:!0,seo:!0,tracking:!0}})));break;default:throw new p(`Invalid version type: ${e}`,"INVALID_VERSION_TYPE")}if(a)throw new p(`Failed to fetch blocks for ${e} version: ${a.message}`,"FETCH_BLOCKS_ERROR");if(!r)throw new p(`No data found for ${e} version with id: ${t}`,"VERSION_NOT_FOUND");return{blocks:r.blocks||[],seo:r.seo||{},tracking:r.tracking||{}}}validateContext(){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET")}};import{and as oi,eq as ar,isNull as si}from"drizzle-orm";import{z as li}from"zod";var Me=class extends y{getValidationSchema(){return li.object({id:li.string()})}async execute(e){var u,h,f,T,A,I;if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let{appId:t}=this.context,{id:r}=e,a=n.appPages,{data:i,error:o}=await m(()=>g.select({id:a.id,name:a.name,slug:a.slug,lang:a.lang,primaryPage:a.primaryPage,seo:a.seo,currentEditor:a.currentEditor,pageType:a.pageType,lastSaved:a.lastSaved,dynamic:a.dynamic,parent:a.parent,blocks:a.blocks,tracking:a.tracking,globalJsonLds:a.globalJsonLds}).from(a).where(oi(ar(a.app,t),ar(a.id,r),si(a.deletedAt))).limit(1));if(o)throw w("PAGE_NOT_FOUND",o);if(!i||i.length===0)throw w("PAGE_NOT_FOUND",new Error("Page not found"));let l=i[0],c=(u=l.primaryPage)!=null?u:l.id,d=(h=l.blocks)!=null?h:[];if(c!==l.id){let{data:E,error:x}=await m(()=>g.select({blocks:a.blocks}).from(a).where(oi(ar(a.app,t),ar(a.id,c),si(a.deletedAt))).limit(1));if(x)throw w("BLOCKS_NOT_FOUND",x);d=(T=(f=E==null?void 0:E[0])==null?void 0:f.blocks)!=null?T:[]}return{...l,blocks:d,id:r,languagePageId:l.id,tracking:(A=l.tracking)!=null?A:{},globalJsonLds:(I=l.globalJsonLds)!=null?I:[]}}};import{z as tt}from"zod";var nr=class extends y{getValidationSchema(){return tt.object({pageType:tt.string(),lang:tt.string(),query:tt.string().optional(),slug:tt.string().optional()})}async execute(e){try{let{pageType:t}=e,r=he(t),a=r?ie(r):void 0;return a?a.getDynamicPages?await a.getDynamicPages({query:e.query,slug:e.slug,lang:e.lang}):[]:[]}catch(t){return this.handleError(t)}}};import{and as Ls,eq as _a,isNull as Us,or as Gs}from"drizzle-orm";import{omit as Bs}from"lodash-es";import{z as ci}from"zod";var $e=class extends y{getValidationSchema(){return ci.object({id:ci.string()})}async execute(e){if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let{appId:t}=this.context,{id:r}=e,{data:a,error:i}=await m(()=>g.select({id:n.appPages.id,name:n.appPages.name,slug:n.appPages.slug,lang:n.appPages.lang,primaryPage:n.appPages.primaryPage,pageType:n.appPages.pageType,seo:n.appPages.seo,currentEditor:n.appPages.currentEditor,online:n.appPages.online,parent:n.appPages.parent,metadata:n.appPages.metadata,dynamic:n.appPages.dynamic,dynamicSlugCustom:n.appPages.dynamicSlugCustom,changes:n.appPages.changes,tracking:n.appPages.tracking,globalJsonLds:n.appPages.globalJsonLds}).from(n.appPages).where(Ls(_a(n.appPages.app,t),Gs(_a(n.appPages.primaryPage,r),_a(n.appPages.id,r)),Us(n.appPages.deletedAt))));if(i)throw w("LANGUAGE_PAGES_ERROR",i);return a.map(o=>Bs(o,["app"]))}};import{and as Fs,asc as Ms,eq as ir,isNull as pi,ne as $s,or as Hs}from"drizzle-orm";import{z as di}from"zod";var or=class extends y{getValidationSchema(){return di.object({lang:di.string().optional()})}async execute(e){var l;if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let{appId:t}=this.context,r=(l=e==null?void 0:e.lang)!=null?l:"",a=n.appPages,{data:i,error:o}=await m(()=>g.select({id:a.id,name:a.name,slug:a.slug}).from(a).where(Fs(ir(a.app,t),pi(a.deletedAt),pi(a.primaryPage),ir(a.dynamic,!1),$s(a.slug,""),Hs(ir(a.lang,""),ir(a.lang,r)))).orderBy(Ms(a.name)));if(o)throw w("ERROR_GETTING_MENU_PAGES",o);return i!=null?i:[]}};import{z as rt}from"zod";import{z as gi}from"zod";var He=class extends y{getValidationSchema(){return gi.object({lang:gi.string()})}async execute(e){try{let{lang:t}=e;return await Ia({lang:t,draft:!0,inBuilder:!0})}catch(t){return this.handleError(t)}}};var sr=class extends y{getValidationSchema(){return rt.object({id:rt.string(),lang:rt.string(),pageType:rt.string().optional(),pageProps:rt.any().optional().default({})})}async execute(e){let{id:t,lang:r,pageType:a,pageProps:i={}}=e,o=new Me,l=new Fe,c=new $e,d=new He;this.context&&(o.setContext(this.context),l.setContext(this.context),c.setContext(this.context),d.setContext(this.context));let[u,h,f,T]=await Promise.all([o.execute({id:t}),l.execute({lang:r,pageType:a,pageProps:i}),c.execute({id:t}),d.execute({lang:r})]);return{draftPage:u,builderPageData:h,languagePages:f,siteGlobalData:T}}};import{z as Vs}from"zod";var Ve=class extends y{getValidationSchema(){return Vs.object({})}async execute(){try{return ba(Mt())}catch(e){return this.handleError(e)}}};import{and as mi,eq as ui,inArray as qs,isNull as hi}from"drizzle-orm";import{isEmpty as js}from"lodash-es";import{z as fi}from"zod";var qe=class extends y{getValidationSchema(){return fi.object({lang:fi.string().optional()})}async execute(e){var h;if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let{appId:t}=this.context,a=(h=(e!=null?e:{lang:""}).lang)!=null?h:"",{data:i,error:o}=await m(()=>g.select({id:n.appPages.id,name:n.appPages.name,slug:n.appPages.slug,pageType:n.appPages.pageType,currentEditor:n.appPages.currentEditor,parent:n.appPages.parent,online:n.appPages.online,lastSaved:n.appPages.lastSaved,createdAt:n.appPages.createdAt,dynamic:n.appPages.dynamic,dynamicSlugCustom:n.appPages.dynamicSlugCustom,primaryPage:n.appPages.primaryPage,changes:n.appPages.changes,lang:n.appPages.lang,designTokens:n.appPages.designTokens,links:n.appPages.links,partialBlocks:n.appPages.partialBlocks,metadata:n.appPages.metadata}).from(n.appPages).where(mi(ui(n.appPages.app,t),ui(n.appPages.lang,a),hi(n.appPages.deletedAt))));if(o)throw w("ERROR_GETTING_WEBSITE_PAGES",o);if(!i||i.length===0)return[];let l=i.filter(f=>!js(f.slug)).map(f=>f.id),{data:c,error:d}=await m(()=>g.select({pageId:n.libraryTemplates.pageId}).from(n.libraryTemplates).where(mi(qs(n.libraryTemplates.pageId,l),hi(n.libraryTemplates.deletedAt))));if(d)throw w("ERROR_GETTING_TEMPLATE_INFO",d);let u=new Set((c||[]).map(f=>f.pageId));return i.map(f=>{var T,A;return{...f,pageType:(T=f.pageType)!=null?T:"page",isTemplate:u.has(f.id),changes:f.changes,lang:f.lang,designTokens:f.designTokens,links:f.links,partialBlocks:f.partialBlocks,metadata:(A=f.metadata)!=null?A:null}})}};import{and as zs,eq as Da}from"drizzle-orm";import{z as yi}from"zod";var lr=class extends y{getValidationSchema(){return yi.object({pageId:yi.string().min(1)})}async execute({pageId:e}){let{userId:t,appId:r}=this.context;return t?(await g.update(n.appPages).set({currentEditor:null}).where(zs(Da(n.appPages.id,e),Da(n.appPages.app,r),Da(n.appPages.currentEditor,t))),{ok:!0}):{ok:!1}}};import{z as va}from"zod";var cr=class extends y{getValidationSchema(){return va.object({pageType:va.string(),query:va.string()})}async execute(e){try{let{pageType:t,query:r}=e,a=he(t),i=a?ie(a):void 0;if(!i)return{error:"Page type not found"};if(i.search){let o=await i.search(r);return o instanceof Error?{error:o.message}:o}return[]}catch(t){return this.handleError(t)}}};import{and as Na,eq as Oa,ilike as Ti,isNull as Ws,or as Ys}from"drizzle-orm";import{z as ka}from"zod";var pr=class extends y{getValidationSchema(){return ka.object({pageType:ka.string().min(1),query:ka.string().optional()})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,{pageType:r,query:a=""}=e,i=this.isUUID(a),o=[Oa(n.appPages.app,t),Oa(n.appPages.pageType,r),Ws(n.appPages.deletedAt)],l;a?i?l=Na(...o,Oa(n.appPages.id,a)):l=Na(...o,Ys(Ti(n.appPages.slug,`%${a}%`),Ti(n.appPages.name,`%${a}%`))):l=Na(...o);let{data:c,error:d}=await m(()=>g.select({id:n.appPages.id,slug:n.appPages.slug,name:n.appPages.name,lang:n.appPages.lang,primaryPage:n.appPages.primaryPage}).from(n.appPages).where(l));if(d)throw new p("Failed to search pages","ERROR_SEARCHING_PAGES",500,d);return c||[]}isUUID(e){return e.length===36}};import{and as La,eq as ee}from"drizzle-orm";import{z as Ai}from"zod";var dr=class extends y{constructor(){super(...arguments);this.appId=""}getValidationSchema(){return Ai.object({id:Ai.string().min(1,"Page ID is required")})}async execute(t){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");this.appId=this.context.appId;try{return await this.takeOffline(t.id)}catch(r){if(r instanceof p)throw r;let a=r instanceof Error?r.message:"Failed to take page offline";throw new p(a,"TAKE_OFFLINE_ERROR")}}async takeOffline(t){let r=await this.getPageType(t),{error:a}=await m(()=>g.update(n.appPages).set({online:!1}).where(La(ee(n.appPages.id,t),ee(n.appPages.app,this.appId))));if(a)throw new p("Error taking page offline","ERROR_TAKING_PAGE_OFFLINE");if(await this.deleteOnlinePage(t),r==="language"){let l=await this.getPrimaryPage(t);return{tags:kt([l]),paths:[]}}if(r==="partial"){let l=await this.getPartialBlockUsage(t);return{tags:kt(l),paths:[]}}let{data:i,error:o}=await m(()=>g.select({id:n.appPages.id,slug:n.appPages.slug,lang:n.appPages.lang,pageType:n.appPages.pageType,name:n.appPages.name,online:n.appPages.online,seo:n.appPages.seo}).from(n.appPages).where(ee(n.appPages.id,t)));if(o||!i||i.length===0)throw new p("Error getting page after taking offline","ERROR_TAKING_PAGE_OFFLINE");return{tags:[...kt([t]),Z(i[0].slug)],paths:[i[0].slug],page:i[0]}}async deleteOnlinePage(t){let{error:r}=await m(()=>g.delete(n.appPagesOnline).where(ee(n.appPagesOnline.id,t)));if(r)throw new p("Error deleting page from online pages table","ERROR_DELETING_PAGE_FROM_ONLINE_PAGES_TABLE");let{error:a}=await m(()=>g.delete(n.appPagesOnline).where(ee(n.appPagesOnline.primaryPage,t)));if(a)throw new p("Error deleting page from online pages table","ERROR_DELETING_PAGE_FROM_ONLINE_PAGES_TABLE")}async getPageType(t){let{data:r,error:a}=await m(()=>g.select({primaryPage:n.appPages.primaryPage,pageType:n.appPages.pageType,slug:n.appPages.slug}).from(n.appPages).where(La(ee(n.appPages.id,t),ee(n.appPages.app,this.appId))));if(a||!r||r.length===0)throw new p("Page not found","PAGE_NOT_FOUND");let i=r[0];return(l=>!l||l.trim()==="")(i.slug)?"partial":i.primaryPage?"language":"primary"}async getPrimaryPage(t){var o;let{data:r,error:a}=await m(()=>g.select({id:n.appPages.id,primaryPage:n.appPages.primaryPage}).from(n.appPages).where(La(ee(n.appPages.id,t),ee(n.appPages.app,this.appId))));if(a||!r||r.length===0)throw new p("Error getting primary page","ERROR_GETTING_PRIMARY_PAGE");let i=r[0];return(o=i.primaryPage)!=null?o:i.id}async getPartialBlockUsage(t){let{data:r,error:a}=await m(()=>g.select({id:n.appPages.id,partialBlocks:n.appPages.partialBlocks}).from(n.appPages).where(ee(n.appPages.app,this.appId)));return a||!r?[]:r.filter(i=>(i.partialBlocks||"").split("|").includes(t)).map(i=>i.id)}};import{and as Ei,eq as gr}from"drizzle-orm";import{z as at}from"zod";var mr=class extends y{getValidationSchema(){return at.object({id:at.string().nonempty(),metadata:at.record(at.string(),at.any())})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,{data:r,error:a}=await m(()=>g.query.appPages.findFirst({where:Ei(gr(n.appPages.id,e.id),gr(n.appPages.app,t)),columns:{id:!0}}));if(a)throw new p(`Failed to fetch page: ${a.message}`,"FETCH_FAILED");if(!r)throw new p("Page not found","PAGE_NOT_FOUND");let{error:i}=await m(()=>g.update(n.appPages).set({metadata:e.metadata}).where(Ei(gr(n.appPages.id,e.id),gr(n.appPages.app,t))));if(i)throw console.error(i),new p("Failed to update page metadata","UPDATE_FAILED");return{success:!0,tags:Lt(e.id)}}};import{and as Ks,eq as bi}from"drizzle-orm";import{z as Pi}from"zod";var ur=class extends y{getValidationSchema(){return Pi.object({revisionId:Pi.string().nonempty("Revision ID is required")})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,{error:r}=await m(()=>g.delete(n.appPagesRevisions).where(Ks(bi(n.appPagesRevisions.uid,e.revisionId),bi(n.appPagesRevisions.app,t))));if(r)throw new p("Failed to delete page revision","DELETE_REVISION_ERROR");return{success:!0}}};import{and as wi,eq as hr}from"drizzle-orm";import{orderBy as Qs}from"lodash-es";import{z as Ii}from"zod";var fr=class extends y{getValidationSchema(){return Ii.object({pageId:Ii.string().min(1,"Page ID is required")})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");try{return await this.getRevisions(e.pageId)}catch(t){if(t instanceof p)throw t;let r=t instanceof Error?t.message:"Failed to get page revisions";throw new p(r,"GET_PAGE_REVISIONS_ERROR")}}async getRevisions(e){let{data:t,error:r}=await m(()=>g.select({currentEditor:n.appPagesOnline.currentEditor,createdAt:n.appPagesOnline.createdAt}).from(n.appPagesOnline).where(wi(hr(n.appPagesOnline.app,this.context.appId),hr(n.appPagesOnline.id,e)))),{data:a,error:i}=await m(()=>g.select({uid:n.appPagesRevisions.uid,currentEditor:n.appPagesRevisions.currentEditor,createdAt:n.appPagesRevisions.createdAt,type:n.appPagesRevisions.type}).from(n.appPagesRevisions).where(wi(hr(n.appPagesRevisions.app,this.context.appId),hr(n.appPagesRevisions.id,e))));if(r){let d=r instanceof Error?`Error getting current page for revisions: ${r.message}`:"Error getting current page for revisions";throw new p(d,"ERROR_GETTING_CURRENT_PAGE_FOR_REVISIONS")}if(i){let d=i instanceof Error?`Error getting page revisions: ${i.message}`:"Error getting page revisions";throw new p(d,"ERROR_GETTING_PAGE_REVISIONS")}let o=t==null?void 0:t[0],c=[...o?[{...o,type:"published",uid:"current"}]:[],...a!=null?a:[]];return Qs(c,["createdAt"],["desc"])}};import{and as yr,eq as xe,inArray as Xs}from"drizzle-orm";import{get as Tr,has as Js,isEmpty as Zs}from"lodash-es";import{z as Ua}from"zod";var Ar=class extends y{getValidationSchema(){return Ua.object({id:Ua.string().nonempty(),type:Ua.enum(["draft","live","revision"])})}async execute(e){var i;if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let t,r;switch(e.type){case"draft":({data:t,error:r}=await m(()=>{var o;return g.query.appPages.findFirst({where:yr(xe(n.appPages.id,e.id),xe(n.appPages.lang,(o=e.lang)!=null?o:""))})}));break;case"live":({data:t,error:r}=await m(()=>{var o;return g.query.appPagesOnline.findFirst({where:yr(xe(n.appPagesOnline.id,e.id),xe(n.appPagesOnline.lang,(o=e.lang)!=null?o:""))})}));break;case"revision":({data:t,error:r}=await m(()=>{var o;return g.query.appPagesRevisions.findFirst({where:yr(xe(n.appPagesRevisions.uid,e.id),xe(n.appPagesRevisions.lang,(o=e.lang)!=null?o:""))})}));break}if(r||!t)throw w("NOT_FOUND",r||new Error("Page not found"));let a=(i=t==null?void 0:t.blocks)!=null?i:[];return a=await this.getMergedBlocks(a,e.type==="draft",this.context.appId),{...t,blocks:a}}async getMergedBlocks(e,t,r){var u;let a=t?n.appPages:n.appPagesOnline,i=e.filter(({_type:h})=>h==="GlobalBlock"||h==="PartialBlock");if(i.length===0)return e;let o=i.map(h=>Tr(h,"partialBlockId",Tr(h,"globalBlock",""))).filter(h=>h!=="");if(o.length===0)return e;let{data:l,error:c}=await m(()=>g.select({id:a.id,blocks:a.blocks}).from(a).where(yr(xe(a.app,r),Xs(a.id,o))));if(c)throw w("PARTIAL_BLOCKS_FETCH_ERROR",c);let d=new Map;l&&l.forEach(h=>{var f;d.set(h.id,(f=h.blocks)!=null?f:[])});for(let h=0;h<i.length;h++){let f=i[h];if(!f)continue;let T=Tr(f,"partialBlockId",Tr(f,"globalBlock",""));if(T==="")continue;let A=(u=d.get(T))!=null?u:[];A.length>0&&(A=A.map(E=>(Zs(E._parent)&&(E._parent=f._parent),Js(f,"_show")&&(E._show=f._show),E)));let I=e.indexOf(f);I!==-1&&e.splice(I,1,...A)}return e}};import{and as Ga,eq as Ce}from"drizzle-orm";import{pick as el}from"lodash-es";import{z as Er}from"zod";var br=class extends y{getValidationSchema(){return Er.object({revisionId:Er.string().nonempty(),discardCurrent:Er.boolean(),pageId:Er.string().optional()})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,r,a;if(e.revisionId==="current"){if(!e.pageId)throw new p("pageId is required when restoring current revision","PAGE_ID_REQUIRED");let{data:i,error:o}=await m(()=>g.query.appPagesOnline.findFirst({where:Ga(Ce(n.appPagesOnline.id,e.pageId),Ce(n.appPagesOnline.app,t)),columns:{id:!0,blocks:!0}}));if(o)throw new p("Error fetching live page","FETCH_ERROR");if(!i)throw new p("Live page not found","PAGE_NOT_FOUND");r=i.id,a=i.blocks}else{let{data:i,error:o}=await m(()=>g.query.appPagesRevisions.findFirst({where:Ga(Ce(n.appPagesRevisions.uid,e.revisionId),Ce(n.appPagesRevisions.app,t)),columns:{id:!0,blocks:!0,type:!0}}));if(o)throw new p("Error fetching revision","FETCH_ERROR");if(!i)throw new p("Revision not found","REVISION_NOT_FOUND");r=i.id,a=i.blocks}if(!e.discardCurrent){let{data:i,error:o}=await m(()=>g.query.appPages.findFirst({where:Ga(Ce(n.appPages.id,r),Ce(n.appPages.app,t))}));if(o)throw new p("Error fetching current page","FETCH_ERROR");if(!i)throw new p("Current page not found","PAGE_NOT_FOUND");let l=i.blocks,c={id:r,blocks:l,type:"draft",createdAt:"now()",...el(i,["name","slug","pageType","lang","app","currentEditor","createdBy"])};await g.insert(n.appPagesRevisions).values(c)}return await g.update(n.appPages).set({blocks:a}).where(Ce(n.appPages.id,r)),{success:!0,pageId:r}}};import{z as Pr}from"zod";var wr=class extends y{getValidationSchema(){return Pr.object({name:Pr.string().min(1),permissions:Pr.array(Pr.string())})}async execute(e){var i,o,l,c;let{data:t,error:r}=await m(()=>g.insert(n.roles).values({name:e.name,permissions:e.permissions,isSystem:!1}).returning({id:n.roles.id,name:n.roles.name,permissions:n.roles.permissions,isSystem:n.roles.isSystem,createdAt:n.roles.createdAt}));if(r)throw new p("Error creating role","ERROR_CREATING_ROLE",500,r);let a=t==null?void 0:t[0];if(!a)throw new p("Role creation returned no data","ERROR_CREATING_ROLE",500);return{id:a.id,name:(i=a.name)!=null?i:"",permissions:(o=a.permissions)!=null?o:[],isSystem:(l=a.isSystem)!=null?l:!1,createdAt:(c=a.createdAt)!=null?c:""}}};import{eq as xi}from"drizzle-orm";import{z as Ci}from"zod";var Ir=class extends y{getValidationSchema(){return Ci.object({name:Ci.string().min(1)})}async execute(e){let{data:t,error:r}=await m(()=>g.select({isSystem:n.roles.isSystem}).from(n.roles).where(xi(n.roles.name,e.name)));if(r)throw new p("Error checking role","ERROR_CHECKING_ROLE",500,r);let a=t==null?void 0:t[0];if(!a)throw new p(`Role '${e.name}' not found`,"ROLE_NOT_FOUND",404);if(a.isSystem)throw new p(`Role '${e.name}' is a system role and cannot be deleted`,"ROLE_IS_SYSTEM",403);let{error:i}=await m(()=>g.delete(n.roles).where(xi(n.roles.name,e.name)));if(i)throw new p("Error deleting role","ERROR_DELETING_ROLE",500,i);return{deleted:!0}}};import{eq as tl}from"drizzle-orm";import{z as Ri}from"zod";var xr=class extends y{getValidationSchema(){return Ri.object({name:Ri.string().min(1)})}async execute(e){var i,o,l,c;let{data:t,error:r}=await m(()=>g.select({id:n.roles.id,name:n.roles.name,permissions:n.roles.permissions,isSystem:n.roles.isSystem,createdAt:n.roles.createdAt}).from(n.roles).where(tl(n.roles.name,e.name)));if(r)throw new p("Error fetching role","ERROR_FETCHING_ROLE",500,r);let a=t==null?void 0:t[0];return a?{id:a.id,name:(i=a.name)!=null?i:"",permissions:(o=a.permissions)!=null?o:[],isSystem:(l=a.isSystem)!=null?l:!1,createdAt:(c=a.createdAt)!=null?c:""}:null}};import{z as rl}from"zod";var Cr=class extends y{getValidationSchema(){return rl.object({})}async execute(){let{data:e,error:t}=await m(()=>g.select({id:n.roles.id,name:n.roles.name,permissions:n.roles.permissions,isSystem:n.roles.isSystem,createdAt:n.roles.createdAt}).from(n.roles));if(t)throw new p("Error fetching roles","ERROR_FETCHING_ROLES",500,t);return(e!=null?e:[]).map(r=>{var a,i,o,l;return{id:r.id,name:(a=r.name)!=null?a:"",permissions:(i=r.permissions)!=null?i:[],isSystem:(o=r.isSystem)!=null?o:!1,createdAt:(l=r.createdAt)!=null?l:""}})}};import{eq as al}from"drizzle-orm";import{z as Rr}from"zod";var Sr=class extends y{getValidationSchema(){return Rr.object({name:Rr.string().min(1),permissions:Rr.array(Rr.string())})}async execute(e){var i,o,l,c;let{data:t,error:r}=await m(()=>g.update(n.roles).set({permissions:e.permissions}).where(al(n.roles.name,e.name)).returning({id:n.roles.id,name:n.roles.name,permissions:n.roles.permissions,isSystem:n.roles.isSystem,createdAt:n.roles.createdAt}));if(r)throw new p("Error updating role","ERROR_UPDATING_ROLE",500,r);let a=t==null?void 0:t[0];if(!a)throw new p(`Role '${e.name}' not found`,"ROLE_NOT_FOUND",404);return{id:a.id,name:(i=a.name)!=null?i:"",permissions:(o=a.permissions)!=null?o:[],isSystem:(l=a.isSystem)!=null?l:!1,createdAt:(c=a.createdAt)!=null?c:""}}};import{and as nl,eq as Ba,inArray as il,isNull as ol}from"drizzle-orm";import{z as Si}from"zod";var _r=class extends y{getValidationSchema(){return Si.object({pageType:Si.string().min(1)})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t}=this.context,{pageType:r}=e,{data:a,error:i}=await m(()=>g.query.libraries.findFirst({where:Ba(n.libraries.app,t),columns:{id:!0}}));if(i)throw new p("Failed to fetch site library","GET_SITE_LIBRARY_FAILED",500,i);let{data:o,error:l}=await m(()=>g.select({id:n.libraries.id}).from(n.libraries).where(Ba(n.libraries.type,"shared")));if(l)throw new p("Failed to fetch shared libraries","GET_SHARED_LIBRARIES_FAILED",500,l);let c=[...a?[a.id]:[],...(o||[]).map(h=>h.id)];if(c.length===0)return[];let{data:d,error:u}=await m(()=>g.select({id:n.libraryTemplates.id,library:n.libraryTemplates.library,pageId:n.libraryTemplates.pageId,pageType:n.libraryTemplates.pageType,name:n.libraryTemplates.name,description:n.libraryTemplates.description,preview:n.libraryTemplates.preview,user:n.libraryTemplates.user,createdAt:n.libraryTemplates.createdAt}).from(n.libraryTemplates).where(nl(Ba(n.libraryTemplates.pageType,r),il(n.libraryTemplates.library,c),ol(n.libraryTemplates.deletedAt))));if(u)throw new p("Failed to fetch templates","GET_TEMPLATES_FAILED",500,u);return d||[]}};import{eq as sl}from"drizzle-orm";import{z as Re}from"zod";var Dr=class extends y{getValidationSchema(){return Re.object({id:Re.string().min(1),description:Re.string().optional(),name:Re.string().min(1),pageType:Re.string().min(1),previewImage:Re.string().optional(),previewImageUrl:Re.string().optional()})}async execute(e){var I;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{appId:t,userId:r}=this.context,{id:a,description:i,name:o,pageType:l,previewImage:c,previewImageUrl:d}=e,{data:u,error:h}=await m(()=>g.query.libraries.findFirst({where:sl(n.libraries.app,t),columns:{id:!0}}));if(h)throw new p("Failed to fetch site library","GET_SITE_LIBRARY_FAILED",500,h);if(!u)throw new p("Library not found for this app","GET_SITE_LIBRARY_FAILED");let f=d;if(c){let{getChaiAction:E}=await import("./actions-registery-SEJTZE5Q.js"),x=E("UPLOAD_TO_STORAGE");x==null||x.setContext(this.context);let C=`template-${Date.now()}.webp`,R=`${t}/templates`,S=await(x==null?void 0:x.execute({file:c,fileName:C,contentType:"image/webp",folder:R}));if(S!=null&&S.error)throw new p("Failed to upload preview image","UPLOAD_PREVIEW_FAILED",500,S.error);f=((I=S==null?void 0:S.data)==null?void 0:I.url)||d}let{data:T,error:A}=await m(()=>g.insert(n.libraryTemplates).values({library:u.id,user:r!=null?r:null,pageId:a,description:i!=null?i:null,name:o+" Template",pageType:l,preview:f!=null?f:null,createdBy:r!=null?r:null}).returning());if(A||!T||T.length===0)throw new p("Failed to mark page as template","UPDATE_FAILED",500,A);return T[0]}};import{eq as ll}from"drizzle-orm";import{z as _i}from"zod";var vr=class extends y{getValidationSchema(){return _i.object({id:_i.string().min(1)})}async execute(e){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{id:t}=e,{error:r}=await m(()=>{var a,i;return g.update(n.libraryTemplates).set({deletedAt:new Date().toISOString(),deletedBy:(i=(a=this.context)==null?void 0:a.userId)!=null?i:null}).where(ll(n.libraryTemplates.pageId,t))});if(r)throw new p("Failed to unmark page as template","DELETE_FAILED",500,r);return{success:!0}}};import{and as cl,eq as Fa}from"drizzle-orm";import{z as Di}from"zod";var Nr=class extends y{getValidationSchema(){return Di.object({id:Di.string().min(1,"Trash Record ID is required")})}async execute(e){var t;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");try{let{data:r,error:a}=await m(()=>g.select().from(n.appTrash).where(cl(Fa(n.appTrash.id,e.id),Fa(n.appTrash.app,this.context.appId))).limit(1));if(a||!r||r.length===0)throw w("TRASH_RECORD_NOT_FOUND","Trash record not found");let i=r[0],o={id:i.id,entityType:i.entityType,entityId:i.entityId||"",name:((t=i.metadata)==null?void 0:t.name)||"",metadata:i.metadata||{},deletedAt:i.deletedAt,deletedBy:i.deletedBy||"",app:i.app||""},l=Ie(o.entityType);if(!l)throw w("ENTITY_HANDLER_NOT_FOUND",`Handler for entity type '${o.entityType}' not found`);return await l.deletePermanently(o,this.context),await m(()=>g.delete(n.appTrash).where(Fa(n.appTrash.id,o.id))),!0}catch(r){return this.handleError(r),!1}}};import{and as pl,asc as dl,desc as gl,eq as vi,sql as Or}from"drizzle-orm";import{z as ye}from"zod";var ml=ye.string().uuid();function ul(){let s=n.appTrash.metadata;return Qr()==="sqlite"?Or`json_extract(${s}, '$.name')`:Or`${s}->>'name'`}var kr=class extends y{getValidationSchema(){return ye.object({page:ye.number().optional().default(1),limit:ye.number().optional().default(20),search:ye.string().optional(),entityType:ye.string().optional(),sortBy:ye.string().optional(),sortOrder:ye.enum(["asc","desc"]).optional()})}async execute(e){var T;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let{page:t=1,limit:r=20,search:a,entityType:i,sortBy:o,sortOrder:l="desc"}=e,c=(t-1)*r,d=ml.safeParse(this.context.appId);if(!d.success)return{items:[],total:0,page:t,pageSize:r};let u=[vi(n.appTrash.app,d.data)];i&&u.push(vi(n.appTrash.entityType,i));let h=ul();if(a&&a.trim()!==""){let A=a.trim();u.push(Or`lower(${h}) like '%' || lower(${A}) || '%'`)}let f=pl(...u);try{let{data:A,error:I}=await m(()=>g.select({count:Or`cast(count(${n.appTrash.id}) as integer)`}).from(n.appTrash).where(f));if(I)throw w("FETCH_TRASH_FAILED",I);let E=((T=A==null?void 0:A[0])==null?void 0:T.count)||0,{data:x,error:C}=await m(()=>g.select().from(n.appTrash).where(f).orderBy((()=>{let S=o==="name"?h:n.appTrash.deletedAt;return l==="asc"?dl(S):gl(S)})()).limit(r).offset(c));if(C)throw w("FETCH_TRASH_FAILED",C);return{items:(x||[]).map(S=>{var D,k,le;return{id:S.id,entityType:S.entityType,entityId:S.entityId||"",name:((D=S.metadata)==null?void 0:D.name)||"",metadata:S.metadata||{},deletedAt:S.deletedAt||((k=S.metadata)==null?void 0:k.deletedAt),deletedBy:S.deletedBy||((le=S.metadata)==null?void 0:le.deletedBy)||"",app:S.app||""}}),total:E,page:t,pageSize:r}}catch(A){this.handleError(A)}}};import{and as hl,eq as Ma}from"drizzle-orm";import{z as Ni}from"zod";var Lr=class extends y{getValidationSchema(){return Ni.object({id:Ni.string().min(1,"Trash Record ID is required")})}async execute(e){var t;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");try{let{data:r,error:a}=await m(()=>g.select().from(n.appTrash).where(hl(Ma(n.appTrash.id,e.id),Ma(n.appTrash.app,this.context.appId))).limit(1));if(a||!r||r.length===0)throw w("TRASH_RECORD_NOT_FOUND","Trash record not found");let i=r[0],o={id:i.id,entityType:i.entityType,entityId:i.entityId||"",name:((t=i.metadata)==null?void 0:t.name)||"",metadata:i.metadata||{},deletedAt:i.deletedAt,deletedBy:i.deletedBy||"",app:i.app||""},l=Ie(o.entityType);if(!l)throw w("ENTITY_HANDLER_NOT_FOUND",`Handler for entity type '${o.entityType}' not found`);let c=!1,d;if(l.hasRestoreConflict?await l.hasRestoreConflict(o,this.context):!1){if(!l.resolveRestoreConflict)throw w("RESTORE_CONFLICT","Restore conflict detected but no resolver available");let f=await l.resolveRestoreConflict(o,this.context);c=f.resolved,d=f.newSlug}await l.restore(o,this.context);let{error:h}=await m(()=>g.delete(n.appTrash).where(Ma(n.appTrash.id,o.id)));if(h)throw w("RESTORE_FAILED",h);return{success:!0,resolvedConflict:c,newSlug:d,...o.entityType==="page"?{tags:ae(o.entityId,{slugs:d?{new:d}:void 0})}:{}}}catch(r){this.handleError(r)}}};import{z as Ur}from"zod";var Gr=class extends y{getValidationSchema(){return Ur.object({entityType:Ur.string().min(1,"Entity Type is required"),ids:Ur.array(Ur.string().min(1))})}async execute(e){var a;if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET");let t=Ie(e.entityType);if(!t)throw new p(`Trashable entity '${e.entityType}' not found`,"ENTITY_NOT_FOUND");let r=[];for(let i of e.ids)try{let o=await t.moveToTrash(i,this.context),{data:l,error:c}=await m(()=>g.insert(n.appTrash).values(o).returning());if(c||!l||l.length===0)throw w("TRASH_FAILED",c||"Failed to create trash record");let d=l[0];r.push({id:d.id,entityType:d.entityType,entityId:d.entityId||"",name:((a=d.metadata)==null?void 0:a.name)||"",metadata:d.metadata||{},deletedAt:d.deletedAt,deletedBy:d.deletedBy||"",app:d.app||"",tags:o.tags||[]})}catch(o){e.ids.length===1&&this.handleError(o),console.error(`Failed to trash entity ${i}:`,o)}return r}};import{z as El}from"zod";var $a={owner:{permissions:["*"]},admin:{permissions:["*"]},superadmin:{permissions:["*"]},editor:{permissions:["app:read","pages:*","partials:*","revisions:*","assets:*","library:*","trash:*","ai:*"]},designer:{permissions:["app:read","pages:*","partials:*","revisions:read","assets:*","library:*","theme:edit","app:publish_theme","ai:*"]},viewer:{permissions:["app:read","pages:read","partials:read","revisions:read","assets:read","library:read"]},user:{permissions:["app:read","pages:read"]}};async function Oi(){let s=ki();return s?"source"in s&&s.source==="custom"?fl():s:$a}async function fl(){let{data:s,error:e}=await m(()=>g.select({name:n.roles.name,permissions:n.roles.permissions}).from(n.roles));return e||!s?{}:s.length===0?$a:s.reduce((t,r)=>{var a;return r.name&&(t[r.name]={permissions:(a=r.permissions)!=null?a:[]}),t},{})}var Mr=Object.keys(b),Br="*";function Fr(s){let e=s.indexOf(":");return e===-1?s:s.slice(0,e)}function xT(s,e){return e?!s||s.length===0?!1:s.includes(Br)||s.includes(e)?!0:s.includes(`${Fr(e)}:*`):!0}function Ha(s,e=Mr){if(!s)return[];let t=new Set;for(let[r,a]of Object.entries(s))if(a===!0)if(r===Br)e.forEach(i=>t.add(i));else if(r.endsWith(":*")){let i=r.slice(0,-2);e.filter(o=>Fr(o)===i).forEach(o=>t.add(o))}else t.add(r);for(let[r,a]of Object.entries(s))if(a===!1)if(r===Br)t.clear();else if(r.endsWith(":*")){let i=r.slice(0,-2);[...t].filter(o=>Fr(o)===i).forEach(o=>t.delete(o))}else t.delete(r);return[...t]}function Li(s,e,t=Mr){let r=o=>{let l=new Set;for(let c of o)if(c===Br)t.forEach(d=>l.add(d));else if(c.endsWith(":*")){let d=c.slice(0,-2);t.filter(u=>Fr(u)===d).forEach(u=>l.add(u))}else l.add(c);return l},a=r(s),i=r(e);return[...a].filter(o=>i.has(o))}function yl(s){return s?Array.isArray(s)?s.reduce((e,t)=>(e[t]=!0,e),{}):s:null}function Tl(s,e){let t=new Set;for(let r of s)if(r==="*")e.forEach(a=>t.add(a));else if(r.endsWith(":*")){let a=r.slice(0,-2);e.filter(i=>i.startsWith(`${a}:`)).forEach(i=>t.add(i))}else t.add(r);return[...t]}function Ui({role:s,roleMap:e,userOverride:t,catalog:r=Mr}){var l,c;let a=(c=(l=e==null?void 0:e[s])==null?void 0:l.permissions)!=null?c:[],i=new Set(Tl(a,r)),o=yl(t);if(o)for(let[d,u]of Object.entries(o))u===!0?Ha({[d]:!0},r).forEach(h=>i.add(h)):u===!1&&Ha({[d]:!0},r).forEach(h=>i.delete(h));return[...i]}import{and as Al,eq as Va}from"drizzle-orm";async function Gi(s){let{appId:e,userId:t}=s;if(!t)throw console.error(`[getUserAccess] Failed: No userId in context for appId: ${e}`),new p("User ID not found in context","UNAUTHORIZED",401);console.log(`[getUserAccess] Querying active appUsers for appId: "${e}", userId: "${t}"`);let{data:r,error:a}=await m(()=>g.select().from(n.appUsers).where(Al(Va(n.appUsers.app,e),Va(n.appUsers.user,t),Va(n.appUsers.status,"active"))));if(a)throw console.error("[getUserAccess] Database query failed:",a),new p("Error checking user access","ERROR_CHECKING_USER_ACCESS",500,a);if(!r||r.length===0)throw console.warn(`[getUserAccess] Unauthorized: No active record in app_users for appId: "${e}", userId: "${t}"`),new p("User does not have access to this app","UNAUTHORIZED",401);return console.log("[getUserAccess] Found active user access record:",JSON.stringify(r[0])),r[0]}var $r=class extends y{getValidationSchema(){return El.any()}async execute(){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET",500);if(this.context.userAccess)return{access:!0,role:this.context.userAccess.role,permissions:this.context.userAccess.permissions};let e=await Gi(this.context),t=e.role||"user",r=await Oi(),a=Ui({role:t,roleMap:r,userOverride:e.permissions});return this.context.delegatedScopes&&(a=Li(a,this.context.delegatedScopes)),{access:!0,role:t,permissions:a}}};import{and as bl,eq as Bi}from"drizzle-orm";import{each as Pl,isEmpty as wl}from"lodash-es";import{z as Il}from"zod";var Hr=class extends y{getValidationSchema(){return Il.undefined()}async execute(){if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let{appId:e}=this.context,{data:t,error:r}=await m(()=>g.select({id:n.appPages.id,designTokens:n.appPages.designTokens,name:n.appPages.name,slug:n.appPages.slug,links:n.appPages.links,partialBlocks:n.appPages.partialBlocks}).from(n.appPages).where(bl(Bi(n.appPages.lang,""),Bi(n.appPages.app,e))));if(r)throw w("FETCH_SITE_DATA_FAILED",r);let a={};return Pl(t,i=>{var o,l;a[i.id]={name:i.name,isPartial:wl(i.slug),partialBlocks:i.partialBlocks?(o=i.partialBlocks)==null?void 0:o.split("|").filter(Boolean):[],links:i.links?i.links.split("|").filter(Boolean):[],designTokens:(l=i.designTokens)!=null?l:{}}}),a}};import{z as Sl}from"zod";import{createHash as xl}from"crypto";import{eq as Cl}from"drizzle-orm";import{first as Rl}from"lodash-es";import{z as Fi}from"zod";var je=class extends y{getValidationSchema(){return Fi.object({draft:Fi.boolean()})}async execute(e){var d;if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let{appId:t}=this.context,{draft:r}=e,a=r?n.apps:n.appsOnline,{data:i,error:o}=await m(()=>g.select({theme:a.theme,fallbackLang:a.fallbackLang,languages:a.languages,settings:a.settings,designTokens:a.designTokens,changes:a.changes,consentConfig:a.consentConfig,configData:a.configData}).from(a).where(Cl(a.id,t)).limit(1));if(o)throw w("ERROR_PROJECT_CONFIG",o);if(!i||i.length===0)throw w("PROJECT_NOT_FOUND",new Error("Project not found"));let l=Rl(i),c=(d=l==null?void 0:l.changes)!=null?d:[];return{...this.getDefaultSettings(),...l,fallbackLang:(l==null?void 0:l.fallbackLang)||this.getDefaultSettings().fallbackLang,languages:(l==null?void 0:l.languages)||this.getDefaultSettings().languages,theme:(l==null?void 0:l.theme)||this.getDefaultSettings().theme,appKey:this.generateDeterministicUuid(t),appChanges:c}}getDefaultSettings(){return{fallbackLang:"en",languages:[],theme:{colors:{card:["#FFFFFF","#09090B"],ring:["#2563EB","#3B82F6"],input:["#E4E4E7","#27272A"],muted:["#F4F4F5","#27272A"],accent:["#F4F4F5","#27272A"],border:["#E4E4E7","#27272A"],popover:["#FFFFFF","#09090B"],primary:["#2563EB","#3B82F6"],secondary:["#F4F4F5","#27272A"],background:["#FFFFFF","#09090B"],foreground:["#09090B","#FFFFFF"],destructive:["#EF4444","#7F1D1D"],"card-foreground":["#09090B","#FFFFFF"],"muted-foreground":["#71717A","#A1A1AA"],"accent-foreground":["#09090B","#FFFFFF"],"popover-foreground":["#09090B","#FFFFFF"],"primary-foreground":["#FFFFFF","#FFFFFF"],"secondary-foreground":["#09090B","#FFFFFF"],"destructive-foreground":["#FFFFFF","#FFFFFF"]},fontFamily:{body:"Roboto",heading:"Poppins"},borderRadius:"30px"},settings:{},designTokens:{},consentConfig:{},configData:{}}}generateDeterministicUuid(e){let t=xl("sha256").update(e).digest("hex");return[t.substring(0,8),t.substring(8,12),"4"+t.substring(13,16),(parseInt(t.substring(16,17),16)&3|8).toString(16)+t.substring(17,20),t.substring(20,32)].join("-")}};var Vr=class extends y{getValidationSchema(){return Sl.object({}).optional().default({})}async execute(){let e=new je,t=new qe,r=new Ve,a=new Be,i=new Ge;this.context&&(e.setContext(this.context),t.setContext(this.context),r.setContext(this.context),a.setContext(this.context),i.setContext(this.context));let[o,l,c,d,u]=await Promise.all([e.execute({draft:!0}),t.execute({lang:""}),r.execute(),a.execute(),i.execute()]);return{websiteSettings:o,websitePages:l,pageTypes:c,libraries:d,collections:u}}};import{and as qr,eq as j,inArray as _l,like as Mi}from"drizzle-orm";import{flattenDeep as $i,isEmpty as jr,uniq as zr}from"lodash-es";import{z as Wr}from"zod";var Yr=class extends y{constructor(){super(...arguments);this.appId="";this.revisionsEnabled=!1}getValidationSchema(){return Wr.object({ids:Wr.array(Wr.string()).optional(),revisions:Wr.boolean().optional()})}async execute(t){var r,a;this.validateContext(),this.appId=this.context.appId,this.revisionsEnabled=(r=t.revisions)!=null?r:!1;try{let i=(a=t.ids)!=null?a:[];if(i.length===0)throw new p("IDS_REQUIRED","At least one page ID or THEME must be provided");let o=await Promise.all(i.map(d=>d==="THEME"?this.publishTheme():d==="DESIGN_TOKENS"?this.publishDesignToken():this.publishPage(d)));await this.clearChanges(i);let l=zr($i(o.map(d=>d.tags))),c=zr($i(o.map(d=>d.paths)));return{tags:l,paths:c}}catch(i){return this.handleExecutionError(i)}}validateContext(){if(!this.context)throw new p("Context not set","CONTEXT_NOT_SET")}async publishTheme(){let t=await this.cloneApp(),{error:r}=await m(()=>g.delete(n.appsOnline).where(j(n.appsOnline.id,this.appId)));if(r)throw new p("Error deleting online theme","ERROR_PUBLISHING_THEME",500,r);let{error:a}=await m(()=>g.insert(n.appsOnline).values({...t,changes:null}));if(a)throw new p("Error inserting online theme","ERROR_PUBLISHING_THEME",500,a);return await this.removeFromChangesArray("THEME","ERROR_PUBLISHING_THEME"),{tags:[`website-settings-${this.appId}`],paths:[]}}async publishDesignToken(){let t=await this.cloneApp(),{error:r}=await m(()=>g.delete(n.appsOnline).where(j(n.appsOnline.id,this.appId)));if(r)throw new p("Error deleting online app","ERROR_PUBLISHING_DESIGN_TOKEN",500,r);let{error:a}=await m(()=>g.insert(n.appsOnline).values({...t,changes:null}));if(a)throw new p("Error inserting online app","ERROR_PUBLISHING_DESIGN_TOKEN",500,a);return await this.removeFromChangesArray("DESIGN_TOKENS","ERROR_PUBLISHING_DESIGN_TOKEN"),{tags:[`website-settings-${this.appId}`],paths:[]}}async removeFromChangesArray(t,r){var d,u;let{data:a,error:i}=await m(()=>g.select({changes:n.apps.changes}).from(n.apps).where(j(n.apps.id,this.appId)));if(i)throw new p("Error fetching changes",r,500,i);let l=((u=(d=a==null?void 0:a[0])==null?void 0:d.changes)!=null?u:[]).filter(h=>h!==t),{error:c}=await m(()=>g.update(n.apps).set({changes:l.length>0?l:null}).where(j(n.apps.id,this.appId)));if(c)throw new p("Error updating changes",r,500,c)}async cloneApp(){let{data:t,error:r}=await m(()=>g.query.apps.findFirst({where:j(n.apps.id,this.appId)}));if(r||!t)throw new p("Site not found","SITE_NOT_FOUND",404,r);return t}async clearChanges(t){let r=t.filter(i=>i!=="THEME"&&i!=="DESIGN_TOKENS");if(r.length===0)return;let{error:a}=await m(()=>g.update(n.appPages).set({changes:null,online:!0}).where(qr(_l(n.appPages.id,r),j(n.appPages.app,this.appId))));if(a)throw new p("Error clearing changes","ERROR_CLEARING_CHANGES",500,a)}async getLinkingPages(t){let{data:r}=await m(()=>g.query.appPagesOnline.findMany({where:qr(j(n.appPagesOnline.app,this.appId),Mi(n.appPagesOnline.links,`%${t}%`)),columns:{id:!0,slug:!0}})),a=[],i=[];return(r!=null?r:[]).forEach(o=>{a.push(`page-${o.id}`),jr(o.slug)||i.push(o.slug)}),{tags:a,paths:i}}async getPartialBlockUsage(t){let{data:r}=await m(()=>g.query.appPagesOnline.findMany({where:qr(j(n.appPagesOnline.app,this.appId),Mi(n.appPagesOnline.partialBlocks,`%${t}%`)),columns:{id:!0,slug:!0}})),a=[],i=[];return(r!=null?r:[]).forEach(o=>{a.push(`page-${o.id}`),jr(o.slug)||i.push(o.slug)}),{tags:a,paths:i}}async publishPage(t){var l;let r=await this.clonePage(t);await this.addOnlinePage(r);let a=(l=r.primaryPage)!=null?l:r.id,i=[`page-${a}`,`breadcrumb-${a}`],o=[];if(jr(r.slug)){let c=await this.getPartialBlockUsage(a);i.push(...c.tags),o.push(...c.paths)}else{o.push(`${r.slug}`),i.push(Z(r.slug));let c=await this.getLinkingPages(a);i.push(...c.tags),o.push(...c.paths)}return{tags:zr(i),paths:zr(o)}}async createRevision(t){if(!this.revisionsEnabled)return!1;let{data:r,error:a}=await m(()=>g.query.appPagesOnline.findFirst({where:j(n.appPagesOnline.id,t)}));if(a||!r||!jr(r.primaryPage))return!1;let{error:i}=await m(()=>g.insert(n.appPagesRevisions).values({...r,type:"published",uid:void 0}));if(i)throw new p("Error creating revision","ERROR_CREATING_REVISION",500,i);return!0}async addOnlinePage(t){await this.createRevision(t.id);let{error:r}=await m(()=>g.delete(n.appPagesOnline).where(j(n.appPagesOnline.id,t.id)));if(r)throw new p("Error deleting online page","ERROR_PUBLISHING_PAGE",500,r);let{changes:a,createdAt:i,...o}=t,{data:l,error:c}=await m(()=>{var u;return g.insert(n.appPagesOnline).values({...o,currentEditor:(u=this.context)==null?void 0:u.userId}).returning()});if(c||!l||l.length===0)throw new p("Error publishing page","ERROR_PUBLISHING_PAGE",500,c);let{error:d}=await m(()=>g.update(n.appPages).set({changes:null}).where(j(n.appPages.id,t.id)));if(d)throw new p("Error clearing page changes","ERROR_PUBLISHING_PAGE",500,d);return l[0]}async clonePage(t){let{data:r,error:a}=await m(()=>g.query.appPages.findFirst({where:qr(j(n.appPages.id,t),j(n.appPages.app,this.appId))}));if(a||!r)throw new p("Page not found","PAGE_NOT_FOUND",404,a);return r}handleExecutionError(t){throw t instanceof p?t:new p(`Failed to publish changes: ${t instanceof Error?t.message:"Unknown error"}`,"PUBLISH_CHANGES_FAILED")}};import{eq as Hi}from"drizzle-orm";import{pick as Dl}from"lodash-es";import{z as Vi}from"zod";var Kr=class extends y{getValidationSchema(){return Vi.object({settings:Vi.any()})}async execute(e){var f;if(!this.context)throw w("CONTEXT_NOT_SET",new Error("CONTEXT_NOT_SET"));let{appId:t}=this.context,r=Dl(e.settings,["theme","designTokens"]),{data:a,error:i}=await m(()=>g.select({changes:n.apps.changes}).from(n.apps).where(Hi(n.apps.id,t)));if(i)throw w("ERROR_UPDATE_WEBSITE_FIELDS",i);let o=(f=a[0].changes)!=null?f:[],l={theme:"THEME",designTokens:"DESIGN_TOKENS"},c=Object.keys(r).map(T=>l[T]).filter(Boolean),d=[...new Set([...o,...c])],u={...r,changes:d},{error:h}=await m(()=>g.update(n.apps).set(u).where(Hi(n.apps.id,t)));if(h)throw w("ERROR_UPDATE_WEBSITE_FIELDS",h);return{success:!0}}};function P(s,e){return s.requiredPermission=e,s}var Ft={AI_EDIT_BLOCK:P(new dt,b["ai:use"]),AI_EDIT_PAGE:P(new mt,b["ai:use"]),AI_GENERATE_IMAGE:P(new ut,b["ai:generate_image"]),AI_EDIT_LANG_PAGE:P(new gt,b["ai:use"]),AI_GENERATE_SEO_FIELD:P(new yt,b["ai:use"]),AI_ENHANCE_CONTEXT:P(new ht,b["ai:use"]),AI_GENERATE_THEME:P(new Tt,b["ai:generate_theme"]),AI_SAVE_CONTEXT:P(new wt,b["ai:use"]),AI_GET_CONTEXT:P(new Et,b["ai:read"]),AI_GET_CREDITS:P(new bt,b["ai:read"]),AI_GET_ADDONS:P(new At,b["ai:read"]),AI_GENERATE_IMAGE_DESCRIPTION:P(new ft,b["ai:use"]),CHECK_USER_ACCESS:new $r,CREATE_PAGE:P(new Kt,b["pages:create"]),DELETE_PAGE:P(new me,b["pages:delete"]),DUPLICATE_PAGE:P(new Jt,b["pages:create"]),UPDATE_PAGE:P(new Ue,b["pages:update"]),UPDATE_PAGE_METADATA:P(new mr,b["pages:update"]),PUBLISH_CHANGES:P(new Yr,b["pages:publish"]),TAKE_OFFLINE:P(new dr,b["pages:unpublish"]),ACQUIRE_PAGE_LOCK:P(new Yt,b["pages:update"]),RELEASE_PAGE_LOCK:P(new lr,b["pages:update"]),GET_WEBSITE_PAGES:P(new qe,b["pages:read"]),GET_MENU_PAGES:P(new or,b["pages:read"]),GET_DRAFT_PAGE:P(new Me,b["pages:read"]),GET_LANGUAGE_PAGES:P(new $e,b["pages:read"]),GET_DYNAMIC_PAGES:P(new nr,b["pages:read"]),GET_PAGE_ALL_DATA:P(new sr,b["pages:read"]),GET_BUILDER_PAGE_DATA:P(new Fe,b["pages:read"]),GET_CHANGES:P(new tr,b["pages:read"]),GET_COMPARE_DATA:P(new rr,b["pages:read"]),SEARCH_PAGES:P(new pr,b["pages:read"]),GET_PAGE_TYPES:P(new Ve,b["pages:read"]),SEARCH_PAGE_TYPE_ITEMS:P(new cr,b["pages:read"]),GET_PAGE_REVISIONS:P(new fr,b["revisions:read"]),GET_REVISION_PAGE:P(new Ar,b["revisions:read"]),DELETE_PAGE_REVISION:P(new ur,b["revisions:delete"]),RESTORE_PAGE_REVISION:P(new br,b["revisions:restore"]),GET_WEBSITE_DATA:P(new Vr,b["app:read"]),GET_WEBSITE_DRAFT_SETTINGS:P(new je,b["app:read"]),GET_SITE_GLOBAL_DATA:P(new He,b["app:read"]),GET_SITE_WIDE_USAGE:P(new Hr,b["app:read"]),GET_COLLECTIONS:P(new Ge,b["app:read"]),UPDATE_WEBSITE_FIELDS:P(new Kr,b["app:update"]),GET_LIBRARIES:P(new Be,b["library:read"]),GET_LIBRARY_GROUPS:P(new Vt,b["library:read"]),GET_LIBRARY_ITEM:P(new jt,b["library:read"]),GET_LIBRARY_ITEMS:P(new zt,b["library:read"]),GET_TEMPLATES_BY_TYPE:P(new _r,b["library:read"]),UPSERT_LIBRARY_ITEM:P(new Wt,b["library:update"]),MARK_AS_TEMPLATE:P(new Dr,b["library:update"]),UNMARK_AS_TEMPLATE:P(new vr,b["library:update"]),DELETE_LIBRARY_ITEM:P(new qt,b["library:delete"]),GET_ASSETS:P(new _t,b["assets:read"]),GET_ASSET:P(new Rt,b["assets:read"]),SEARCH_IMAGES:P(new Dt,b["assets:read"]),CREATE_ASSET:P(new It,b["assets:create"]),DOWNLOAD_SEARCH_IMAGE:P(new Ct,b["assets:create"]),UPDATE_ASSET:P(new vt,b["assets:update"]),DELETE_ASSET:P(new xt,b["assets:delete"]),TRASH_ENTITY:P(new Gr,b["pages:delete"]),GET_TRASHED_ITEMS:P(new kr,b["trash:read"]),RESTORE_TRASHED_ITEM:P(new Lr,b["trash:restore"]),DELETE_PERMANENTLY:P(new Nr,b["trash:delete_permanently"]),GET_ROLES:P(new Cr,b["roles:read"]),GET_ROLE:P(new xr,b["roles:read"]),CREATE_ROLE:P(new wr,b["roles:create"]),UPDATE_ROLE:P(new Sr,b["roles:update"]),DELETE_ROLE:P(new Ir,b["roles:delete"]),GET_BLOCK_ASYNC_PROPS:new Ht};var vl={drizzle:null,schema:rn},Y={debugLevel:0,globalDataProvider:Ea,pageTypes:ya,collections:[],blockDataProviders:{},trash:Aa,actions:Ft,builderActions:Ft,extraPermissions:[],roles:void 0,ai:Le,db:vl};var O=Y;function ps(s){O=s}function ds(){return O}function Mt(){return O.pageTypes}function he(s){return O.pageTypes.find(e=>e.key===s)}function Xe(s){let e=he(s);return e?ie(e):void 0}function gs(){return Mt().map(ie)}function Pa(){return O.collections}function wa(s){return O.collections.find(e=>e.id===s)}function ms(){return O.trash}function Ie(s){return O.trash.find(e=>e.key===s)}function Mn(){return O.globalDataProvider}async function Ia(s){var e;try{return(e=await Mn()(s))!=null?e:{}}catch(t){return console.error(t),{}}}function ma(){return O.blockDataProviders}function ua(s){return O.blockDataProviders[s]}function ki(){return O.roles}function Qe(){return O.ai}function $n(){return O.actions}function Hn(s){return O.actions[s]}function us(){return $n()}function hs(s){return Hn(s)}function Vn(s){let e={...O.actions,...s};O={...O,actions:e,builderActions:e}}function fs(s){O={...O,ai:s}}function ys(s){Vn(s)}function Ts(s){O={...O,trash:s}}function As(s){O={...O,blockDataProviders:{...O.blockDataProviders,...s}}}function tb(s={}){Xr(),O={...Y,pageTypes:[],collections:[],trash:[],...s}}function ie(s){var e;return{...s,hasSlug:s.partial?!1:(e=s.hasSlug)!=null?e:!0}}export{p as a,y as b,pc as c,dc as d,U as e,ga as f,K as g,pg as h,dg as i,gg as j,mg as k,ug as l,hg as m,kt as n,Cg as o,Rg as p,sm as q,Mr as r,xT as s,Ha as t,Li as u,Y as v,ps as w,ds as x,Mt as y,he as z,Xe as A,gs as B,Pa as C,wa as D,ms as E,Ie as F,Mn as G,Ia as H,ma as I,ua as J,ki as K,Qe as L,$n as M,Hn as N,us as O,hs as P,Vn as Q,fs as R,ys as S,Ts as T,As as U,tb as V,ie as W,Zo as X};
|